47 #ifndef FONTS_CACHE_MAX 52 #define FONTS_CACHE_MAX 0x00020000 59 #define MAX_FONT_OBJECTS 16 66 static FT_Library mg_ft_lib = 0;
68 static U32BIT mg_cache_in_use;
69 static U32BIT mg_total_cache_hits;
70 static U16BIT mg_cached_fontsizes;
71 static U16BIT mg_last_screen_w = 0;
72 static U16BIT mg_last_screen_h = 0;
73 static U16BIT mg_max_fonts_allowed = 1;
80 static void FreeFontFile(
S16BIT font_index );
82 static void initialiseFontDetails(
S_FontDetails *fnt_d_ptr );
94 const unsigned char *font_data;
97 TRACE(TALWAYS, (
"About to Initialise Font %x", mg_ft_lib))
115 initialiseFontDetails( mg_font_array[f_ndx] );
122 else if (FT_Init_FreeType( &mg_ft_lib ) == 0)
124 TRACE(TALWAYS, (
"Initialised OK %x", mg_ft_lib))
126 assert( mg_font_array[0] == NULL );
129 mg_total_cache_hits = 0;
130 mg_cached_fontsizes = 0;
131 mg_max_fonts_allowed = 1;
138 TRACE(TALWAYS, (
"MG_FontLoadFile OK %d", font_data_len))
144 TRACE(TERROR, (
"MG_FontLoadFile FAILED"))
146 FT_Done_FreeType( mg_ft_lib );
152 TRACE(TERROR, (
"FT_Init_FreeType FAILED"))
174 mg_max_fonts_allowed = max;
199 FT_Done_FreeType( mg_ft_lib );
222 TRACE(TFONT, (
"About to Initialise Font ptr=%p sz=%d", data, length))
224 while ((f_ndx != mg_max_fonts_allowed) && (mg_font_array[f_ndx] != NULL))
227 if (f_ndx != mg_max_fonts_allowed)
229 assert( mg_font_array[f_ndx] == NULL );
233 if (font_ptr != NULL)
235 TRACE(TFONT, (
"font_ptr->next=%p", font_ptr->
next))
236 font_ptr->
next = NULL;
237 font_ptr->
face = NULL;
242 if (file_data == NULL)
251 memcpy( file_data, data, length );
254 mg_font_array[f_ndx] = font_ptr;
259 file_data = (
U8BIT *)data;
261 mg_font_array[f_ndx] = font_ptr;
263 while (font_ptr != NULL)
265 TRACE(TFONT, (
"font_ptr=%p, font_ptr->face=%p", font_ptr, font_ptr->
face))
266 if ((length != 0 && FT_New_Memory_Face( mg_ft_lib, file_data, length, face_num, &font_ptr->
face ) == 0) ||
267 (length == 0 && FT_New_Face( mg_ft_lib, (
const char *)file_data, face_num, &font_ptr->
face ) == 0))
271 if (memcmp( file_data,
"PFR0", 4 ) == 0)
279 TRACE(TFONT, (
"font_ptr=%p, font_ptr->face=%p", font_ptr, font_ptr->
face))
280 TRACE(TFONT, (
"font_ptr->face->stream=%p, font_ptr->face->stream->read=%p", font_ptr->
face->stream, font_ptr->
face->stream->read))
281 initialiseFontDetails( font_ptr );
282 TRACE(TFONT, (
"f_ndx=%d", f_ndx))
285 const U8BIT uk_profile_sizes[6] = { 20, 22, 36, 31, 26, 24 };
287 assert( mg_font_array[0]->face->num_faces == 1 );
290 for (i = 2; i != 6; i++)
294 TRACE(TERROR, (
"Failed to add font %d,PLAIN", uk_profile_sizes[i]))
301 for (i = 0; i != 6; i++)
305 TRACE(TERROR, (
"Failed to add font %d,SQUARE", uk_profile_sizes[i]))
308 for (i = 0; i != 6; i++)
312 TRACE(TERROR, (
"Failed to add font %d,PLAIN", uk_profile_sizes[i]))
321 TRACE(TFONT, (
" face_num=%d", face_num))
322 TRACE(TFONT, (
" mg_font_array[f_ndx]->face->num_faces=%d", mg_font_array[f_ndx]->face->num_faces))
323 if (face_num < mg_font_array[f_ndx]->face->num_faces)
331 font_ptr->
next = NULL;
338 TRACE(TERROR, (
" f_ndx=%d", f_ndx))
339 font_ptr->
next = NULL;
340 font_ptr->
face = NULL;
342 font_ptr = font_ptr->
next;
347 TRACE(TERROR, (
" FAILED %d", f_ndx))
363 TRACE(TERROR, (
"Reached MAX fonts allowed, %d", f_ndx))
370 TRACE(TFONT, (
" End %d", rtnVal))
384 if ((mg_font_array[font_index] != NULL) &&
385 (mg_font_array[font_index]->file_data != NULL)
391 FreeFontFile( font_index );
404 return mg_font_array[font_index];
418 FT_Face the_face = font_ptr->
face;
419 FT_GlyphSlot the_glyph = the_face->glyph;
420 FT_UInt glyph_index_figspace, *glyph_array;
430 TRACE(TFONT, (
"FT_Set_Char_Size face=%p w=%d h=%d", the_face, fontsize_ptr->
width, fontsize_ptr->
height))
431 if (FT_Set_Char_Size( the_face, fontsize_ptr->
width, fontsize_ptr->
height, 72, 72 ) != 0)
433 TRACE(TERROR, (
"FT_Set_Char_Size FAILED"))
438 glyph_index_figspace = FT_Get_Char_Index( the_face,
'0' );
439 if (FT_Load_Glyph( the_face, font_ptr->
glyph_ndx_space, FT_LOAD_RENDER ) == 0)
441 fontsize_ptr->
space_adv = (
S8BIT)((the_face->glyph->advance.x + 32) >> 6);
444 TRACE(TFONT, (
"adv=0x%x s=%d", the_face->glyph->advance.x, fontsize_ptr->
space_adv))
448 if (FT_Load_Glyph( the_face, glyph_index_figspace, FT_LOAD_RENDER ) == 0)
450 fontsize_ptr->
figure_adv = (
S8BIT)((the_face->glyph->advance.x + 32) >> 6);
454 if (FT_Set_Char_Size( the_face, fontsize_ptr->
width, fontsize_ptr->
height, 72, 72 ) != 0)
456 TRACE(TERROR, (
"FT_Set_Char_Size FAILED"))
466 if (glyph_array[chr] && FT_Load_Glyph(the_face, glyph_array[chr], FT_LOAD_RENDER) == 0)
468 cache_size += the_glyph->bitmap.width * the_glyph->bitmap.rows;
469 TRACE(TFONTCACHE, (
"Glyph %d (%d,%d) Csize=%d", glyph_array[chr], the_glyph->bitmap.width, the_glyph->bitmap.rows, cache_size))
472 fontsize_ptr->
mem_size = cache_size;
489 mg_font_array[fnt_index] == NULL)
513 if (mg_font_array[fndx] != NULL)
516 ppfs = &(mg_font_array[fndx]->
first_sz);
517 while (*ppfs != NULL)
521 *ppfs = (*ppfs)->
next;
529 ppfs = &((*ppfs)->next);
550 if (mg_font_array[fndx] != NULL)
552 pfs = mg_font_array[fndx]->
first_sz;
557 return mg_font_array[fndx];
576 TRACE(TFONT, (
"f_sz is NULL"));
606 TRACE(TFONT, (
"(%d %d %x)", fnt_index, fnt_size, fnt_style))
610 fnt_id = (fnt_index << 16) | (fnt_style << 8) | fnt_size;
612 ftd_ptr = mg_font_array[fnt_index];
614 while ((fsz_ptr != NULL) && (fsz_ptr->
fnt_id != fnt_id))
616 fsz_ptr = fsz_ptr->
next;
621 FT_UInt outline_resolution;
622 FT_Face the_face = ftd_ptr->
face;
623 S32BIT fnt_sd_sz, fnt_hd_sz, units, ratio_x, ratio_y;
625 U16BIT bb_hd_h, bb_sd_h, bb_sd_w, bb_hd_t, bb_sd_t;
637 fnt_sd_sz = fnt_size << 6;
641 fnt_hd_sz = fnt_sd_sz;
642 fnt_sd_sz -= fnt_size << 1;
650 fsz_ptr->
height = fnt_hd_sz;
652 fnt_bbox = the_face->bbox;
658 FT_Fixed metrics_x_scale, metrics_y_scale;
660 FT_Get_PFR_Metrics(the_face,
669 fnt_bbox.xMin = -324;
670 fnt_bbox.xMax = 2048;
671 fnt_bbox.yMin = -508;
672 fnt_bbox.yMax = 1866;
674 outline_resolution = 2048;
680 outline_resolution = the_face->units_per_EM;
683 TRACE(TFONT, (
"xMin=%d,xMax=%d,yMin=%d,yMax=%d,o_res=%d",
684 fnt_bbox.xMin, fnt_bbox.xMax, fnt_bbox.yMin, fnt_bbox.yMax, outline_resolution))
686 units = outline_resolution << 6;
688 if (fnt_bbox.yMax > 0)
690 bb_sd_t = (
U16BIT)(((fnt_bbox.yMax * fnt_sd_sz) + (units - 1)) / units);
691 if (fnt_style & FONT_STYLE_NO_SCALE)
697 bb_hd_t = (
U16BIT)(((fnt_bbox.yMax * fnt_hd_sz) + (units - 1)) / units);
698 TRACE(TFONT, (
"fnt_hd_sz=%d,units=%d,bb_hd_t=%d", fnt_hd_sz, units, bb_hd_t))
706 if (fnt_bbox.yMin < 0)
708 bb_sd_h = bb_sd_t + (
U16BIT)(((-fnt_bbox.yMin * fnt_sd_sz) + (units - 1)) / units);
709 if (fnt_style & FONT_STYLE_NO_SCALE)
715 bb_hd_h = bb_hd_t + (
U16BIT)(((-fnt_bbox.yMin * fnt_hd_sz) + (units - 1)) / units);
717 TRACE(TFONT, (
"fnt_hd_sz=%d,units=%d,bb_hd_h=%d", fnt_hd_sz, units, bb_hd_h))
727 if (fnt_bbox.xMin < 0)
730 s_size = (-fnt_bbox.xMin * fnt_size * 45);
737 s_size += (outline_resolution * 56) - 1;
741 s_size = -fnt_bbox.xMin * fnt_size + outline_resolution - 1;
744 s_size = ((-fnt_bbox.xMin * fnt_sd_sz) + (units - 1)) / units;
766 while (((ratio_y & 1) == 0) && ((ratio_x & 1) == 0))
771 while (((ratio_y % 3) == 0) && ((ratio_x % 3) == 0))
776 while (((ratio_y % 5) == 0) && ((ratio_x % 5) == 0))
783 if (fnt_bbox.xMin < 0)
785 if (fnt_style & FONT_STYLE_NO_SCALE)
787 s_size = (-fnt_bbox.xMin * fnt_hd_sz * ratio_x) / units;
791 s_size = ((-fnt_bbox.xMin * fnt_hd_sz * ratio_x) + (units - 1)) / units;
807 if (!(fnt_style & FONT_STYLE_NO_SCALE))
809 fnt_hd_sz -= (fnt_hd_sz >> 7);
812 fsz_ptr->
width = ((fnt_hd_sz * ratio_x) + (ratio_y >> 1)) / ratio_y;
814 s_size = (fnt_bbox.xMax - fnt_bbox.xMin) * fnt_hd_sz * ratio_x;
815 s_size = (s_size + units - 1) / units;
817 TRACE(TFONT, (
"%d %d %d %d", fnt_bbox.xMax, fnt_bbox.xMin, fnt_hd_sz, ratio_x))
826 SetupCaching( ftd_ptr, fsz_ptr );
828 TRACE(TFONT, (
"font_size=%d CacheSize=%d\n", fnt_size, fsz_ptr->
mem_size))
853 allocateCache( font_ptr, f_szdata );
860 mg_total_cache_hits++;
872 static void initialiseFontDetails(
S_FontDetails *fnt_d_ptr )
874 FT_Face the_face = fnt_d_ptr->
face;
875 FT_UInt glyph_index_fig;
880 TRACE(TFONT, (
" Font D ptr=%p face=%p", fnt_d_ptr, the_face))
887 glyph_index_fig = FT_Get_Char_Index( the_face,
'0' );
888 assert( glyph_index_fig != 0 );
889 TRACE(TFONT, (
" G_fig=%d", glyph_index_fig))
896 if (FT_Get_PFR_Advance( the_face, fnt_d_ptr->
glyph_ndx_space, &advance ) == 0)
901 if (FT_Get_PFR_Advance( the_face, glyph_index_fig, &advance ) == 0)
910 FT_Get_PFR_Advance( the_face, fnt_d_ptr->
glyph_ndx[nx], &advance ) == 0)
919 if (FT_Load_Glyph( the_face, fnt_d_ptr->
glyph_ndx_space, FT_LOAD_NO_SCALE ) == 0)
924 if (FT_Load_Glyph( the_face, glyph_index_fig, FT_LOAD_NO_SCALE ) == 0)
926 fnt_d_ptr->
fig_horiz_adv = the_face->glyph->metrics.horiAdvance;
933 FT_Load_Glyph( the_face, fnt_d_ptr->
glyph_ndx[nx], FT_LOAD_NO_SCALE ) == 0)
938 fnt_d_ptr->
horiz_adv[nx] = the_face->glyph->metrics.horiAdvance;
960 mg_cached_fontsizes--;
972 FT_Face the_face = fd_ptr->
face;
973 FT_GlyphSlot the_glyph = the_face->glyph;
975 U8BIT *bitmaps, *src;
977 U32BIT req_size, lowest_hit, bmp_nx;
986 lowest_hit = mg_total_cache_hits + 1;
990 assert( mg_font_array[y] );
996 if (mg_cached_fontsizes == 1)
999 assert( mg_cached_fontsizes == 0);
1000 assert( mg_cache_in_use == 0 );
1008 if ((mg_cached_fontsizes == 2) || (lowest_hit == pfs->
cache_hit))
1013 lowest_hit = mg_total_cache_hits + 1;
1032 TRACE(TFONT, (
"FT_Set_Char_Size face=%p sz=%d w=%d h=%d", the_face, sz_data->
fnt_id & 0xff, sz_data->
width, sz_data->
height))
1033 if (FT_Set_Char_Size( the_face, sz_data->
width, sz_data->
height, 72, 72 ) == 0)
1039 mg_cache_in_use += req_size;
1040 mg_cached_fontsizes++;
1043 bitmaps = (
U8BIT *)p_cache;
1053 FT_Load_Glyph( the_face, fd_ptr->
glyph_ndx[chr], FT_LOAD_RENDER ) == 0)
1056 U8BIT bwidth = (
U8BIT)the_glyph->bitmap.width;
1057 U8BIT bheight = (
U8BIT)the_glyph->bitmap.rows;
1058 int ptch = the_glyph->bitmap.pitch;
1062 assert( ptch == bwidth );
1066 TRACE(TERROR, (
"bwidth %d > sz_data->bound_box.width %d", bwidth, sz_data->
bound_box.
width))
1069 if (bmp_nx + (bheight * bwidth) > req_size)
1072 TRACE(TERROR, (
"!!! Cache size is not big enough !!! (%d,%d,%d,%d)", bmp_nx, bheight, bwidth, req_size))
1077 p_cache->
top = the_glyph->bitmap_top;
1078 p_cache->
left = the_glyph->bitmap_left;
1079 p_cache->
width = bwidth;
1080 p_cache->
height = bheight;
1082 adv = the_glyph->linearHoriAdvance + 0x8000;
1083 if (the_glyph->metrics.horiBearingX < 0)
1085 S32BIT tmp = -the_glyph->metrics.horiBearingX;
1088 tmp = tmp * (sz_data->
fnt_id & 0xff) * 45 + (2048 * 64) - 1;
1089 p_cache->
sdleft = tmp >> 17;
1093 tmp = tmp * (sz_data->
fnt_id & 0xff) * 45 + (2048 * 56) - 1;
1094 p_cache->
sdleft = tmp / (2048 * 56);
1104 src = the_glyph->bitmap.buffer;
1108 TRACE(TFONTCACHE, (
"fsz=%d,fw=%d '%c' %d l=%d,w=%d,a=%d lha_mod=%x",
1129 TRACE(TFONTCACHE, (
"fsz=%d,fw=%d '%c' %d l=%d,w=%d,a=%d lha_mod=%x",
1132 if (p_cache->
left && (adv & 0xffff) < 0xc000)
1145 for (x = 0; x != (bheight * bwidth); x++)
1156 for (y = 0; y != bheight; y++)
1158 for (x = 0; x != bwidth; x++)
1160 bitmaps[bmp_nx++] = src[x];
1164 TRACE(TFONTCACHE, (
"FT_Alloc %d (%d,%d) sz=%ld", fd_ptr->
glyph_ndx[chr], the_face->glyph->bitmap.width, the_face->glyph->bitmap.rows, bmp_nx))
1181 for (chr = 0; chr != 10; chr++, p_cache++)
1187 mg_total_cache_hits++;
1198 static void FreeFontFile(
S16BIT font_index )
1202 TRACE(TFONT, (
" ndx=%d", font_index))
1203 while (mg_font_array[font_index] != NULL)
1205 font_ptr = mg_font_array[font_index];
1206 mg_font_array[font_index] = font_ptr->
next;
1209 FT_Done_Face( font_ptr->
face );
struct sFontDetails * next
S16BIT MG_FontLoadFile(const U8BIT *data, U32BIT length)
Load font data file into memory for freetype.
void MG_FontFreeFile(S16BIT font_index)
free memory associated with file
Font file handling with the Freetype.
S_FontSize * MG_GetFontSize(U16BIT fnt_index, U8BIT fnt_size, U8BIT fnt_style)
Tiresias Screen Font PFR data.
#define FONT_STYLE_NO_SCALE
void MG_ReleaseFont(H_FontSize f_sz)
Allocate font of particular size from font file.
FT_UInt horiz_adv[CHAR_CACHE_SIZE]
H_FontSize MG_AllocateFont(S16BIT fnt_index, U8BIT fnt_size, U8BIT fnt_style)
Allocate font of particular size from font file.
This file defines the profile for the MHEG engine.
void MG_FontExit(void)
Free all data associated with built-in font and terminate freetype library.
BOOLEAN MG_FontInit(BOOLEAN isHD)
Initialise freetype library and load "built-in" font.
struct _CacheSbit CacheSbit
#define FONT_STYLE_SQUARE
Font file handling with the Freetype.
void MG_ReleaseFontPtr(S_FontDetails *fp)
FT_UInt glyph_ndx[CHAR_CACHE_SIZE]
S_FontDetails * MG_GetFontPtr(S16BIT font_index)
Get Pointer to Font.
S_FontDetails * MG_FindFont(H_FontSize f_sz)
Get font from size.
void MG_CheckCache(S_FontSize *f_szdata)
void MG_GetFontMetrics(H_FontSize f_sz, S_FontMetrics *pMetrics)
Get font Metrics.
FT_UInt metric_resolution
void MG_SetMaxFonts(U16BIT max)
Set Max allowable fonts for profile.
Interface to the MHEG text render that uses Freetype font library.
Engine support utility functions for MHEG5.