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); }
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); }
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); }
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); }