1
zero-epwing-go/widefont.c

1075 lines
27 KiB
C
Raw Normal View History

2021-01-09 22:39:52 +00:00
/* automatically generated from narwfont.c. */
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "font.h"
#include "build-post.h"
/*
* Unexported functions.
*/
static EB_Error_Code eb_wide_character_bitmap_jis(EB_Book *book,
int character_number, char *bitmap);
static EB_Error_Code eb_wide_character_bitmap_latin(EB_Book *book,
int character_number, char *bitmap);
/*
* Open a font file.
*/
EB_Error_Code
eb_open_wide_font_file(EB_Book *book, EB_Font_Code font_code)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
EB_Font *wide_font;
char font_path_name[EB_MAX_PATH_LENGTH + 1];
Zio_Code zio_code;
LOG(("in: eb_open_wide_font(book=%d, font_code=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, (int)font_code));
2021-01-09 22:39:52 +00:00
subbook = book->subbook_current;
wide_font = subbook->wide_fonts + font_code;
if (wide_font->font_code == EB_FONT_INVALID) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_FAIL_OPEN_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
if (0 <= zio_file(&wide_font->zio))
2021-01-09 23:22:43 +00:00
goto succeeded;
2021-01-09 22:39:52 +00:00
/*
* If the book is EBWING, open the wide font file.
* (In EB books, font data are stored in the `START' file.)
*/
zio_code = ZIO_INVALID;
if (book->disc_code == EB_DISC_EB) {
2021-01-09 23:22:43 +00:00
if (wide_font->initialized) {
if (zio_mode(&wide_font->zio) != ZIO_INVALID)
zio_code = ZIO_REOPEN;
} else {
zio_code = zio_mode(&subbook->text_zio);
}
eb_compose_path_name2(book->path, subbook->directory_name,
subbook->text_file_name, font_path_name);
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
if (wide_font->initialized) {
if (zio_mode(&wide_font->zio) != ZIO_INVALID)
zio_code = ZIO_REOPEN;
eb_compose_path_name3(book->path, subbook->directory_name,
subbook->gaiji_directory_name, wide_font->file_name,
font_path_name);
} else {
eb_canonicalize_file_name(wide_font->file_name);
if (eb_find_file_name3(book->path, subbook->directory_name,
subbook->gaiji_directory_name, wide_font->file_name,
wide_font->file_name) != EB_SUCCESS) {
error_code = EB_ERR_FAIL_OPEN_FONT;
goto failed;
}
eb_compose_path_name3(book->path, subbook->directory_name,
subbook->gaiji_directory_name, wide_font->file_name,
font_path_name);
eb_path_name_zio_code(font_path_name, ZIO_PLAIN, &zio_code);
}
2021-01-09 22:39:52 +00:00
}
if (zio_code != ZIO_INVALID
2021-01-09 23:22:43 +00:00
&& zio_open(&wide_font->zio, font_path_name, zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
succeeded:
LOG(("out: eb_open_wide_font_file(file=%d) = %s",
2021-01-09 23:22:43 +00:00
zio_file(&wide_font->zio), eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_open_wide_font_file() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Read font header.
*/
EB_Error_Code
eb_load_wide_font_header(EB_Book *book, EB_Font_Code font_code)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
EB_Font *wide_font;
char buffer[16];
int character_count;
Zio *zio;
LOG(("in: eb_load_wide_font_header(book=%d, font_code=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, (int)font_code));
2021-01-09 22:39:52 +00:00
subbook = book->subbook_current;
wide_font = subbook->wide_fonts + font_code;
zio = &wide_font->zio;
if (wide_font->initialized)
2021-01-09 23:22:43 +00:00
goto succeeded;
2021-01-09 22:39:52 +00:00
/*
* Read information from the text file.
*/
if (zio_lseek(zio, ((off_t) wide_font->page - 1) * EB_SIZE_PAGE,
2021-01-09 23:22:43 +00:00
SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
if (zio_read(zio, buffer, 16) != 16) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_FAIL_READ_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* If the number of characters (`character_count') is 0, the font
* is unavailable. We return EB_ERR_NO_SUCH_FONT.
*/
character_count = eb_uint2(buffer + 12);
if (character_count == 0) {
2021-01-09 23:22:43 +00:00
zio_close(zio);
error_code = EB_ERR_NO_SUCH_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Set the information.
*/
wide_font->start = eb_uint2(buffer + 10);
if (book->character_code == EB_CHARCODE_ISO8859_1) {
2021-01-09 23:22:43 +00:00
wide_font->end = wide_font->start
+ ((character_count / 0xfe) << 8) + (character_count % 0xfe) - 1;
if (0xfe < (wide_font->end & 0xff))
wide_font->end += 3;
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
wide_font->end = wide_font->start
+ ((character_count / 0x5e) << 8) + (character_count % 0x5e) - 1;
if (0x7e < (wide_font->end & 0xff))
wide_font->end += 0xa3;
2021-01-09 22:39:52 +00:00
}
if (book->character_code == EB_CHARCODE_ISO8859_1) {
2021-01-09 23:22:43 +00:00
if ((wide_font->start & 0xff) < 0x01
|| 0xfe < (wide_font->start & 0xff)
|| wide_font->start < 0x0001
|| 0x1efe < wide_font->end) {
error_code = EB_ERR_UNEXP_FONT;
goto failed;
}
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
if ((wide_font->start & 0xff) < 0x21
|| 0x7e < (wide_font->start & 0xff)
|| wide_font->start < 0xa121
|| 0xfe7e < wide_font->end) {
error_code = EB_ERR_UNEXP_FONT;
goto failed;
}
2021-01-09 22:39:52 +00:00
}
succeeded:
LOG(("out: eb_load_wide_font_header()", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_load_wide_font_header()", eb_error_string(error_code)));
return error_code;
}
/*
* Read font glyph data.
*/
EB_Error_Code
eb_load_wide_font_glyphs(EB_Book *book, EB_Font_Code font_code)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
EB_Font *wide_font;
int character_count;
size_t glyph_size;
size_t total_glyph_size;
Zio *zio;
LOG(("in: eb_load_wide_font_glyphs(book=%d, font_code=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, (int)font_code));
2021-01-09 22:39:52 +00:00
subbook = book->subbook_current;
wide_font = subbook->wide_fonts + font_code;
zio = &wide_font->zio;
if (wide_font->glyphs != NULL)
2021-01-09 23:22:43 +00:00
goto succeeded;
2021-01-09 22:39:52 +00:00
/*
* Calculate size of glyph data (`total_glyph_size').
*
* Set the number of local defined characters to `character_count'.
* Set the number of character glpyhs in a page to `page_glyph_count'.
* Set size of glyph data to `total_glyph_size'.
*/
if (book->character_code == EB_CHARCODE_ISO8859_1) {
2021-01-09 23:22:43 +00:00
character_count
= ((wide_font->end >> 8) - (wide_font->start >> 8)) * 0xfe
+ ((wide_font->end & 0xff) - (wide_font->start & 0xff)) + 1;
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
character_count
= ((wide_font->end >> 8) - (wide_font->start >> 8)) * 0x5e
+ ((wide_font->end & 0xff) - (wide_font->start & 0xff)) + 1;
2021-01-09 22:39:52 +00:00
}
eb_wide_font_size2(font_code, &glyph_size);
total_glyph_size
2021-01-09 23:22:43 +00:00
= (character_count / (1024 / glyph_size)) * 1024
+ (character_count % (1024 / glyph_size)) * glyph_size;
2021-01-09 22:39:52 +00:00
/*
* Allocate memory for glyph data.
*/
wide_font->glyphs = (char *) malloc(total_glyph_size);
if (wide_font->glyphs == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_MEMORY_EXHAUSTED;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Read glyphs.
*/
if (zio_lseek(zio, (off_t) wide_font->page * EB_SIZE_PAGE, SEEK_SET)
2021-01-09 23:22:43 +00:00
< 0) {
error_code = EB_ERR_FAIL_SEEK_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
if (zio_read(zio, wide_font->glyphs, total_glyph_size)
2021-01-09 23:22:43 +00:00
!= total_glyph_size) {
error_code = EB_ERR_FAIL_READ_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
succeeded:
LOG(("out: eb_load_wide_font_glyphs()", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_load_wide_font_glyphs()", eb_error_string(error_code)));
if (wide_font->glyphs != NULL) {
2021-01-09 23:22:43 +00:00
free(wide_font->glyphs);
wide_font->glyphs = NULL;
2021-01-09 22:39:52 +00:00
}
return error_code;
}
/*
* Examine whether the current subbook in `book' has a wide font.
*/
int
eb_have_wide_font(EB_Book *book)
{
int i;
LOG(("in: eb_have_wide_font(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
/*
* If the wide font has already set, the subbook has wide fonts.
*/
if (book->subbook_current->wide_current != NULL)
2021-01-09 23:22:43 +00:00
goto succeeded;
2021-01-09 22:39:52 +00:00
/*
* Scan the font table.
*/
for (i = 0; i < EB_MAX_FONTS; i++) {
2021-01-09 23:22:43 +00:00
if (book->subbook_current->wide_fonts[i].font_code
!= EB_FONT_INVALID)
break;
2021-01-09 22:39:52 +00:00
}
if (EB_MAX_FONTS <= i)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
succeeded:
LOG(("out: eb_have_wide_font() = %d", 1));
return 1;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_have_wide_font() = %d", 0));
return 0;
}
/*
* Get width of the font `font_code' in the current subbook of `book'.
*/
EB_Error_Code
eb_wide_font_width(EB_Book *book, int *width)
{
EB_Error_Code error_code;
EB_Font_Code font_code;
LOG(("in: eb_wide_font_width(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* The wide font must exist in the current subbook.
*/
if (book->subbook_current->wide_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Calculate width.
*/
font_code = book->subbook_current->wide_current->font_code;
error_code = eb_wide_font_width2(font_code, width);
if (error_code != EB_SUCCESS)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
LOG(("out: eb_wide_font_width(width=%d) = %s", (int)*width,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*width = 0;
LOG(("out: eb_wide_font_width() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Get width of the font `font_code'.
*/
EB_Error_Code
eb_wide_font_width2(EB_Font_Code font_code, int *width)
{
EB_Error_Code error_code;
LOG(("in: eb_wide_font_width2(font_code=%d)", (int)font_code));
switch (font_code) {
case EB_FONT_16:
2021-01-09 23:22:43 +00:00
*width = EB_WIDTH_WIDE_FONT_16;
break;
2021-01-09 22:39:52 +00:00
case EB_FONT_24:
2021-01-09 23:22:43 +00:00
*width = EB_WIDTH_WIDE_FONT_24;
break;
2021-01-09 22:39:52 +00:00
case EB_FONT_30:
2021-01-09 23:22:43 +00:00
*width = EB_WIDTH_WIDE_FONT_30;
break;
2021-01-09 22:39:52 +00:00
case EB_FONT_48:
2021-01-09 23:22:43 +00:00
*width = EB_WIDTH_WIDE_FONT_48;
break;
2021-01-09 22:39:52 +00:00
default:
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_SUCH_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_wide_font_width2(width=%d) = %s", *width,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*width = 0;
LOG(("out: eb_wide_font_width2() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Get the bitmap size of the font `font_code' in the current subbook
* of `book'.
*/
EB_Error_Code
eb_wide_font_size(EB_Book *book, size_t *size)
{
EB_Error_Code error_code;
EB_Font_Code font_code;
int width;
int height;
LOG(("in: eb_wide_font_size(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* The wide font must exist in the current subbook.
*/
if (book->subbook_current->wide_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Calculate size.
*/
font_code = book->subbook_current->wide_current->font_code;
error_code = eb_wide_font_width2(font_code, &width);
if (error_code != EB_SUCCESS)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
error_code = eb_font_height2(font_code, &height);
if (error_code != EB_SUCCESS)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
*size = (width / 8) * height;
LOG(("out: eb_wide_font_size(size=%ld) = %s", (long)*size,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*size = 0;
LOG(("out: eb_wide_font_size() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Get the bitmap size of a character in `font_code' of the current
* subbook.
*/
EB_Error_Code
eb_wide_font_size2(EB_Font_Code font_code, size_t *size)
{
EB_Error_Code error_code;
LOG(("in: eb_wide_font_size2(font_code=%d)", (int)font_code));
switch (font_code) {
case EB_FONT_16:
2021-01-09 23:22:43 +00:00
*size = EB_SIZE_WIDE_FONT_16;
break;
2021-01-09 22:39:52 +00:00
case EB_FONT_24:
2021-01-09 23:22:43 +00:00
*size = EB_SIZE_WIDE_FONT_24;
break;
2021-01-09 22:39:52 +00:00
case EB_FONT_30:
2021-01-09 23:22:43 +00:00
*size = EB_SIZE_WIDE_FONT_30;
break;
2021-01-09 22:39:52 +00:00
case EB_FONT_48:
2021-01-09 23:22:43 +00:00
*size = EB_SIZE_WIDE_FONT_48;
break;
2021-01-09 22:39:52 +00:00
default:
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_SUCH_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_wide_font_size2(size=%ld) = %s", (long)*size,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*size = 0;
LOG(("out: eb_wide_font_size2() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Get the character number of the start of the wide font of the current
* subbook in `book'.
*/
EB_Error_Code
eb_wide_font_start(EB_Book *book, int *start)
{
EB_Error_Code error_code;
LOG(("in: eb_wide_font_start(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* The wide font must exist in the current subbook.
*/
if (book->subbook_current->wide_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
*start = book->subbook_current->wide_current->start;
LOG(("out: eb_wide_font_start(start=%d) = %s", *start,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_wide_font_start() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Get the character number of the end of the wide font of the current
* subbook in `book'.
*/
EB_Error_Code
eb_wide_font_end(EB_Book *book, int *end)
{
EB_Error_Code error_code;
LOG(("in: eb_wide_font_end(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* The wide font must exist in the current subbook.
*/
if (book->subbook_current->wide_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
*end = book->subbook_current->wide_current->end;
LOG(("out: eb_wide_font_end(end=%d) = %s", *end,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_wide_font_end() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Get bitmap data of the character with character number `character_number'
* in the current wide font of the current subbook in `book'.
*/
EB_Error_Code
eb_wide_font_character_bitmap(EB_Book *book, int character_number,
char *bitmap)
{
EB_Error_Code error_code;
LOG(("in: eb_wide_font_character_bitmap(book=%d, character_number=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, character_number));
2021-01-09 22:39:52 +00:00
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* The wide font must exist in the current subbook.
*/
if (book->subbook_current->wide_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
if (book->character_code == EB_CHARCODE_ISO8859_1) {
2021-01-09 23:22:43 +00:00
error_code = eb_wide_character_bitmap_latin(book, character_number,
bitmap);
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
error_code = eb_wide_character_bitmap_jis(book, character_number,
bitmap);
2021-01-09 22:39:52 +00:00
}
if (error_code != EB_SUCCESS)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
LOG(("out: eb_wide_font_character_bitmap() = %s",
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*bitmap = '\0';
LOG(("out: eb_wide_font_character_bitmap() = %s",
2021-01-09 23:22:43 +00:00
eb_error_string(error_code)));
2021-01-09 22:39:52 +00:00
return error_code;
}
/*
* Get bitmap data of the character with character number `character_number'
* in the current wide font of the current subbook in `book'.
*/
static EB_Error_Code
eb_wide_character_bitmap_jis(EB_Book *book, int character_number,
char *bitmap)
{
EB_Error_Code error_code;
EB_Font *wide_current;
int start;
int end;
int character_index;
off_t offset;
size_t size;
Zio *zio;
LOG(("in: eb_wide_font_character_bitmap_jis(book=%d, \
character_number=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, character_number));
2021-01-09 22:39:52 +00:00
start = book->subbook_current->wide_current->start;
end = book->subbook_current->wide_current->end;
wide_current = book->subbook_current->wide_current;
/*
* Check for `character_number'. Is it in a range of bitmaps?
* This test works correctly even when the font doesn't exist in
* the current subbook because `start' and `end' have set to -1
* in the case.
*/
if (character_number < start
2021-01-09 23:22:43 +00:00
|| end < character_number
|| (character_number & 0xff) < 0x21
|| 0x7e < (character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Calculate the size and the location of bitmap data.
*/
error_code = eb_wide_font_size(book, &size);
if (error_code != EB_SUCCESS)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
character_index = ((character_number >> 8) - (start >> 8)) * 0x5e
2021-01-09 23:22:43 +00:00
+ ((character_number & 0xff) - (start & 0xff));
2021-01-09 22:39:52 +00:00
offset
2021-01-09 23:22:43 +00:00
= (character_index / (1024 / size)) * 1024
+ (character_index % (1024 / size)) * size;
2021-01-09 22:39:52 +00:00
/*
* Read bitmap data.
*/
if (wide_current->glyphs == NULL) {
2021-01-09 23:22:43 +00:00
zio = &wide_current->zio;
if (zio_lseek(zio,
(off_t) wide_current->page * EB_SIZE_PAGE + offset,
SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_FONT;
goto failed;
}
if (zio_read(zio, bitmap, size) != size) {
error_code = EB_ERR_FAIL_READ_FONT;
goto failed;
}
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
memcpy(bitmap, wide_current->glyphs + offset, size);
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_wide_font_character_bitmap_jis() = %s",
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*bitmap = '\0';
LOG(("out: eb_wide_font_character_bitmap_jis() = %s",
2021-01-09 23:22:43 +00:00
eb_error_string(error_code)));
2021-01-09 22:39:52 +00:00
return error_code;
}
/*
* Get bitmap data of the character with character number `character_number'
* in the current wide font of the current subbook in `book'.
*/
static EB_Error_Code
eb_wide_character_bitmap_latin(EB_Book *book, int character_number,
char *bitmap)
{
EB_Error_Code error_code;
EB_Font *wide_current;
int start;
int end;
int character_index;
off_t offset;
size_t size;
Zio *zio;
LOG(("in: eb_wide_font_character_bitmap_latin(book=%d, \
character_number=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, character_number));
2021-01-09 22:39:52 +00:00
start = book->subbook_current->wide_current->start;
end = book->subbook_current->wide_current->end;
wide_current = book->subbook_current->wide_current;
/*
* Check for `ch'. Is it in a range of bitmaps?
* This test works correctly even when the font doesn't exist in
* the current subbook because `start' and `end' have set to -1
* in the case.
*/
if (character_number < start
2021-01-09 23:22:43 +00:00
|| end < character_number
|| (character_number & 0xff) < 0x01
|| 0xfe < (character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Calculate the size and the location of bitmap data.
*/
error_code = eb_wide_font_size(book, &size);
if (error_code != EB_SUCCESS)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
character_index = ((character_number >> 8) - (start >> 8)) * 0xfe
2021-01-09 23:22:43 +00:00
+ ((character_number & 0xff) - (start & 0xff));
2021-01-09 22:39:52 +00:00
offset
2021-01-09 23:22:43 +00:00
= (character_index / (1024 / size)) * 1024
+ (character_index % (1024 / size)) * size;
2021-01-09 22:39:52 +00:00
/*
* Read bitmap data.
*/
if (wide_current->glyphs == NULL) {
2021-01-09 23:22:43 +00:00
zio = &wide_current->zio;
if (zio_lseek(zio,
(off_t) wide_current->page * EB_SIZE_PAGE + offset,
SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_FONT;
goto failed;
}
if (zio_read(zio, bitmap, size) != size) {
error_code = EB_ERR_FAIL_READ_FONT;
goto failed;
}
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
memcpy(bitmap, wide_current->glyphs + offset, size);
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_wide_font_character_bitmap_latin() = %s",
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*bitmap = '\0';
LOG(("out: eb_wide_font_character_bitmap_latin() = %s",
2021-01-09 23:22:43 +00:00
eb_error_string(error_code)));
2021-01-09 22:39:52 +00:00
return error_code;
}
/*
* Return next `n'th character number from `character_number'.
*/
EB_Error_Code
eb_forward_wide_font_character(EB_Book *book, int n, int *character_number)
{
EB_Error_Code error_code;
int start;
int end;
int i;
if (n < 0)
2021-01-09 23:22:43 +00:00
return eb_backward_wide_font_character(book, -n, character_number);
2021-01-09 22:39:52 +00:00
LOG(("in: eb_forward_wide_font_character(book=%d, n=%d, \
character_number=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, n, *character_number));
2021-01-09 22:39:52 +00:00
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* The wide font must exist in the current subbook.
*/
if (book->subbook_current->wide_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
start = book->subbook_current->wide_current->start;
end = book->subbook_current->wide_current->end;
if (book->character_code == EB_CHARCODE_ISO8859_1) {
2021-01-09 23:22:43 +00:00
/*
* Check for `*character_number'. (ISO 8859 1)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x01
|| 0xfe < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
}
/*
* Get character number. (ISO 8859 1)
*/
for (i = 0; i < n; i++) {
if (0xfe <= (*character_number & 0xff))
*character_number += 3;
else
*character_number += 1;
if (end < *character_number) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
}
}
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
/*
* Check for `*character_number'. (JIS X 0208)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x21
|| 0x7e < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
}
/*
* Get character number. (JIS X 0208)
*/
for (i = 0; i < n; i++) {
if (0x7e <= (*character_number & 0xff))
*character_number += 0xa3;
else
*character_number += 1;
if (end < *character_number) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
}
}
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_forward_wide_font_character(character_number=%d) = %s",
2021-01-09 23:22:43 +00:00
*character_number, eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*character_number = -1;
LOG(("out: eb_forward_wide_font_character() = %s",
2021-01-09 23:22:43 +00:00
eb_error_string(error_code)));
2021-01-09 22:39:52 +00:00
return error_code;
}
/*
* Return previous `n'th character number from `*character_number'.
*/
EB_Error_Code
eb_backward_wide_font_character(EB_Book *book, int n, int *character_number)
{
EB_Error_Code error_code;
int start;
int end;
int i;
if (n < 0)
2021-01-09 23:22:43 +00:00
return eb_forward_wide_font_character(book, -n, character_number);
2021-01-09 22:39:52 +00:00
LOG(("in: eb_backward_wide_font_character(book=%d, n=%d, \
character_number=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, n, *character_number));
2021-01-09 22:39:52 +00:00
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* The wide font must exist in the current subbook.
*/
if (book->subbook_current->wide_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_FONT;
goto failed;
2021-01-09 22:39:52 +00:00
}
start = book->subbook_current->wide_current->start;
end = book->subbook_current->wide_current->end;
if (book->character_code == EB_CHARCODE_ISO8859_1) {
2021-01-09 23:22:43 +00:00
/*
* Check for `*character_number'. (ISO 8859 1)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x01
|| 0xfe < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
}
/*
* Get character number. (ISO 8859 1)
*/
for (i = 0; i < n; i++) {
if ((*character_number & 0xff) <= 0x01)
*character_number -= 3;
else
*character_number -= 1;
if (*character_number < start) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
}
}
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
/*
* Check for `*character_number'. (JIS X 0208)
*/
if (*character_number < start
|| end < *character_number
|| (*character_number & 0xff) < 0x21
|| 0x7e < (*character_number & 0xff)) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
}
/*
* Get character number. (JIS X 0208)
*/
for (i = 0; i < n; i++) {
if ((*character_number & 0xff) <= 0x21)
*character_number -= 0xa3;
else
*character_number -= 1;
if (*character_number < start) {
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
goto failed;
}
}
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_backward_wide_font_character(character_number=%d) = %s",
2021-01-09 23:22:43 +00:00
*character_number, eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*character_number = -1;
LOG(("out: eb_backward_wide_font_character() = %s",
2021-01-09 23:22:43 +00:00
eb_error_string(error_code)));
2021-01-09 22:39:52 +00:00
return error_code;
}