Beispiel #1
0
/*
 * 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);
}
Beispiel #2
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;
}