1. 不知啥原因,microwindows 認定 PCF 裏的結構都是用 LSB 方式儲存,我查到的 PCF 格式只有少部份欄位是用 LSB ,大多是用 MSB 方式儲存,所以必須修正 src\engine\font_pcf.c 才能讀取 fedora 7 的 PCF 字型檔,不然會直接當掉的。

2. 如果 PCF 是 ISO 10646 (萬國碼)的格式,會導致 Nano-X 因為記憶體區段錯誤跳掉。如果不想修改 nona-X 內的字型 Buffer 設定,只要使用 fontforge 時,將 BDF 的編碼強制轉換成 ISO 8859-1 後就可以正確使用了。

3. 將 MicroSoft Windows 底下的 TureType 字型轉換成 PCF 檔案製作流程
a. 先使用 xmbdfed 將 TureType(TTF) 字形檔轉換成 BDF 字型檔
== http://crl.nmsu.edu/~mleisher/xmbdfed.html
++ ./xmbdfed -ps 20 -hr 75 -vr 75
#### -ps 20 <- 設定字型大小
#### -hr 75 <- 設定水平解析度
#### -vr 75 <- 設定垂直解析度
++ 點選 File -> Import -> TureTypeFint ,選擇要輸入的 TTF 字型檔
++ 然後按 OK 後,會出現字型所要運用的平台環境,這時請在 Platform 選擇 MicroSoft ,在 Encoding 選擇 ISO10646,然後選擇 OK 就會開始載入字型。
++ 在字型載入完後,選擇另存新檔 (Save As) 後將字型存到自己找得到的路徑下,這樣 BDF 字型檔就產生了。
b.
用 fontforge 將字形檔的編碼轉換成 ISO8859-1。
== fontforge-20061220-1.fc7.i386
++ run
fontforge。
++ open xxx.bdf。
++
Encoding->reencode->ISO 8859-1(Latin1)。
++
File->Generate Fonts...。
c. bdftopcf -o
xxx.pcf xxx.bdf。

4. 修正內容
--- microwindows-0.91-old/src/engine/font_pcf.c    2003-06-16 11:20:09.000000000 +0800
+++ microwindows-0.91-new/src/engine/font_pcf.c    2008-01-10 14:28:37.000000000 +0800
@@ -245,6 +245,37 @@
     return dwswap(n);
 }
 
+/* read a 16-bit integer MSB16 format*/
+static unsigned short
+readMSB16(FILEP file)
+{
+    unsigned short s;
+
+    FREAD(file, &s, sizeof(s));
+#if !MW_CPU_BIG_ENDIAN
+    return ((((s) << 8) & 0xff00) | (((s) >> 8) & 0x00ff));
+#else
+    return s;
+#endif
+}
+
+/* read a 32-bit integer MSB32 format*/
+static unsigned long
+readMSB32(FILEP file)
+{
+    unsigned long n;
+
+    FREAD(file, &n, sizeof(n));
+#if !MW_CPU_BIG_ENDIAN
+    return ((((n) << 24) & 0xff000000L) | \
+           (((n) <<  8) & 0x00ff0000L) | \
+           (((n) >>  8) & 0x0000ff00L) | \
+           (((n) >> 24) & 0x000000ffL) );
+#else
+    return n;
+#endif
+}
+
 /* Get the offset of the given field */
 static int
 pcf_get_offset(int item)
@@ -272,21 +303,26 @@
     struct prop_entry *p;
 
     unsigned char *string_buffer, *spos;
+    unsigned long (*read32)(FILEP);
 
     if ((offset = pcf_get_offset(PCF_PROPERTIES)) == -1)
         return (-1);
     FSEEK(file, offset, SEEK_SET);
 
     format = readLSB32(file);
-    num_props = readLSB32(file);
+    if (format & PCF_BIT_MASK)
+        read32 = readMSB32;
+    else
+        read32 = readLSB32;
+    num_props = read32(file);
 
     p = *prop = (struct prop_entry *) malloc(num_props *
                          sizeof(struct prop_entry));
 
     for (i = 0; i < num_props; i++) {
-        p[i].name = readLSB32(file);
+        p[i].name = read32(file);
         p[i].is_string = readINT8(file);
-        p[i].value = readLSB32(file);
+        p[i].value = read32(file);
     }
 
     /* Pad to 32 bit multiples */
@@ -295,7 +331,7 @@
 
 
     /* Read the entire set of strings into memory */
-    ssize = readLSB32(file);
+    ssize = read32(file);
     spos = string_buffer = (unsigned char *) ALLOCA(ssize);
     FREAD(file, string_buffer, ssize);
 
@@ -333,6 +369,7 @@
     unsigned long *o;
     unsigned char *b;
     unsigned long bmsize[GLYPHPADOPTIONS];
+    unsigned long (*read32)(FILEP);
 
     if ((offset = pcf_get_offset(PCF_BITMAPS)) == -1)
         return -1;
@@ -340,15 +377,18 @@
 
     format = readLSB32(file);
     endian = (format & PCF_BIT_MASK)? PCF_LSB_FIRST: PCF_MSB_FIRST;
-
-    num_glyphs = readLSB32(file);
+    if (endian == PCF_LSB_FIRST)
+        read32 = readMSB32;
+    else
+        read32 = readLSB32;
+    num_glyphs = read32(file);
 
     o = *offsets = (unsigned long *)malloc(num_glyphs * sizeof(unsigned long));
     for (i=0; i < num_glyphs; ++i)
-        o[i] = readLSB32(file);
+        o[i] = read32(file);
 
     for (i=0; i < GLYPHPADOPTIONS; ++i)
-        bmsize[i] = readLSB32(file);
+        bmsize[i] = read32(file);
 
     pad = format & PCF_GLYPH_PAD_MASK;
     *bits_size = bmsize[pad]? bmsize[pad] : 1;
@@ -358,14 +398,9 @@
     FREAD(file, b, *bits_size);
 
     /* convert bitmaps*/
-    bit_order_invert(b, *bits_size);
-#if MW_CPU_BIG_ENDIAN
-    if (endian == PCF_LSB_FIRST)
-        two_byte_swap(b, *bits_size);
-#else
     if (endian == PCF_MSB_FIRST)
-        two_byte_swap(b, *bits_size);
-#endif
+        bit_order_invert(b, *bits_size);
+    two_byte_swap(b, *bits_size);
     return num_glyphs;
 }
 
@@ -376,29 +411,39 @@
     long i, size, offset;
     unsigned long format;
     struct metric_entry *m;
+    unsigned long  (*read32)(FILEP);
+    unsigned short (*read16)(FILEP);
 
     if ((offset = pcf_get_offset(PCF_METRICS)) == -1)
         return -1;
     FSEEK(file, offset, SEEK_SET);
 
     format = readLSB32(file);
+    if (format & PCF_BIT_MASK) {
+        read16 = readMSB16;
+        read32 = readMSB32;
+    }
+    else {
+        read16 = readLSB16;
+        read32 = readLSB32;
+    }
 
     if ((format & PCF_FORMAT_MASK) == PCF_DEFAULT_FORMAT) {
-        size = readLSB32(file);        /* 32 bits - Number of metrics*/
+        size = read32(file);        /* 32 bits - Number of metrics*/
 
         m = *metrics = (struct metric_entry *) malloc(size *
             sizeof(struct metric_entry));
 
         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);
+            m[i].rightBearing = read16(file);
+            m[i].width = read16(file);
+            m[i].ascent = read16(file);
+            m[i].descent = read16(file);
+            m[i].attributes = read16(file);
         }
     } else {
-        size = readLSB16(file);        /* 16 bits - Number of metrics*/
+        size = read16(file);        /* 16 bits - Number of metrics*/
 
         m = *metrics = (struct metric_entry *) malloc(size *
             sizeof(struct metric_entry));
@@ -421,30 +466,35 @@
     long offset, n;
     unsigned long format;
     struct encoding_entry *e;
+    unsigned short (*read16)(FILEP);
 
     if ((offset = pcf_get_offset(PCF_BDF_ENCODINGS)) == -1)
         return -1;
     FSEEK(file, offset, SEEK_SET);
 
     format = readLSB32(file);
+    if (format & PCF_BIT_MASK)
+        read16 = readMSB16;
+    else
+        read16 = readLSB16;
 
     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);
+    e->min_byte2 = read16(file);
+    e->max_byte2 = read16(file);
+    e->min_byte1 = read16(file);
+    e->max_byte1 = read16(file);
+    e->defaultchar = read16(file);
     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);
         /*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;
 }

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()