Subject:
PCF font support
From:
####@####.####
Date:
18 Aug 2008 16:31:50 -0000
Message-Id: <48A9A473.9090005@neurosoft.ru>
Hi,
I'm using microwindows with PCF fonts on my ARM-based board. I've faced
with two problems.
1. Variable "long mwTextCoding" appeared in file "wingdi.c". It's
default value MWTF_UTF8, so ASCII -coding PCF fonts does not work
correctly.
I can't found a way, how I change mwTextCoding value from my program.
For my porpose, I've change its' default value to MWTF_ASCII.
2. I've found, microwindows faults, if fields PCF_BYTE_MASK ore
PCF_BIT_MASK in *.pcf file not equivalent to zero.
To solve this problem, I have made patch. It's concerning
mostly /engine/font_pcf.c , but two macros I've added in /include/swap.h.
Patch attached to my mail.
diff -urN ./src/engine/font_pcf.c ./new-src/engine/font_pcf.c
--- ./src/engine/font_pcf.c 2005-06-24 04:26:57.000000000 +0400
+++ ./new-src/engine/font_pcf.c 2008-08-18 14:30:39.000000000 +0400
@@ -1,4 +1,4 @@
-/*
+/*
* PCF font engine for Microwindows
* Copyright (c) 2002, 2003 Greg Haerr ####@####.####
* Copyright (c) 2001, 2002 by Century Embedded Technologies
@@ -234,6 +234,16 @@
FREAD(file, &s, sizeof(s));
return wswap(s);
}
+/* read a 16-bit integer MSB16 format*/
+static unsigned short
+readMSB16(FILEP file)
+{
+ unsigned char s[2];
+
+ FREAD(file, s, 2);
+ return wreadBE(s);
+}
+#define READ16(file, endian) endian ? readMSB16(file) : readLSB16(file)
/* read a 32-bit integer LSB32 format*/
static unsigned long
@@ -244,6 +254,16 @@
FREAD(file, &n, sizeof(n));
return dwswap(n);
}
+/* read a 32-bit integer MSB32 format*/
+static unsigned long
+readMSB32(FILEP file)
+{
+ unsigned char n[4];
+
+ FREAD(file, n, 4);
+ return dwreadBE(n);
+}
+#define READ32(file, endian) endian ? readMSB32(file) : readLSB32(file)
/* Get the offset of the given field */
static int
@@ -329,41 +349,60 @@
unsigned long num_glyphs;
unsigned long pad;
unsigned int i;
- int endian;
+ int endian, bitorder;
unsigned long *o;
unsigned char *b;
unsigned long bmsize[GLYPHPADOPTIONS];
+ DPRINTF("pcf_readbitmaps call pcf_get_offset()\n");
if ((offset = pcf_get_offset(PCF_BITMAPS)) == -1)
return -1;
+ DPRINTF("pcf_get_offset() return %ld\n", offset);
FSEEK(file, offset, SEEK_SET);
format = readLSB32(file);
- endian = (format & PCF_BIT_MASK)? PCF_LSB_FIRST: PCF_MSB_FIRST;
+ bitorder = (format & PCF_BIT_MASK)? PCF_MSB_FIRST: PCF_LSB_FIRST;
+ endian = (format & PCF_BYTE_MASK)? PCF_MSB_FIRST: PCF_LSB_FIRST;
- num_glyphs = readLSB32(file);
+ DPRINTF("pcf_readbitmaps call readLSB32()\n");
+ num_glyphs = READ32(file,endian);
+ DPRINTF("num_glyphs = %ld\n", num_glyphs);
o = *offsets = (unsigned long *)malloc(num_glyphs * sizeof(unsigned long));
+ if(!o){
+ EPRINTF("pcf_readbitmaps can't allocate memory\n");
+ return -1;
+ }
for (i=0; i < num_glyphs; ++i)
- o[i] = readLSB32(file);
+ o[i] = READ32(file,endian);
+ DPRINTF("pcf_readbitmaps have read %ld ints\n", num_glyphs);
for (i=0; i < GLYPHPADOPTIONS; ++i)
- bmsize[i] = readLSB32(file);
+ bmsize[i] = READ32(file,endian);
pad = format & PCF_GLYPH_PAD_MASK;
*bits_size = bmsize[pad]? bmsize[pad] : 1;
+ DPRINTF("pcf_readbitmaps have read %d ints\n", GLYPHPADOPTIONS);
/* alloc and read bitmap data*/
b = *bits = (unsigned char *) malloc(*bits_size);
+ if(!b){
+ EPRINTF("pcf_readbitmaps can't allocate memory for bitmap\n");
+ return -1;
+ }
FREAD(file, b, *bits_size);
+ DPRINTF("pcf_readbitmaps have read %ld bytes\n", *bits_size);
/* convert bitmaps*/
- bit_order_invert(b, *bits_size);
+ DPRINTF("pcf_readbitmaps call bit_order_invert()\n");
+ if(bitorder == PCF_LSB_FIRST) bit_order_invert(b, *bits_size);
+
+/* TODO FIXME I'm not sure, next code is right? */
#if MW_CPU_BIG_ENDIAN
- if (endian == PCF_LSB_FIRST)
- two_byte_swap(b, *bits_size);
+// if (bitorder == PCF_MSB_FIRST)
+// two_byte_swap(b, *bits_size);
#else
- if (endian == PCF_MSB_FIRST)
+// if (bitorder == PCF_LSB_FIRST)
two_byte_swap(b, *bits_size);
#endif
return num_glyphs;
@@ -376,32 +415,42 @@
long i, size, offset;
unsigned long format;
struct metric_entry *m;
+ int endian;
if ((offset = pcf_get_offset(PCF_METRICS)) == -1)
return -1;
FSEEK(file, offset, SEEK_SET);
format = readLSB32(file);
+ endian = (format & PCF_BYTE_MASK)? PCF_MSB_FIRST: PCF_LSB_FIRST;
if ((format & PCF_FORMAT_MASK) == PCF_DEFAULT_FORMAT) {
- size = readLSB32(file); /* 32 bits - Number of metrics*/
+ size = READ32(file,endian); /* 32 bits - Number of metrics*/
m = *metrics = (struct metric_entry *) malloc(size *
sizeof(struct metric_entry));
+ if(!m){
+ EPRINTF("pcf_readmetrics can't allocate memory\n");
+ return -1;
+ }
for (i=0; i < size; i++) {
- m[i].leftBearing = readLSB16(file);
- m[i].rightBearing = readLSB16(file);
- m[i].width = readLSB16(file);
- m[i].ascent = readLSB16(file);
- m[i].descent = readLSB16(file);
- m[i].attributes = readLSB16(file);
+ m[i].leftBearing = READ16(file,endian);
+ m[i].rightBearing = READ16(file,endian);
+ m[i].width = READ16(file,endian);
+ m[i].ascent = READ16(file,endian);
+ m[i].descent = READ16(file,endian);
+ m[i].attributes = READ16(file,endian);
}
} else {
- size = readLSB16(file); /* 16 bits - Number of metrics*/
+ size = READ16(file,endian); /* 16 bits - Number of metrics*/
m = *metrics = (struct metric_entry *) malloc(size *
sizeof(struct metric_entry));
+ if(!m){
+ EPRINTF("pcf_readmetrics can't allocate memory\n");
+ return -1;
+ }
for (i = 0; i < size; i++) {
m[i].leftBearing = readINT8(file) - 0x80;
@@ -421,30 +470,36 @@
long offset, n;
unsigned long format;
struct encoding_entry *e;
+ int endian;
if ((offset = pcf_get_offset(PCF_BDF_ENCODINGS)) == -1)
return -1;
FSEEK(file, offset, SEEK_SET);
format = readLSB32(file);
+ endian = (format & PCF_BYTE_MASK)? PCF_MSB_FIRST: PCF_LSB_FIRST;
e = *encoding = (struct encoding_entry *)
malloc(sizeof(struct encoding_entry));
- e->min_byte2 = readLSB16(file);
- e->max_byte2 = readLSB16(file);
- e->min_byte1 = readLSB16(file);
- e->max_byte1 = readLSB16(file);
- e->defaultchar = readLSB16(file);
+ if(!e){
+ EPRINTF("pcf_readmetrics can't allocate memory\n");
+ return -1;
+ }
+ e->min_byte2 = READ16(file,endian);
+ e->max_byte2 = READ16(file,endian);
+ e->min_byte1 = READ16(file,endian);
+ e->max_byte1 = READ16(file,endian);
+ e->defaultchar = READ16(file,endian);
e->count = (e->max_byte2 - e->min_byte2 + 1) *
(e->max_byte1 - e->min_byte1 + 1);
e->map = (unsigned short *) malloc(e->count * sizeof(unsigned short));
DPRINTF("def char %d (%x)\n", e->defaultchar, e->defaultchar);
for (n = 0; n < e->count; ++n) {
- e->map[n] = readLSB16(file);
+ e->map[n] = READ16(file,endian);
/*DPRINTF("ncode %x (%c) %x\n", n, n, e->map[n]);*/
}
- DPRINTF("size %d byte1 %d,%d byte2 %d,%d\n", e->count,
+ DPRINTF("size %ld byte1 %d,%d byte2 %d,%d\n", e->count,
e->min_byte1, e->max_byte1, e->min_byte2, e->max_byte2);
return e->count;
}
@@ -503,14 +558,17 @@
char fname[256];
/* Try to open the file */
+ DPRINTF("pcf_createfont() call FOPEN(%s)\n",name);
file = FOPEN(name, "rb");
if (!file) {
strcpy(fname, PCF_FONT_DIR "/");
strcpy(fname + sizeof(PCF_FONT_DIR), name);
file = FOPEN(fname, "rb");
}
- if (!file)
+ if (!file){
+ EPRINTF("can't open font %s",name);
return NULL;
+ }
if (!(pf = (MWCOREFONT *) malloc(sizeof(MWCOREFONT)))) {
err = -1;
@@ -524,12 +582,15 @@
/* Read the table of contents */
+ DPRINTF("pcf_createfont() call pcf_read_toc()\n");
if (pcf_read_toc(file, &toc, &toc_size) == -1) {
err = -1;
+ DPRINTF("pcf_read_toc() return -1\n");
goto leave_func;
}
/* Now, read in the bitmaps */
+ DPRINTF("pcf_createfont() call pcf_readbitmaps()\n");
glyph_count = pcf_readbitmaps(file, &glyphs, &bsize, &glyphs_offsets);
DPRINTF("glyph_count = %d (%x)\n", glyph_count, glyph_count);
@@ -538,7 +599,9 @@
goto leave_func;
}
+ DPRINTF("pcf_createfont() call pcf_read_encoding()\n");
if (pcf_read_encoding(file, &encoding) == -1) {
+ DPRINTF("pcf_read_encoding() return -1\n");
err = -1;
goto leave_func;
}
@@ -547,6 +610,7 @@
/* Read in the metrics */
count = pcf_readmetrics(file, &metrics);
+ DPRINTF("pcf_readmetrics() return %d\n", count);
/* Calculate various maximum values */
for (i = 0; i < count; i++) {
@@ -562,6 +626,9 @@
pf->cfont->maxwidth = max_width;
pf->cfont->height = max_height;
pf->cfont->ascent = max_ascent;
+ DPRINTF("pf->cfont->maxwidth = %d\n", pf->cfont->maxwidth);
+ DPRINTF("pf->cfont->height = %d\n", pf->cfont->height);
+ DPRINTF("pf->cfont->ascent = %d\n", pf->cfont->ascent);
/* Allocate enough room to hold all of the bits and the offsets */
bwidth = (max_width + 15) / 16;
@@ -609,7 +676,7 @@
if (bearing < 0) /* negative bearing not handled yet*/
bearing = 0;
carry_shift = 16 - bearing;
-
+
for (w = 0; w < lwidth; w++) {
*output++ = (val[w] >> bearing) | carry;
carry = val[w] << carry_shift;
@@ -637,7 +704,7 @@
}
pf->cfont->size = encoding->count;
- uc16 = pf->cfont->firstchar > 255 ||
+ uc16 = pf->cfont->firstchar > 255 ||
(pf->cfont->firstchar + pf->cfont->size) > 255;
pf->fontprocs = uc16? &pcf_fontprocs16: &pcf_fontprocs;
pf->fontsize = pf->fontrotation = pf->fontattr = 0;
diff -urN ./src/include/swap.h ./new-src/include/swap.h
--- ./src/include/swap.h 2007-11-22 04:01:53.000000000 +0300
+++ ./new-src/include/swap.h 2008-08-15 19:28:38.000000000 +0400
@@ -44,6 +44,20 @@
(((unsigned char *)(addr))[2] << 16) | \
(((unsigned char *)(addr))[3] << 24)))
+/**
+ * Read big endian format 32-bit number from buffer, possibly not
+ * aligned, and convert to the host CPU format.
+ */
+#define dwreadBE(addr) ((((unsigned char *)(addr))[3] | \
+ (((unsigned char *)(addr))[2] << 8) | \
+ (((unsigned char *)(addr))[1] << 16) | \
+ (((unsigned char *)(addr))[0] << 24)))
+/**
+ * Read big endian format 32-bit number from buffer, possibly not
+ * aligned, and convert to the host CPU format.
+ */
+#define wreadBE(addr) ((((unsigned char *)(addr))[1] | \
+ (((unsigned char *)(addr))[0] << 8)))
/* ********************************************************************* */
/* Now, some platform-specific optimized macros. */