|
发表于 2004-11-3 10:04:37
|
显示全部楼层
[quote:2a7d0653cb="momotalo"][quote:2a7d0653cb="firefly"]唉!還是老老實實一點一點畫出來的字最實在。
從別人那兒提取的字,能拿到台面上嗎?
能夠大大方方的號稱是 GPL 的字型嗎?
恐怕自己都會覺得不好意思吧 :-([/quote]
firefly大侠在这里,向firefly的工作表示敬意!
我从你的New Sung中用我自己写的一个Qt程序提取出来了点阵,但好象有很多字的大小不一样。比如16X16px的字,出来的点阵有15X16,14X16等等,我现在不清楚是我的程序的问题,还是你制作点阵的时候专门这样设置的。
另外今天收到Arne Götje(leader of Unifonts project)的信,还没有来得及回,大家如果能够联合起来,分工合作,进展一定会更快!我可以把我的这个Wiki平台提供出来(比如建立映像),让一个社区参与点阵中文的制作,这样也不会再烦劳firefly大侠点坏另外一个鼠标了 (可惜,宣传不利,现在点阵中文Wiki的参与者与日递减 )[/quote]
提取的點陣大小不一,是因為 Bitmap 是以實際大小儲存在 truetype 中,在畫在畫布之前,還要計算出這個字符在畫布中的相對位置,請參考以下這段小弟實驗用的小程式,可以解出正確大小,稍微改寫,就能使用在您的程式之中:
[code:1]
// 程式名稱 : getbmp.cpp
// 作者 : Firefly([email protected])
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H
#include FT_BBOX_H
#include <iostream>
#include <fstream>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
static FT_Library library;
static FT_Face face;
static unsigned int pix_size = 0;
static string font_name = "";
static string map_name = "";
static unsigned int char_code = 0;
static bool output_bdf = false;
static FT_Int32 load_flags = FT_LOAD_DEFAULT;
static FT_Int32 loadFlags = FT_LOAD_DEFAULT|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
static void reset_scale( int pointSize )
{
(void)FT_Set_Pixel_Sizes( face, 0, pointSize);
}
int main(int argc, char **argv)
{
static struct option long_opt[] =
{
{"size", 1, 0, 0},
{"font", 1, 0, 0},
{"char", 1, 0, 0},
{"of", 1, 0, 0},
{"ah", 0, 0, 0},
{"nb", 0, 0, 0},
{0, 0, 0, 0}
};
int opt_idx = 0, c = 0;
while((c = getopt_long(argc, argv, "s:f:m:c:ab:",
long_opt, &opt_idx)) != -1)
{
switch (c)
{
case 0:
if (optarg) // 有參數
{
if (long_opt[opt_idx].name == "size")
pix_size = atoi(optarg);
if (long_opt[opt_idx].name == "font")
font_name = optarg;
if (long_opt[opt_idx].name == "char")
char_code = atoi(optarg);
if (long_opt[opt_idx].name == "of")
{
if ((string)optarg == "bdf")
{
output_bdf = true;
}
}
}
else // 無參數
{
if (long_opt[opt_idx].name == "ah")
loadFlags |= FT_LOAD_FORCE_AUTOHINT;
if (long_opt[opt_idx].name == "nb")
loadFlags |= FT_LOAD_NO_BITMAP;
}
break;
case 's' : // size
pix_size = atoi(optarg);
break;
case 'f' : // font
font_name = optarg;
break;
case 'c' : // char code
char_code = atoi(optarg);
break;
}
}
#define FLOOR(x) ((x) & -64)
#define CEIL(x) (((x)+63) & -64)
#define TRUNC(x) ((x) >> 6)
#define ROUND(x) (((x)+32) & -64)
// 初始化 Freetype 引擎
if (FT_Init_FreeType(&library))
{
cerr << "Could not initialize FreeType library." << endl;
exit(1);
}
if (FT_New_Face(library, (char *)font_name.c_str(), 0, &face))
{
cerr << "Could not open font.(" << font_name << ")" << endl;
exit(1);
}
if (FT_Select_Charmap(face,ft_encoding_unicode))
{
cerr << "Not a unicode font." << endl;
exit(1);
}
reset_scale(pix_size);
int ascender = (face->ascender*pix_size + face->units_per_EM/2)/face->units_per_EM;
int descender = pix_size - ascender;
FT_ULong charcode;
FT_UInt gindex;
unsigned int count = 0;
charcode = FT_Get_First_Char(face, &gindex);
while (gindex)
{
if (FT_Load_Char(face, charcode, load_flags))
{
charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue;
}
FT_GlyphSlot slot = face->glyph;
if (slot->format != ft_glyph_format_bitmap)
{
charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue;
}
count ++;
int ymax = slot->bitmap_top - 1;
int ymin = slot->bitmap_top - slot->bitmap.rows;
int height = slot->bitmap.rows;
if (slot->bitmap.rows == 0)
{
ymax = ymin;
height = 1;
}
int xmin = slot->bitmap_left;
int xmax = slot->bitmap_left + slot->bitmap.width - 1;
int width = slot->bitmap.width;
if (slot->bitmap.width == 0)
{
xmax = xmin;
width = 1;
}
int true_width = TRUNC(slot->metrics.horiAdvance);
int per_bytes_line = (true_width + 7 ) >> 3;
int true_height = (height > pix_size) ? height : pix_size;
int buf_size = per_bytes_line * true_height;
unsigned char *bufBitmap = (unsigned char *) malloc (buf_size);
memset (bufBitmap, 0, buf_size);
int pitch = slot->bitmap.pitch ? slot->bitmap.pitch : 1;
int size = (ymax - ymin + 1) * pitch;
unsigned char *buffer = (unsigned char *)malloc(size);
memset(buffer, 0, size);
if (slot->bitmap.rows && slot->bitmap.width)
memcpy(buffer, slot->bitmap.buffer, size);
int xoff = TRUNC(slot->metrics.horiBearingX);
int yoff = TRUNC(slot->metrics.horiBearingY - slot->metrics.height);
if (yoff < -(descender))
{
yoff = -(descender);
}
printf("Char code = 0x%X ( %d x %d )(Xoff:%d Yoff:%d) trueX:%d trueY:%d, ascender=%d, descender=%d\n", charcode, width, height, xoff, yoff, true_width, true_height, ascender, descender);
int x, y;
unsigned char *line = buffer;
int top = ascender - yoff - height;
if (top < 0)
{
top = 0;
}
unsigned char *dest = bufBitmap + (per_bytes_line * top);
for (y=0 ; y < height; y++)
{
int bits = 7;
for (x=0; x < width; x++)
{
int on = (line[x >>3] & 1 << bits);
if (on)
{
int offset = x + xoff;
int bitoffset = 7 - (offset % 8);
dest[offset >>3] |= 1 << bitoffset;
}
bits = bits ? bits -1 : 7;
}
line += pitch;
dest += per_bytes_line;
}
line = bufBitmap;
for (y=0 ; y < true_height; y++)
{
int bits = 7;
for (x=0; x < true_width; x++)
{
cout << ((line[x >>3 ] & 1 << bits )? '*' : ' ');
bits = bits ? bits -1 : 7;
}
cout << "| " << "[ " ;
for (x=0; x <per_bytes_line ; x++)
{
printf("%02x", line[x]);
}
cout << " ]" << endl;
line += per_bytes_line;
}
free(buffer);
free(bufBitmap);
charcode = FT_Get_Next_Char(face, charcode, &gindex);
}
cerr << "Total Characters = " << count << endl;
return 0;
}
[/code:1]
[code:1]
編譯方法
g++ getbmp.cpp -o getbmp `freetype-config --cflags --libs`
執行
./getbmp -s [pixel_size] -f [字型檔案名稱]
[/code:1] |
|