/* * Allocate bitmaps according to the phys_install list. */ static int i_cpr_bitmap_setup(void) { struct memlist *pmem; cbd_t *dp, *tail; void *space; size_t size; /* * The number of bitmap descriptors will be the count of * phys_install ranges plus 1 for a trailing NULL struct. */ cpr_nbitmaps = 1; for (pmem = phys_install; pmem; pmem = pmem->ml_next) cpr_nbitmaps++; if (cpr_nbitmaps > (CPR_MAX_BMDESC - 1)) { cpr_err(CE_WARN, "too many physical memory ranges %d, max %d", cpr_nbitmaps, CPR_MAX_BMDESC - 1); return (EFBIG); } /* Alloc an array of bitmap descriptors. */ dp = kmem_zalloc(cpr_nbitmaps * sizeof (*dp), KM_NOSLEEP); if (dp == NULL) { cpr_nbitmaps = 0; return (ENOMEM); } tail = dp + cpr_nbitmaps; CPR->c_bmda = dp; for (pmem = phys_install; pmem; pmem = pmem->ml_next) { size = BITMAP_BYTES(pmem->ml_size); space = kmem_zalloc(size * 2, KM_NOSLEEP); if (space == NULL) return (ENOMEM); ASSERT(dp < tail); dp->cbd_magic = CPR_BITMAP_MAGIC; dp->cbd_spfn = mmu_btop(pmem->ml_address); dp->cbd_epfn = mmu_btop(pmem->ml_address + pmem->ml_size) - 1; dp->cbd_size = size; dp->cbd_reg_bitmap = (cpr_ptr)space; dp->cbd_vlt_bitmap = (cpr_ptr)((caddr_t)space + size); dp++; } /* set magic for the last descriptor */ ASSERT(dp == (tail - 1)); dp->cbd_magic = CPR_BITMAP_MAGIC; return (0); }
/* read bdf font bitmaps, return 0 on error*/ int bdf_read_bitmaps(Common::SeekableReadStream &fp, NewFontData* pf) { long ofs = 0; int maxwidth = 0; int i, k, encoding = 0, width = 0; int bbw = 0, bbh = 0, bbx = 0, bby = 0; int proportional = 0; int need_bbx = 0; int encodetable = 0; long l; char buf[256]; /* initially mark offsets as not used*/ for (i = 0; i < pf->size; ++i) pf->offset[i] = (unsigned long)-1; for (;;) { if (!bdf_getline(fp, buf, sizeof(buf))) { warning("Error: EOF on file"); return 0; } if (isprefix(buf, "STARTCHAR")) { encoding = width = bbw = bbh = bbx = bby = -1; continue; } if (isprefix(buf, "ENCODING ")) { if (sscanf(buf, "ENCODING %d", &encoding) != 1) { warning("Error: bad 'ENCODING'"); return 0; } if (encoding < start_char || encoding > limit_char) encoding = -1; continue; } if (isprefix(buf, "DWIDTH ")) { if (sscanf(buf, "DWIDTH %d", &width) != 1) { warning("Error: bad 'DWIDTH'"); return 0; } /* use font boundingbox width if DWIDTH <= 0*/ if (width <= 0) width = pf->fbbw - pf->fbbx; continue; } if (isprefix(buf, "BBX ")) { if (sscanf(buf, "BBX %d %d %d %d", &bbw, &bbh, &bbx, &bby) != 4) { warning("Error: bad 'BBX'"); return 0; } continue; } if (strequal(buf, "BITMAP")) { bitmap_t *ch_bitmap = pf->bits + ofs; int ch_words; if (encoding < 0) continue; /* set bits offset in encode map*/ if (pf->offset[encoding-pf->firstchar] != (unsigned long)-1) { warning("Error: duplicate encoding for character %d (0x%02x), ignoring duplicate", encoding, encoding); continue; } pf->offset[encoding-pf->firstchar] = ofs; pf->width[encoding-pf->firstchar] = width; pf->bbx[encoding-pf->firstchar].w = bbw; pf->bbx[encoding-pf->firstchar].h = bbh; pf->bbx[encoding-pf->firstchar].x = bbx; pf->bbx[encoding-pf->firstchar].y = bby; if (width > maxwidth) maxwidth = width; /* clear bitmap*/ memset(ch_bitmap, 0, BITMAP_BYTES(bbw) * bbh); ch_words = BITMAP_WORDS(bbw); /* read bitmaps*/ for (i = 0; i < bbh; ++i) { if (!bdf_getline(fp, buf, sizeof(buf))) { warning("Error: EOF reading BITMAP data"); return 0; } if (isprefix(buf, "ENDCHAR")) break; for (k = 0; k < ch_words; ++k) { bitmap_t value; value = bdf_hexval((unsigned char *)buf); if (bbw > 8) { WRITE_UINT16(ch_bitmap, value); } else { WRITE_UINT16(ch_bitmap, value << 8); } ch_bitmap++; } } ofs += ch_words * bbh; continue; } if (strequal(buf, "ENDFONT")) break; } /* set max width*/ pf->maxwidth = maxwidth; /* change unused offset/width values to default char values*/ for (i = 0; i < pf->size; ++i) { int defchar = pf->defaultchar - pf->firstchar; if (pf->offset[i] == (unsigned long)-1) { pf->offset[i] = pf->offset[defchar]; pf->width[i] = pf->width[defchar]; pf->bbx[i].w = pf->bbx[defchar].w; pf->bbx[i].h = pf->bbx[defchar].h; pf->bbx[i].x = pf->bbx[defchar].x; pf->bbx[i].y = pf->bbx[defchar].y; } } /* determine whether font doesn't require encode table*/ l = 0; for (i = 0; i < pf->size; ++i) { if (pf->offset[i] != (unsigned long)l) { encodetable = 1; break; } l += BITMAP_WORDS(pf->bbx[i].w) * pf->bbx[i].h; } if (!encodetable) { free(pf->offset); pf->offset = NULL; } /* determine whether font is fixed-width*/ for (i = 0; i < pf->size; ++i) { if (pf->width[i] != maxwidth) { proportional = 1; break; } } if (!proportional) { free(pf->width); pf->width = NULL; } /* determine if the font needs a bbx table */ for (i = 0; i < pf->size; ++i) { if (pf->bbx[i].w != pf->fbbw || pf->bbx[i].h != pf->fbbh || pf->bbx[i].x != pf->fbbx || pf->bbx[i].y != pf->fbby) { need_bbx = 1; break; } } if (!need_bbx) { free(pf->bbx); pf->bbx = NULL; } /* reallocate bits array to actual bits used*/ if (ofs < pf->bits_size) { bitmap_t *tmp = (bitmap_t *)realloc(pf->bits, ofs * sizeof(bitmap_t)); if (tmp != NULL || ofs == 0) pf->bits = tmp; else error("bdf_read_bitmaps: Error while reallocating memory"); pf->bits_size = ofs; } else { if (ofs > pf->bits_size) { warning("Warning: DWIDTH spec > max FONTBOUNDINGBOX"); if (ofs > pf->bits_size+EXTRA) { warning("Error: Not enough bits initially allocated"); return 0; } pf->bits_size = ofs; } } return 1; }