524 lines
13 KiB
C
524 lines
13 KiB
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"
|
|
|
|
/*
|
|
* Initialize all fonts in the current subbook.
|
|
*/
|
|
void
|
|
eb_initialize_fonts(EB_Book *book)
|
|
{
|
|
EB_Subbook *subbook;
|
|
EB_Font *font;
|
|
int i;
|
|
|
|
LOG(("in: eb_initialize_fonts(book=%d)", (int)book->code));
|
|
|
|
subbook = book->subbook_current;
|
|
|
|
for (i = 0, font = subbook->narrow_fonts; i < EB_MAX_FONTS; i++, font++) {
|
|
font->font_code = EB_FONT_INVALID;
|
|
font->initialized = 0;
|
|
font->start = -1;
|
|
font->end = -1;
|
|
font->page = 0;
|
|
font->glyphs = NULL;
|
|
zio_initialize(&font->zio);
|
|
}
|
|
|
|
for (i = 0, font = subbook->wide_fonts; i < EB_MAX_FONTS; i++, font++) {
|
|
font->font_code = EB_FONT_INVALID;
|
|
font->initialized = 0;
|
|
font->start = -1;
|
|
font->end = -1;
|
|
font->page = 0;
|
|
font->glyphs = NULL;
|
|
zio_initialize(&font->zio);
|
|
}
|
|
|
|
LOG(("out: eb_initialize_fonts()"));
|
|
}
|
|
|
|
|
|
/*
|
|
* Load font files.
|
|
*/
|
|
void
|
|
eb_load_font_headers(EB_Book *book)
|
|
{
|
|
EB_Error_Code error_code;
|
|
EB_Subbook *subbook;
|
|
EB_Font_Code i;
|
|
|
|
LOG(("in: eb_load_fonts(book=%d)", (int)book->code));
|
|
|
|
subbook = book->subbook_current;
|
|
|
|
/*
|
|
* Load narrow font headers.
|
|
*/
|
|
for (i = 0; i < EB_MAX_FONTS; i++) {
|
|
if (subbook->narrow_fonts[i].font_code == EB_FONT_INVALID
|
|
|| subbook->narrow_fonts[i].initialized)
|
|
continue;
|
|
|
|
error_code = eb_open_narrow_font_file(book, i);
|
|
if (error_code == EB_SUCCESS)
|
|
error_code = eb_load_narrow_font_header(book, i);
|
|
if (error_code != EB_SUCCESS)
|
|
subbook->narrow_fonts[i].font_code = EB_FONT_INVALID;
|
|
subbook->narrow_fonts[i].initialized = 1;
|
|
zio_close(&subbook->narrow_fonts[i].zio);
|
|
}
|
|
|
|
/*
|
|
* Load wide font header.
|
|
*/
|
|
for (i = 0; i < EB_MAX_FONTS; i++) {
|
|
if (subbook->wide_fonts[i].font_code == EB_FONT_INVALID
|
|
|| subbook->wide_fonts[i].initialized)
|
|
continue;
|
|
|
|
error_code = eb_open_wide_font_file(book, i);
|
|
if (error_code == EB_SUCCESS)
|
|
error_code = eb_load_wide_font_header(book, i);
|
|
if (error_code != EB_SUCCESS)
|
|
subbook->wide_fonts[i].font_code = EB_FONT_INVALID;
|
|
subbook->wide_fonts[i].initialized = 1;
|
|
zio_close(&subbook->wide_fonts[i].zio);
|
|
}
|
|
|
|
LOG(("out: eb_load_font_headers()"));
|
|
}
|
|
|
|
|
|
/*
|
|
* Finalize all fonts in the current subbook.
|
|
*/
|
|
void
|
|
eb_finalize_fonts(EB_Book *book)
|
|
{
|
|
EB_Subbook *subbook;
|
|
EB_Font *font;
|
|
int i;
|
|
|
|
LOG(("in: eb_finalize_fonts(book=%d)", (int)book->code));
|
|
|
|
subbook = book->subbook_current;
|
|
|
|
for (i = 0, font = subbook->narrow_fonts; i < EB_MAX_FONTS; i++, font++) {
|
|
zio_finalize(&font->zio);
|
|
if (font->glyphs != NULL) {
|
|
free(font->glyphs);
|
|
font->glyphs = NULL;
|
|
}
|
|
}
|
|
|
|
for (i = 0, font = subbook->wide_fonts; i < EB_MAX_FONTS; i++, font++) {
|
|
zio_finalize(&font->zio);
|
|
if (font->glyphs != NULL) {
|
|
free(font->glyphs);
|
|
font->glyphs = NULL;
|
|
}
|
|
}
|
|
|
|
LOG(("out: eb_finalize_fonts()"));
|
|
}
|
|
|
|
|
|
/*
|
|
* Look up the height of the current font of the current subbook in
|
|
* `book'.
|
|
*/
|
|
EB_Error_Code
|
|
eb_font(EB_Book *book, EB_Font_Code *font_code)
|
|
{
|
|
EB_Error_Code error_code;
|
|
|
|
LOG(("in: eb_font(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;
|
|
}
|
|
|
|
/*
|
|
* Look up the height of the current font.
|
|
*/
|
|
if (book->subbook_current->narrow_current != NULL)
|
|
*font_code = book->subbook_current->narrow_current->font_code;
|
|
else if (book->subbook_current->wide_current != NULL)
|
|
*font_code = book->subbook_current->wide_current->font_code;
|
|
else {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
LOG(("out: eb_font(font_code=%d) = %s", (int)*font_code,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
*font_code = EB_FONT_INVALID;
|
|
LOG(("out: eb_font() = %s", eb_error_string(error_code)));
|
|
return error_code;
|
|
}
|
|
|
|
|
|
/*
|
|
* Set the font with `font_code' as the current font of the current
|
|
* subbook in `book'.
|
|
*/
|
|
EB_Error_Code
|
|
eb_set_font(EB_Book *book, EB_Font_Code font_code)
|
|
{
|
|
EB_Error_Code error_code;
|
|
EB_Subbook *subbook;
|
|
|
|
LOG(("in: eb_set_font(book=%d, font_code=%d)", (int)book->code,
|
|
(int)font_code));
|
|
|
|
/*
|
|
* Check `font_code'.
|
|
*/
|
|
if (font_code < 0 || EB_MAX_FONTS <= font_code) {
|
|
error_code = EB_ERR_NO_SUCH_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Current subbook must have been set.
|
|
*/
|
|
subbook = book->subbook_current;
|
|
if (subbook == NULL) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* If the current font is the font with `font_code', return immediately.
|
|
* Otherwise close the current font and continue.
|
|
*/
|
|
if (subbook->narrow_current != NULL) {
|
|
if (subbook->narrow_current->font_code == font_code)
|
|
goto succeeded;
|
|
if (book->disc_code == EB_DISC_EPWING)
|
|
zio_close(&subbook->narrow_current->zio);
|
|
subbook->narrow_current = NULL;
|
|
}
|
|
if (subbook->wide_current != NULL) {
|
|
if (subbook->wide_current->font_code == font_code)
|
|
goto succeeded;
|
|
if (book->disc_code == EB_DISC_EPWING)
|
|
zio_close(&subbook->wide_current->zio);
|
|
subbook->wide_current = NULL;
|
|
}
|
|
|
|
/*
|
|
* Set the current font.
|
|
*/
|
|
if (subbook->narrow_fonts[font_code].font_code != EB_FONT_INVALID)
|
|
subbook->narrow_current = subbook->narrow_fonts + font_code;
|
|
if (subbook->wide_fonts[font_code].font_code != EB_FONT_INVALID)
|
|
subbook->wide_current = subbook->wide_fonts + font_code;
|
|
|
|
if (subbook->narrow_current == NULL && subbook->wide_current == NULL) {
|
|
error_code = EB_ERR_NO_SUCH_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Initialize current font informtaion.
|
|
*/
|
|
if (subbook->narrow_current != NULL) {
|
|
error_code = eb_open_narrow_font_file(book, font_code);
|
|
if (error_code != EB_SUCCESS)
|
|
goto failed;
|
|
}
|
|
if (subbook->wide_current != NULL) {
|
|
error_code = eb_open_wide_font_file(book, font_code);
|
|
if (error_code != EB_SUCCESS)
|
|
goto failed;
|
|
}
|
|
|
|
|
|
succeeded:
|
|
LOG(("out: eb_set_font() = %s", eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
eb_unset_font(book);
|
|
LOG(("out: eb_set_font() = %s", eb_error_string(error_code)));
|
|
return error_code;
|
|
}
|
|
|
|
|
|
/*
|
|
* Unset the font in the current subbook in `book'.
|
|
*/
|
|
void
|
|
eb_unset_font(EB_Book *book)
|
|
{
|
|
EB_Subbook *subbook;
|
|
|
|
LOG(("in: eb_unset_font(book=%d)", (int)book->code));
|
|
|
|
subbook = book->subbook_current;
|
|
|
|
if (subbook == NULL)
|
|
goto succeeded;
|
|
|
|
/*
|
|
* Close font files.
|
|
*/
|
|
if (subbook->narrow_current != NULL) {
|
|
zio_close(&subbook->narrow_current->zio);
|
|
if (subbook->narrow_current->glyphs != NULL) {
|
|
free(subbook->narrow_current->glyphs);
|
|
subbook->narrow_current->glyphs = NULL;
|
|
}
|
|
}
|
|
if (subbook->wide_current != NULL) {
|
|
zio_close(&subbook->wide_current->zio);
|
|
if (subbook->wide_current->glyphs != NULL) {
|
|
free(subbook->wide_current->glyphs);
|
|
subbook->wide_current->glyphs = NULL;
|
|
}
|
|
}
|
|
|
|
book->subbook_current->narrow_current = NULL;
|
|
book->subbook_current->wide_current = NULL;
|
|
|
|
succeeded:
|
|
LOG(("out: eb_unset_font()"));
|
|
}
|
|
|
|
|
|
/*
|
|
* Make a list of fonts in the current subbook in `book'.
|
|
*/
|
|
EB_Error_Code
|
|
eb_font_list(EB_Book *book, EB_Font_Code *font_list, int *font_count)
|
|
{
|
|
EB_Error_Code error_code;
|
|
EB_Subbook *subbook;
|
|
EB_Font_Code *list_p;
|
|
int i;
|
|
|
|
LOG(("in: eb_font_list(book=%d)", (int)book->code));
|
|
|
|
/*
|
|
* Current subbook must have been set.
|
|
*/
|
|
subbook = book->subbook_current;
|
|
if (subbook == NULL) {
|
|
error_code = EB_ERR_NO_CUR_SUB;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Scan the font table in the book.
|
|
*/
|
|
subbook = book->subbook_current;
|
|
list_p = font_list;
|
|
*font_count = 0;
|
|
for (i = 0; i < EB_MAX_FONTS; i++) {
|
|
if (subbook->narrow_fonts[i].font_code != EB_FONT_INVALID
|
|
|| subbook->wide_fonts[i].font_code != EB_FONT_INVALID) {
|
|
*list_p++ = i;
|
|
*font_count += 1;
|
|
}
|
|
}
|
|
|
|
LOG(("out: eb_font(font_count=%d) = %s", *font_count,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
LOG(("out: eb_font_list() = %s", eb_error_string(error_code)));
|
|
return error_code;
|
|
}
|
|
|
|
|
|
/*
|
|
* Test whether the current subbook in `book' has a font with
|
|
* `font_code' or not.
|
|
*/
|
|
int
|
|
eb_have_font(EB_Book *book, EB_Font_Code font_code)
|
|
{
|
|
EB_Subbook *subbook;
|
|
|
|
LOG(("in: eb_have_font(book=%d, font_code=%d)", (int)book->code,
|
|
(int)font_code));
|
|
|
|
/*
|
|
* Check `font_code'.
|
|
*/
|
|
if (font_code < 0 || EB_MAX_FONTS <= font_code)
|
|
goto failed;
|
|
|
|
/*
|
|
* Current subbook must have been set.
|
|
*/
|
|
subbook = book->subbook_current;
|
|
if (subbook == NULL)
|
|
goto failed;
|
|
|
|
if (subbook->narrow_fonts[font_code].font_code == EB_FONT_INVALID
|
|
&& subbook->wide_fonts[font_code].font_code == EB_FONT_INVALID)
|
|
goto failed;
|
|
|
|
LOG(("out: eb_have_font() = %d", 1));
|
|
|
|
return 1;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
LOG(("out: eb_have_font() = %d", 0));
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* Get height of the font `font_code' in the current subbook of `book'.
|
|
*/
|
|
EB_Error_Code
|
|
eb_font_height(EB_Book *book, int *height)
|
|
{
|
|
EB_Error_Code error_code;
|
|
EB_Font_Code font_code;
|
|
|
|
LOG(("in: eb_font_height(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 narrow font must exist in the current subbook.
|
|
*/
|
|
if (book->subbook_current->narrow_current != NULL)
|
|
font_code = book->subbook_current->narrow_current->font_code;
|
|
else if (book->subbook_current->wide_current != NULL)
|
|
font_code = book->subbook_current->wide_current->font_code;
|
|
else {
|
|
error_code = EB_ERR_NO_CUR_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Calculate height.
|
|
*/
|
|
error_code = eb_font_height2(font_code, height);
|
|
if (error_code != EB_SUCCESS)
|
|
goto failed;
|
|
|
|
LOG(("out: eb_font_heigt(height=%d) = %s", *height,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
*height = 0;
|
|
LOG(("out: eb_font_height() = %s", eb_error_string(error_code)));
|
|
return error_code;
|
|
}
|
|
|
|
|
|
/*
|
|
* Get height of the font `font_code'.
|
|
*/
|
|
EB_Error_Code
|
|
eb_font_height2(EB_Font_Code font_code, int *height)
|
|
{
|
|
EB_Error_Code error_code;
|
|
|
|
LOG(("in: eb_font_height2(font_code=%d)", (int)font_code));
|
|
|
|
switch (font_code) {
|
|
case EB_FONT_16:
|
|
*height = EB_HEIGHT_FONT_16;
|
|
break;
|
|
case EB_FONT_24:
|
|
*height = EB_HEIGHT_FONT_24;
|
|
break;
|
|
case EB_FONT_30:
|
|
*height = EB_HEIGHT_FONT_30;
|
|
break;
|
|
case EB_FONT_48:
|
|
*height = EB_HEIGHT_FONT_48;
|
|
break;
|
|
default:
|
|
error_code = EB_ERR_NO_SUCH_FONT;
|
|
goto failed;
|
|
}
|
|
|
|
LOG(("out: eb_font_heigt2(height=%d) = %s", *height,
|
|
eb_error_string(EB_SUCCESS)));
|
|
|
|
return EB_SUCCESS;
|
|
|
|
/*
|
|
* An error occurs...
|
|
*/
|
|
failed:
|
|
*height = 0;
|
|
LOG(("out: eb_font_height2() = %s", eb_error_string(error_code)));
|
|
return error_code;
|
|
}
|