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;
76 E_HDMode mg_hd_mode = NORMAL_SD;
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))
101 assert(((
int)mg_ctxt.out_osd_height * 16) == ((
int)mg_ctxt.out_osd_width * 9));
103 mg_hd_mode = NORMAL_HD;
110 if ((mg_last_screen_h != mg_ctxt.out_osd_height) || (mg_last_screen_w != mg_ctxt.out_osd_width))
113 for (f_ndx = 0; f_ndx != MAX_FONT_OBJECTS && mg_font_array[f_ndx]; f_ndx++)
115 initialiseFontDetails( mg_font_array[f_ndx] );
117 mg_last_screen_h = mg_ctxt.out_osd_height;
118 mg_last_screen_w = mg_ctxt.out_osd_width;
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;
133 font_data = FILE_DATA_PTR;
134 font_data_len = FILE_DATA_SIZE;
138 TRACE(TALWAYS, (
"MG_FontLoadFile OK %d", font_data_len))
139 mg_last_screen_h = mg_ctxt.out_osd_height;
140 mg_last_screen_w = mg_ctxt.out_osd_width;
144 TRACE(TERROR, (
"MG_FontLoadFile FAILED"))
146 FT_Done_FreeType( mg_ft_lib );
152 TRACE(TERROR, (
"FT_Init_FreeType FAILED"))
156 return (mg_ft_lib != 0) ? TRUE : FALSE;
166 if (max > BUILT_IN_FONT)
168 if (max > MAX_FONT_OBJECTS)
170 mg_max_fonts_allowed = MAX_FONT_OBJECTS;
174 mg_max_fonts_allowed = max;
191 for (f_ndx = MAX_FONT_OBJECTS - 1; f_ndx != 0; f_ndx--)
197 mg_hd_mode = NORMAL_SD;
199 FT_Done_FreeType( mg_ft_lib );
220 f_ndx = BUILT_IN_FONT;
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;
238 font_ptr->first_sz = NULL;
239 if (f_ndx != BUILT_IN_FONT && length != 0)
241 file_data = (U8BIT *)OSD_MemAlloc( length );
242 if (file_data == NULL)
244 FT2_MemFree( font_ptr );
251 memcpy( file_data, data, length );
252 font_ptr->file_data = file_data;
253 font_ptr->file_size = length;
254 mg_font_array[f_ndx] = font_ptr;
259 file_data = (U8BIT *)data;
260 font_ptr->file_data = NULL;
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))
270 font_ptr->font_ndx = f_ndx;
271 if (memcmp( file_data,
"PFR0", 4 ) == 0)
273 font_ptr->face_type = FTYPE_PFR;
277 font_ptr->face_type = FTYPE_TTF;
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))
283 if (f_ndx == BUILT_IN_FONT)
285 const U8BIT uk_profile_sizes[6] = { 20, 22, 36, 31, 26, 24 };
287 assert( mg_font_array[0]->face->num_faces == 1 );
288 if (mg_hd_mode == NORMAL_SD)
290 for (i = 2; i != 6; i++)
292 if (
MG_GetFontSize( BUILT_IN_FONT, uk_profile_sizes[i], FONT_STYLE_PLAIN ) == NULL)
294 TRACE(TERROR, (
"Failed to add font %d,PLAIN", uk_profile_sizes[i]))
301 for (i = 0; i != 6; i++)
303 if (
MG_GetFontSize( BUILT_IN_FONT, uk_profile_sizes[i], FONT_STYLE_SQUARE ) == NULL)
305 TRACE(TERROR, (
"Failed to add font %d,SQUARE", uk_profile_sizes[i]))
308 for (i = 0; i != 6; i++)
310 if (
MG_GetFontSize( BUILT_IN_FONT, uk_profile_sizes[i], FONT_STYLE_PLAIN ) == NULL)
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;
332 rtnVal = (S16BIT)f_ndx;
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))
381 if ((font_index > BUILT_IN_FONT) && (font_index < MAX_FONT_OBJECTS))
384 if ((mg_font_array[font_index] != NULL) &&
385 (mg_font_array[font_index]->file_data != NULL)
389 OSD_MemFree((U8BIT *)mg_font_array[font_index]->file_data );
391 FreeFontFile( font_index );
402 assert( font_index >= 0 && font_index < MAX_FONT_OBJECTS );
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"))
434 fontsize_ptr->mem_size = 0;
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);
442 if ((fontsize_ptr->fnt_id >> 8) & FONT_STYLE_NO_SCALE)
444 TRACE(TFONT, (
"adv=0x%x s=%d", the_face->glyph->advance.x, fontsize_ptr->space_adv))
445 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);
452 TRACE(TFONT, (
"advances: space=%d fig-sp=%d", fontsize_ptr->space_adv, fontsize_ptr->figure_adv))
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"))
457 fontsize_ptr->mem_size = 0;
463 glyph_array = font_ptr->glyph_ndx;
464 for (chr = 0; chr != CHAR_CACHE_SIZE; chr++)
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;
474 fontsize_ptr->sbit_cache = 0;
475 fontsize_ptr->cache_hit = 0;
488 if (fnt_index < 0 || fnt_index >= MAX_FONT_OBJECTS ||
489 mg_font_array[fnt_index] == NULL)
511 for (fndx = 0; fndx != MAX_FONT_OBJECTS; fndx++)
513 if (mg_font_array[fndx] != NULL)
516 ppfs = &(mg_font_array[fndx]->first_sz);
517 while (*ppfs != NULL)
521 *ppfs = (*ppfs)->next;
524 fndx = MAX_FONT_OBJECTS - 1;
529 ppfs = &((*ppfs)->next);
548 for (fndx = 0; fndx != MAX_FONT_OBJECTS; fndx++)
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"));
577 pMetrics->ascent = 0;
578 pMetrics->descent = 0;
579 pMetrics->height = 0;
580 pMetrics->minWidth = 0;
581 pMetrics->maxWidth = 0;
585 TRACE(TFONT, (
"bbsdw=%d bbsdh=%d bb(%d,%d,%d,%d)", f_sz->bb_sd_width, f_sz->bb_sd_height,
586 f_sz->bound_box.left, f_sz->bound_box.top, f_sz->bound_box.width, f_sz->bound_box.height));
587 pMetrics->ascent = f_sz->bound_box.top;
588 pMetrics->descent = f_sz->bound_box.height - f_sz->bound_box.top;
589 pMetrics->height = f_sz->bound_box.height;
590 pMetrics->minWidth = f_sz->bound_box.left;
591 pMetrics->maxWidth = f_sz->bound_box.width;
606 TRACE(TFONT, (
"(%d %d %x)", fnt_index, fnt_size, fnt_style))
607 assert( fnt_index < MAX_FONT_OBJECTS && mg_font_array[fnt_index] );
610 fnt_id = (fnt_index << 16) | (fnt_style << 8) | fnt_size;
612 ftd_ptr = mg_font_array[fnt_index];
613 fsz_ptr = ftd_ptr->first_sz;
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;
632 fsz_ptr->next = ftd_ptr->first_sz;
633 ftd_ptr->first_sz = fsz_ptr;
634 fsz_ptr->fnt_id = fnt_id;
637 fnt_sd_sz = fnt_size << 6;
639 if (fnt_style & FONT_STYLE_NO_SCALE)
641 fnt_hd_sz = fnt_sd_sz;
642 fnt_sd_sz -= fnt_size << 1;
647 fnt_hd_sz = (fnt_sd_sz * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div;
650 fsz_ptr->height = fnt_hd_sz;
652 fnt_bbox = the_face->bbox;
654 if (ftd_ptr->font_ndx == BUILT_IN_FONT)
656 if (ftd_ptr->face_type == FTYPE_PFR)
658 FT_Fixed metrics_x_scale, metrics_y_scale;
660 FT_Get_PFR_Metrics(the_face,
662 &ftd_ptr->metric_resolution,
669 fnt_bbox.xMin = -324;
670 fnt_bbox.xMax = 2048;
671 fnt_bbox.yMin = -508;
672 fnt_bbox.yMax = 1866;
673 ftd_ptr->metric_resolution = 2048;
674 outline_resolution = 2048;
679 ftd_ptr->metric_resolution = the_face->units_per_EM;
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);
731 if (fnt_style & FONT_STYLE_SQUARE)
733 fsz_ptr->spxl_xleftoffset = (s_size + units - 1) / units;
737 s_size += (outline_resolution * 56) - 1;
738 fsz_ptr->spxl_xleftoffset = s_size / (outline_resolution * 56);
741 s_size = -fnt_bbox.xMin * fnt_size + outline_resolution - 1;
742 fsz_ptr->pnts_xleftoffset = s_size / outline_resolution;
744 s_size = ((-fnt_bbox.xMin * fnt_sd_sz) + (units - 1)) / units;
745 bb_sd_w = (U16BIT)s_size;
750 fsz_ptr->spxl_xleftoffset = 0;
751 fsz_ptr->pnts_xleftoffset = 0;
756 if (fnt_style & FONT_STYLE_SQUARE)
764 ratio_x = mg_ctxt.osd_x.mlt * 9;
765 ratio_y = mg_ctxt.osd_y.mlt * 14;
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;
793 if (mg_hd_mode == NORMAL_HD)
797 s_size += mg_ctxt.out_osd_width / 720;
801 fsz_ptr->bound_box.left = (U16BIT)s_size;
805 fsz_ptr->bound_box.left = 0;
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;
816 fsz_ptr->bound_box.width = (U16BIT)s_size;
817 TRACE(TFONT, (
"%d %d %d %d", fnt_bbox.xMax, fnt_bbox.xMin, fnt_hd_sz, ratio_x))
819 TRACE(TFONT, (
"HD bbox=(l=%d w=%d t=%d h=%d)", fsz_ptr->bound_box.left, (U16BIT)s_size, bb_hd_t, bb_hd_h))
820 fsz_ptr->bb_sd_height = (U8BIT)bb_sd_h;
821 fsz_ptr->bb_sd_width = (U8BIT)bb_sd_w;
822 fsz_ptr->bb_sd_top = (U8BIT)bb_sd_t;
823 fsz_ptr->bound_box.height = bb_hd_h;
824 fsz_ptr->bound_box.top = bb_hd_t;
826 SetupCaching( ftd_ptr, fsz_ptr );
828 TRACE(TFONT, (
"font_size=%d CacheSize=%d\n", fnt_size, fsz_ptr->mem_size))
830 ftd_ptr->current_fnt_id = fnt_id;
844 if (f_szdata->sbit_cache == 0)
848 if (f_szdata->mem_size < (FONTS_CACHE_MAX - (CHAR_CACHE_SIZE *
sizeof(
CacheSbit))))
853 allocateCache( font_ptr, f_szdata );
859 f_szdata->cache_hit++;
860 mg_total_cache_hits++;
861 f_szdata->cache_last = 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;
878 fnt_d_ptr->first_sz = NULL;
880 TRACE(TFONT, (
" Font D ptr=%p face=%p", fnt_d_ptr, the_face))
882 for (nx = 0; nx != CHAR_CACHE_SIZE; nx++)
884 fnt_d_ptr->glyph_ndx[nx] = FT_Get_Char_Index( the_face, nx + FIRST_CACHE_CHAR );
886 fnt_d_ptr->glyph_ndx_space = FT_Get_Char_Index( 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))
892 if (fnt_d_ptr->face_type == FTYPE_PFR)
896 if (FT_Get_PFR_Advance( the_face, fnt_d_ptr->glyph_ndx_space, &advance ) == 0)
898 fnt_d_ptr->space_horiz_adv = advance;
900 TRACE(TFONT, (
" G_sp_adv=%d", fnt_d_ptr->space_horiz_adv))
901 if (FT_Get_PFR_Advance( the_face, glyph_index_fig, &advance ) == 0)
903 fnt_d_ptr->fig_horiz_adv = advance;
906 for (nx = 0; nx != CHAR_CACHE_SIZE; nx++)
909 if (fnt_d_ptr->glyph_ndx[nx] &&
910 FT_Get_PFR_Advance( the_face, fnt_d_ptr->glyph_ndx[nx], &advance ) == 0)
913 fnt_d_ptr->horiz_adv[nx] = advance;
919 if (FT_Load_Glyph( the_face, fnt_d_ptr->glyph_ndx_space, FT_LOAD_NO_SCALE ) == 0)
921 fnt_d_ptr->space_horiz_adv = the_face->glyph->metrics.horiAdvance;
923 TRACE(TFONT, (
" G_sp_adv=%d", fnt_d_ptr->space_horiz_adv))
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;
929 for (nx = 0; nx != CHAR_CACHE_SIZE; nx++)
932 if (fnt_d_ptr->glyph_ndx[nx] &&
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;
942 fnt_d_ptr->horiz_adv[nx] = 0;
956 if (fsz_ptr->sbit_cache)
958 FT2_MemFree( fsz_ptr->sbit_cache );
959 fsz_ptr->sbit_cache = NULL;
960 mg_cached_fontsizes--;
961 mg_cache_in_use -= fsz_ptr->mem_size + (CHAR_CACHE_SIZE *
sizeof(
CacheSbit));
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;
978 U16BIT chr, x, y = 0;
980 assert( sz_data->sbit_cache == 0 );
982 req_size = (CHAR_CACHE_SIZE *
sizeof(
CacheSbit)) +
985 assert( req_size < FONTS_CACHE_MAX );
986 lowest_hit = mg_total_cache_hits + 1;
987 while ((mg_cache_in_use + req_size) > FONTS_CACHE_MAX)
990 assert( mg_font_array[y] );
991 pfs = mg_font_array[y]->first_sz;
994 if (pfs->sbit_cache != NULL)
996 if (mg_cached_fontsizes == 1)
999 assert( mg_cached_fontsizes == 0);
1000 assert( mg_cache_in_use == 0 );
1005 if (pfs->cache_last != mg_total_cache_hits)
1008 if ((mg_cached_fontsizes == 2) || (lowest_hit == pfs->cache_hit))
1013 lowest_hit = mg_total_cache_hits + 1;
1016 else if (lowest_hit > pfs->cache_hit)
1018 lowest_hit = pfs->cache_hit;
1026 if (y == MAX_FONT_OBJECTS || mg_font_array[y] == NULL)
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)
1035 fd_ptr->current_fnt_id = sz_data->fnt_id;
1036 p_cache = (
CacheSbit *)FT2_MemAlloc( req_size );
1039 mg_cache_in_use += req_size;
1040 mg_cached_fontsizes++;
1042 sz_data->sbit_cache = p_cache;
1043 bitmaps = (U8BIT *)p_cache;
1044 bitmaps += (CHAR_CACHE_SIZE *
sizeof(
CacheSbit));
1045 req_size -= (CHAR_CACHE_SIZE *
sizeof(
CacheSbit));
1048 for (bmp_nx = 0, chr = 0; chr != CHAR_CACHE_SIZE; chr++, p_cache++)
1050 p_cache->bmp_ndx = bmp_nx;
1052 if (fd_ptr->glyph_ndx[chr] &&
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 );
1064 if (bwidth > sz_data->bound_box.width)
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;
1086 if (((sz_data->fnt_id >> 8) & 0xff) == FONT_STYLE_SQUARE)
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);
1099 p_cache->sdleft = 0;
1101 p_cache->advance = (S8BIT)(adv >> 16);
1104 src = the_glyph->bitmap.buffer;
1105 if (p_cache->width > p_cache->advance)
1108 TRACE(TFONTCACHE, (
"fsz=%d,fw=%d '%c' %d l=%d,w=%d,a=%d lha_mod=%x",
1109 sz_data->fnt_id, sz_data->width, chr + FIRST_CACHE_CHAR, chr,
1110 p_cache->left, p_cache->width, p_cache->advance, adv & 0xffff))
1112 else if (p_cache->width + (p_cache->left * 2) < p_cache->advance)
1114 if (mg_hd_mode == NORMAL_SD)
1118 case (
'm' - FIRST_CACHE_CHAR):
1127 while (p_cache->width + p_cache->left > p_cache->advance)
1129 TRACE(TFONTCACHE, (
"fsz=%d,fw=%d '%c' %d l=%d,w=%d,a=%d lha_mod=%x",
1130 sz_data->fnt_id, sz_data->width, chr + FIRST_CACHE_CHAR, chr,
1131 p_cache->left, p_cache->width, p_cache->advance, adv & 0xffff))
1132 if (p_cache->left && (adv & 0xffff) < 0xc000)
1141 if (chr == 1 && mg_hd_mode == NORMAL_SD && (sz_data->fnt_id & 0xff) == 31)
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))
1172 p_cache->height = 0;
1173 p_cache->advance = 0;
1180 p_cache = sz_data->sbit_cache + (
'0' - FIRST_CACHE_CHAR);
1181 for (chr = 0; chr != 10; chr++, p_cache++)
1183 p_cache->advance = sz_data->figure_adv;
1186 sz_data->cache_hit++;
1187 mg_total_cache_hits++;
1188 sz_data->cache_last = 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 );
1211 fsz = font_ptr->first_sz;
1219 FT2_MemFree( font_ptr );
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.
void MG_ReleaseFont(H_FontSize f_sz)
Allocate font of particular size from font file.
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.
Font file handling with the Freetype.
void MG_ReleaseFontPtr(S_FontDetails *fp)
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.
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.