/*************************************************************** ** (c)2009 Broadcom Corporation ** ** This program is the proprietary software of Broadcom Corporation and/or its licensors, ** and may only be used, duplicated, modified or distributed pursuant to the terms and ** conditions of a separate, written license agreement executed between you and Broadcom ** (an "Authorized License"). Except as set forth in an Authorized License, Broadcom grants ** no license (express or implied), right to use, or waiver of any kind with respect to the ** Software, and Broadcom expressly reserves all rights in and to the Software and all ** intellectual property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU ** HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY ** NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. ** ** Except as expressly set forth in the Authorized License, ** ** 1. This program, including its structure, sequence and organization, constitutes the valuable trade ** secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof, ** and to use this information only in connection with your use of Broadcom integrated circuit products. ** ** 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" ** AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR ** WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO ** THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES ** OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, ** LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION ** OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF ** USE OR PERFORMANCE OF THE SOFTWARE. ** ** 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS ** LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR ** EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR ** USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF ** THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ** ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE ** LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ** ANY LIMITED REMEDY. ** ** Created: 8/22/2002 by Jeffrey P. Fisher ** ** $brcm_Workfile: bgfx_font.c $ ** $brcm_Revision: Refsw_7550/3 $ ** $brcm_Date: 11/26/09 11:27a $ ** ** Revision History: ** ** $brcm_Log: /nexus/lib/softgfx/src/bgfx_font.c $ ** ** Refsw_7550/3 11/26/09 11:27a kagrawal ** SW7550-77: Fixed compile time warning ** ** Refsw_7550/2 9/25/09 12:54p kagrawal ** SW7550-50: Performance optimized gfx from 7003 latest ** ** Refsw_7550/1 9/7/09 5:04p kagrawal ** SW7550-3: Initial check-in for Soft Graphics ** ****************************************************************/ /** include files **/ #if (BCHP_CHIP != 7003) #define BDISPATCH_BYPASS #endif #include "bgfx.h" #undef BDISPATCH_BYPASS #if !defined LINUX && !defined B_OS_UCOS_II #include "bdispatch.h" #endif BDBG_MODULE(bgfx); static bgfx_glyph_t *bgfx_init_glyph(bgfx_font_t *font_p, FT_ULong a_char, int glyph_idx); /* global SGL structure */ typedef struct bgfx_t { #ifdef CONFIG_FREETYPE FT_Library ft_library; #else int tbd; /* fixes warning */ #endif }bgfx_t; #ifdef CONFIG_FREETYPE static bgfx_t g_bgfx = { NULL }; #endif /****************************************************************} * INPUTS: none * OUTPUTS: none * RETURNS: non-zero on failure * FUNCTION: Initialize the SGIL font library * ****************************************************************/ int bgfx_font_init() { int result = 0; SGL_TRACE(("font_init\n")); #ifdef CONFIG_FREETYPE bgfx_lock(); { FT_Error err; err = FT_Init_FreeType( &g_bgfx.ft_library ); if (err) { g_bgfx.ft_library = NULL; result = -1; SGL_DEBUG(("font_init - FT_Init_FreeType(%d)\n",err)); } } bgfx_unlock(); #endif SGL_TRACE(("font_init - done\n")); return result; } /****************************************************************} * INPUTS: none * OUTPUTS: none * RETURNS: non-zero on failure * FUNCTION: release sgl global resources, primarily for handling freetype * ****************************************************************/ void bgfx_font_done() { SGL_TRACE(("font_done\n")); #ifdef CONFIG_FREETYPE bgfx_lock(); if (g_bgfx.ft_library) FT_Done_FreeType( g_bgfx.ft_library ); g_bgfx.ft_library = NULL; bgfx_unlock(); #endif } #ifdef CONFIG_FREETYPE /**************************************************************** * INPUTS: fr_p - font ripper parameters * OUTPUTS: none * RETURNS: number of glyph entries * DESCRIPTION: Get the maximum number of glyph index entries. * ****************************************************************/ int get_max_glyph_index(bgfx_font_t *font_p) { FT_ULong charcode; FT_UInt gindex; int cnt = 0; charcode = FT_Get_First_Char( font_p->face, &gindex ); while ( gindex != 0 ) { ++cnt; charcode = FT_Get_Next_Char( font_p->face, charcode, &gindex ); } return cnt; } /**************************************************************** * INPUTS: font_p - font definition * OUTPUTS: none * RETURNS: none-zero on failure * FUNCTION: create the charmap. * ****************************************************************/ int bgfx_create_char_map(bgfx_font_t *font_p) { int i = 0; FT_ULong charcode; FT_UInt gindex; font_p->cache_size = get_max_glyph_index(font_p); if (font_p->char_map_size <= 0) { SGL_DEBUG(("bgfx_create_char_map failed, no unicode encoding for this font.\n")); return -1; } font_p->char_map = (bgfx_glyph_t**)SGL_MALLOC(sizeof(bgfx_glyph_t*) * font_p->cache_size ); if (!font_p->glyph_cache) { SGL_DEBUG(("bgfx_create_char_map failed, could not allocate memory for char map.\n")); return -1; } bgfx_lock(); charcode = FT_Get_First_Char( font_p->face, &gindex ); while ( gindex != 0 ) { font_p->char_map[i++] = charcode; charcode = FT_Get_Next_Char( font_p->face, charcode, &gindex ); } bgfx_unlock(); SGL_TRACE(("bgfx_create_char_map - %d chars.\n",i)); return 0; } #endif /* CONFIG_FREETYPE */ /**************************************************************** * INPUTS: font_p - font definition * typeface_name - name of the typeface * height - font height * OUTPUTS: none * RETURNS: none-zero on failure * FUNCTION: Load the font typeface. * * The general usage convention in SGIL is to avoid memory allocation * in SGIL functions. For example before calling bgfx_new_font a * valid font_t structure must be created and passed to bgfx_new_font. * The font_t structure is modified but not allocated by bgfx_new_font. * A primary exception is that the glyph cache and glyphs are * allocated and manage internally. Therefore, it is important to * call bgfx_free_font to allow SGIL to perform cleanup on the glyph cache. ****************************************************************/ int bgfx_new_font(bgfx_font_t *font_p, const char *typeface_name, unsigned char height,unsigned long flags) { SGL_TRACE(("bgfx_new_font - %s:%d,%ld\n",typeface_name,height,flags)); #ifdef CONFIG_FREETYPE { FT_Error err; unsigned long i; bgfx_glyph_t *glyph; bgfx_lock(); err = FT_New_Face( g_bgfx.ft_library, typeface_name,0, &font_p->face ); if (err) { SGL_DEBUG(("bgfx_new_font could not open typeface %s\n",typeface_name)); bgfx_unlock(); return -1; } err = FT_Select_Charmap( font_p->face, ft_encoding_unicode ); #if FREETYPE_MINOR > 0 if (err) { SGL_DEBUG(("bgfx_new_font could not open unicode charmap, default to latin\n")); err = FT_Select_Charmap( font_p->face, ft_encoding_latin_1 ); } #endif if (err) { SGL_DEBUG(("bgfx_new_font could not select charmap for font %s\n",typeface_name)); bgfx_unlock(); return -1; } err = FT_Set_Pixel_Sizes( font_p->face, 0, height); if (err) { SGL_DEBUG(("bgfx_new_font could set font height to %d\n",height)); FT_Done_Face( font_p->face ); bgfx_unlock(); return -1; } if (flags & SGL_MONO) font_p->face->generic.data = (void *) (FT_LOAD_DEFAULT | FT_LOAD_MONOCHROME); else font_p->face->generic.data = (void *) FT_LOAD_DEFAULT; font_p->ascender = font_p->face->size->metrics.ascender >> 6; font_p->descender = font_p->face->size->metrics.descender >> 6; font_p->height = (font_p->face->size->metrics.ascender - font_p->face->size->metrics.descender) >> 6; font_p->maxadvance = font_p->face->size->metrics.max_advance >> 6; /* create glyph cache */ if (flags & SGL_CACHE_GLYPHS) { font_p->cache_size = font_p->face->num_glyphs; font_p->glyph_cache = (bgfx_glyph_t**)SGL_MALLOC(sizeof(bgfx_glyph_t*) * font_p->cache_size); if (font_p->glyph_cache) SGL_MEMSET(font_p->glyph_cache,0,sizeof(bgfx_glyph_t*) * font_p->cache_size); else font_p->cache_size = 0; } else { font_p->cache_size = 0; font_p->glyph_cache = NULL; } font_p->format = flags; bgfx_unlock(); if (bgfx_create_char_map(font_p) != 0) { SGL_DEBUG(("bgfx_new_font could not create charmap\n")); FT_Done_Face( font_p->face ); return -1; } if (flags & SGL_PRELOAD_GLYPHS) { for (i = 0; i < font_p->cache_size; ++i) glyph = bgfx_init_glyph(font_p,font_p->char_map[i],i); } } return 0; #else BSTD_UNUSED(font_p); return -1; /* must load fonts when there is no freetype support */ #endif } /**************************************************************** * INPUTS: font_p - font definition * OUTPUTS: none * RETURNS: none * FUNCTION: Free font typeface. * ****************************************************************/ void bgfx_free_font(bgfx_font_t *font_p) { if (font_p->glyph_cache[0]->buf) free(font_p->glyph_cache[0]->buf); if (font_p->glyph_cache[0]) free(font_p->glyph_cache[0]); if (font_p->char_map) free(font_p->char_map); if (font_p->glyph_cache) free(font_p->glyph_cache); #if 0 int i; for (i = 0; i < font_p->cache_size; ++i) { bgfx_glyph_t *glyph = font_p->glyph_cache[i]; if (glyph) { SGL_FREE(glyph->buf); SGL_FREE(glyph); font_p->glyph_cache[i] = NULL; } } SGL_FREE(font_p->glyph_cache); #ifdef CONFIG_FREETYPE FT_Done_Face (font_p->face); #endif #endif } /**************************************************************** * INPUTS: font_p - font * a_char - the character * glyph_idx - glyph index * OUTPUTS: info - return char info * RETURNS: glyph reference * FUNCTION: Initialize a glyph data structure (FREETYPE ONLY). * ****************************************************************/ static bgfx_glyph_t *bgfx_init_glyph(bgfx_font_t *font_p, FT_ULong a_char, int glyph_idx) { #ifdef CONFIG_FREETYPE FT_Error err; FT_Int ld_flags; FT_UInt index; bgfx_glyph_t *new_glyph; unsigned long nbytes; SGL_TRACE(("bgfx_init_glyph 0x%08lx\n",a_char)); bgfx_lock(); index = FT_Get_Char_Index(font_p->face,a_char); if (index == 0) { SGL_DEBUG(("bgfx_init_glyph could not find char 0x%08lx in FreeType char map\n",a_char)); bgfx_unlock(); return NULL; } ld_flags = (FT_Int) font_p->face->generic.data; ld_flags |= FT_LOAD_RENDER; err = FT_Load_Glyph( font_p->face, index, ld_flags ); if (err) { SGL_DEBUG(("bgfx_init_glyph could not load glyph %d\n",index)); bgfx_unlock(); return NULL; } /* allocate memory for glyph */ new_glyph = (bgfx_glyph_t*)SGL_MALLOC(sizeof(bgfx_glyph_t)); if (!new_glyph) { SGL_DEBUG(("bgfx_init_glyph could allocate memory for glyph\n")); bgfx_unlock(); return NULL; } new_glyph->left = font_p->face->glyph->bitmap_left; new_glyph->top = font_p->face->glyph->bitmap_top; new_glyph->advance = font_p->face->glyph->advance.x >> 6; new_glyph->width = font_p->face->glyph->bitmap.width; new_glyph->height = font_p->face->glyph->bitmap.rows; new_glyph->pitch = font_p->face->glyph->bitmap.pitch; nbytes = font_p->face->glyph->bitmap.pitch * font_p->face->glyph->bitmap.rows; new_glyph->buf = (unsigned char*)SGL_MALLOC(nbytes); if (!new_glyph->buf) { SGL_FREE(new_glyph); SGL_DEBUG(("bgfx_init_glyph could allocate memory for glyph\n")); bgfx_unlock(); return NULL; } /* copy glyph data */ SGL_MEMCPY(new_glyph->buf, font_p->face->glyph->bitmap.buffer,nbytes); font_p->glyph_cache[glyph_idx] = new_glyph; bgfx_unlock(); return new_glyph; #else BSTD_UNUSED(font_p); BSTD_UNUSED(a_char); BSTD_UNUSED(glyph_idx); return NULL; #endif } /**************************************************************** * INPUTS: font_p - font * a_char - char value * OUTPUTS: none * RETURNS: glyph cache index or -1 on failure * FUNCTION: Get a glyph cache index from the char_map. * ****************************************************************/ static inline int bgfx_map_char(bgfx_font_t *font_p, unsigned long a_char) { register int i; for (i = 0; i < font_p->cache_size; ++i) { if (font_p->char_map[i] == a_char) return i; } return -1; } /**************************************************************** * INPUTS: font_p - font * a_char - char value * OUTPUTS: info - return char info * RETURNS: glyph reference * FUNCTION: Get a glyph from the glyph cache or a fresh rendering. * ****************************************************************/ bgfx_glyph_t *bgfx_get_glyph(bgfx_font_t *font_p, unsigned long a_char) { int cache_index; SGL_TRACE(("bgfx_get_glyph 0x%08lx\n",a_char)); /* Check for glyph in glyph cache */ cache_index = bgfx_map_char(font_p,a_char); if (cache_index < 0) { SGL_DEBUG(("bgfx_get_glyph failed 0x%08lx not in font.\n",a_char)); return NULL; } SGL_TRACE(("bgfx_get_glyph find char in cache 0x%08lx (%ld)\n",cache_index,cache_index)); if (font_p->glyph_cache[cache_index] != NULL) { SGL_TRACE(("bgfx_get_glyph found char in cache\n")); return font_p->glyph_cache[cache_index]; } return bgfx_init_glyph(font_p,a_char,cache_index); } /**************************************************************** * INPUTS: font_p - font definition * str_p - array of single 32-bit unicode characters * str_len - number of 32-bit characters in string * OUTPUTS: w,h - width and height in pixels of the string * RETURNS: none * FUNCTION: Caclulate the bound rectangle for the string. * ****************************************************************/ void bgfx_string_info(bgfx_font_t *font_p, /* initialized font structure */ const unsigned long *str_p, /* array of single 32-bit unicode characters */ int str_len, /* number of 32-bit characters in string */ int *w, /* width in pixels */ int *h /* height in pixels */ ) { unsigned long current; int offset; bgfx_glyph_t * bgfx_glyph; #ifdef CONFIG_FREETYPE bgfx_glyph_t info; FT_Error err; FT_Int ld_flags; FT_UInt index; #endif *w = 0; *h = 0; bgfx_glyph = NULL; SGL_TRACE(("bgfx_string_info %s\n",str_p)); for (offset = 0; offset < str_len; offset++) { current = str_p[offset]; SGL_TRACE(("bgfx_string_info (0x%08lx)\n",current)); /* if using glyph cache use the get glyph rather than render directly to surface buffer */ if (font_p->cache_size > 0) { bgfx_glyph = bgfx_get_glyph(font_p,current); } #ifdef CONFIG_FREETYPE if (!bgfx_glyph) { bgfx_lock(); bgfx_glyph = &info; index = FT_Get_Char_Index( font_p->face, current ); SGL_TRACE(("bgfx_string_info %d\n",index)); ld_flags = (FT_Int) font_p->face->generic.data; ld_flags |= FT_LOAD_RENDER; err = FT_Load_Glyph( font_p->face, index, ld_flags ); if (err) { SGL_DEBUG(("bgfx_string_info could not load glyph %p\n",bgfx_glyph)); bgfx_unlock(); return; } bgfx_unlock(); bgfx_glyph->left = font_p->face->glyph->bitmap_left; bgfx_glyph->top = font_p->face->glyph->bitmap_top; bgfx_glyph->advance = font_p->face->glyph->advance.x >> 6; bgfx_glyph->width = font_p->face->glyph->bitmap.width; bgfx_glyph->height = font_p->face->glyph->bitmap.rows; bgfx_glyph->buf = font_p->face->glyph->bitmap.buffer; bgfx_glyph->pitch = font_p->face->glyph->bitmap.pitch; } #endif if (!bgfx_glyph) { SGL_DEBUG(("bgfx_string_info could not load glyph for char 0x%08lx\n",current)); return; } if (bgfx_glyph->height > *h) { *h = bgfx_glyph->height; } *w += bgfx_glyph->advance; } } #if 1 /**************************************************************** * INPUTS: font_p - font definition * file_p - file descriptor * OUTPUTS: none * RETURNS: none-zero on failure * FUNCTION: Load the font typeface from a binary file. * ****************************************************************/ static int bgfx_calc_mem_font(bgfx_font_t *font_p,void *file_p) { int err,size; int i; int result = -1; size = 0; size += sizeof(FT_ULong) * font_p->cache_size; /* Load bitmaps */ for (i = 0; i < font_p->cache_size; ++i) { bgfx_glyph_t glyph; SGL_IO_CHECK (bgfx_read((void*)&glyph.left,1,sizeof(glyph.left),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph.top,1,sizeof(glyph.top),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph.advance,1,sizeof(glyph.advance),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph.width,1,sizeof(glyph.width),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph.height,1,sizeof(glyph.height),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph.pitch,1,sizeof(glyph.pitch),file_p)); SGL_TRACE(("bgfx_load_font glyph %ld\n",i)); SGL_TRACE(("bgfx_load_font glyph->pitch %d\n",glyph.pitch)); SGL_TRACE(("bgfx_load_font glyph->height %d\n",glyph.height)); SGL_TRACE(("bgfx_load_font glyph->left %d\n",glyph.left)); if ((glyph.pitch * glyph.height) > 0) { size += glyph.pitch * glyph.height; bgfx_set(file_p,bgfx_tell(file_p) + (glyph.pitch * glyph.height), 0); } } result = 0; done: if (result != 0) return -1; return size; } /**************************************************************** * INPUTS: font_p - font definition * file_p - file descriptor * OUTPUTS: none * RETURNS: none-zero on failure * FUNCTION: Load the font typeface from a binary file. * ****************************************************************/ int bgfx_load_font(bgfx_font_t *font_p,void *file_p) { int result = -1; int err; unsigned long fsize,pos; int i; bgfx_glyph_t *glyph_bufs = NULL; bgfx_glyph_t *glyph = NULL; unsigned char* fbuf = NULL; /* write font header */ SGL_MEMSET(font_p,0,sizeof(bgfx_font_t)); SGL_IO_CHECK (bgfx_read((void*)&font_p->ascender,1, sizeof(font_p->ascender),file_p)); font_p->ascender = SGL_SWAP_INT(font_p->ascender); SGL_IO_CHECK (bgfx_read((void*)&font_p->descender,1, sizeof(font_p->descender),file_p)); font_p->descender = SGL_SWAP_INT(font_p->descender); SGL_IO_CHECK (bgfx_read((void*)&font_p->height,1, sizeof(font_p->height),file_p)); font_p->height = SGL_SWAP_INT(font_p->height); SGL_IO_CHECK (bgfx_read((void*)&font_p->maxadvance,1, sizeof(font_p->maxadvance),file_p)); font_p->maxadvance = SGL_SWAP_INT(font_p->maxadvance); SGL_IO_CHECK (bgfx_read((void*)&font_p->format,1, sizeof(font_p->format),file_p)); font_p->format = SGL_SWAP_ULONG(font_p->format); SGL_IO_CHECK (bgfx_read((void*)&font_p->cache_size,1, sizeof(font_p->cache_size),file_p)); font_p->cache_size = SGL_SWAP_INT(font_p->cache_size); font_p->glyph_cache = (bgfx_glyph_t**)SGL_MALLOC(sizeof(bgfx_glyph_t*) * font_p->cache_size ); SGL_MEMSET(font_p->glyph_cache,0,sizeof(bgfx_glyph_t*) * font_p->cache_size); glyph_bufs = (bgfx_glyph_t*)SGL_MALLOC(sizeof(bgfx_glyph_t) * font_p->cache_size ); font_p->char_map = (FT_ULong*)SGL_MALLOC(sizeof(FT_ULong) * font_p->cache_size ); if (!font_p->char_map || !glyph_bufs || !font_p->glyph_cache) goto done; /* load character map */ for (i = 0; i < font_p->cache_size; ++i) { SGL_IO_CHECK (bgfx_read((void*)&(font_p->char_map[i]),1, sizeof(FT_ULong), file_p )); font_p->char_map[i] = SGL_SWAP_ULONG(font_p->char_map[i]); } pos = bgfx_tell(file_p); fsize = bgfx_calc_mem_font(font_p,file_p); bgfx_set(file_p,pos,0); fbuf = SGL_MALLOC(fsize); if ((fsize <= 0) || !fbuf) goto done; /* Load bitmaps */ for (i = 0; i < font_p->cache_size; ++i) { SGL_MEMSET(glyph_bufs,0,sizeof(bgfx_glyph_t)); glyph = glyph_bufs++; font_p->glyph_cache[i] = glyph; SGL_IO_CHECK (bgfx_read((void*)&glyph->left,1,sizeof(glyph->left),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->top,1,sizeof(glyph->top),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->advance,1,sizeof(glyph->advance),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->width,1,sizeof(glyph->width),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->height,1,sizeof(glyph->height),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->pitch,1,sizeof(glyph->pitch),file_p)); SGL_TRACE(("bgfx_load_font glyph %ld\n",i)); SGL_TRACE(("bgfx_load_font glyph->pitch %d\n",glyph->pitch)); SGL_TRACE(("bgfx_load_font glyph->height %d\n",glyph->height)); SGL_TRACE(("bgfx_load_font glyph->left %d\n",glyph->left)); if ((glyph->pitch * glyph->height) > 0) { //glyph->buf = (char*)SGL_MALLOC((glyph->pitch * glyph->height)); glyph->buf = (char*)fbuf; SGL_IO_CHECK (bgfx_read(glyph->buf,1, (glyph->pitch * glyph->height),file_p)); fbuf += (glyph->pitch * glyph->height); } SGL_TRACE(("bgfx_load_font glyph->buf %p\n",glyph->buf)); } result = 0; done: if (result != 0) { if (font_p->glyph_cache) free(font_p->glyph_cache); if (font_p->char_map) free(font_p->char_map); if (glyph_bufs) free(glyph_bufs); if (fbuf) free(fbuf); } return result; } #else /**************************************************************** * INPUTS: font_p - font definition * file_p - file descriptor * OUTPUTS: none * RETURNS: none-zero on failure * FUNCTION: Load the font typeface from a binary file. * ****************************************************************/ int bgfx_load_font(bgfx_font_t *font_p,void *file_p) { int result = -1; int err; unsigned long i; bgfx_glyph_t *glyph; unsigned int size; /* write font header */ SGL_MEMSET(font_p,0,sizeof(bgfx_font_t)); SGL_IO_CHECK (bgfx_read((void*)&font_p->ascender,1, sizeof(font_p->ascender),file_p)); font_p->ascender = SGL_SWAP_INT(font_p->ascender); SGL_IO_CHECK (bgfx_read((void*)&font_p->descender,1, sizeof(font_p->descender),file_p)); font_p->descender = SGL_SWAP_INT(font_p->descender); SGL_IO_CHECK (bgfx_read((void*)&font_p->height,1, sizeof(font_p->height),file_p)); font_p->height = SGL_SWAP_INT(font_p->height); SGL_IO_CHECK (bgfx_read((void*)&font_p->maxadvance,1, sizeof(font_p->maxadvance),file_p)); font_p->maxadvance = SGL_SWAP_INT(font_p->maxadvance); SGL_IO_CHECK (bgfx_read((void*)&font_p->format,1, sizeof(font_p->format),file_p)); font_p->format = SGL_SWAP_ULONG(font_p->format); SGL_IO_CHECK (bgfx_read((void*)&font_p->cache_size,1, sizeof(font_p->cache_size),file_p)); font_p->cache_size = SGL_SWAP_INT(font_p->cache_size); font_p->glyph_cache = (bgfx_glyph_t**)SGL_MALLOC(sizeof(bgfx_glyph_t*) * font_p->cache_size ); size = sizeof(bgfx_glyph_t*) * font_p->cache_size; printf("%s:%d size = %d\n",__FUNCTION__,__LINE__,size); if (!font_p->glyph_cache) goto done; SGL_MEMSET(font_p->glyph_cache,0,sizeof(bgfx_glyph_t*) * font_p->cache_size); font_p->char_map = (FT_ULong*)SGL_MALLOC(sizeof(FT_ULong) * font_p->cache_size ); size += sizeof(FT_ULong) * font_p->cache_size; printf("%s:%d size = %d\n",__FUNCTION__,__LINE__,size); if (!font_p->char_map) goto done; /* load character map */ for (i = 0; i < font_p->cache_size; ++i) { SGL_IO_CHECK (bgfx_read((void*)&(font_p->char_map[i]),1, sizeof(FT_ULong), file_p )); font_p->char_map[i] = SGL_SWAP_ULONG(font_p->char_map[i]); } /* Load bitmaps */ for (i = 0; i < font_p->cache_size; ++i) { glyph = (bgfx_glyph_t*)SGL_MALLOC(sizeof(bgfx_glyph_t)); size += sizeof(bgfx_glyph_t); printf("%s:%d size = %d\n",__FUNCTION__,__LINE__,size); if (!glyph) goto done; SGL_MEMSET(glyph,0,sizeof(bgfx_glyph_t)); font_p->glyph_cache[i] = glyph; SGL_IO_CHECK (bgfx_read((void*)&glyph->left,1,sizeof(glyph->left),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->top,1,sizeof(glyph->top),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->advance,1,sizeof(glyph->advance),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->width,1,sizeof(glyph->width),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->height,1,sizeof(glyph->height),file_p)); SGL_IO_CHECK (bgfx_read((void*)&glyph->pitch,1,sizeof(glyph->pitch),file_p)); SGL_TRACE(("bgfx_load_font glyph %ld\n",i)); SGL_TRACE(("bgfx_load_font glyph->pitch %d\n",glyph->pitch)); SGL_TRACE(("bgfx_load_font glyph->height %d\n",glyph->height)); SGL_TRACE(("bgfx_load_font glyph->left %d\n",glyph->left)); if ((glyph->pitch * glyph->height) > 0) { glyph->buf = (char*)SGL_MALLOC((glyph->pitch * glyph->height)); size += glyph->pitch * glyph->height; printf("%s:%d size = %d(%d,%d)\n",__FUNCTION__,__LINE__,size,glyph->pitch,glyph->height); if (!glyph->buf) goto done; SGL_IO_CHECK (bgfx_read(glyph->buf,1, (glyph->pitch * glyph->height),file_p)); } SGL_TRACE(("bgfx_load_font glyph->buf %p\n",glyph->buf)); } result = 0; done: if (result != 0) { if (font_p->char_map) free(font_p->char_map); for (i = 0; i < font_p->cache_size; ++i) { if (font_p->glyph_cache[i]) { if (font_p->glyph_cache[i]->buf) SGL_FREE(font_p->glyph_cache[i]->buf); SGL_FREE(font_p->glyph_cache[i]); } } } return result; } #endif