1

initial commit for font extraction

This commit is contained in:
Alex Yatskov 2017-02-11 19:46:46 -08:00
parent 3e90d20da1
commit 19980ef3de
4 changed files with 189 additions and 9 deletions

175
book.c
View File

@ -198,6 +198,43 @@ static void entry_encode(json_t* entry_json, const Book_Entry* entry, int flags)
} }
} }
static void font_glyph_encode(json_t* glyph_json, const Book_Glyph* glyph) {
json_t* bitmap_json_array = json_array();
for (unsigned i = 0; i < ARRSIZE(glyph->bitmap); ++i) {
json_array_append_new(bitmap_json_array, json_integer(glyph->bitmap[i]));
}
json_object_set_new(glyph_json, "bitmap", bitmap_json_array);
json_object_set_new(glyph_json, "code", json_integer(glyph->code));
}
static void font_glyph_set_encode(json_t* glyph_set_json, const Book_Glyph_Set* glyph_set) {
json_t* glyph_json_array = json_array();
for (int i = 0; i < glyph_set->count; ++i) {
json_t* glyph_json = json_object();
font_glyph_encode(glyph_json, &glyph_set->glyphs[i]);
json_array_append_new(glyph_json_array, glyph_json);
}
json_object_set_new(glyph_set_json, "glyphs", glyph_json_array);
json_object_set_new(glyph_set_json, "width", json_integer(glyph_set->width));
json_object_set_new(glyph_set_json, "height", json_integer(glyph_set->height));
}
static void font_encode(json_t* font_json, const Book_Font* font) {
if (font->narrow.count > 0) {
json_t* narrow_json = json_object();
font_glyph_set_encode(narrow_json, &font->narrow);
json_object_set_new(font_json, "narrow", narrow_json);
}
if (font->wide.count > 0) {
json_t* wide_json = json_object();
font_glyph_set_encode(wide_json, &font->wide);
json_object_set_new(font_json, "wide", wide_json);
}
}
static void subbook_encode(json_t* subbook_json, const Book_Subbook* subbook, int flags) { static void subbook_encode(json_t* subbook_json, const Book_Subbook* subbook, int flags) {
if (subbook->title != NULL) { if (subbook->title != NULL) {
json_object_set_new(subbook_json, "title", json_string(subbook->title)); json_object_set_new(subbook_json, "title", json_string(subbook->title));
@ -212,6 +249,20 @@ static void subbook_encode(json_t* subbook_json, const Book_Subbook* subbook, in
json_object_set_new(subbook_json, "copyrightOffset", json_integer(subbook->copyright.offset)); json_object_set_new(subbook_json, "copyrightOffset", json_integer(subbook->copyright.offset));
} }
if (flags & FLAG_FONTS) {
json_t* font_json_array = json_array();
for (unsigned i = 0; i < ARRSIZE(subbook->fonts); ++i) {
const Book_Font* font = subbook->fonts + i;
if (font->wide.count > 0 || font->narrow.count) {
json_t* font_json = json_object();
font_encode(font_json, font);
json_array_append_new(font_json_array, font_json);
}
}
json_object_set_new(subbook_json, "fonts", font_json_array);
}
json_t* entry_json_array = json_array(); json_t* entry_json_array = json_array();
for (int i = 0; i < subbook->entry_count; ++i) { for (int i = 0; i < subbook->entry_count; ++i) {
json_t* entry_json = json_object(); json_t* entry_json = json_object();
@ -270,7 +321,113 @@ static void subbook_entries_import(Book_Subbook* subbook, EB_Book* eb_book, EB_H
while (hit_count > 0); while (hit_count > 0);
} }
static void subbook_import(Book_Subbook* subbook, EB_Book* eb_book, EB_Hookset* eb_hookset) { static void subbook_font_import(Book_Font* font, EB_Book* eb_book, EB_Font_Code code) {
if (eb_set_font(eb_book, code) != EB_SUCCESS) {
return;
}
do {
switch (code) {
case EB_FONT_16:
font->narrow.width = EB_WIDTH_NARROW_FONT_16;
font->narrow.height = EB_HEIGHT_FONT_16;
break;
case EB_FONT_24:
font->narrow.width = EB_WIDTH_NARROW_FONT_24;
font->narrow.height = EB_HEIGHT_FONT_24;
break;
case EB_FONT_30:
font->narrow.width = EB_WIDTH_NARROW_FONT_30;
font->narrow.height = EB_HEIGHT_FONT_30;
break;
case EB_FONT_48:
font->narrow.width = EB_WIDTH_NARROW_FONT_48;
font->narrow.height = EB_HEIGHT_FONT_48;
break;
}
int font_code = 0;
if (eb_narrow_font_start(eb_book, &font_code) != EB_SUCCESS) {
break;
}
int glyph_alloc = 256;
font->narrow.glyphs = malloc(sizeof(Book_Glyph) * glyph_alloc);
for (;;) {
if (font->narrow.count == glyph_alloc) {
glyph_alloc *= 2;
font->narrow.glyphs = realloc(font->narrow.glyphs, glyph_alloc);
}
Book_Glyph* glyph = &font->narrow.glyphs[font->narrow.count];
glyph->code = font_code;
if (eb_narrow_font_character_bitmap(eb_book, font_code, glyph->bitmap) != EB_SUCCESS) {
break;
}
++font->narrow.count;
if (eb_forward_narrow_font_character(eb_book, 1, &font_code) != EB_SUCCESS) {
break;
}
}
}
while (0);
do {
switch (code) {
case EB_FONT_16:
font->wide.width = EB_WIDTH_WIDE_FONT_16;
font->wide.height = EB_HEIGHT_FONT_16;
break;
case EB_FONT_24:
font->wide.width = EB_WIDTH_WIDE_FONT_24;
font->wide.height = EB_HEIGHT_FONT_24;
break;
case EB_FONT_30:
font->wide.width = EB_WIDTH_WIDE_FONT_30;
font->wide.height = EB_HEIGHT_FONT_30;
break;
case EB_FONT_48:
font->wide.width = EB_WIDTH_WIDE_FONT_48;
font->wide.height = EB_HEIGHT_FONT_48;
break;
}
int font_code = 0;
if (eb_wide_font_start(eb_book, &font_code) != EB_SUCCESS) {
break;
}
int glyph_alloc = 256;
font->wide.glyphs = malloc(sizeof(Book_Glyph) * glyph_alloc);
for (;;) {
if (font->wide.count == glyph_alloc) {
glyph_alloc *= 2;
font->wide.glyphs = realloc(font->wide.glyphs, glyph_alloc);
}
Book_Glyph* glyph = &font->wide.glyphs[font->wide.count];
glyph->code = font_code;
if (eb_wide_font_character_bitmap(eb_book, font_code, glyph->bitmap) != EB_SUCCESS) {
break;
}
++font->wide.count;
if (eb_forward_wide_font_character(eb_book, 1, &font_code) != EB_SUCCESS) {
break;
}
}
}
while (0);
}
static void subbook_import(Book_Subbook* subbook, EB_Book* eb_book, EB_Hookset* eb_hookset, int flags) {
char title[EB_MAX_TITLE_LENGTH + 1]; char title[EB_MAX_TITLE_LENGTH + 1];
if (eb_subbook_title(eb_book, title) == EB_SUCCESS) { if (eb_subbook_title(eb_book, title) == EB_SUCCESS) {
subbook->title = eucjp_to_utf8(title); subbook->title = eucjp_to_utf8(title);
@ -294,6 +451,14 @@ static void subbook_import(Book_Subbook* subbook, EB_Book* eb_book, EB_Hookset*
if (eb_search_all_asis(eb_book) == EB_SUCCESS) { if (eb_search_all_asis(eb_book) == EB_SUCCESS) {
subbook_entries_import(subbook, eb_book, eb_hookset); subbook_entries_import(subbook, eb_book, eb_hookset);
} }
memset(subbook->fonts, 0, sizeof(subbook->fonts));
if (flags & FLAG_FONTS) {
const EB_Font_Code codes[] = {EB_FONT_16, EB_FONT_24, EB_FONT_30, EB_FONT_48};
for (unsigned i = 0; i < ARRSIZE(codes); ++i) {
subbook_font_import(&subbook->fonts[i], eb_book, codes[i]);
}
}
} }
/* /*
@ -316,6 +481,12 @@ void book_free(Book* book) {
free(entry->text.text); free(entry->text.text);
} }
for (unsigned j = 0; j < ARRSIZE(subbook->fonts); ++j) {
const Book_Font* font = &subbook->fonts[j];
free(font->narrow.glyphs);
free(font->wide.glyphs);
}
free(subbook->entries); free(subbook->entries);
} }
@ -405,7 +576,7 @@ int book_import(Book* book, const char path[], int flags) {
for (int i = 0; i < book->subbook_count; ++i) { for (int i = 0; i < book->subbook_count; ++i) {
Book_Subbook* subbook = book->subbooks + i; Book_Subbook* subbook = book->subbooks + i;
if ((error = eb_set_subbook(&eb_book, sub_codes[i])) == EB_SUCCESS) { if ((error = eb_set_subbook(&eb_book, sub_codes[i])) == EB_SUCCESS) {
subbook_import(subbook, &eb_book, &eb_hookset); subbook_import(subbook, &eb_book, &eb_hookset, flags);
} }
else { else {
fprintf(stderr, "error: failed to set subbook (%s)\n", eb_error_message(error)); fprintf(stderr, "error: failed to set subbook (%s)\n", eb_error_message(error));

17
book.h
View File

@ -42,14 +42,20 @@ typedef struct {
} Book_Entry; } Book_Entry;
typedef struct { typedef struct {
unsigned char bitmap[EB_SIZE_WIDE_FONT_48]; char bitmap[EB_SIZE_WIDE_FONT_48];
int code;
} Book_Glyph; } Book_Glyph;
typedef struct { typedef struct {
Book_Glyph* glyphs; Book_Glyph* glyphs;
int glyph_count; int width;
int glyph_size; int height;
int glyph_wide; int count;
} Book_Glyph_Set;
typedef struct {
Book_Glyph_Set wide;
Book_Glyph_Set narrow;
} Book_Font; } Book_Font;
typedef struct { typedef struct {
@ -60,8 +66,7 @@ typedef struct {
int entry_count; int entry_count;
int entry_alloc; int entry_alloc;
Book_Font* fonts; Book_Font fonts[4];
int font_count;
} Book_Subbook; } Book_Subbook;
typedef struct { typedef struct {

4
main.c
View File

@ -35,6 +35,7 @@ int main(int argc, char *argv[]) {
{ "pretty", no_argument, NULL, 'p' }, { "pretty", no_argument, NULL, 'p' },
{ "markup", no_argument, NULL, 'm' }, { "markup", no_argument, NULL, 'm' },
{ "positions", no_argument, NULL, 's' }, { "positions", no_argument, NULL, 's' },
{ "fonts", no_argument, NULL, 'f' },
{ NULL, 0, NULL, 0 }, { NULL, 0, NULL, 0 },
}; };
@ -53,6 +54,9 @@ int main(int argc, char *argv[]) {
case 's': case 's':
flags |= FLAG_POSITIONS; flags |= FLAG_POSITIONS;
break; break;
case 'f':
flags |= FLAG_FONTS;
break;
default: default:
return 1; return 1;
} }

2
util.h
View File

@ -33,7 +33,7 @@ enum {
FLAG_PRETTY_PRINT = 1 << 0, FLAG_PRETTY_PRINT = 1 << 0,
FLAG_HOOK_MARKUP = 1 << 1, FLAG_HOOK_MARKUP = 1 << 1,
FLAG_POSITIONS = 1 << 2, FLAG_POSITIONS = 1 << 2,
FLAG_FONT_TAGS = 1 << 3, FLAG_FONTS = 1 << 3,
}; };
#endif /* UTIL_H */ #endif /* UTIL_H */