nanogui: Thread: PCF font support


[<<] [<] Page 1 of 1 [>] [>>]
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.                         */
Subject: Re: [nanogui] PCF font support
From: "Greg Haerr" ####@####.####
Date: 18 Aug 2008 17:44:17 -0000
Message-Id: <027401c90159$deea1650$6501a8c0@gregnewport>

> 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.

Unfortunately, win32 api doesn't have any mechanism to change
the default encoding, including specification in a seperate
parameter.  We probably need an MwSetTextEncoding or
something to specify the default text encoding for standard
win32 api calls.  You can use the internal MwTextOutExt
which allows a parameter for text encoding, but its not standard.



> 
> 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.

Thanks for the patch.  I could have sworn that a version of the
PCF font subdriver handled these, but looks like they were
removed by yet another contributed patch.  I'll get this into
CVS soon so that others can use it, as this may solve
some issues discussed recently.

Regards,

Greg
Subject: Re: [nanogui] PCF font support
From: Evgeny Romanov ####@####.####
Date: 19 Aug 2008 09:15:08 -0000
Message-Id: <48AA8F86.5000107@neurosoft.ru>

Hi,

Function CreateFont declared like:

HFONT WINAPI
CreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation,
    int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut,
    DWORD fdwCharSet,DWORD fdwOutputPrecision,DWORD fdwClipPrecision,
    DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCSTR lpszFace);

According to Win-API ECMA-234, the fdwCharSet parameter can be one of
the following values:
ANSI_CHARSET: 0
DEFAULT_CHARSET: 1
SYMBOL_CHARSET: 2
SHIFTJIS_CHARSET: 128
OEM_CHARSET: 255


This parameter is stored in "MWLOGFONT" structure in field "lfCharSet".
This structure passed to GdCreateFont function, but ignored there.

MWFONTOBJ contains "PMWFONT", pointer to sfructure "_mwfont".
Structure "_mwfont" contains pointer to structure "MWFONTPROCS".
Structure MWFONTPROCS contains field "MWTEXTFLAGS encoding". Probably,
in this field should be used for character set storing? Instead of
global variable "long mwTextCoding"?


Greg Haerr пишет:
>> 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.
>>     
>
> Unfortunately, win32 api doesn't have any mechanism to change
> the default encoding, including specification in a seperate
> parameter.  We probably need an MwSetTextEncoding or
> something to specify the default text encoding for standard
> win32 api calls.  You can use the internal MwTextOutExt
> which allows a parameter for text encoding, but its not standard.
>   
P. S. MSDN say:

/fdwCharSet/
    [in] Specifies the character set. The following values are predefined:

    ANSI_CHARSET
    BALTIC_CHARSET
    CHINESEBIG5_CHARSET
    DEFAULT_CHARSET
    EASTEUROPE_CHARSET
    GB2312_CHARSET
    GREEK_CHARSET
    HANGUL_CHARSET
    MAC_CHARSET
    OEM_CHARSET
    RUSSIAN_CHARSET
    SHIFTJIS_CHARSET
    SYMBOL_CHARSET
    TURKISH_CHARSET

    *Windows NT/2000 or Middle-Eastern Windows 3.1 or later:*
        HEBREW_CHARSET
        ARABIC_CHARSET
    *Windows NT/2000 or Thai Windows 3.1 or later:*
        THAI_CHARSET

    The OEM_CHARSET value specifies a character set that is
    operating-system dependent.

    *Windows 95/98/Me: *You can use the DEFAULT_CHARSET value to allow
    the name and size of a font to fully describe the logical font. If
    the specified font name does not exist, a font from any character
    set can be substituted for the specified font, so you should use
    DEFAULT_CHARSET sparingly to avoid unexpected results.

    *Windows NT/2000 or later: *DEFAULT_CHARSET is set to a value based
    on the current system locale. For example, when the system locale is
    English (United States), it is set as ANSI_CHARSET.

    Fonts with other character sets may exist in the operating system.
    If an application uses a font with an unknown character set, it
    should not attempt to translate or interpret strings that are
    rendered with that font.

    To ensure consistent results when creating a font, do not specify
    OEM_CHARSET or DEFAULT_CHARSET. If you specify a typeface name in
    the /lpszFace /parameter, make sure that the /fdwCharSet/ value
    matches the character set of the typeface specified in /lpszFace./




-- 
Sincerely yours,
Evgeny





Subject: Re: [nanogui] PCF font support
From: Evgeny Romanov ####@####.####
Date: 19 Aug 2008 13:00:51 -0000
Message-Id: <48AAC466.6070402@neurosoft.ru>

Hi,

I've found function to change "mwTextCoding". I's "void 
MwSetTextCoding(long mode);". To use it, nesessary
 #include "wintern.h"

Probably, it's better to store charset in "PFONT 
pfont->fontprocs->encoding" in "GdCreateFont()" function and copy it to 
"mwTextCoding" in "SelectObject()"?
I have not find, where "PFONT pfont->fontprocs->encoding" is set.

Greg Haerr пишет:
>> 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.
>>     
>
> Unfortunately, win32 api doesn't have any mechanism to change
> the default encoding, including specification in a seperate
> parameter.  We probably need an MwSetTextEncoding or
> something to specify the default text encoding for standard
> win32 api calls.  You can use the internal MwTextOutExt
> which allows a parameter for text encoding, but its not standard.
>
>   
> Regards,
>
> Greg
>
>   

-- 
Sincerely yours,
Evgeny



Subject: Re: [nanogui] PCF font support
From: "Greg Haerr" ####@####.####
Date: 20 Aug 2008 02:53:49 -0000
Message-Id: <057001c9026f$c504eeb0$6501a8c0@gregnewport>

> Probably, it's better to store charset in "PFONT 
pfont->fontprocs->encoding" in "GdCreateFont()" function and copy it to 
"mwTextCoding" in "SelectObject()"?
I have not find, where "PFONT pfont->fontprocs->encoding" is set.

No, fontprocs->encoding is used to specify the static
constant font encoding, which does not change.  It is
the encoding the font uses internally.  MwSetTextEncoding
is an internal api that sets the USER, not font encoding
passed in the associated text string.

Regards,

Greg
Subject: Re: [nanogui] PCF font support
From: Evgeny Romanov ####@####.####
Date: 25 Aug 2008 10:20:48 -0000
Message-Id: <48B28803.7010800@neurosoft.ru>

Hi,

There is file font_pcf.c-20050708  in
ftp://microwindows.censoft.com/pub/microwindows/patch-0.92 directory.
This source should correctly support PCF format, but it's absent in
latest snapshot. There are older version of font_pcf.c in the latest
snapshot

>> 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.
>>     
>
> Thanks for the patch.  I could have sworn that a version of the
> PCF font subdriver handled these, but looks like they were
> removed by yet another contributed patch.  I'll get this into
> CVS soon so that others can use it, as this may solve
> some issues discussed recently.
>
> Regards,
>
> Greg
>
>   


-- 
Sincerely yours,
Evgeny



[<<] [<] Page 1 of 1 [>] [>>]


Powered by ezmlm-browse 0.20.