Remove font processing functionality, to be handled through Go
This commit is contained in:
parent
e5afd5dfe1
commit
9722b74fa9
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
|
|||||||
project(zero-epwing)
|
project(zero-epwing)
|
||||||
include_directories(eb)
|
include_directories(eb)
|
||||||
link_directories(eb/eb/.libs jansson/lib)
|
link_directories(eb/eb/.libs jansson/lib)
|
||||||
add_executable(zero-epwing main.c book.c font.c convert.c hooks.c)
|
add_executable(zero-epwing main.c book.c convert.c hooks.c)
|
||||||
target_link_libraries(zero-epwing libm.a libeb.a libm.a libz.a libjansson.a)
|
target_link_libraries(zero-epwing libm.a libeb.a libm.a libz.a libjansson.a)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_link_libraries(zero-epwing libiconv.a)
|
target_link_libraries(zero-epwing libiconv.a)
|
||||||
|
37
book.c
37
book.c
@ -48,7 +48,7 @@ typedef struct {
|
|||||||
* Helper functions
|
* Helper functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char* book_read(EB_Book* book, EB_Hookset* hookset, const EB_Position* position, Book_Mode mode, const Font_Table* table, int flags) {
|
static char* book_read(EB_Book* book, EB_Hookset* hookset, const EB_Position* position, Book_Mode mode) {
|
||||||
if (eb_seek_text(book, position) != EB_SUCCESS) {
|
if (eb_seek_text(book, position) != EB_SUCCESS) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -57,17 +57,13 @@ static char* book_read(EB_Book* book, EB_Hookset* hookset, const EB_Position* po
|
|||||||
ssize_t data_length = 0;
|
ssize_t data_length = 0;
|
||||||
EB_Error_Code error;
|
EB_Error_Code error;
|
||||||
|
|
||||||
Hook_Params params = {};
|
|
||||||
params.table = table;
|
|
||||||
params.flags = flags;
|
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case BOOK_MODE_TEXT:
|
case BOOK_MODE_TEXT:
|
||||||
error = eb_read_text(
|
error = eb_read_text(
|
||||||
book,
|
book,
|
||||||
NULL,
|
NULL,
|
||||||
hookset,
|
hookset,
|
||||||
¶ms,
|
NULL,
|
||||||
ARRSIZE(data) - 1,
|
ARRSIZE(data) - 1,
|
||||||
data,
|
data,
|
||||||
&data_length
|
&data_length
|
||||||
@ -78,7 +74,7 @@ static char* book_read(EB_Book* book, EB_Hookset* hookset, const EB_Position* po
|
|||||||
book,
|
book,
|
||||||
NULL,
|
NULL,
|
||||||
hookset,
|
hookset,
|
||||||
¶ms,
|
NULL,
|
||||||
ARRSIZE(data) - 1,
|
ARRSIZE(data) - 1,
|
||||||
data,
|
data,
|
||||||
&data_length
|
&data_length
|
||||||
@ -97,13 +93,12 @@ static char* book_read(EB_Book* book, EB_Hookset* hookset, const EB_Position* po
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
font_stub_decode(result, strlen(result) + 1, result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Book_Block book_read_content(EB_Book* book, EB_Hookset* hookset, const EB_Position* position, Book_Mode mode, const Font_Table* table, int flags) {
|
static Book_Block book_read_content(EB_Book* book, EB_Hookset* hookset, const EB_Position* position, Book_Mode mode) {
|
||||||
Book_Block block = {};
|
Book_Block block = {};
|
||||||
block.text = book_read(book, hookset, position, mode, table, flags);
|
block.text = book_read(book, hookset, position, mode);
|
||||||
block.page = position->page;
|
block.page = position->page;
|
||||||
block.offset = position->offset;
|
block.offset = position->offset;
|
||||||
return block;
|
return block;
|
||||||
@ -241,7 +236,7 @@ static void book_encode(json_t* book_json, const Book* book, int flags) {
|
|||||||
* Importing from EPWING
|
* Importing from EPWING
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void subbook_entries_import(Book_Subbook* subbook, EB_Book* eb_book, EB_Hookset* eb_hookset, const Font_Table* table, int flags) {
|
static void subbook_entries_import(Book_Subbook* subbook, EB_Book* eb_book, EB_Hookset* eb_hookset) {
|
||||||
if (subbook->entry_alloc == 0) {
|
if (subbook->entry_alloc == 0) {
|
||||||
subbook->entry_alloc = 16384;
|
subbook->entry_alloc = 16384;
|
||||||
subbook->entries = malloc(subbook->entry_alloc * sizeof(Book_Entry));
|
subbook->entries = malloc(subbook->entry_alloc * sizeof(Book_Entry));
|
||||||
@ -264,38 +259,36 @@ static void subbook_entries_import(Book_Subbook* subbook, EB_Book* eb_book, EB_H
|
|||||||
}
|
}
|
||||||
|
|
||||||
Book_Entry* entry = subbook->entries + subbook->entry_count++;
|
Book_Entry* entry = subbook->entries + subbook->entry_count++;
|
||||||
entry->heading = book_read_content(eb_book, eb_hookset, &hit->heading, BOOK_MODE_HEADING, table, flags);
|
entry->heading = book_read_content(eb_book, eb_hookset, &hit->heading, BOOK_MODE_HEADING);
|
||||||
entry->text = book_read_content(eb_book, eb_hookset, &hit->text, BOOK_MODE_TEXT, table, flags);
|
entry->text = book_read_content(eb_book, eb_hookset, &hit->text, BOOK_MODE_TEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (hit_count > 0);
|
while (hit_count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subbook_import(Book_Subbook* subbook, const Font_Context* context, EB_Book* eb_book, EB_Hookset* eb_hookset, int flags) {
|
static void subbook_import(Book_Subbook* subbook, EB_Book* eb_book, EB_Hookset* eb_hookset, int flags) {
|
||||||
const Font_Table* table = NULL;
|
|
||||||
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);
|
||||||
table = font_table_select(context, subbook->title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eb_have_copyright(eb_book)) {
|
if (eb_have_copyright(eb_book)) {
|
||||||
EB_Position position;
|
EB_Position position;
|
||||||
if (eb_copyright(eb_book, &position) == EB_SUCCESS) {
|
if (eb_copyright(eb_book, &position) == EB_SUCCESS) {
|
||||||
subbook->copyright = book_read_content(eb_book, eb_hookset, &position, BOOK_MODE_TEXT, table, flags);
|
subbook->copyright = book_read_content(eb_book, eb_hookset, &position, BOOK_MODE_TEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eb_search_all_alphabet(eb_book) == EB_SUCCESS) {
|
if (eb_search_all_alphabet(eb_book) == EB_SUCCESS) {
|
||||||
subbook_entries_import(subbook, eb_book, eb_hookset, table, flags);
|
subbook_entries_import(subbook, eb_book, eb_hookset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eb_search_all_kana(eb_book) == EB_SUCCESS) {
|
if (eb_search_all_kana(eb_book) == EB_SUCCESS) {
|
||||||
subbook_entries_import(subbook, eb_book, eb_hookset, table, flags);
|
subbook_entries_import(subbook, 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, table, flags);
|
subbook_entries_import(subbook, eb_book, eb_hookset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +333,7 @@ int book_export(FILE* fp, const Book* book, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int book_import(Book* book, const Font_Context* context, const char path[], int flags) {
|
int book_import(Book* book, const char path[], int flags) {
|
||||||
EB_Error_Code error;
|
EB_Error_Code error;
|
||||||
if ((error = eb_initialize_library()) != EB_SUCCESS) {
|
if ((error = eb_initialize_library()) != EB_SUCCESS) {
|
||||||
fprintf(stderr, "Failed to initialize library: %s\n", eb_error_message(error));
|
fprintf(stderr, "Failed to initialize library: %s\n", eb_error_message(error));
|
||||||
@ -408,7 +401,7 @@ int book_import(Book* book, const Font_Context* context, const char path[], int
|
|||||||
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, context, &eb_book, &eb_hookset, flags);
|
subbook_import(subbook, &eb_book, &eb_hookset, flags);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Failed to set subbook: %s\n", eb_error_message(error));
|
fprintf(stderr, "Failed to set subbook: %s\n", eb_error_message(error));
|
||||||
|
4
book.h
4
book.h
@ -21,8 +21,6 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "font.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
@ -59,7 +57,7 @@ typedef struct {
|
|||||||
|
|
||||||
void book_init(Book* book);
|
void book_init(Book* book);
|
||||||
void book_free(Book* book);
|
void book_free(Book* book);
|
||||||
int book_import(Book* book, const Font_Context* context, const char path[], int flags);
|
int book_import(Book* book, const char path[], int flags);
|
||||||
int book_export(FILE* fp, const Book* book, int flags);
|
int book_export(FILE* fp, const Book* book, int flags);
|
||||||
|
|
||||||
#endif /* BOOK_H */
|
#endif /* BOOK_H */
|
||||||
|
271
font.c
271
font.c
@ -1,271 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
|
|
||||||
* Author: Alex Yatskov <alex@foosoft.net>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "jansson/include/jansson.h"
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
#include "font.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Local functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int ascii_to_nibble(char c) {
|
|
||||||
if (c >= '0' && c <= '9') {
|
|
||||||
return c - '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c >= 'a' && c <= 'f') {
|
|
||||||
return 0x0a + (c - 'a');
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char nibble_to_ascii(int n) {
|
|
||||||
const char hex[] = {
|
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
|
||||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
|
||||||
};
|
|
||||||
|
|
||||||
return n <= 0x0f ? hex[n] : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is_ascii_nibble(char c) {
|
|
||||||
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
|
|
||||||
}
|
|
||||||
|
|
||||||
static void encode_sequence(char output[], int size, const char utf8[]) {
|
|
||||||
strncpy(output, "{#", size);
|
|
||||||
int offset = strlen(output);
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_UTF8_BYTES; ++i) {
|
|
||||||
const unsigned char byte = utf8[i];
|
|
||||||
if (byte == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= size - 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
output[offset++] = nibble_to_ascii(byte >> 0x04);
|
|
||||||
|
|
||||||
if (offset >= size - 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
output[offset++] = nibble_to_ascii(byte & 0x0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
output[offset] = 0;
|
|
||||||
strncat(output, "}", size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_entry(Font_Entry* entry, const json_t* entry_json) {
|
|
||||||
entry->code = json_integer_value(json_array_get(entry_json, 0));
|
|
||||||
const char* utf8 = json_string_value(json_array_get(entry_json, 1));
|
|
||||||
if (utf8 == NULL) {
|
|
||||||
*entry->utf8 = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
strncpy(entry->utf8, utf8, ARRSIZE(entry->utf8));
|
|
||||||
entry->utf8[ARRSIZE(entry->utf8) - 1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_entries(Font_Entry** entries, int* count, const json_t* entry_array_json) {
|
|
||||||
*count = json_array_size(entry_array_json);
|
|
||||||
if (*count == 0) {
|
|
||||||
*entries = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*entries = malloc(sizeof(Font_Entry) * *count);
|
|
||||||
for (int i = 0; i < *count; ++i) {
|
|
||||||
parse_entry(*entries + i, json_array_get(entry_array_json, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_table(Font_Table* table, const json_t* table_json) {
|
|
||||||
const char* name = json_string_value(json_object_get(table_json, "name"));
|
|
||||||
if (name == NULL) {
|
|
||||||
*table->name = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
strncpy(table->name, name, ARRSIZE(table->name));
|
|
||||||
table->name[ARRSIZE(table->name) - 1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_entries(
|
|
||||||
(Font_Entry**)&table->table_wide,
|
|
||||||
&table->table_wide_size,
|
|
||||||
json_object_get(table_json, "wide")
|
|
||||||
);
|
|
||||||
|
|
||||||
parse_entries(
|
|
||||||
(Font_Entry**)&table->table_narrow,
|
|
||||||
&table->table_narrow_size,
|
|
||||||
json_object_get(table_json, "narrow")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_table_array(Font_Context* context, const json_t* table_array_json) {
|
|
||||||
context->table_count = json_array_size(table_array_json);
|
|
||||||
if (context->table_count == 0) {
|
|
||||||
context->tables = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
context->tables = malloc(sizeof(Font_Table) * context->table_count);
|
|
||||||
for (int i = 0; i < context->table_count; ++i) {
|
|
||||||
parse_table(context->tables + i, json_array_get(table_array_json, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Exported functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Font_Table* font_table_select(const Font_Context* context, const char name[]) {
|
|
||||||
for (int i = 0; i < context->table_count; ++i) {
|
|
||||||
const Font_Table* table = context->tables + i;
|
|
||||||
if (strstr(name, table->name) != NULL) {
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_stub_encode(char output[], int size, int code, const Font_Table* table, Font_Width width, int flags) {
|
|
||||||
do {
|
|
||||||
if (table == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Font_Entry* entries = NULL;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
switch (width) {
|
|
||||||
case FONT_WIDTH_WIDE:
|
|
||||||
entries = table->table_wide;
|
|
||||||
count = table->table_wide_size;
|
|
||||||
break;
|
|
||||||
case FONT_WIDTH_NARROW:
|
|
||||||
entries = table->table_narrow;
|
|
||||||
count = table->table_narrow_size;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(entries != NULL);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
const Font_Entry* entry = entries + i;
|
|
||||||
if (entry->code == code) {
|
|
||||||
encode_sequence(output, size, entry->utf8);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
while (0);
|
|
||||||
|
|
||||||
if (flags & FLAG_FONT_TAGS) {
|
|
||||||
snprintf(output, size, "{?%.8x}", code);
|
|
||||||
output[size - 1] = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
encode_sequence(output, size, "\xef\xbf\xbd");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_stub_decode(char output[], int size, const char input[]) {
|
|
||||||
const char* ptr_in = input;
|
|
||||||
char* ptr_out = output;
|
|
||||||
int decode = 0;
|
|
||||||
|
|
||||||
while (*ptr_in != 0 && ptr_out - output < size - 1) {
|
|
||||||
if (strncmp(ptr_in, "{#", 2) == 0) {
|
|
||||||
decode = 1;
|
|
||||||
ptr_in += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decode) {
|
|
||||||
const char high_ascii = *ptr_in++;
|
|
||||||
if (high_ascii == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char low_ascii = *ptr_in++;
|
|
||||||
if (low_ascii == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (high_ascii == '}') {
|
|
||||||
decode = 0;
|
|
||||||
--ptr_in;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(is_ascii_nibble(high_ascii));
|
|
||||||
assert(is_ascii_nibble(low_ascii));
|
|
||||||
*ptr_out++ = ascii_to_nibble(high_ascii) << 0x04 | ascii_to_nibble(low_ascii);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*ptr_out++ = *ptr_in++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*ptr_out = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int font_context_init(Font_Context* context, const char path[]) {
|
|
||||||
context->table_count = 0;
|
|
||||||
context->tables = NULL;
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_t* table_array_json = json_load_file(path, 0, NULL);
|
|
||||||
if (table_array_json == NULL) {
|
|
||||||
fprintf(stderr, "Failed to load font file %s\n", path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_table_array(context, table_array_json);
|
|
||||||
json_decref(table_array_json);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_context_destroy(Font_Context* context) {
|
|
||||||
for (int i = 0; i < context->table_count; ++i) {
|
|
||||||
Font_Table* table = context->tables + i;
|
|
||||||
free((Font_Entry*)table->table_wide);
|
|
||||||
free((Font_Entry*)table->table_narrow);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(context->tables);
|
|
||||||
|
|
||||||
context->tables = NULL;
|
|
||||||
context->table_count = 0;
|
|
||||||
}
|
|
68
font.h
68
font.h
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
|
|
||||||
* Author: Alex Yatskov <alex@foosoft.net>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FONT_H
|
|
||||||
#define FONT_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MAX_UTF8_BYTES 10
|
|
||||||
#define MAX_STUB_BYTES 32
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Types
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int code;
|
|
||||||
char utf8[MAX_UTF8_BYTES];
|
|
||||||
} Font_Entry;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char name[256];
|
|
||||||
const Font_Entry* table_wide;
|
|
||||||
int table_wide_size;
|
|
||||||
const Font_Entry* table_narrow;
|
|
||||||
int table_narrow_size;
|
|
||||||
} Font_Table;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Font_Table* tables;
|
|
||||||
int table_count;
|
|
||||||
} Font_Context;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FONT_WIDTH_WIDE,
|
|
||||||
FONT_WIDTH_NARROW,
|
|
||||||
} Font_Width;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
int font_context_init(Font_Context* context, const char path[]);
|
|
||||||
void font_context_destroy(Font_Context* context);
|
|
||||||
|
|
||||||
const Font_Table* font_table_select(const Font_Context* context, const char name[]);
|
|
||||||
|
|
||||||
void font_stub_encode(char output[], int size, int code, const Font_Table* table, Font_Width width, int flags);
|
|
||||||
void font_stub_decode(char output[], int size, const char input[]);
|
|
||||||
|
|
||||||
#endif /* FONT_H */
|
|
22
hooks.c
22
hooks.c
@ -116,8 +116,8 @@ static EB_Error_Code hook_end_reference( /* EB_HOOK_END_REFERENCE */
|
|||||||
char ref[256];
|
char ref[256];
|
||||||
snprintf(ref, ARRSIZE(ref), "<end_reference page=%d offset=%d>", argv[1], argv[2]);
|
snprintf(ref, ARRSIZE(ref), "<end_reference page=%d offset=%d>", argv[1], argv[2]);
|
||||||
ref[ARRSIZE(ref) - 1] = 0;
|
ref[ARRSIZE(ref) - 1] = 0;
|
||||||
eb_write_text_string(book, ref);
|
|
||||||
|
|
||||||
|
eb_write_text_string(book, ref);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,15 +130,15 @@ static EB_Error_Code hook_narrow_font( /* EB_HOOK_NARROW_FONT */
|
|||||||
const unsigned int argv[]
|
const unsigned int argv[]
|
||||||
) {
|
) {
|
||||||
(void)appendix;
|
(void)appendix;
|
||||||
|
(void)container;
|
||||||
(void)code;
|
(void)code;
|
||||||
|
|
||||||
Hook_Params* params = (Hook_Params*)container;
|
char stub[32];
|
||||||
|
|
||||||
assert(argc >= 1);
|
assert(argc >= 1);
|
||||||
char stub[MAX_STUB_BYTES];
|
snprintf(stub, ARRSIZE(stub), "{{n_%u}}", argv[0]);
|
||||||
font_stub_encode(stub, ARRSIZE(stub), argv[0], params->table, FONT_WIDTH_NARROW, params->flags);
|
stub[ARRSIZE(stub) - 1] = 0;
|
||||||
eb_write_text_string(book, stub);
|
|
||||||
|
|
||||||
|
eb_write_text_string(book, stub);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,15 +151,15 @@ static EB_Error_Code hook_wide_font( /* EB_HOOK_WIDE_FONT */
|
|||||||
const unsigned int argv[]
|
const unsigned int argv[]
|
||||||
) {
|
) {
|
||||||
(void)appendix;
|
(void)appendix;
|
||||||
|
(void)container;
|
||||||
(void)code;
|
(void)code;
|
||||||
|
|
||||||
Hook_Params* params = (Hook_Params*)container;
|
char stub[32];
|
||||||
|
assert(argc >= 1);
|
||||||
|
snprintf(stub, ARRSIZE(stub), "{{w_%u}}", argv[0]);
|
||||||
|
stub[ARRSIZE(stub) - 1] = 0;
|
||||||
|
|
||||||
assert(argc > 0);
|
|
||||||
char stub[MAX_STUB_BYTES];
|
|
||||||
font_stub_encode(stub, ARRSIZE(stub), argv[0], params->table, FONT_WIDTH_WIDE, params->flags);
|
|
||||||
eb_write_text_string(book, stub);
|
eb_write_text_string(book, stub);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
hooks.h
10
hooks.h
@ -19,18 +19,8 @@
|
|||||||
#ifndef HOOKS_H
|
#ifndef HOOKS_H
|
||||||
#define HOOKS_H
|
#define HOOKS_H
|
||||||
|
|
||||||
#include "font.h"
|
|
||||||
#include "eb/eb/eb.h"
|
#include "eb/eb/eb.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Types
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const void* table;
|
|
||||||
int flags;
|
|
||||||
} Hook_Params;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions
|
* Functions
|
||||||
*/
|
*/
|
||||||
|
18
main.c
18
main.c
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "book.h"
|
#include "book.h"
|
||||||
#include "font.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point
|
* Entry point
|
||||||
@ -29,24 +28,18 @@
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
const struct option options[] = {
|
const struct option options[] = {
|
||||||
{ "font-table", required_argument, NULL, 'f' },
|
|
||||||
{ "pretty-print", no_argument, NULL, 'p' },
|
{ "pretty-print", no_argument, NULL, 'p' },
|
||||||
{ "markup", no_argument, NULL, 'm' },
|
{ "markup", no_argument, NULL, 'm' },
|
||||||
{ "positions", no_argument, NULL, 's' },
|
{ "positions", no_argument, NULL, 's' },
|
||||||
{ "font-tags", no_argument, NULL, 't' },
|
|
||||||
{ NULL, 0, NULL, 0 },
|
{ NULL, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
char* dict_path = NULL;
|
char* dict_path = NULL;
|
||||||
char* font_path = NULL;
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
int c = 0;
|
int c = 0;
|
||||||
while ((c = getopt_long(argc, argv, "f:d:pmst", options, NULL)) != -1) {
|
while ((c = getopt_long(argc, argv, "f:d:pmst", options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'f':
|
|
||||||
font_path = optarg;
|
|
||||||
break;
|
|
||||||
case 'p':
|
case 'p':
|
||||||
flags |= FLAG_PRETTY_PRINT;
|
flags |= FLAG_PRETTY_PRINT;
|
||||||
break;
|
break;
|
||||||
@ -56,9 +49,6 @@ int main(int argc, char *argv[]) {
|
|||||||
case 's':
|
case 's':
|
||||||
flags |= FLAG_POSITIONS;
|
flags |= FLAG_POSITIONS;
|
||||||
break;
|
break;
|
||||||
case 't':
|
|
||||||
flags |= FLAG_FONT_TAGS;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -71,20 +61,14 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
dict_path = argv[optind];
|
dict_path = argv[optind];
|
||||||
|
|
||||||
Font_Context context;
|
|
||||||
if (!font_context_init(&context, font_path == 0 ? NULL : font_path)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Book book;
|
Book book;
|
||||||
book_init(&book);
|
book_init(&book);
|
||||||
|
|
||||||
const int success =
|
const int success =
|
||||||
book_import(&book, &context, dict_path, flags) &&
|
book_import(&book, dict_path, flags) &&
|
||||||
book_export(stdout, &book, flags);
|
book_export(stdout, &book, flags);
|
||||||
|
|
||||||
book_free(&book);
|
book_free(&book);
|
||||||
|
|
||||||
font_context_destroy(&context);
|
|
||||||
return success ? 0 : 1;
|
return success ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user