Console

我在哪裡可以找到現代版的“rock”(或“t”)控制台字型?

  • September 7, 2015

在 Slackware 和 RedHat-pre-Fedora 時代,有一種控制台字型,有時稱為“rock”或“t”。我已經搜尋了很多次,但找不到任何參考。如果可能的話,我認為將它帶回 Ubuntu 會很有趣。有誰知道它現在會被稱為什麼,或者如果我可以將它的 TrueType 版本放在其他系統上?

AFAIK 沒有此字型到任何輪廓變體的現有埠。然而,這裡有一些細節和技巧,可能會對您有所幫助。

t.fnt Tektite是由(前?)clySmic Software創建的,很可能是 Ralph B Smith Jr,總裁/首席程序員/廚師/洗瓶機。它是一種點陣圖字型,包含在 DOS 和 OS/2 的 VFONT 程序中。它為 VGA 系統載入替換字型。作者給它的名字是Tektite,被描述為*“一種“建築師”風格的字型。*

VFONT 可以在檔案 CVFONT.ZIP 和 CVFONTA.ZIP中下載。Tektite字型是後者的一部分。前者是僅適用於 DOS 的舊版本。

VFONT 和提取:

該檔案由 DOS 程序、VFONT.COM、OS/2 程序 VFONT2.EXE、字型數據庫 VFONT.DAT 和 README.MAN 組成。VFONT.DAT 包含背靠背儲存的 13 種點陣圖字型。要提取 Tektite 字型,請執行以下操作:

dd if=VFONT.DAT of=t.fnt bs=1 skip=28672 count=4096

這會為您提供一個 RAW 類型的字型檔,例如 Slackware 中包含的字型檔。

每種字型為 4096 字節。因此,要提取其他人只需更改跳過選項。即c.fnt之後t.fnt給你一個跳過值28672 + 4096 = 32768。所有字型都包含在 Linux 中,要進行完整的提取,可以這樣做:

#!/bin/bash

pos=0
for n in s sd r ro rl mu ml t c b m mr sc; do
   dd if=VFONT.DAT of=$n.fnt bs=1 skip=$pos count=4096
   ((pos += 4096))
done

…或者,當然,從包含它們的各種發行版之一下載它。

這些文件可以直接在終端中載入,例如:

setfont t.fnt

Linux 中的命名

該字型在 Linux 中由 VFONT 程序的選項命名。泰克泰特有/T。其他字型也包括在內,也由 VFONT 的命令行選項命名。(/S = s.fnt,/SD = sd.fnt,/RO = ro.fnt …等)

原始字型

(過時但公認的)RAW 字型格式是最簡單的字型格式。它沒有頁眉、頁腳、轉義字節等。它通常有 8 個像素(位)的寬度——就像 VFONT 字型一樣。它們總是有 256 個字形。

由此我們可以通過以下方式輕鬆計算高度:

     file_size (bits)               8 × 4096
h = -------------------- e.g.  h = ------------- = 16
         w × 256                    8 × 256

由於所有 VFONT 字型的大小都是 4096,我們也知道它們的高度都是 16 像素(位)。這也使得每個字形都是 16 個字節。

ASCII 渲染

當涉及到 0x20(空格)- 0x7e(波浪號)時,字型符合 ASCII 範圍,我們可以對字形進行簡單的 ASCII 渲染。

例如,字母A的位置為 65。由於每個字形是 8×16 = 128 位,我們將它們放在 128 / 8 = 16 字節處。

由於 65 × 16 = 1040,我們可以通過以下方式提取字形A(這裡包括轉換為二進制和替換 0 和 1 以使其更具可讀性):

xxd -s 1040 -l 16 -b -c 1 t.fnt | cut -d' ' -f 2 | tr 0 ' ' | tr 1 '#'

這給了我們:

Output from  |          Data in file
command:    |  Binary:   Hex:  Offset  Offset
            |                  Hex:     Dec:
            |  00000000  00    410     1040
            |  00000000  00    411     1041
  ##        |  00011000  18    412     1042
  ##        |  00011000  18    413     1043
 ####       |  00111100  3c    414     1044
 #  #       |  00100100  24    415     1045
##  ##      |  01100110  66    416     1046
## ###      |  01101110  6e    417     1047
#### #      |  01111010  7a    418     1048
###   ##     |  11100011  e3    419     1049
##    ##     |  11000011  c3    41a     1050
##    ##     |  11000011  c3    41b     1051
            |  00000000  00    41c     1052
            |  00000000  00    41d     1053
            |  00000000  00    41e     1054
            |  00000000  00    41f     1055

使用一些簡單的 C 程式碼,我們還可以渲染一些簡單的 PBM 圖像。以下是 VFONT 中所有字型的範例輸出:

VFONT 樣品

使用 FontForge 進行編輯

如果你想使用字型,我猜你可能會去FontForge。由於它無法辨識 RAW 字型,因此您必須將其轉換為另一種格式。更簡單的轉換之一可能是 BDF。一種選擇是使用John Elliot 的 PSF Tools。首先從 RAW 轉換為 PSF,然後將 PSF 轉換為 BDF:

raw2psf t.fnt t.psf
psf2bdf t.psf t.bdf

現在可以在 FontForge 中打開 BDF 文件

由於該過程相當簡單(所有 VFONT 都相同),您還可以使用此腳本直接轉換為 BDF 格式:

範例用法:

./raw2bdf Tektite t.fnt > t.bdf

為您提供 BDF 形式的 Tektite 字型。

#!/bin/bash

if [ $# -lt 2 ]; then
   printf "Usage: %s <NAME> <raw-fnt-file>\n" $0
   exit
fi

name=$1
file=$2

cat <<EOM
STARTFONT 2.1
FONT $name
SIZE 16 75 75
FONTBOUNDINGBOX 8 16 0 -4
STARTPROPERTIES 3
FONT_DESCENT 4
FONT_ASCENT 12
DEFAULT_CHAR 255
ENDPROPERTIES
CHARS 256
EOM

hexdump -ve '/1 "%02x\n"' "$file" | awk '
   BEGIN {
       n = 0;
   }
   (!((NR - 1) % 16)) {
       if (n > 0)
           print "ENDCHAR"
       printf "STARTCHAR C00%02x\n"\
               "ENCODING %d\n"\
               "SWIDTH 666 0\n"\
               "DWIDTH 8 0\n"\
               "BBX 8 16 0 -4\n"\
               "BITMAP\n",
               n, n
       ++n
   }
   {
       print $0
   }
   END {
       print "ENDCHAR"
       print "ENDFONT"
   }
'

其他版本

Tektite 字型有幾個修改版本。如果您搜尋它,可選擇將*“clysmic”*添加到您可以學習的搜尋片語中。

圖像渲染

為了完整起見,我添加了混搭的 C 程式碼以創建上面的圖像。display並且convertImageMagick的一部分。

範例用法:

$ ./fntsampler t.fnt hello a

##                ###     ###           
##                 ##      ##           
##                 ##      ##           
##  ###   #####    ##      ##     ##### 
## ## ## ##   ##   ##      ##    ##   ##
####  ####  ###    ##      ##   ##    ##
###   #######      ##      ##   ##    ##
##    ####         ##      ##   ##    ##
##    ####    ##   ##      ##   ##   ## 
##    ## ######    ##      ##    #####  

$ ./fntsampler t.fnt "Hello World!" > hello.pbm
$ display hello.pbm

Hello Wold in Tekite

以上所有字型的範例圖像由以下人員創建:

$ for f in *.fnt; do ./fntsampler "$f" "$(printf "%-6s Hello ABC abc 123" "$f")" | convert - "${f%.*}.png"; done

$ convert -negate -append *.png collection.png

程式碼:

#include <stdio.h>
#include <errno.h>
#include <string.h>

int usage(char *me, char *s)
{
   fprintf(stderr,
       "Usage: %s <RAW-font-file> \"<string>\" [format] [[invert] | [dot] [blank]]\n\n"
       "  format    p : PBM image (default).\n"
       "            a : ASCII.\n"
       "  invert    i : invert b/w in PBM.\n"
       "  dot\n"
       "  blank       : Dot / blank in ASCII mode.\n\n"
       "%s\n"
       ,
       me, errno ? "" : s
   );
   if (errno)
       perror(s);
   return 1;
}

int main(int argc, char *argv[])
{
   char *me = argv[0];
   char buf[4096];
   size_t n;
   char *p;
   int i, j, k;

   FILE *fh;
   char *s;
   char fmt = 'p', dot = '1', blank = '0';

   if (argc < 3)
       return usage(me, "Missing argument(s)");

   if (!(fh = fopen(argv[1], "r")))
       return usage(me, "Unable to open file");
   if ((fread(buf, 1, 4096, fh) != 4096))
       return usage(me, "Bad file size");

   s = argv[2];
   if ((n = strlen(s)) < 1)
       return usage(me, "Empty string");

   if (argc > 3)
       fmt = argv[3][0];
   if (fmt != 'a' && fmt != 'p')
       return usage(me, "Unknown format");

   if (fmt == 'a') {
       dot = argc > 4 ? argv[4][0] : '#';
       blank = argc > 5 ? argv[5][0] : ' ';
   } else {
       if (argc > 4 && argv[4][0] == 'i') {
           dot = '0';
           blank = '1';
       }
       printf("P1\n");
       printf("#Text: \"%s\", using %s\n", s, argv[1]);
       printf("%u 16\n", n * 8);
   }

   for (i = 0; i < 16; ++i) {
       for (j = 0; j < (int)n; ++j) {
           p = buf + (s[j] * 16) + i;
           for (k = 7; k >= 0; --k) {
               putchar((*p >> k) & 0x01 ? dot : blank);
           }
           /*putchar(' '); */
       }
       putchar('\n');
   }

   return 0;
}

引用自:https://unix.stackexchange.com/questions/226593