Example #1
0
static void do_load(int fd, struct psf_header *psfhdr, size_t len)
{
	int unit;
	int fontsize;
	int hastable;
	unsigned head0, head = head;

	/* test for psf first */
	if (len >= sizeof(struct psf_header) && PSF_MAGIC_OK(psfhdr)) {
		if (psfhdr->mode > PSF_MAXMODE)
			bb_error_msg_and_die("unsupported psf file mode");
		fontsize = ((psfhdr->mode & PSF_MODE512) ? 512 : 256);
#if !defined(PIO_FONTX) || defined(__sparc__)
		if (fontsize != 256)
			bb_error_msg_and_die("only fontsize 256 supported");
#endif
		hastable = (psfhdr->mode & PSF_MODEHASTAB);
		unit = psfhdr->charsize;
		head0 = sizeof(struct psf_header);

		head = head0 + fontsize * unit;
		if (head > len || (!hastable && head != len))
			bb_error_msg_and_die("input file: bad length");
	} else {
		/* file with three code pages? */
		if (len == 9780) {
			head0 = 40;
			unit = 16;
		} else {
			/* bare font */
			if (len & 0377)
				bb_error_msg_and_die("input file: bad length");
			head0 = 0;
			unit = len / 256;
		}
		fontsize = 256;
		hastable = 0;
	}

	do_loadfont(fd, (unsigned char *)psfhdr + head0, unit, fontsize);
	if (hastable)
		do_loadtable(fd, (unsigned char *)psfhdr + head, len - head, fontsize);
}
static void loadnewfont(int fd)
{
	int unit;
	char inbuf[32768];			/* primitive */
	unsigned int inputlth, offset;

	/*
	 * We used to look at the length of the input file
	 * with stat(); now that we accept compressed files,
	 * just read the entire file.
	 */
	inputlth = fread(inbuf, 1, sizeof(inbuf), stdin);
	if (ferror(stdin))
		perror_msg_and_die("Error reading input font");
	/* use malloc/realloc in case of giant files;
	   maybe these do not occur: 16kB for the font,
	   and 16kB for the map leaves 32 unicode values
	   for each font position */
	if (!feof(stdin))
		perror_msg_and_die("Font too large");

	/* test for psf first */
	{
		struct psf_header psfhdr;
		int fontsize;
		int hastable;
		unsigned int head0, head;

		if (inputlth < sizeof(struct psf_header))
			goto no_psf;

		psfhdr = *(struct psf_header *) &inbuf[0];

		if (!PSF_MAGIC_OK(psfhdr))
			goto no_psf;

		if (psfhdr.mode > PSF_MAXMODE)
			error_msg_and_die("Unsupported psf file mode");
		fontsize = ((psfhdr.mode & PSF_MODE512) ? 512 : 256);
#if !defined( PIO_FONTX ) || defined( __sparc__ )
		if (fontsize != 256)
			error_msg_and_die("Only fontsize 256 supported");
#endif
		hastable = (psfhdr.mode & PSF_MODEHASTAB);
		unit = psfhdr.charsize;
		head0 = sizeof(struct psf_header);

		head = head0 + fontsize * unit;
		if (head > inputlth || (!hastable && head != inputlth))
			error_msg_and_die("Input file: bad length");
		do_loadfont(fd, inbuf + head0, unit, fontsize);
		if (hastable)
			do_loadtable(fd, inbuf + head, inputlth - head, fontsize);
		return;
	}
  no_psf:

	/* file with three code pages? */
	if (inputlth == 9780) {
		offset = 40;
		unit = 16;
	} else {
		/* bare font */
		if (inputlth & 0377)
			error_msg_and_die("Bad input file size");
		offset = 0;
		unit = inputlth / 256;
	}
	do_loadfont(fd, inbuf + offset, unit, 256);
}
Example #3
0
static void do_load(int fd, unsigned char *buffer, size_t len)
{
	int height;
	int width = 8;
	int charsize;
	int fontsize = 256;
	int has_table = 0;
	unsigned char *font = buffer;
	unsigned char *table;

	if (len >= sizeof(struct psf1_header) && PSF1_MAGIC_OK(psf1h(buffer))) {
		if (psf1h(buffer)->mode > PSF1_MAXMODE)
			bb_error_msg_and_die("unsupported psf file mode");
		if (psf1h(buffer)->mode & PSF1_MODE512)
			fontsize = 512;
		if (psf1h(buffer)->mode & PSF1_MODEHASTAB)
			has_table = 1;
		height = charsize = psf1h(buffer)->charsize;
		font += sizeof(struct psf1_header);
	} else
#if ENABLE_FEATURE_LOADFONT_PSF2
	if (len >= sizeof(struct psf2_header) && PSF2_MAGIC_OK(psf2h(buffer))) {
		if (psf2h(buffer)->version > PSF2_MAXVERSION)
			bb_error_msg_and_die("unsupported psf file version");
		fontsize = psf2h(buffer)->length;
		if (psf2h(buffer)->flags & PSF2_HAS_UNICODE_TABLE)
			has_table = 2;
		charsize = psf2h(buffer)->charsize;
		height = psf2h(buffer)->height;
		width = psf2h(buffer)->width;
		font += psf2h(buffer)->headersize;
	} else
#endif
#if ENABLE_FEATURE_LOADFONT_RAW
	if (len == 9780) {	/* file with three code pages? */
		charsize = height = 16;
		font += 40;
	} else if ((len & 0377) == 0) {		/* bare font */
		charsize = height = len / 256;
	} else
#endif
	{
		bb_error_msg_and_die("input file: bad length or unsupported font type");
	}

#if !defined(PIO_FONTX) || defined(__sparc__)
	if (fontsize != 256)
		bb_error_msg_and_die("only fontsize 256 supported");
#endif

	table = font + fontsize * charsize;
	buffer += len;

	if (table > buffer || (!has_table && table != buffer))
		bb_error_msg_and_die("input file: bad length");

	do_loadfont(fd, font, height, width, charsize, fontsize);

	if (has_table)
		do_loadtable(fd, table, buffer - table, fontsize, has_table - 1);
}
Example #4
0
static void
loadnewfont(int fd, char *ifil, int iunit, int hwunit, int no_m, int no_u)
{
	lkfile_t fp;
	char defname[20];
	int height, width, bytewidth, def = 0;
	char *inbuf, *fontbuf;
	int inputlth, fontbuflth, fontsize, offset;
	struct unicode_list *uclistheads;

	if (!*ifil) {
		/* try to find some default file */

		def = 1;		/* maybe also load default unimap */

		if (iunit < 0 || iunit > 32)
			iunit = 0;
		if (iunit == 0) {
			if (findfont(ifil = "default", &fp) &&
			    findfont(ifil = "default8x16", &fp) &&
			    findfont(ifil = "default8x14", &fp) &&
			    findfont(ifil = "default8x8", &fp)) {
				fprintf(stderr, _("Cannot find default font\n"));
				exit(EX_NOINPUT);
			}
		} else {
			sprintf(defname, "default8x%d", iunit);
			if (findfont(ifil = defname, &fp) &&
			    findfont(ifil = "default", &fp)) {
				fprintf(stderr, _("Cannot find %s font\n"), ifil);
				exit(EX_NOINPUT);
			}
		}
	} else {
		if (findfont(ifil, &fp)) {
			fprintf(stderr, _("Cannot open font file %s\n"), ifil);
			exit(EX_NOINPUT);
		}
	}

	if (verbose > 1)
		printf(_("Reading font file %s\n"), ifil);

	inbuf = fontbuf = NULL;
	inputlth = fontbuflth = fontsize = 0;
	width = 8;
	uclistheads = NULL;
	if(readpsffont(fp.fd, &inbuf, &inputlth, &fontbuf, &fontbuflth,
		       &width, &fontsize, 0,
		       no_u ? NULL : &uclistheads) == 0) {
		lk_fpclose(&fp);
		/* we've got a psf font */
		bytewidth = (width+7) / 8;
		height = fontbuflth / (bytewidth * fontsize);

		do_loadfont(fd, fontbuf, width, height, hwunit,
			    fontsize, fp.pathname);
		if (uclistheads && !no_u)
			do_loadtable(fd, uclistheads, fontsize);
#if 1
		if (!uclistheads && !no_u && def)
			loadunicodemap(fd, "def.uni");
#endif
		return;
	}
	lk_fpclose(&fp);		// avoid zombies, [email protected] (#88501)

	/* instructions to combine fonts? */
	{ char *combineheader = "# combine partial fonts\n";
	  int chlth = strlen(combineheader);
	  char *p, *q;
	  if (inputlth >= chlth && !strncmp(inbuf, combineheader, chlth)) {
		  char *ifiles[MAXIFILES];
		  int ifilct = 0;
		  q = inbuf + chlth;
		  while(q < inbuf + inputlth) {
			  p = q;
			  while (q < inbuf+inputlth && *q != '\n')
				  q++;
			  if (q == inbuf+inputlth) {
				  fprintf(stderr,
					  _("No final newline in combine file\n"));
				  exit(EX_DATAERR);
			  }
			  *q++ = 0;
			  if (ifilct == MAXIFILES) {
				  fprintf(stderr,
					  _("Too many files to combine\n"));
				  exit(EX_DATAERR);
			  }
			  ifiles[ifilct++] = p;
		  }
		  /* recursive call */
		  loadnewfonts(fd, ifiles, ifilct, iunit, hwunit, no_m, no_u);
		  return;
	  }
	}

	/* file with three code pages? */
	if (inputlth == 9780) {
		offset = position_codepage(iunit);
		height = iunit;
		fontsize = 256;
		width = 8;
	} else if (inputlth == 32768) {
		/* restorefont -w writes a SVGA font to file
		   restorefont -r restores it
		   These fonts have size 32768, for two 512-char fonts.
		   In fact, when BROKEN_GRAPHICS_PROGRAMS is defined,
		   and it always is, there is no default font that is saved,
		   so probably the second half is always garbage. */
		fprintf(stderr, _("Hmm - a font from restorefont? "
				  "Using the first half.\n"));
		inputlth = 16384; 	/* ignore rest */
		fontsize = 512;
		offset = 0;
		width = 8;
		height = 32;
		if (!hwunit)
			hwunit = 16;
	} else {
		int rem = (inputlth % 256);
		if (rem == 0 || rem == 40) {
			/* 0: bare code page bitmap */
			/* 40: preceded by .cp header */
			/* we might check some header details */
			offset = rem;
		} else {
			fprintf(stderr, _("Bad input file size\n"));
			exit(EX_DATAERR);
		}
		fontsize = 256;
		width = 8;
		height = inputlth/256;
	}
	do_loadfont(fd, inbuf+offset, width, height, hwunit, fontsize,
		    fp.pathname);
}
Example #5
0
static void
loadnewfonts(int fd, char **ifiles, int ifilct,
	     int iunit, int hwunit, int no_m, int no_u)
{
	char *ifil, *inbuf, *fontbuf, *bigfontbuf;
	int inputlth, fontbuflth, fontsize, height, width, bytewidth;
	int bigfontbuflth, bigfontsize, bigheight, bigwidth;
	struct unicode_list *uclistheads;
	int i;
	lkfile_t fp;

	if (ifilct == 1) {
		loadnewfont(fd, ifiles[0], iunit, hwunit, no_m, no_u);
		return;
	}

	/* several fonts that must be merged */
	/* We just concatenate the bitmaps - only allow psf fonts */
	bigfontbuf = NULL;
	bigfontbuflth = 0;
	bigfontsize = 0;
	uclistheads = NULL;
	bigheight = 0;
	bigwidth = 0;

	for (i=0; i<ifilct; i++) {
		ifil = ifiles[i];
		if (findfont(ifil, &fp) && findpartialfont(ifil, &fp)) {
			fprintf(stderr, _("Cannot open font file %s\n"), ifil);
			exit(EX_NOINPUT);
		}

		inbuf = fontbuf = NULL;
		inputlth = fontbuflth = 0;
		fontsize = 0;

		if(readpsffont(fp.fd, &inbuf, &inputlth, &fontbuf, &fontbuflth,
			       &width, &fontsize, bigfontsize,
			       no_u ? NULL : &uclistheads)) {
			fprintf(stderr, _("When loading several fonts, all "
					  "must be psf fonts - %s isn't\n"),
				fp.pathname);
			lk_fpclose(&fp);
			exit(EX_DATAERR);
		}
		lk_fpclose(&fp);		// avoid zombies, [email protected] (#88501)
		bytewidth = (width+7) / 8;
		height = fontbuflth / (bytewidth * fontsize);
		if (verbose)
			printf(_("Read %d-char %dx%d font from file %s\n"),
			       fontsize, width, height, fp.pathname);

		if (bigheight == 0)
			bigheight = height;
		else if (bigheight != height) {
			fprintf(stderr, _("When loading several fonts, all "
					  "must have the same height\n"));
			exit(EX_DATAERR);
		}
		if (bigwidth == 0)
			bigwidth = width;
		else if (bigwidth != width) {
			fprintf(stderr, _("When loading several fonts, all "
					  "must have the same width\n"));
			exit(EX_DATAERR);
		}

		bigfontsize += fontsize;
		bigfontbuflth += fontbuflth;
		bigfontbuf = xrealloc(bigfontbuf, bigfontbuflth);
		memcpy(bigfontbuf+bigfontbuflth-fontbuflth,
		       fontbuf, fontbuflth);
	}
	do_loadfont(fd, bigfontbuf, bigwidth, bigheight, hwunit,
		    bigfontsize, NULL);

	if (uclistheads && !no_u)
		do_loadtable(fd, uclistheads, bigfontsize);
}