source: svn/trunk/newcon3bcm2_21bu/nexus/lib/softgfx/src/bgfx_font.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 26.3 KB
Line 
1/***************************************************************
2**     (c)2009 Broadcom Corporation
3** 
4**  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5**  and may only be used, duplicated, modified or distributed pursuant to the terms and
6**  conditions of a separate, written license agreement executed between you and Broadcom
7**  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8**  no license (express or implied), right to use, or waiver of any kind with respect to the
9**  Software, and Broadcom expressly reserves all rights in and to the Software and all
10**  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11**  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12**  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. 
13**   
14**  Except as expressly set forth in the Authorized License,
15**   
16**  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17**  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18**  and to use this information only in connection with your use of Broadcom integrated circuit products.
19**   
20**  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21**  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22**  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23**  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24**  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25**  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26**  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27**  USE OR PERFORMANCE OF THE SOFTWARE.
28** 
29**  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30**  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31**  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32**  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33**  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34**  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35**  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36**  ANY LIMITED REMEDY.
37**
38** Created: 8/22/2002 by Jeffrey P. Fisher
39**
40** $brcm_Workfile: bgfx_font.c $
41** $brcm_Revision: Refsw_7550/3 $
42** $brcm_Date: 11/26/09 11:27a $
43**
44** Revision History:
45**
46** $brcm_Log: /nexus/lib/softgfx/src/bgfx_font.c $
47**
48** Refsw_7550/3   11/26/09 11:27a kagrawal
49** SW7550-77: Fixed compile time warning
50**
51** Refsw_7550/2   9/25/09 12:54p kagrawal
52** SW7550-50: Performance optimized gfx from 7003 latest
53**
54** Refsw_7550/1   9/7/09 5:04p kagrawal
55** SW7550-3: Initial check-in for Soft Graphics
56**
57****************************************************************/
58
59/** include files **/
60#if (BCHP_CHIP != 7003)
61#define BDISPATCH_BYPASS
62#endif
63#include "bgfx.h"
64#undef BDISPATCH_BYPASS
65#if !defined LINUX && !defined B_OS_UCOS_II
66#include "bdispatch.h"
67#endif
68
69BDBG_MODULE(bgfx);
70
71static bgfx_glyph_t *bgfx_init_glyph(bgfx_font_t *font_p, FT_ULong  a_char, int glyph_idx);
72
73/* global SGL structure */
74typedef struct bgfx_t
75{
76#ifdef CONFIG_FREETYPE
77        FT_Library      ft_library;
78#else
79    int tbd; /* fixes warning */
80#endif
81}bgfx_t;
82
83#ifdef CONFIG_FREETYPE
84        static bgfx_t g_bgfx = { NULL };
85#endif
86
87/****************************************************************}
88* INPUTS:       none
89* OUTPUTS:      none
90* RETURNS:      non-zero on failure
91* FUNCTION: Initialize the SGIL font library
92*
93****************************************************************/
94int bgfx_font_init()
95{
96        int result = 0;
97
98    SGL_TRACE(("font_init\n"));
99#ifdef CONFIG_FREETYPE
100        bgfx_lock();
101        {
102                FT_Error err;
103                err = FT_Init_FreeType( &g_bgfx.ft_library );
104                if (err)
105                {
106                        g_bgfx.ft_library = NULL;
107                        result = -1;
108                        SGL_DEBUG(("font_init - FT_Init_FreeType(%d)\n",err));
109                }
110        }
111        bgfx_unlock();
112#endif
113    SGL_TRACE(("font_init - done\n"));
114        return result;
115}
116
117/****************************************************************}
118* INPUTS:       none
119* OUTPUTS:      none
120* RETURNS:      non-zero on failure
121* FUNCTION: release sgl global resources, primarily for handling freetype
122*
123****************************************************************/
124void bgfx_font_done()
125{
126    SGL_TRACE(("font_done\n"));
127#ifdef CONFIG_FREETYPE
128    bgfx_lock();
129       
130    if (g_bgfx.ft_library)
131                FT_Done_FreeType( g_bgfx.ft_library );
132        g_bgfx.ft_library = NULL;
133        bgfx_unlock();
134#endif
135}
136
137#ifdef CONFIG_FREETYPE
138/****************************************************************
139* INPUTS:               fr_p - font ripper parameters
140* OUTPUTS:              none
141* RETURNS:              number of glyph entries
142* DESCRIPTION:  Get the maximum number of glyph index entries.
143*
144****************************************************************/
145
146int get_max_glyph_index(bgfx_font_t *font_p)
147{
148        FT_ULong  charcode;                                             
149        FT_UInt   gindex;                                               
150        int cnt = 0;                                                                                                     
151
152        charcode = FT_Get_First_Char( font_p->face, &gindex );                   
153        while ( gindex != 0 )                                           
154        {   
155                ++cnt;
156                charcode = FT_Get_Next_Char( font_p->face, charcode, &gindex );       
157        }
158        return cnt;
159}
160
161/****************************************************************
162* INPUTS:   font_p - font definition
163* OUTPUTS:      none
164* RETURNS:      none-zero on failure
165* FUNCTION:     create the charmap.
166*
167****************************************************************/
168int bgfx_create_char_map(bgfx_font_t *font_p)
169{   
170    int i = 0;
171        FT_ULong  charcode;                                             
172        FT_UInt   gindex;
173
174        font_p->cache_size = get_max_glyph_index(font_p);
175        if (font_p->char_map_size <= 0)
176        {
177                SGL_DEBUG(("bgfx_create_char_map failed, no unicode encoding for this font.\n"));
178                return -1;
179        }
180        font_p->char_map = (bgfx_glyph_t**)SGL_MALLOC(sizeof(bgfx_glyph_t*) * font_p->cache_size );
181   
182        if (!font_p->glyph_cache)
183        {
184                SGL_DEBUG(("bgfx_create_char_map failed, could not allocate memory for char map.\n"));
185                return -1;
186        }
187       
188    bgfx_lock();
189        charcode = FT_Get_First_Char( font_p->face, &gindex );                   
190        while ( gindex != 0 )                                           
191        {   
192                font_p->char_map[i++] = charcode;
193
194                charcode = FT_Get_Next_Char( font_p->face, charcode, &gindex );
195        }
196        bgfx_unlock();
197    SGL_TRACE(("bgfx_create_char_map - %d chars.\n",i));
198
199    return 0;
200}
201#endif /* CONFIG_FREETYPE */
202
203/****************************************************************
204* INPUTS:   font_p - font definition
205*           typeface_name - name of the typeface
206*           height - font height
207* OUTPUTS:      none
208* RETURNS:      none-zero on failure
209* FUNCTION:     Load the font typeface.
210*
211* The general usage convention in SGIL is to avoid memory allocation
212* in SGIL functions.  For example before calling bgfx_new_font a
213* valid font_t structure must be created and passed to bgfx_new_font.
214* The font_t structure is modified but not allocated by bgfx_new_font. 
215* A primary exception is that the glyph cache and glyphs are
216* allocated and manage internally.  Therefore, it is important to
217* call bgfx_free_font to allow SGIL to perform cleanup on the glyph cache.
218****************************************************************/
219int bgfx_new_font(bgfx_font_t *font_p,
220                                 const char *typeface_name, unsigned char height,unsigned long flags)
221{
222    SGL_TRACE(("bgfx_new_font - %s:%d,%ld\n",typeface_name,height,flags));
223#ifdef CONFIG_FREETYPE
224        {
225                FT_Error     err;
226                unsigned long i;
227                bgfx_glyph_t *glyph;
228       
229                bgfx_lock();
230       
231                err = FT_New_Face( g_bgfx.ft_library, typeface_name,0,  &font_p->face );
232                if (err)
233                {
234                        SGL_DEBUG(("bgfx_new_font could not open typeface %s\n",typeface_name));
235                        bgfx_unlock();
236                        return -1;
237                }
238       
239                err = FT_Select_Charmap( font_p->face, ft_encoding_unicode );
240        #if FREETYPE_MINOR > 0
241                if (err)
242                {
243                        SGL_DEBUG(("bgfx_new_font could not open unicode charmap, default to latin\n"));
244                        err = FT_Select_Charmap( font_p->face, ft_encoding_latin_1 );
245                }
246        #endif
247                if (err)
248                {
249                        SGL_DEBUG(("bgfx_new_font could not select charmap for font %s\n",typeface_name));
250                        bgfx_unlock();
251                        return -1;
252                }
253                err = FT_Set_Pixel_Sizes( font_p->face, 0, height);
254                if (err)
255                {
256                        SGL_DEBUG(("bgfx_new_font could set font height to %d\n",height));
257                        FT_Done_Face( font_p->face );
258                        bgfx_unlock();
259                        return -1;
260                }
261                if (flags & SGL_MONO)
262                        font_p->face->generic.data = (void *) (FT_LOAD_DEFAULT | FT_LOAD_MONOCHROME);
263                else
264                        font_p->face->generic.data = (void *) FT_LOAD_DEFAULT;
265                font_p->ascender    = font_p->face->size->metrics.ascender  >> 6;
266                font_p->descender   = font_p->face->size->metrics.descender >> 6;
267                font_p->height      = (font_p->face->size->metrics.ascender -
268                                                           font_p->face->size->metrics.descender) >> 6;
269                font_p->maxadvance  = font_p->face->size->metrics.max_advance >> 6;
270               
271                /* create glyph cache */
272                if (flags & SGL_CACHE_GLYPHS)
273                {
274                        font_p->cache_size = font_p->face->num_glyphs;
275                        font_p->glyph_cache = (bgfx_glyph_t**)SGL_MALLOC(sizeof(bgfx_glyph_t*) * font_p->cache_size);
276                        if (font_p->glyph_cache)
277                                SGL_MEMSET(font_p->glyph_cache,0,sizeof(bgfx_glyph_t*) * font_p->cache_size);
278                        else
279                                font_p->cache_size = 0;
280                }
281                else
282                {
283                        font_p->cache_size = 0;
284                        font_p->glyph_cache = NULL;
285                }
286                font_p->format = flags;
287                bgfx_unlock();
288               
289                if (bgfx_create_char_map(font_p) != 0)
290                {
291                        SGL_DEBUG(("bgfx_new_font could not create charmap\n"));
292                        FT_Done_Face( font_p->face );
293                        return -1;
294                }
295       
296                if (flags & SGL_PRELOAD_GLYPHS)
297                {
298                        for (i = 0; i < font_p->cache_size; ++i)
299                                glyph = bgfx_init_glyph(font_p,font_p->char_map[i],i);
300                }
301        }
302        return 0;
303#else
304    BSTD_UNUSED(font_p);
305        return -1; /* must load fonts when there is no freetype support */
306#endif
307}
308/****************************************************************
309* INPUTS:   font_p - font definition
310* OUTPUTS:      none
311* RETURNS:      none
312* FUNCTION:     Free font typeface.
313*
314****************************************************************/
315void bgfx_free_font(bgfx_font_t *font_p)
316{
317        if (font_p->glyph_cache[0]->buf)
318                free(font_p->glyph_cache[0]->buf);
319        if (font_p->glyph_cache[0])
320                free(font_p->glyph_cache[0]);
321        if (font_p->char_map)
322                free(font_p->char_map);
323        if (font_p->glyph_cache)
324                free(font_p->glyph_cache);
325#if 0
326    int i;
327    for (i = 0; i < font_p->cache_size; ++i)
328    {
329        bgfx_glyph_t *glyph = font_p->glyph_cache[i];
330        if (glyph)
331        {
332            SGL_FREE(glyph->buf);
333            SGL_FREE(glyph);
334            font_p->glyph_cache[i] = NULL;
335        }
336    }
337        SGL_FREE(font_p->glyph_cache);
338#ifdef CONFIG_FREETYPE
339    FT_Done_Face (font_p->face);
340#endif
341#endif
342}
343
344/****************************************************************
345* INPUTS:       font_p - font
346*                       a_char - the character
347*                       glyph_idx - glyph index
348* OUTPUTS:      info - return char info
349* RETURNS:      glyph reference
350* FUNCTION:     Initialize a glyph data structure (FREETYPE ONLY).
351*
352****************************************************************/
353static bgfx_glyph_t *bgfx_init_glyph(bgfx_font_t *font_p, FT_ULong  a_char, int glyph_idx)
354{
355#ifdef CONFIG_FREETYPE
356        FT_Error err;
357        FT_Int   ld_flags;
358        FT_UInt  index;
359    bgfx_glyph_t *new_glyph;
360    unsigned long nbytes;
361
362        SGL_TRACE(("bgfx_init_glyph 0x%08lx\n",a_char));
363
364        bgfx_lock();
365
366        index = FT_Get_Char_Index(font_p->face,a_char);
367        if (index == 0)
368        {
369                SGL_DEBUG(("bgfx_init_glyph could not find char 0x%08lx in FreeType char map\n",a_char));
370                bgfx_unlock();
371                return NULL;
372        }
373
374        ld_flags = (FT_Int) font_p->face->generic.data;
375        ld_flags |= FT_LOAD_RENDER;
376        err = FT_Load_Glyph( font_p->face, index, ld_flags );
377        if (err)
378        {
379                SGL_DEBUG(("bgfx_init_glyph could not load glyph %d\n",index));
380                bgfx_unlock();
381                return NULL;
382        }
383
384    /* allocate memory for glyph */
385
386    new_glyph = (bgfx_glyph_t*)SGL_MALLOC(sizeof(bgfx_glyph_t));
387        if (!new_glyph)
388        {
389                SGL_DEBUG(("bgfx_init_glyph could allocate memory for glyph\n"));
390                bgfx_unlock();
391                return NULL;
392        }
393        new_glyph->left = font_p->face->glyph->bitmap_left;
394        new_glyph->top  = font_p->face->glyph->bitmap_top;
395        new_glyph->advance = font_p->face->glyph->advance.x >> 6;
396        new_glyph->width = font_p->face->glyph->bitmap.width;
397        new_glyph->height = font_p->face->glyph->bitmap.rows;
398    new_glyph->pitch = font_p->face->glyph->bitmap.pitch;
399   
400    nbytes = font_p->face->glyph->bitmap.pitch * font_p->face->glyph->bitmap.rows;
401    new_glyph->buf = (unsigned char*)SGL_MALLOC(nbytes);
402
403        if (!new_glyph->buf)
404        {
405                SGL_FREE(new_glyph);
406        SGL_DEBUG(("bgfx_init_glyph could allocate memory for glyph\n"));
407                bgfx_unlock();
408                return NULL;
409        }
410
411    /* copy glyph data */
412    SGL_MEMCPY(new_glyph->buf, font_p->face->glyph->bitmap.buffer,nbytes);
413    font_p->glyph_cache[glyph_idx] = new_glyph;
414
415        bgfx_unlock();
416        return new_glyph;
417#else
418    BSTD_UNUSED(font_p);
419    BSTD_UNUSED(a_char);
420    BSTD_UNUSED(glyph_idx);
421        return NULL;
422#endif
423}
424/****************************************************************
425* INPUTS:       font_p - font
426*                       a_char - char value
427* OUTPUTS:      none
428* RETURNS:      glyph cache index or -1 on failure
429* FUNCTION:     Get a glyph cache index from the char_map.
430*
431****************************************************************/
432static inline int bgfx_map_char(bgfx_font_t *font_p, unsigned long a_char)
433{
434        register int i;
435        for (i = 0; i < font_p->cache_size; ++i)
436        {
437                if (font_p->char_map[i] == a_char)
438                        return i;
439        }
440        return -1;
441}
442/****************************************************************
443* INPUTS:       font_p - font
444*                       a_char - char value
445* OUTPUTS:      info - return char info
446* RETURNS:      glyph reference
447* FUNCTION:     Get a glyph from the glyph cache or a fresh rendering.
448*
449****************************************************************/
450bgfx_glyph_t *bgfx_get_glyph(bgfx_font_t *font_p, unsigned long a_char)
451{
452        int cache_index;
453        SGL_TRACE(("bgfx_get_glyph 0x%08lx\n",a_char));
454
455    /* Check for glyph in glyph cache */
456        cache_index = bgfx_map_char(font_p,a_char);
457    if (cache_index < 0)
458    {
459        SGL_DEBUG(("bgfx_get_glyph failed 0x%08lx not in font.\n",a_char));
460        return NULL;
461    }
462
463    SGL_TRACE(("bgfx_get_glyph find char in cache 0x%08lx (%ld)\n",cache_index,cache_index));
464    if (font_p->glyph_cache[cache_index] != NULL)
465    {
466        SGL_TRACE(("bgfx_get_glyph found char in cache\n"));
467        return font_p->glyph_cache[cache_index];
468    }
469        return bgfx_init_glyph(font_p,a_char,cache_index);
470}
471/****************************************************************
472* INPUTS:       font_p - font definition
473*                       str_p - array of single 32-bit unicode characters
474*                       str_len - number of 32-bit characters in string
475* OUTPUTS:      w,h - width and height in pixels of the string
476* RETURNS:      none
477* FUNCTION:     Caclulate the bound rectangle for the string.
478*
479****************************************************************/
480
481void bgfx_string_info(bgfx_font_t *font_p,                                      /* initialized font structure */
482                                                        const unsigned long *str_p,     /* array of single 32-bit unicode characters */
483                                                        int     str_len,                                        /* number of 32-bit characters in string */
484                                                        int *w,                                                 /* width in pixels */
485                                                        int *h                                                  /* height in pixels */
486                                                        )
487{
488        unsigned long current;
489        int offset;
490        bgfx_glyph_t * bgfx_glyph;
491#ifdef CONFIG_FREETYPE
492    bgfx_glyph_t info;
493        FT_Error err;
494        FT_Int   ld_flags;
495        FT_UInt  index;
496#endif
497        *w = 0; *h = 0;
498        bgfx_glyph = NULL;
499        SGL_TRACE(("bgfx_string_info %s\n",str_p));
500
501        for (offset = 0; offset < str_len; offset++)
502        {
503                current = str_p[offset];
504                SGL_TRACE(("bgfx_string_info (0x%08lx)\n",current));
505
506                /* if using glyph cache use the get glyph rather than render directly to surface buffer */
507                if (font_p->cache_size > 0)
508                {
509                        bgfx_glyph = bgfx_get_glyph(font_p,current);
510                }
511#ifdef CONFIG_FREETYPE
512                if (!bgfx_glyph)
513                {   
514                        bgfx_lock();
515                        bgfx_glyph = &info;
516       
517                        index = FT_Get_Char_Index( font_p->face, current );
518                        SGL_TRACE(("bgfx_string_info %d\n",index));
519               
520                        ld_flags = (FT_Int) font_p->face->generic.data;
521                        ld_flags |= FT_LOAD_RENDER;
522                        err = FT_Load_Glyph( font_p->face, index, ld_flags );
523                        if (err)
524                        {
525                                SGL_DEBUG(("bgfx_string_info could not load glyph %p\n",bgfx_glyph));
526                                bgfx_unlock();
527                                return;
528                        }
529                        bgfx_unlock();
530       
531                        bgfx_glyph->left = font_p->face->glyph->bitmap_left;
532                        bgfx_glyph->top  = font_p->face->glyph->bitmap_top;
533               
534                        bgfx_glyph->advance = font_p->face->glyph->advance.x >> 6;
535                        bgfx_glyph->width = font_p->face->glyph->bitmap.width;
536               
537                        bgfx_glyph->height = font_p->face->glyph->bitmap.rows;
538                 
539                        bgfx_glyph->buf = font_p->face->glyph->bitmap.buffer;
540                        bgfx_glyph->pitch = font_p->face->glyph->bitmap.pitch;
541                }
542#endif
543                if (!bgfx_glyph)
544                {
545                        SGL_DEBUG(("bgfx_string_info could not load glyph for char 0x%08lx\n",current));
546                        return;
547                }
548                if (bgfx_glyph->height > *h)
549                {
550                        *h = bgfx_glyph->height;
551                }
552                *w += bgfx_glyph->advance;
553        }
554}
555#if 1
556/****************************************************************
557* INPUTS:   font_p - font definition
558*           file_p - file descriptor
559* OUTPUTS:      none
560* RETURNS:      none-zero on failure
561* FUNCTION:     Load the font typeface from a binary file.
562*
563****************************************************************/
564static int bgfx_calc_mem_font(bgfx_font_t *font_p,void *file_p)   
565{
566    int err,size;
567    int i;
568    int result = -1;
569
570    size = 0;
571        size += sizeof(FT_ULong) * font_p->cache_size;
572
573        /* Load bitmaps */
574    for (i = 0; i < font_p->cache_size; ++i)
575    {
576                bgfx_glyph_t glyph;
577
578        SGL_IO_CHECK (bgfx_read((void*)&glyph.left,1,sizeof(glyph.left),file_p));
579        SGL_IO_CHECK (bgfx_read((void*)&glyph.top,1,sizeof(glyph.top),file_p));
580        SGL_IO_CHECK (bgfx_read((void*)&glyph.advance,1,sizeof(glyph.advance),file_p));
581        SGL_IO_CHECK (bgfx_read((void*)&glyph.width,1,sizeof(glyph.width),file_p));
582        SGL_IO_CHECK (bgfx_read((void*)&glyph.height,1,sizeof(glyph.height),file_p));
583        SGL_IO_CHECK (bgfx_read((void*)&glyph.pitch,1,sizeof(glyph.pitch),file_p));
584        SGL_TRACE(("bgfx_load_font glyph %ld\n",i));
585        SGL_TRACE(("bgfx_load_font glyph->pitch %d\n",glyph.pitch));
586        SGL_TRACE(("bgfx_load_font glyph->height %d\n",glyph.height));
587        SGL_TRACE(("bgfx_load_font glyph->left %d\n",glyph.left));
588        if ((glyph.pitch * glyph.height) > 0)
589        {
590                        size += glyph.pitch * glyph.height;
591            bgfx_set(file_p,bgfx_tell(file_p) + (glyph.pitch * glyph.height), 0);
592        }
593    }
594        result = 0;
595done:
596        if (result != 0)
597                return -1;
598    return size;
599}
600
601/****************************************************************
602* INPUTS:   font_p - font definition
603*           file_p - file descriptor
604* OUTPUTS:      none
605* RETURNS:      none-zero on failure
606* FUNCTION:     Load the font typeface from a binary file.
607*
608****************************************************************/
609int bgfx_load_font(bgfx_font_t *font_p,void *file_p)   
610{
611    int result = -1;
612    int err;
613    unsigned long fsize,pos;
614    int i;
615        bgfx_glyph_t *glyph_bufs = NULL;
616        bgfx_glyph_t *glyph = NULL;
617        unsigned char* fbuf = NULL;
618   
619        /* write font header */
620    SGL_MEMSET(font_p,0,sizeof(bgfx_font_t));
621    SGL_IO_CHECK (bgfx_read((void*)&font_p->ascender,1, sizeof(font_p->ascender),file_p));
622        font_p->ascender = SGL_SWAP_INT(font_p->ascender);
623    SGL_IO_CHECK (bgfx_read((void*)&font_p->descender,1, sizeof(font_p->descender),file_p));
624        font_p->descender = SGL_SWAP_INT(font_p->descender);
625    SGL_IO_CHECK (bgfx_read((void*)&font_p->height,1, sizeof(font_p->height),file_p));
626        font_p->height = SGL_SWAP_INT(font_p->height);
627    SGL_IO_CHECK (bgfx_read((void*)&font_p->maxadvance,1, sizeof(font_p->maxadvance),file_p));
628        font_p->maxadvance = SGL_SWAP_INT(font_p->maxadvance);
629    SGL_IO_CHECK (bgfx_read((void*)&font_p->format,1, sizeof(font_p->format),file_p));
630        font_p->format = SGL_SWAP_ULONG(font_p->format);
631    SGL_IO_CHECK (bgfx_read((void*)&font_p->cache_size,1, sizeof(font_p->cache_size),file_p));
632        font_p->cache_size = SGL_SWAP_INT(font_p->cache_size);
633
634        font_p->glyph_cache = (bgfx_glyph_t**)SGL_MALLOC(sizeof(bgfx_glyph_t*) * font_p->cache_size );
635       
636        SGL_MEMSET(font_p->glyph_cache,0,sizeof(bgfx_glyph_t*) * font_p->cache_size);
637       
638        glyph_bufs = (bgfx_glyph_t*)SGL_MALLOC(sizeof(bgfx_glyph_t) * font_p->cache_size );
639        font_p->char_map = (FT_ULong*)SGL_MALLOC(sizeof(FT_ULong) * font_p->cache_size );
640
641        if (!font_p->char_map || !glyph_bufs || !font_p->glyph_cache)
642        goto done;
643
644        /* load character map */
645    for (i = 0; i < font_p->cache_size; ++i)
646        {
647                SGL_IO_CHECK (bgfx_read((void*)&(font_p->char_map[i]),1, sizeof(FT_ULong), file_p ));
648                font_p->char_map[i] = SGL_SWAP_ULONG(font_p->char_map[i]);
649        }
650
651        pos = bgfx_tell(file_p);
652        fsize = bgfx_calc_mem_font(font_p,file_p);
653        bgfx_set(file_p,pos,0);
654
655        fbuf = SGL_MALLOC(fsize);
656        if ((fsize <= 0) || !fbuf)
657                goto done;
658
659        /* Load bitmaps */
660    for (i = 0; i < font_p->cache_size; ++i)
661    {
662        SGL_MEMSET(glyph_bufs,0,sizeof(bgfx_glyph_t));
663                glyph = glyph_bufs++;
664        font_p->glyph_cache[i] = glyph;
665        SGL_IO_CHECK (bgfx_read((void*)&glyph->left,1,sizeof(glyph->left),file_p));
666        SGL_IO_CHECK (bgfx_read((void*)&glyph->top,1,sizeof(glyph->top),file_p));
667        SGL_IO_CHECK (bgfx_read((void*)&glyph->advance,1,sizeof(glyph->advance),file_p));
668        SGL_IO_CHECK (bgfx_read((void*)&glyph->width,1,sizeof(glyph->width),file_p));
669        SGL_IO_CHECK (bgfx_read((void*)&glyph->height,1,sizeof(glyph->height),file_p));
670        SGL_IO_CHECK (bgfx_read((void*)&glyph->pitch,1,sizeof(glyph->pitch),file_p));
671        SGL_TRACE(("bgfx_load_font glyph %ld\n",i));
672        SGL_TRACE(("bgfx_load_font glyph->pitch %d\n",glyph->pitch));
673        SGL_TRACE(("bgfx_load_font glyph->height %d\n",glyph->height));
674        SGL_TRACE(("bgfx_load_font glyph->left %d\n",glyph->left));
675        if ((glyph->pitch * glyph->height) > 0)
676        {
677            //glyph->buf = (char*)SGL_MALLOC((glyph->pitch * glyph->height));
678            glyph->buf = (char*)fbuf;
679            SGL_IO_CHECK (bgfx_read(glyph->buf,1, (glyph->pitch * glyph->height),file_p));
680                        fbuf += (glyph->pitch * glyph->height);
681        }
682        SGL_TRACE(("bgfx_load_font glyph->buf %p\n",glyph->buf));
683    }
684    result = 0;
685
686 done:
687         if (result != 0)
688         {
689                 if (font_p->glyph_cache)
690                         free(font_p->glyph_cache);
691                 if (font_p->char_map)
692                         free(font_p->char_map);
693                 if (glyph_bufs)
694                         free(glyph_bufs);
695                 if (fbuf)
696                         free(fbuf);
697         }
698    return result;
699}
700#else
701
702/****************************************************************
703* INPUTS:   font_p - font definition
704*           file_p - file descriptor
705* OUTPUTS:      none
706* RETURNS:      none-zero on failure
707* FUNCTION:     Load the font typeface from a binary file.
708*
709****************************************************************/
710int bgfx_load_font(bgfx_font_t *font_p,void *file_p)   
711{
712    int result = -1;
713    int err;
714    unsigned long i;
715    bgfx_glyph_t *glyph;
716        unsigned int size;
717   
718        /* write font header */
719    SGL_MEMSET(font_p,0,sizeof(bgfx_font_t));
720    SGL_IO_CHECK (bgfx_read((void*)&font_p->ascender,1, sizeof(font_p->ascender),file_p));
721        font_p->ascender = SGL_SWAP_INT(font_p->ascender);
722    SGL_IO_CHECK (bgfx_read((void*)&font_p->descender,1, sizeof(font_p->descender),file_p));
723        font_p->descender = SGL_SWAP_INT(font_p->descender);
724    SGL_IO_CHECK (bgfx_read((void*)&font_p->height,1, sizeof(font_p->height),file_p));
725        font_p->height = SGL_SWAP_INT(font_p->height);
726    SGL_IO_CHECK (bgfx_read((void*)&font_p->maxadvance,1, sizeof(font_p->maxadvance),file_p));
727        font_p->maxadvance = SGL_SWAP_INT(font_p->maxadvance);
728    SGL_IO_CHECK (bgfx_read((void*)&font_p->format,1, sizeof(font_p->format),file_p));
729        font_p->format = SGL_SWAP_ULONG(font_p->format);
730    SGL_IO_CHECK (bgfx_read((void*)&font_p->cache_size,1, sizeof(font_p->cache_size),file_p));
731        font_p->cache_size = SGL_SWAP_INT(font_p->cache_size);
732
733        font_p->glyph_cache = (bgfx_glyph_t**)SGL_MALLOC(sizeof(bgfx_glyph_t*) * font_p->cache_size );
734    size = sizeof(bgfx_glyph_t*) * font_p->cache_size;
735        printf("%s:%d size = %d\n",__FUNCTION__,__LINE__,size);
736
737        if (!font_p->glyph_cache)
738        goto done;
739   
740        SGL_MEMSET(font_p->glyph_cache,0,sizeof(bgfx_glyph_t*) * font_p->cache_size);
741   
742        font_p->char_map = (FT_ULong*)SGL_MALLOC(sizeof(FT_ULong) * font_p->cache_size );
743        size += sizeof(FT_ULong) * font_p->cache_size;
744        printf("%s:%d size = %d\n",__FUNCTION__,__LINE__,size);
745   
746        if (!font_p->char_map)
747        goto done;
748
749        /* load character map */
750    for (i = 0; i < font_p->cache_size; ++i)
751        {
752                SGL_IO_CHECK (bgfx_read((void*)&(font_p->char_map[i]),1, sizeof(FT_ULong), file_p ));
753                font_p->char_map[i] = SGL_SWAP_ULONG(font_p->char_map[i]);
754        }
755
756        /* Load bitmaps */
757    for (i = 0; i < font_p->cache_size; ++i)
758    {
759        glyph = (bgfx_glyph_t*)SGL_MALLOC(sizeof(bgfx_glyph_t));
760                size += sizeof(bgfx_glyph_t);
761                printf("%s:%d size = %d\n",__FUNCTION__,__LINE__,size);
762       
763                if (!glyph)
764            goto done;
765
766        SGL_MEMSET(glyph,0,sizeof(bgfx_glyph_t));
767        font_p->glyph_cache[i] = glyph;
768
769        SGL_IO_CHECK (bgfx_read((void*)&glyph->left,1,sizeof(glyph->left),file_p));
770        SGL_IO_CHECK (bgfx_read((void*)&glyph->top,1,sizeof(glyph->top),file_p));
771        SGL_IO_CHECK (bgfx_read((void*)&glyph->advance,1,sizeof(glyph->advance),file_p));
772        SGL_IO_CHECK (bgfx_read((void*)&glyph->width,1,sizeof(glyph->width),file_p));
773        SGL_IO_CHECK (bgfx_read((void*)&glyph->height,1,sizeof(glyph->height),file_p));
774        SGL_IO_CHECK (bgfx_read((void*)&glyph->pitch,1,sizeof(glyph->pitch),file_p));
775        SGL_TRACE(("bgfx_load_font glyph %ld\n",i));
776        SGL_TRACE(("bgfx_load_font glyph->pitch %d\n",glyph->pitch));
777        SGL_TRACE(("bgfx_load_font glyph->height %d\n",glyph->height));
778        SGL_TRACE(("bgfx_load_font glyph->left %d\n",glyph->left));
779        if ((glyph->pitch * glyph->height) > 0)
780        {
781            glyph->buf = (char*)SGL_MALLOC((glyph->pitch * glyph->height));
782                        size += glyph->pitch * glyph->height;
783                        printf("%s:%d size = %d(%d,%d)\n",__FUNCTION__,__LINE__,size,glyph->pitch,glyph->height);
784            if (!glyph->buf)
785                goto done;
786            SGL_IO_CHECK (bgfx_read(glyph->buf,1, (glyph->pitch * glyph->height),file_p));
787        }
788        SGL_TRACE(("bgfx_load_font glyph->buf %p\n",glyph->buf));
789    }
790    result = 0;
791
792 done:
793    if (result != 0)
794    {
795        if (font_p->char_map)
796            free(font_p->char_map);
797        for (i = 0; i < font_p->cache_size; ++i)
798        {
799            if (font_p->glyph_cache[i])
800            {
801                if (font_p->glyph_cache[i]->buf)
802                    SGL_FREE(font_p->glyph_cache[i]->buf);
803                SGL_FREE(font_p->glyph_cache[i]);
804            }
805        }
806    }
807    return result;
808}
809
810#endif
811
Note: See TracBrowser for help on using the repository browser.