1075 lines
27 KiB
C
1075 lines
27 KiB
C
/* 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)",
|
|
(int)book->code, (int)font_code));
|
|
|
|
subbook = book->subbook_current;
|
|
wide_font = subbook->wide_fonts + font_code;
|
|
|
|
if (wide_font->font_code == EB_FONT_INVALID) {
|
|
error_code = EB_ERR_FAIL_OPEN_FONT;
|
|
goto failed;
|
|
}
|
|
if (0 <= zio_file(&wide_font->zio))
|
|
goto succeeded;
|
|
|
|
/*
|
|
* 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) {
|
|
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);
|
|
|
|
} else {
|
|
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);
|
|
}
|
|
}
|
|
|
|
if (zio_code != ZIO_INVALID
|
|
&& zio_open(&wide_font->zio, font_path_name, zio_code) < 0) {
|
|
error_code = EB_ERR_FAIL_OPEN_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
succeeded:
|
|
LOG(("out: eb_open_wide_font_file(file=%d) = %s",
|
|
zio_file(&wide_font->zio), eb_error_string(EB_SUCCESS)));
|
|
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)",
|
|
(int)book->code, (int)font_code));
|
|
|
|
subbook = book->subbook_current;
|
|
wide_font = subbook->wide_fonts + font_code;
|
|
zio = &wide_font->zio;
|
|
|
|
if (wide_font->initialized)
|
|
goto succeeded;
|
|
|
|
/*
|
|
* Read information from the text file.
|
|
*/
|
|
if (zio_lseek(zio, ((off_t) wide_font->page - 1) * EB_SIZE_PAGE,
|
|
SEEK_SET) < 0) {
|
|
error_code = EB_ERR_FAIL_SEEK_FONT;
|
|
goto failed;
|
|
}
|
|
if (zio_read(zio, buffer, 16) != 16) {
|
|
error_code = EB_ERR_FAIL_READ_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* 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) {
|
|
zio_close(zio);
|
|
error_code = EB_ERR_NO_SUCH_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Set the information.
|
|
*/
|
|
wide_font->start = eb_uint2(buffer + 10);
|
|
if (book->character_code == EB_CHARCODE_ISO8859_1) {
|
|
wide_font->end = wide_font->start
|
|
+ ((character_count / 0xfe) << 8) + (character_count % 0xfe) - 1;
|
|
if (0xfe < (wide_font->end & 0xff))
|
|
wide_font->end += 3;
|
|
} else {
|
|
wide_font->end = wide_font->start
|
|
+ ((character_count / 0x5e) << 8) + (character_count % 0x5e) - 1;
|
|
if (0x7e < (wide_font->end & 0xff))
|
|
wide_font->end += 0xa3;
|
|
}
|
|
|
|
if (book->character_code == EB_CHARCODE_ISO8859_1) {
|
|
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;
|
|
}
|
|
} else {
|
|
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;
|
|
}
|
|
}
|
|
|
|
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)",
|
|
(int)book->code, (int)font_code));
|
|
|
|
subbook = book->subbook_current;
|
|
wide_font = subbook->wide_fonts + font_code;
|
|
zio = &wide_font->zio;
|
|
|
|
if (wide_font->glyphs != NULL)
|
|
goto succeeded;
|
|
|
|
/*
|
|
* 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) {
|
|
character_count
|
|
= ((wide_font->end >> 8) - (wide_font->start >> 8)) * 0xfe
|
|
+ ((wide_font->end & 0xff) - (wide_font->start & 0xff)) + 1;
|
|
} else {
|
|
character_count
|
|
= ((wide_font->end >> 8) - (wide_font->start >> 8)) * 0x5e
|
|
+ ((wide_font->end & 0xff) - (wide_font->start & 0xff)) + 1;
|
|
}
|
|
|
|
eb_wide_font_size2(font_code, &glyph_size);
|
|
total_glyph_size
|
|
= (character_count / (1024 / glyph_size)) * 1024
|
|
+ (character_count % (1024 / glyph_size)) * glyph_size;
|
|
|
|
/*
|
|
* Allocate memory for glyph data.
|
|
*/
|
|
wide_font->glyphs = (char *) malloc(total_glyph_size);
|
|
if (wide_font->glyphs == NULL) {
|
|
error_code = EB_ERR_MEMORY_EXHAUSTED;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Read glyphs.
|
|
*/
|
|
if (zio_lseek(zio, (off_t) wide_font->page * EB_SIZE_PAGE, SEEK_SET)
|
|
< 0) {
|
|
error_code = EB_ERR_FAIL_SEEK_FONT;
|
|
goto failed;
|
|
}
|
|
if (zio_read(zio, wide_font->glyphs, total_glyph_size)
|
|
!= total_glyph_size) {
|
|
error_code = EB_ERR_FAIL_READ_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
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) {
|
|
free(wide_font->glyphs);
|
|
wide_font->glyphs = NULL;
|
|
}
|
|
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)
|
|
goto failed;
|
|
|
|
/*
|
|
* If the wide font has already set, the subbook has wide fonts.
|
|
*/
|
|
if (book->subbook_current->wide_current != NULL)
|
|
goto succeeded;
|
|
|
|
/*
|
|
* Scan the font table.
|
|
*/
|
|
for (i = 0; i < EB_MAX_FONTS; i++) {
|
|
if (book->subbook_current->wide_fonts[i].font_code
|
|
!= EB_FONT_INVALID)
|
|
break;
|
|
}
|
|
|
|
if (EB_MAX_FONTS <= i)
|
|
goto failed;
|
|
|
|
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) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* The wide font must exist in the current subbook.
|
|
*/
|
|
if (book->subbook_current->wide_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* 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)
|
|
goto failed;
|
|
|
|
LOG(("out: eb_wide_font_width(width=%d) = %s", (int)*width,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
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:
|
|
*width = EB_WIDTH_WIDE_FONT_16;
|
|
break;
|
|
case EB_FONT_24:
|
|
*width = EB_WIDTH_WIDE_FONT_24;
|
|
break;
|
|
case EB_FONT_30:
|
|
*width = EB_WIDTH_WIDE_FONT_30;
|
|
break;
|
|
case EB_FONT_48:
|
|
*width = EB_WIDTH_WIDE_FONT_48;
|
|
break;
|
|
default:
|
|
error_code = EB_ERR_NO_SUCH_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
LOG(("out: eb_wide_font_width2(width=%d) = %s", *width,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
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) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* The wide font must exist in the current subbook.
|
|
*/
|
|
if (book->subbook_current->wide_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* 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)
|
|
goto failed;
|
|
error_code = eb_font_height2(font_code, &height);
|
|
if (error_code != EB_SUCCESS)
|
|
goto failed;
|
|
*size = (width / 8) * height;
|
|
|
|
LOG(("out: eb_wide_font_size(size=%ld) = %s", (long)*size,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
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:
|
|
*size = EB_SIZE_WIDE_FONT_16;
|
|
break;
|
|
case EB_FONT_24:
|
|
*size = EB_SIZE_WIDE_FONT_24;
|
|
break;
|
|
case EB_FONT_30:
|
|
*size = EB_SIZE_WIDE_FONT_30;
|
|
break;
|
|
case EB_FONT_48:
|
|
*size = EB_SIZE_WIDE_FONT_48;
|
|
break;
|
|
default:
|
|
error_code = EB_ERR_NO_SUCH_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
LOG(("out: eb_wide_font_size2(size=%ld) = %s", (long)*size,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
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) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* The wide font must exist in the current subbook.
|
|
*/
|
|
if (book->subbook_current->wide_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
*start = book->subbook_current->wide_current->start;
|
|
|
|
LOG(("out: eb_wide_font_start(start=%d) = %s", *start,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
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) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* The wide font must exist in the current subbook.
|
|
*/
|
|
if (book->subbook_current->wide_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
*end = book->subbook_current->wide_current->end;
|
|
|
|
LOG(("out: eb_wide_font_end(end=%d) = %s", *end,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
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)",
|
|
(int)book->code, character_number));
|
|
|
|
/*
|
|
* Current subbook must have been set.
|
|
*/
|
|
if (book->subbook_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* The wide font must exist in the current subbook.
|
|
*/
|
|
if (book->subbook_current->wide_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
if (book->character_code == EB_CHARCODE_ISO8859_1) {
|
|
error_code = eb_wide_character_bitmap_latin(book, character_number,
|
|
bitmap);
|
|
} else {
|
|
error_code = eb_wide_character_bitmap_jis(book, character_number,
|
|
bitmap);
|
|
}
|
|
if (error_code != EB_SUCCESS)
|
|
goto failed;
|
|
|
|
LOG(("out: eb_wide_font_character_bitmap() = %s",
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
*bitmap = '\0';
|
|
LOG(("out: eb_wide_font_character_bitmap() = %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'.
|
|
*/
|
|
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)",
|
|
(int)book->code, character_number));
|
|
|
|
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
|
|
|| end < character_number
|
|
|| (character_number & 0xff) < 0x21
|
|
|| 0x7e < (character_number & 0xff)) {
|
|
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Calculate the size and the location of bitmap data.
|
|
*/
|
|
error_code = eb_wide_font_size(book, &size);
|
|
if (error_code != EB_SUCCESS)
|
|
goto failed;
|
|
|
|
character_index = ((character_number >> 8) - (start >> 8)) * 0x5e
|
|
+ ((character_number & 0xff) - (start & 0xff));
|
|
offset
|
|
= (character_index / (1024 / size)) * 1024
|
|
+ (character_index % (1024 / size)) * size;
|
|
|
|
/*
|
|
* Read bitmap data.
|
|
*/
|
|
if (wide_current->glyphs == NULL) {
|
|
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;
|
|
}
|
|
} else {
|
|
memcpy(bitmap, wide_current->glyphs + offset, size);
|
|
}
|
|
|
|
LOG(("out: eb_wide_font_character_bitmap_jis() = %s",
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
*bitmap = '\0';
|
|
LOG(("out: eb_wide_font_character_bitmap_jis() = %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'.
|
|
*/
|
|
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)",
|
|
(int)book->code, character_number));
|
|
|
|
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
|
|
|| end < character_number
|
|
|| (character_number & 0xff) < 0x01
|
|
|| 0xfe < (character_number & 0xff)) {
|
|
error_code = EB_ERR_NO_SUCH_CHAR_BMP;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Calculate the size and the location of bitmap data.
|
|
*/
|
|
error_code = eb_wide_font_size(book, &size);
|
|
if (error_code != EB_SUCCESS)
|
|
goto failed;
|
|
|
|
character_index = ((character_number >> 8) - (start >> 8)) * 0xfe
|
|
+ ((character_number & 0xff) - (start & 0xff));
|
|
offset
|
|
= (character_index / (1024 / size)) * 1024
|
|
+ (character_index % (1024 / size)) * size;
|
|
|
|
/*
|
|
* Read bitmap data.
|
|
*/
|
|
if (wide_current->glyphs == NULL) {
|
|
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;
|
|
}
|
|
} else {
|
|
memcpy(bitmap, wide_current->glyphs + offset, size);
|
|
}
|
|
|
|
LOG(("out: eb_wide_font_character_bitmap_latin() = %s",
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
*bitmap = '\0';
|
|
LOG(("out: eb_wide_font_character_bitmap_latin() = %s",
|
|
eb_error_string(error_code)));
|
|
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)
|
|
return eb_backward_wide_font_character(book, -n, character_number);
|
|
|
|
LOG(("in: eb_forward_wide_font_character(book=%d, n=%d, \
|
|
character_number=%d)",
|
|
(int)book->code, n, *character_number));
|
|
|
|
/*
|
|
* Current subbook must have been set.
|
|
*/
|
|
if (book->subbook_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* The wide font must exist in the current subbook.
|
|
*/
|
|
if (book->subbook_current->wide_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
start = book->subbook_current->wide_current->start;
|
|
end = book->subbook_current->wide_current->end;
|
|
|
|
if (book->character_code == EB_CHARCODE_ISO8859_1) {
|
|
/*
|
|
* 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;
|
|
}
|
|
}
|
|
} else {
|
|
/*
|
|
* 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOG(("out: eb_forward_wide_font_character(character_number=%d) = %s",
|
|
*character_number, eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
*character_number = -1;
|
|
LOG(("out: eb_forward_wide_font_character() = %s",
|
|
eb_error_string(error_code)));
|
|
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)
|
|
return eb_forward_wide_font_character(book, -n, character_number);
|
|
|
|
LOG(("in: eb_backward_wide_font_character(book=%d, n=%d, \
|
|
character_number=%d)",
|
|
(int)book->code, n, *character_number));
|
|
|
|
/*
|
|
* Current subbook must have been set.
|
|
*/
|
|
if (book->subbook_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* The wide font must exist in the current subbook.
|
|
*/
|
|
if (book->subbook_current->wide_current == NULL) {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
start = book->subbook_current->wide_current->start;
|
|
end = book->subbook_current->wide_current->end;
|
|
|
|
if (book->character_code == EB_CHARCODE_ISO8859_1) {
|
|
/*
|
|
* 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;
|
|
}
|
|
}
|
|
} else {
|
|
/*
|
|
* 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOG(("out: eb_backward_wide_font_character(character_number=%d) = %s",
|
|
*character_number, eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
*character_number = -1;
|
|
LOG(("out: eb_backward_wide_font_character() = %s",
|
|
eb_error_string(error_code)));
|
|
return error_code;
|
|
}
|