以前的 DOS,或仿 DOS 環境,可以在 BIOS 的 F000:FA6E 取得
ASCII bitmap,在 WinXP上可以 LoadLibrary("ntdll.dll"),
用裡頭的 ZwOpenSection 與 ZwMapViewOfSection 取得此
section 的映射,但此法在 Vista 下不能用。
DOS 倚天中文下則由 B800:0000 開始取 (Big5, color) pair,
再對到 16 or 24 號字形檔 (.15 or .24x) 取出 bitmap。
Windows 上有許多 true type font,這些向量字不存在 bitmap,
只能用 GetGlyphOutline 或 TextOut 去轉出點陣圖。
現今由於字型檔繁多,較便捷的做法是用 Win32 API 指定字型檔與字樣,
將字畫到 canvas 上,再把座標數出來,譬如:
#include <windows.h> #include <stdio.h> //輸出文字 s, 字體=face, 字形大小=size void show_text (HDC hdc, wchar_t* s, int size=16, wchar_t* face= L"細明體") { int x,y, len = wcslen(s); HFONT font = CreateFont (size,0,0,0,400,0,0,0,0,0,0,0,0,face); HGDIOBJ oldFont = SelectObject (hdc, font); SetBkColor (hdc,RGB(255,255,255)); SetTextColor (hdc, 0); //黑色 TextOut (hdc, 0,0, s, len); for (y=0; y<size; y++, puts("")) for (x=0; x<len*size; x++) printf (GetPixel (hdc,x,y)? " ":"█"); SelectObject (hdc, oldFont); DeleteObject (font); } int main () { SetConsoleTitle (L"Conso"); HDC hdc = GetDC (FindWindow (0, L"Conso")); show_text (hdc, L"選擇"); DeleteDC (hdc); return system ("pause"); }輸出:
█ ████ ████ ██ ██ █ █ █ █ █ █████████ ████ ████ █ █ █ █ █ █ █ █ █████ █████████ ██ █ █ █ █ █ █ ███ ███ █ ███████ █ █ █ █ █ █ █ █████████ ████ ████████ ██ █ █ █ █ █ ███ █ █ █ ██████████ █ █ ███████ █ █ █ █ █ ██ ██ ██ █ █████████ ██ ██ ███ █ █ █████████ █ █
底下是另一種 ttf 轉點陣的寫法,需用 Unicode mode 編譯:
//將文字 ch 的點陣圖存入 buf 中, 點陣圖大小記錄於 bytes 中傳回 //字體=face, 字形大小=size, [此函式在 Unicode 模式下測試正常] int text_bitmap (HDC hdc, UINT ch, char* buf, GLYPHMETRICS& gm, int size=16, wchar_t* face= L"細明體") { MAT2 mat = {{0,1},{0,0},{0,0},{0,1}}; //轉置矩陣 HFONT font = CreateFont (size,0,0,0,400,0,0,0,0,0,0,0,0,face); HGDIOBJ oldFont = SelectObject (hdc, font); int bytes = GetGlyphOutline (hdc, ch, 1, &gm, 0, 0, &mat); if (bytes != GDI_ERROR) GetGlyphOutline (hdc, ch, 1, &gm, bytes, buf, &mat); SelectObject (hdc, oldFont); DeleteObject (font); return bytes; } int main () { SetConsoleTitle (L"Conso"); HDC hdc = GetDC (FindWindow (0, L"Conso")); GLYPHMETRICS gm; char a[512]; int sz = text_bitmap (hdc, L'選', a, gm); int nx = sz/gm.gmBlackBoxY; //每行占幾Byte, gmBlackBoxX=位元寬度 //亦即 ((gm.gmBlackBoxX+31)>>5)<<2 for (int x,j,i=0; i<sz; puts("")) for (x=0; x<nx; x++, i++) for (j=1<<8; j; j>>=1) printf (a[i]&j? "█":" "); DeleteDC (hdc); return system ("pause"); }輸出:
█ █████ ████ ██ █ ██ █ █ █████ ████ ██ █ █ ██ █ ██ █ █ ████ ███ █ ██ █ █████ █████████ █ ██ █ █ ███████████ █ ██ █ ██ ██ ██ ███ ██ ██ ██████████
沒有留言:
張貼留言