|
|
@@ -55,7 +55,16 @@ static int const blocklist[] = |
|
|
|
0, 0 |
|
|
|
}; |
|
|
|
|
|
|
|
struct glyph |
|
|
|
{ |
|
|
|
uint32_t unicode; |
|
|
|
char buf[10]; |
|
|
|
unsigned int same_as; |
|
|
|
unsigned int data_index; |
|
|
|
}; |
|
|
|
|
|
|
|
static void fix_glyph(FT_Bitmap *, uint32_t, unsigned int, unsigned int); |
|
|
|
static int printf_unicode(struct glyph *); |
|
|
|
static int printf_hex(char const *, uint8_t *, int); |
|
|
|
static int printf_u32(char const *, uint32_t); |
|
|
|
static int printf_u16(char const *, uint16_t); |
|
|
@@ -69,9 +78,10 @@ int main(int argc, char *argv[]) |
|
|
|
PangoRectangle r; |
|
|
|
|
|
|
|
FT_Bitmap img; |
|
|
|
int width, height, b, i, n, blocks, glyphs; |
|
|
|
unsigned int glyph_size, control_size, data_size; |
|
|
|
int width, height, b, i, blocks, glyphs; |
|
|
|
unsigned int n, index, glyph_size, control_size, data_size; |
|
|
|
uint8_t *glyph_data; |
|
|
|
struct glyph *gtab; |
|
|
|
|
|
|
|
unsigned int bpp, dpi; |
|
|
|
char const *prefix, *font; |
|
|
@@ -128,7 +138,6 @@ int main(int argc, char *argv[]) |
|
|
|
width = PANGO_PIXELS(r.width); |
|
|
|
height = PANGO_PIXELS(r.height); |
|
|
|
glyph_size = ((width * height) + (8 / bpp) - 1) / (8 / bpp); |
|
|
|
glyph_data = malloc(glyph_size); |
|
|
|
|
|
|
|
/* Compute blocks and glyphs count */ |
|
|
|
blocks = 0; |
|
|
@@ -142,6 +151,9 @@ int main(int argc, char *argv[]) |
|
|
|
control_size = 24 + 12 * blocks + 8 * glyphs; |
|
|
|
data_size = glyph_size * glyphs; |
|
|
|
|
|
|
|
gtab = malloc(glyphs * sizeof(struct glyph)); |
|
|
|
glyph_data = malloc(data_size); |
|
|
|
|
|
|
|
/* Let's go! */ |
|
|
|
printf("/* libcucul font file\n"); |
|
|
|
printf(" * \"%s\": %i dpi, %i bpp, %ix%i glyphs\n", |
|
|
@@ -183,51 +195,30 @@ int main(int argc, char *argv[]) |
|
|
|
} |
|
|
|
printf("\n"); |
|
|
|
|
|
|
|
printf("/* glyph_info: */\n"); |
|
|
|
n = 0; |
|
|
|
for(b = 0; blocklist[b + 1]; b += 2) |
|
|
|
{ |
|
|
|
for(i = blocklist[b]; i < blocklist[b + 1]; i++) |
|
|
|
{ |
|
|
|
printf_u16("\"%s", width); |
|
|
|
printf_u16("%s", height); |
|
|
|
printf_u32("%s\"\n", n * glyph_size); |
|
|
|
n++; |
|
|
|
} |
|
|
|
} |
|
|
|
printf("\n"); |
|
|
|
|
|
|
|
printf("/* font_data: */\n"); |
|
|
|
/* Render all glyphs, so that we can know their offset */ |
|
|
|
n = index = 0; |
|
|
|
for(b = 0; blocklist[b + 1]; b += 2) |
|
|
|
{ |
|
|
|
for(i = blocklist[b]; i < blocklist[b + 1]; i++) |
|
|
|
{ |
|
|
|
unsigned int ch = i; |
|
|
|
char buf[10]; |
|
|
|
int x, y, bytes; |
|
|
|
unsigned int k; |
|
|
|
|
|
|
|
bytes = _cucul_utf32_to_utf8(buf, ch); |
|
|
|
buf[bytes] = '\0'; |
|
|
|
|
|
|
|
/* Print glyph value in comment */ |
|
|
|
printf("/* U+%.04X: \"", i); |
|
|
|
|
|
|
|
if(i < 0x20 || (i >= 0x80 && i <= 0xa0)) |
|
|
|
printf("\\x%.02x\" */", i); |
|
|
|
else |
|
|
|
printf("%s\" */ ", buf); |
|
|
|
gtab[n].unicode = i; |
|
|
|
bytes = _cucul_utf32_to_utf8(gtab[n].buf, gtab[n].unicode); |
|
|
|
gtab[n].buf[bytes] = '\0'; |
|
|
|
|
|
|
|
/* Render glyph on a bitmap */ |
|
|
|
pango_layout_set_text(l, buf, -1); |
|
|
|
memset(glyph_data, 0, glyph_size); |
|
|
|
pango_layout_set_text(l, gtab[n].buf, -1); |
|
|
|
memset(img.buffer, 0, img.pitch * height); |
|
|
|
pango_ft2_render_layout(&img, l, 0, 0); |
|
|
|
|
|
|
|
/* Fix glyphs that we know how to handle better */ |
|
|
|
fix_glyph(&img, ch, width, height); |
|
|
|
fix_glyph(&img, gtab[n].unicode, width, height); |
|
|
|
|
|
|
|
/* Write bitmap as an escaped C string */ |
|
|
|
n = 0; |
|
|
|
memset(glyph_data + n * glyph_size, 0, glyph_size); |
|
|
|
k = 0; |
|
|
|
for(y = 0; y < height; y++) |
|
|
|
{ |
|
|
|
for(x = 0; x < width; x++) |
|
|
@@ -235,17 +226,75 @@ int main(int argc, char *argv[]) |
|
|
|
uint8_t pixel = img.buffer[y * img.pitch + x]; |
|
|
|
|
|
|
|
pixel >>= (8 - bpp); |
|
|
|
glyph_data[n / 8] |= pixel << (8 - bpp - (n % 8)); |
|
|
|
n += bpp; |
|
|
|
glyph_data[n * glyph_size + k / 8] |
|
|
|
|= pixel << (8 - bpp - (k % 8)); |
|
|
|
k += bpp; |
|
|
|
} |
|
|
|
} |
|
|
|
printf_hex("\"%s\"\n", glyph_data, glyph_size); |
|
|
|
|
|
|
|
/* Check whether this is the same glyph as another one. Please |
|
|
|
* don't bullshit me about sorting, hashing and stuff like that, |
|
|
|
* our data is small enough for this to work. */ |
|
|
|
for(k = 0; k < n; k++) |
|
|
|
{ |
|
|
|
if(!memcmp(glyph_data + k * glyph_size, |
|
|
|
glyph_data + n * glyph_size, glyph_size)) |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
gtab[n].data_index = index; |
|
|
|
gtab[n].same_as = k; |
|
|
|
|
|
|
|
if(k == n) |
|
|
|
index++; |
|
|
|
|
|
|
|
n++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
printf("/* glyph_info: */\n"); |
|
|
|
n = 0; |
|
|
|
for(b = 0; blocklist[b + 1]; b += 2) |
|
|
|
{ |
|
|
|
for(i = blocklist[b]; i < blocklist[b + 1]; i++) |
|
|
|
{ |
|
|
|
printf_u16("\"%s", width); |
|
|
|
printf_u16("%s", height); |
|
|
|
printf_u32("%s\"\n", gtab[gtab[n].same_as].data_index * glyph_size); |
|
|
|
n++; |
|
|
|
} |
|
|
|
} |
|
|
|
printf("\n"); |
|
|
|
|
|
|
|
printf("/* font_data: */\n"); |
|
|
|
n = 0; |
|
|
|
for(b = 0; blocklist[b + 1]; b += 2) |
|
|
|
{ |
|
|
|
for(i = blocklist[b]; i < blocklist[b + 1]; i++) |
|
|
|
{ |
|
|
|
/* Print glyph value in comment */ |
|
|
|
printf("/* "); |
|
|
|
printf_unicode(>ab[n]); |
|
|
|
|
|
|
|
if(gtab[n].same_as == n) |
|
|
|
printf_hex(" */ \"%s\"\n", |
|
|
|
glyph_data + n * glyph_size, glyph_size); |
|
|
|
else |
|
|
|
{ |
|
|
|
printf(" is "); |
|
|
|
printf_unicode(>ab[gtab[n].same_as]); |
|
|
|
printf(" */\n"); |
|
|
|
} |
|
|
|
|
|
|
|
n++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
printf(";\n"); |
|
|
|
|
|
|
|
free(img.buffer); |
|
|
|
free(gtab); |
|
|
|
free(glyph_data); |
|
|
|
g_object_unref(l); |
|
|
|
g_object_unref(cx); |
|
|
|
|
|
|
@@ -328,6 +377,20 @@ static void fix_glyph(FT_Bitmap *i, uint32_t ch, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static int printf_unicode(struct glyph *g) |
|
|
|
{ |
|
|
|
int written = 0; |
|
|
|
|
|
|
|
written += printf("U+%.04X: \"", g->unicode); |
|
|
|
|
|
|
|
if(g->unicode < 0x20 || (g->unicode >= 0x7f && g->unicode <= 0xa0)) |
|
|
|
written += printf("\\x%.02x\"", g->unicode); |
|
|
|
else |
|
|
|
written += printf("%s\"", g->buf); |
|
|
|
|
|
|
|
return written; |
|
|
|
} |
|
|
|
|
|
|
|
static int printf_u32(char const *fmt, uint32_t i) |
|
|
|
{ |
|
|
|
uint32_t ni = hton32(i); |
|
|
|