/* * 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; eb_lock(&book->lock); 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))); eb_unlock(&book->lock); return EB_SUCCESS; /* * An error occurs... */ failed: *font_code = EB_FONT_INVALID; LOG(("out: eb_font() = %s", eb_error_string(error_code))); eb_unlock(&book->lock); 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; eb_lock(&book->lock); 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 (is_ebnet_url(book->path)) { error_code = eb_load_narrow_font_glyphs(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; if (is_ebnet_url(book->path)) { error_code = eb_load_wide_font_glyphs(book, font_code); if (error_code != EB_SUCCESS) goto failed; } } succeeded: LOG(("out: eb_set_font() = %s", eb_error_string(EB_SUCCESS))); eb_unlock(&book->lock); 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; eb_lock(&book->lock); 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()")); eb_unlock(&book->lock); } /* * 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; eb_lock(&book->lock); 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))); eb_unlock(&book->lock); return EB_SUCCESS; /* * An error occurs... */ failed: LOG(("out: eb_font_list() = %s", eb_error_string(error_code))); eb_unlock(&book->lock); 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; eb_lock(&book->lock); 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)); eb_unlock(&book->lock); return 1; /* * An error occurs... */ failed: LOG(("out: eb_have_font() = %d", 0)); eb_unlock(&book->lock); 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; eb_lock(&book->lock); 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))); eb_unlock(&book->lock); return EB_SUCCESS; /* * An error occurs... */ failed: *height = 0; LOG(("out: eb_font_height() = %s", eb_error_string(error_code))); eb_unlock(&book->lock); 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; }