MHEG5  18.9.0
MHEG5 Documentation
mg_font.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2010 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include "glue_assert.h"
27 #include "glue_memory.h"
28 #include "glue_debug.h"
29 #include "mh5profile.h"
30 #include "mh5support.h"
31 #include "mg_ctxt.h"
32 #include "mg_drawtext.h"
33 
34 #include "mg_fontapi.h"
35 #include "mg_font.h"
36 
37 
38 /* Include Tiresias Screen Font PFR data for UK Profile,
39  * header file contains the macros: FILE_DATA_PTR, FILE_DATA_SIZE */
40 #include "Tires-o_751nz_pfr.h"
41 
42 /* 7.5.1 -> xMin=-324,yMin=-508,xMax=2048,yMax=1866 */
43 /* -40 -62 271 231 */
44 
45 /*---constant definitions for this file--------------------------------------*/
46 
47 #ifndef FONTS_CACHE_MAX
48 /* Makefile does not say anything, so lets have a default of 131072 bytes.
49  * It could be zero and the code should still work fine - if a little slower
50  * For SD, with the four font sizes: max cache requirements: 70333 bytes
51  */
52  #define FONTS_CACHE_MAX 0x00020000
53 #endif
54 
55 /* Total number of fonts for MHEG -
56  * Five font objects - one for UK profile and four downloaded font
57  * But Total number for Hbbtv could a lot more - so limit to 16
58  */
59 #define MAX_FONT_OBJECTS 16
60 
61 
62 /*---local typedef structs for this file-------------------------------------*/
63 
64 /*---local (static) variable declarations for this file----------------------*/
65 
66 static FT_Library mg_ft_lib = 0;
67 
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;
74 static S_FontDetails *mg_font_array[MAX_FONT_OBJECTS];
75 
77 
78 /*---local function prototypes for this file---------------------------------*/
79 
80 static void FreeFontFile( S16BIT font_index );
81 static void allocateCache( S_FontDetails *fd_ptr, S_FontSize *sz_data );
82 static void initialiseFontDetails( S_FontDetails *fnt_d_ptr );
83 static void freeCache( S_FontSize *fsz_ptr );
84 
85 /*---global function definitions---------------------------------------------*/
86 
93 {
94  const unsigned char *font_data;
95  int font_data_len;
96 
97  TRACE(TALWAYS, ("About to Initialise Font %x", mg_ft_lib))
98 
99  if (isHD)
100  {
101  assert(((int)mg_ctxt.out_osd_height * 16) == ((int)mg_ctxt.out_osd_width * 9));
102  /* A normal HD platform */
104  }
105  /* else mg_hd_mode stays as NORMAL_SD - i.e. no HD functionality
106  */
107  if (mg_ft_lib != 0)
108  {
109  /* already initialised library, so just check to see if need to adjust scaling */
110  if ((mg_last_screen_h != mg_ctxt.out_osd_height) || (mg_last_screen_w != mg_ctxt.out_osd_width))
111  {
112  int f_ndx;
113  for (f_ndx = 0; f_ndx != MAX_FONT_OBJECTS && mg_font_array[f_ndx]; f_ndx++)
114  {
115  initialiseFontDetails( mg_font_array[f_ndx] );
116  }
117  mg_last_screen_h = mg_ctxt.out_osd_height;
118  mg_last_screen_w = mg_ctxt.out_osd_width;
119  }
120  }
121  /* Initialise the Freetype library */
122  else if (FT_Init_FreeType( &mg_ft_lib ) == 0)
123  {
124  TRACE(TALWAYS, ("Initialised OK %x", mg_ft_lib))
125 
126  assert( mg_font_array[0] == NULL );
127 
128  mg_cache_in_use = 0;
129  mg_total_cache_hits = 0;
130  mg_cached_fontsizes = 0;
131  mg_max_fonts_allowed = 1;
132 
133  font_data = FILE_DATA_PTR;
134  font_data_len = FILE_DATA_SIZE;
135 
136  if (MG_FontLoadFile( font_data, font_data_len ) == 0)
137  {
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;
141  }
142  else
143  {
144  TRACE(TERROR, ("MG_FontLoadFile FAILED"))
145  /* MG_LoadFontFile returned error, -1 */
146  FT_Done_FreeType( mg_ft_lib );
147  mg_ft_lib = 0;
148  }
149  }
150  else
151  {
152  TRACE(TERROR, ("FT_Init_FreeType FAILED"))
153  mg_ft_lib = 0;
154  }
155 
156  return (mg_ft_lib != 0) ? TRUE : FALSE;
157 }
158 
165 {
166  if (max > BUILT_IN_FONT)
167  {
168  if (max > MAX_FONT_OBJECTS)
169  {
170  mg_max_fonts_allowed = MAX_FONT_OBJECTS;
171  }
172  else
173  {
174  mg_max_fonts_allowed = max;
175  }
176  }
177 }
178 
185 void MG_FontExit(void)
186 {
187  if (mg_ft_lib)
188  {
189  int f_ndx;
190 
191  for (f_ndx = MAX_FONT_OBJECTS - 1; f_ndx != 0; f_ndx--)
192  {
193  MG_FontFreeFile( f_ndx );
194  }
195  FreeFontFile( 0 );
196 
198 
199  FT_Done_FreeType( mg_ft_lib );
200  mg_ft_lib = 0;
201  }
202 }
203 
211 {
212  S_FontDetails *font_ptr;
213  U16BIT f_ndx;
214  S16BIT rtnVal;
215  U8BIT face_num;
216  U8BIT *file_data;
217 
218  assert( data );
219  rtnVal = -1;
220  f_ndx = BUILT_IN_FONT;
221 
222  TRACE(TFONT, ("About to Initialise Font ptr=%p sz=%d", data, length))
223 
224  while ((f_ndx != mg_max_fonts_allowed) && (mg_font_array[f_ndx] != NULL))
225  f_ndx++;
226 
227  if (f_ndx != mg_max_fonts_allowed)
228  {
229  assert( mg_font_array[f_ndx] == NULL );
230  face_num = 0;
231  font_ptr = (S_FontDetails *) FT2_MemAlloc( sizeof(S_FontDetails));
232  TRACE(TFONT, ("ndx=%d font_ptr=%p sz=%d", f_ndx, font_ptr, sizeof(S_FontDetails)))
233  if (font_ptr != NULL)
234  {
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)
240  {
241  file_data = (U8BIT *)OSD_MemAlloc( length );
242  if (file_data == NULL)
243  {
244  FT2_MemFree( font_ptr );
245  font_ptr = NULL;
246  /* return index to default font */
247  rtnVal = 0;
248  }
249  else
250  {
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;
255  }
256  }
257  else
258  {
259  file_data = (U8BIT *)data;
260  font_ptr->file_data = NULL;
261  mg_font_array[f_ndx] = font_ptr;
262  }
263  while (font_ptr != NULL)
264  {
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))
268  {
269  face_num++;
270  font_ptr->font_ndx = f_ndx;
271  if (memcmp( file_data, "PFR0", 4 ) == 0)
272  {
273  font_ptr->face_type = FTYPE_PFR;
274  }
275  else
276  {
277  font_ptr->face_type = FTYPE_TTF;
278  }
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)
284  {
285  const U8BIT uk_profile_sizes[6] = { 20, 22, 36, 31, 26, 24 };
286  int i;
287  assert( mg_font_array[0]->face->num_faces == 1 );
288  if (mg_hd_mode == NORMAL_SD)
289  {
290  for (i = 2; i != 6; i++)
291  {
292  if (MG_GetFontSize( BUILT_IN_FONT, uk_profile_sizes[i], FONT_STYLE_PLAIN ) == NULL)
293  {
294  TRACE(TERROR, ("Failed to add font %d,PLAIN", uk_profile_sizes[i]))
295  }
296  }
297  }
298  else
299  {
300  /* support HD-MHEG */
301  for (i = 0; i != 6; i++)
302  {
303  if (MG_GetFontSize( BUILT_IN_FONT, uk_profile_sizes[i], FONT_STYLE_SQUARE ) == NULL)
304  {
305  TRACE(TERROR, ("Failed to add font %d,SQUARE", uk_profile_sizes[i]))
306  }
307  }
308  for (i = 0; i != 6; i++)
309  {
310  if (MG_GetFontSize( BUILT_IN_FONT, uk_profile_sizes[i], FONT_STYLE_PLAIN ) == NULL)
311  {
312  TRACE(TERROR, ("Failed to add font %d,PLAIN", uk_profile_sizes[i]))
313  }
314  }
315  }
316  }
317  /* else
318  * downloaded font object - wait 'til we draw to find out what size is required
319  */
320 
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)
324  {
325  /* more faces to do */
326  font_ptr->next = (S_FontDetails *) FT2_MemAlloc( sizeof(S_FontDetails));
327  }
328  else
329  {
330  /* Success */
331  font_ptr->next = NULL;
332  rtnVal = (S16BIT)f_ndx;
333  }
334  }
335  else
336  {
337  /* Error */
338  TRACE(TERROR, (" f_ndx=%d", f_ndx))
339  font_ptr->next = NULL;
340  font_ptr->face = NULL;
341  }
342  font_ptr = font_ptr->next;
343  }
344  }
345  if (rtnVal == -1)
346  {
347  TRACE(TERROR, (" FAILED %d", f_ndx))
348  if (f_ndx != 0)
349  {
350  MG_FontFreeFile( f_ndx );
351  /* when attempting to add downloaded font and get a failure, return index to default font */
352  rtnVal = 0;
353  }
354  else
355  {
356  FreeFontFile( 0 );
357  /* failed to load default font */
358  }
359  }
360  }
361  else
362  {
363  TRACE(TERROR, ("Reached MAX fonts allowed, %d", f_ndx))
364  /* when attempting to add downloaded font and get a failure, return index
365  * to default font
366  */
367  rtnVal = 0;
368  }
369 
370  TRACE(TFONT, (" End %d", rtnVal))
371  return rtnVal; /* return font index */
372 }
373 
379 void MG_FontFreeFile( S16BIT font_index )
380 {
381  if ((font_index > BUILT_IN_FONT) && (font_index < MAX_FONT_OBJECTS))
382  {
383  /*not builtin font*/
384  if ((mg_font_array[font_index] != NULL) &&
385  (mg_font_array[font_index]->file_data != NULL)
386  )
387  {
388  /* free downloaded font file data */
389  OSD_MemFree((U8BIT *)mg_font_array[font_index]->file_data );
390  }
391  FreeFontFile( font_index );
392  }
393 }
394 
401 {
402  assert( font_index >= 0 && font_index < MAX_FONT_OBJECTS );
403 
404  return mg_font_array[font_index];
405 }
406 
413 {
414 }
415 
416 static void SetupCaching( S_FontDetails *font_ptr, S_FontSize *fontsize_ptr )
417 {
418  FT_Face the_face = font_ptr->face;
419  FT_GlyphSlot the_glyph = the_face->glyph;
420  FT_UInt glyph_index_figspace, *glyph_array;
421  U32BIT cache_size;
422  int chr;
423 
424  /* Because of FreeType's weird behaviour in test HD046, we must do following:
425  * 1. Set char size,
426  * 2. Load a glyph.
427  * 3. Set char size again
428  * 4. Load glyphs for rendering
429  * Only then will results for the glyph bitmaps be consistant */
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)
432  {
433  TRACE(TERROR, ("FT_Set_Char_Size FAILED"))
434  fontsize_ptr->mem_size = 0;
435  }
436  else
437  {
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)
440  {
441  fontsize_ptr->space_adv = (S8BIT)((the_face->glyph->advance.x + 32) >> 6);
442  if ((fontsize_ptr->fnt_id >> 8) & FONT_STYLE_NO_SCALE)
443  {
444  TRACE(TFONT, ("adv=0x%x s=%d", the_face->glyph->advance.x, fontsize_ptr->space_adv))
445  fontsize_ptr->space_adv--;
446  }
447  }
448  if (FT_Load_Glyph( the_face, glyph_index_figspace, FT_LOAD_RENDER ) == 0)
449  {
450  fontsize_ptr->figure_adv = (S8BIT)((the_face->glyph->advance.x + 32) >> 6);
451  }
452  TRACE(TFONT, ("advances: space=%d fig-sp=%d", fontsize_ptr->space_adv, fontsize_ptr->figure_adv))
453  }
454  if (FT_Set_Char_Size( the_face, fontsize_ptr->width, fontsize_ptr->height, 72, 72 ) != 0)
455  {
456  TRACE(TERROR, ("FT_Set_Char_Size FAILED"))
457  fontsize_ptr->mem_size = 0;
458  }
459  else
460  {
461  /* Now do bitmap cache stuff */
462  cache_size = 0;
463  glyph_array = font_ptr->glyph_ndx;
464  for (chr = 0; chr != CHAR_CACHE_SIZE; chr++)
465  {
466  if (glyph_array[chr] && FT_Load_Glyph(the_face, glyph_array[chr], FT_LOAD_RENDER) == 0)
467  {
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))
470  }
471  }
472  fontsize_ptr->mem_size = cache_size;
473  }
474  fontsize_ptr->sbit_cache = 0;
475  fontsize_ptr->cache_hit = 0;
476  TRACE(TFONT, (""))
477 }
478 
485 H_FontSize MG_AllocateFont(S16BIT fnt_index, U8BIT fnt_size, U8BIT fnt_style)
486 {
487  S_FontSize *f_sz;
488  if (fnt_index < 0 || fnt_index >= MAX_FONT_OBJECTS ||
489  mg_font_array[fnt_index] == NULL)
490  {
491  f_sz = MG_GetFontSize( BUILT_IN_FONT, fnt_size, fnt_style );
492  }
493  else
494  {
495  f_sz = MG_GetFontSize((U16BIT)fnt_index, fnt_size, fnt_style );
496  }
497  return f_sz;
498 }
499 
507 {
508  S16BIT fndx;
509  if (f_sz != NULL)
510  {
511  for (fndx = 0; fndx != MAX_FONT_OBJECTS; fndx++)
512  {
513  if (mg_font_array[fndx] != NULL)
514  {
515  S_FontSize **ppfs;
516  ppfs = &(mg_font_array[fndx]->first_sz);
517  while (*ppfs != NULL)
518  {
519  if (*ppfs == f_sz)
520  {
521  *ppfs = (*ppfs)->next;
522  freeCache( f_sz );
523  FT2_MemFree( f_sz );
524  fndx = MAX_FONT_OBJECTS - 1;
525  break;
526  }
527  else
528  {
529  ppfs = &((*ppfs)->next);
530  }
531  }
532  }
533  }
534  }
535 }
536 
543 {
544  S16BIT fndx;
545  S_FontSize *pfs;
546  if (f_sz != NULL)
547  {
548  for (fndx = 0; fndx != MAX_FONT_OBJECTS; fndx++)
549  {
550  if (mg_font_array[fndx] != NULL)
551  {
552  pfs = mg_font_array[fndx]->first_sz;
553  while (pfs != NULL)
554  {
555  if (pfs == f_sz)
556  {
557  return mg_font_array[fndx];
558  }
559  pfs = pfs->next;
560  }
561  }
562  }
563  }
564  return NULL;
565 }
566 
573 {
574  if (f_sz == NULL)
575  {
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;
582  }
583  else
584  {
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;
592  }
593 }
594 
600 S_FontSize* MG_GetFontSize( U16BIT fnt_index, U8BIT fnt_size, U8BIT fnt_style )
601 {
602  S_FontSize *fsz_ptr;
603  S_FontDetails *ftd_ptr;
604  U32BIT fnt_id;
605 
606  TRACE(TFONT, ("(%d %d %x)", fnt_index, fnt_size, fnt_style))
607  assert( fnt_index < MAX_FONT_OBJECTS && mg_font_array[fnt_index] );
608 
609  /* Make unique font ID for a particular font spec */
610  fnt_id = (fnt_index << 16) | (fnt_style << 8) | fnt_size;
611 
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))
615  {
616  fsz_ptr = fsz_ptr->next;
617  }
618  if (fsz_ptr == NULL)
619  {
620  FT_BBox fnt_bbox;
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;
624  S32BIT s_size;
625  U16BIT bb_hd_h, bb_sd_h, bb_sd_w, bb_hd_t, bb_sd_t;
626 
627  /* font size not existing - add new one */
628 
629  fsz_ptr = (S_FontSize *)FT2_MemAlloc(sizeof(S_FontSize));
630  if (fsz_ptr != NULL)
631  {
632  fsz_ptr->next = ftd_ptr->first_sz;
633  ftd_ptr->first_sz = fsz_ptr;
634  fsz_ptr->fnt_id = fnt_id;
635 
636  /* FreeType sizes in 1/64th of a point */
637  fnt_sd_sz = fnt_size << 6;
638 
639  if (fnt_style & FONT_STYLE_NO_SCALE)
640  {
641  fnt_hd_sz = fnt_sd_sz;
642  fnt_sd_sz -= fnt_size << 1; /* bounding box size reduced by 1/32 */
643  }
644  else
645  {
646  /* make any scale up for the screen */
647  fnt_hd_sz = (fnt_sd_sz * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div;
648  }
649 
650  fsz_ptr->height = fnt_hd_sz;
651 
652  fnt_bbox = the_face->bbox;
653 
654  if (ftd_ptr->font_ndx == BUILT_IN_FONT)
655  {
656  if (ftd_ptr->face_type == FTYPE_PFR)
657  {
658  FT_Fixed metrics_x_scale, metrics_y_scale;
659 
660  FT_Get_PFR_Metrics(the_face,
661  &outline_resolution,
662  &ftd_ptr->metric_resolution,
663  &metrics_x_scale,
664  &metrics_y_scale);
665  }
666  else
667  {
668  /* For UK profile: use values from Tiresias true-type font version 7.5.1 */
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;
675  }
676  }
677  else
678  {
679  ftd_ptr->metric_resolution = the_face->units_per_EM;
680  outline_resolution = the_face->units_per_EM;
681  }
682 
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))
685 
686  units = outline_resolution << 6;
687 
688  if (fnt_bbox.yMax > 0)
689  {
690  bb_sd_t = (U16BIT)(((fnt_bbox.yMax * fnt_sd_sz) + (units - 1)) / units);
691  if (fnt_style & FONT_STYLE_NO_SCALE)
692  {
693  bb_hd_t = bb_sd_t;
694  }
695  else
696  {
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))
699  }
700  }
701  else
702  {
703  bb_sd_t = 0;
704  bb_hd_t = 0;
705  }
706  if (fnt_bbox.yMin < 0)
707  {
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)
710  {
711  bb_hd_h = bb_sd_h;
712  }
713  else
714  {
715  bb_hd_h = bb_hd_t + (U16BIT)(((-fnt_bbox.yMin * fnt_hd_sz) + (units - 1)) / units);
716  //bb_hd_h = (U16BIT)((((fnt_bbox.yMax-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))
718  }
719  }
720  else
721  {
722  bb_sd_h = bb_sd_t;
723  bb_hd_h = bb_hd_t;
724  }
725 
726  /* For UK profile: even the latest version of tiresias font has same 'xMin' value as version 7.5.1*/
727  if (fnt_bbox.xMin < 0)
728  {
729  /* spxl_xleftoffset should be calculated with ((-xMin*FontSize*parY)/(outlineRes *parX)) and rounded up*/
730  s_size = (-fnt_bbox.xMin * fnt_size * 45);
731  if (fnt_style & FONT_STYLE_SQUARE)
732  {
733  fsz_ptr->spxl_xleftoffset = (s_size + units - 1) / units;
734  }
735  else
736  {
737  s_size += (outline_resolution * 56) - 1;
738  fsz_ptr->spxl_xleftoffset = s_size / (outline_resolution * 56);
739  }
740 
741  s_size = -fnt_bbox.xMin * fnt_size + outline_resolution - 1;
742  fsz_ptr->pnts_xleftoffset = s_size / outline_resolution;
743 
744  s_size = ((-fnt_bbox.xMin * fnt_sd_sz) + (units - 1)) / units;
745  bb_sd_w = (U16BIT)s_size;
746  }
747  else
748  {
749  /* spxl_xleftoffset should be zero when xMin is positive */
750  fsz_ptr->spxl_xleftoffset = 0;
751  fsz_ptr->pnts_xleftoffset = 0;
752 
753  bb_sd_w = 1; /* min of 1 pixel */
754  }
755 
756  if (fnt_style & FONT_STYLE_SQUARE)
757  {
758  ratio_x = 1;
759  ratio_y = 1;
760  }
761  else
762  {
763  /* PLAIN STYLE */
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))
767  {
768  ratio_y >>= 1;
769  ratio_x >>= 1;
770  }
771  while (((ratio_y % 3) == 0) && ((ratio_x % 3) == 0))
772  {
773  ratio_y /= 3;
774  ratio_x /= 3;
775  }
776  while (((ratio_y % 5) == 0) && ((ratio_x % 5) == 0))
777  {
778  ratio_y /= 5;
779  ratio_x /= 5;
780  }
781  units *= ratio_y;
782  }
783  if (fnt_bbox.xMin < 0)
784  {
785  if (fnt_style & FONT_STYLE_NO_SCALE)
786  {
787  s_size = (-fnt_bbox.xMin * fnt_hd_sz * ratio_x) / units;
788  }
789  else
790  {
791  s_size = ((-fnt_bbox.xMin * fnt_hd_sz * ratio_x) + (units - 1)) / units;
792  /* Test 5.5.8 scene 1, left edge must not overlap line */
793  if (mg_hd_mode == NORMAL_HD)
794  {
795  if (fnt_size <= 26)
796  {
797  s_size += mg_ctxt.out_osd_width / 720;
798  }
799  }
800  }
801  fsz_ptr->bound_box.left = (U16BIT)s_size;
802  }
803  else
804  {
805  fsz_ptr->bound_box.left = 0;
806  }
807  if (!(fnt_style & FONT_STYLE_NO_SCALE))
808  {
809  fnt_hd_sz -= (fnt_hd_sz >> 7);
810  }
811  /* else { fnt_hd_sz -= (fnt_hd_sz >> 6); } */
812  fsz_ptr->width = ((fnt_hd_sz * ratio_x) + (ratio_y >> 1)) / ratio_y;
813  /* For UK profile: width is not used for profile calc */
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))
818 
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;
825 
826  SetupCaching( ftd_ptr, fsz_ptr );
827 
828  TRACE(TFONT, ("font_size=%d CacheSize=%d\n", fnt_size, fsz_ptr->mem_size))
829 
830  ftd_ptr->current_fnt_id = fnt_id;
831  }
832  }
833  return fsz_ptr;
834 }
835 
841 void MG_CheckCache( S_FontSize *f_szdata )
842 {
843  S_FontDetails *font_ptr;
844  if (f_szdata->sbit_cache == 0)
845  {
846  /* this font size has not got cache data, See if the define cache max will allow it
847  */
848  if (f_szdata->mem_size < (FONTS_CACHE_MAX - (CHAR_CACHE_SIZE * sizeof(CacheSbit))))
849  {
850  font_ptr = MG_FindFont( f_szdata );
851  if (font_ptr)
852  {
853  allocateCache( font_ptr, f_szdata );
854  }
855  }
856  }
857  else
858  {
859  f_szdata->cache_hit++;
860  mg_total_cache_hits++;
861  f_szdata->cache_last = mg_total_cache_hits;
862  }
863 }
864 
865 /*---local function definitions----------------------------------------------*/
866 
872 static void initialiseFontDetails( S_FontDetails *fnt_d_ptr )
873 {
874  FT_Face the_face = fnt_d_ptr->face;
875  FT_UInt glyph_index_fig;
876  U16BIT nx;
877 
878  fnt_d_ptr->first_sz = NULL;
879 
880  TRACE(TFONT, (" Font D ptr=%p face=%p", fnt_d_ptr, the_face))
881 
882  for (nx = 0; nx != CHAR_CACHE_SIZE; nx++)
883  {
884  fnt_d_ptr->glyph_ndx[nx] = FT_Get_Char_Index( the_face, nx + FIRST_CACHE_CHAR );
885  }
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))
890 
891 
892  if (fnt_d_ptr->face_type == FTYPE_PFR)
893  {
894  FT_Pos advance;
895 
896  if (FT_Get_PFR_Advance( the_face, fnt_d_ptr->glyph_ndx_space, &advance ) == 0)
897  {
898  fnt_d_ptr->space_horiz_adv = advance;
899  }
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)
902  {
903  fnt_d_ptr->fig_horiz_adv = advance;
904  }
905 
906  for (nx = 0; nx != CHAR_CACHE_SIZE; nx++)
907  {
908  /* array starts with 'space' char */
909  if (fnt_d_ptr->glyph_ndx[nx] &&
910  FT_Get_PFR_Advance( the_face, fnt_d_ptr->glyph_ndx[nx], &advance ) == 0)
911  {
912  /*TRACE(TFONT,("'%c' ha=%ld", nx+FIRST_CACHE_CHAR, advance ))*/
913  fnt_d_ptr->horiz_adv[nx] = advance;
914  }
915  }
916  }
917  else
918  {
919  if (FT_Load_Glyph( the_face, fnt_d_ptr->glyph_ndx_space, FT_LOAD_NO_SCALE ) == 0)
920  {
921  fnt_d_ptr->space_horiz_adv = the_face->glyph->metrics.horiAdvance;
922  }
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)
925  {
926  fnt_d_ptr->fig_horiz_adv = the_face->glyph->metrics.horiAdvance;
927  }
928 
929  for (nx = 0; nx != CHAR_CACHE_SIZE; nx++)
930  {
931  /* array starts with 'space' char */
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)
934  {
935  /*TRACE(TFONT,("'%c' w=%ld,ha=%ld", nx+FIRST_CACHE_CHAR,
936  the_face->glyph->metrics.width,
937  the_face->glyph->metrics.horiAdvance ))*/
938  fnt_d_ptr->horiz_adv[nx] = the_face->glyph->metrics.horiAdvance;
939  }
940  else
941  {
942  fnt_d_ptr->horiz_adv[nx] = 0;
943  }
944  }
945  }
946 }
947 
953 static void freeCache( S_FontSize *fsz_ptr )
954 {
955  assert( fsz_ptr );
956  if (fsz_ptr->sbit_cache)
957  {
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));
962  }
963 }
964 
970 static void allocateCache( S_FontDetails *fd_ptr, S_FontSize *sz_data )
971 {
972  FT_Face the_face = fd_ptr->face;
973  FT_GlyphSlot the_glyph = the_face->glyph;
974  CacheSbit *p_cache;
975  U8BIT *bitmaps, *src;
976  S_FontSize *pfs;
977  U32BIT req_size, lowest_hit, bmp_nx;
978  U16BIT chr, x, y = 0;
979 
980  assert( sz_data->sbit_cache == 0 );
981 
982  req_size = (CHAR_CACHE_SIZE * sizeof(CacheSbit)) + /* cache description space */
983  sz_data->mem_size; /* plus bitmap space */
984 
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)
988  {
989  /* need to purge cache of less recently used character size */
990  assert( mg_font_array[y] );
991  pfs = mg_font_array[y]->first_sz;
992  while (pfs != NULL)
993  {
994  if (pfs->sbit_cache != NULL)
995  {
996  if (mg_cached_fontsizes == 1)
997  {
998  freeCache( pfs );
999  assert( mg_cached_fontsizes == 0);
1000  assert( mg_cache_in_use == 0 );
1001  break;
1002  }
1003  else
1004  {
1005  if (pfs->cache_last != mg_total_cache_hits)
1006  {
1007  /* not the last used font size */
1008  if ((mg_cached_fontsizes == 2) || (lowest_hit == pfs->cache_hit))
1009  {
1010  /* Either only 2 in cache, or assume this is second time
1011  * around outer loop and this one really is the lowest hit */
1012  freeCache( pfs );
1013  lowest_hit = mg_total_cache_hits + 1;
1014  break;
1015  }
1016  else if (lowest_hit > pfs->cache_hit)
1017  {
1018  lowest_hit = pfs->cache_hit;
1019  }
1020  }
1021  }
1022  }
1023  pfs = pfs->next;
1024  }
1025  y++;
1026  if (y == MAX_FONT_OBJECTS || mg_font_array[y] == NULL)
1027  {
1028  y = 0;
1029  }
1030  }
1031 
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)
1034  {
1035  fd_ptr->current_fnt_id = sz_data->fnt_id;
1036  p_cache = (CacheSbit *)FT2_MemAlloc( req_size );
1037  if (p_cache)
1038  {
1039  mg_cache_in_use += req_size;
1040  mg_cached_fontsizes++;
1041 
1042  sz_data->sbit_cache = p_cache; /* save the malloced data */
1043  bitmaps = (U8BIT *)p_cache;
1044  bitmaps += (CHAR_CACHE_SIZE * sizeof(CacheSbit)); /* bitmaps points to the data area */
1045  req_size -= (CHAR_CACHE_SIZE * sizeof(CacheSbit)); /* for debugging */
1046 
1047  /* now fill in the data */
1048  for (bmp_nx = 0, chr = 0; chr != CHAR_CACHE_SIZE; chr++, p_cache++)
1049  {
1050  p_cache->bmp_ndx = bmp_nx; /* store start index for this glyph's bitmap */
1051 
1052  if (fd_ptr->glyph_ndx[chr] &&
1053  FT_Load_Glyph( the_face, fd_ptr->glyph_ndx[chr], FT_LOAD_RENDER ) == 0)
1054  {
1055  U32BIT adv;
1056  U8BIT bwidth = (U8BIT)the_glyph->bitmap.width;
1057  U8BIT bheight = (U8BIT)the_glyph->bitmap.rows;
1058  int ptch = the_glyph->bitmap.pitch;
1059  if (ptch < 0)
1060  ptch = -ptch;
1061 
1062  assert( ptch == bwidth );
1063  #ifdef TRACING
1064  if (bwidth > sz_data->bound_box.width)
1065  {
1066  TRACE(TERROR, ("bwidth %d > sz_data->bound_box.width %d", bwidth, sz_data->bound_box.width))
1067  }
1068  #endif
1069  if (bmp_nx + (bheight * bwidth) > req_size)
1070  {
1071  /* Should never get here! Could only happen if Freetype is not behaving itself */
1072  TRACE(TERROR, ("!!! Cache size is not big enough !!! (%d,%d,%d,%d)", bmp_nx, bheight, bwidth, req_size))
1073  break;
1074  }
1075 
1076  /* Store bitmap dimensions */
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;
1081  /* calculate advance */
1082  adv = the_glyph->linearHoriAdvance + 0x8000;
1083  if (the_glyph->metrics.horiBearingX < 0)
1084  {
1085  S32BIT tmp = -the_glyph->metrics.horiBearingX;
1086  if (((sz_data->fnt_id >> 8) & 0xff) == FONT_STYLE_SQUARE)
1087  {
1088  tmp = tmp * (sz_data->fnt_id & 0xff) * 45 + (2048 * 64) - 1;
1089  p_cache->sdleft = tmp >> 17;
1090  }
1091  else
1092  {
1093  tmp = tmp * (sz_data->fnt_id & 0xff) * 45 + (2048 * 56) - 1;
1094  p_cache->sdleft = tmp / (2048 * 56);
1095  }
1096  }
1097  else
1098  {
1099  p_cache->sdleft = 0;
1100  }
1101  p_cache->advance = (S8BIT)(adv >> 16);
1102 
1103  /* Some minor adjustments - for Tiresias font */
1104  src = the_glyph->bitmap.buffer;
1105  if (p_cache->width > p_cache->advance)
1106  {
1107  /* Do nothing */
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))
1111  }
1112  else if (p_cache->width + (p_cache->left * 2) < p_cache->advance)
1113  {
1114  if (mg_hd_mode == NORMAL_SD)
1115  {
1116  switch (chr)
1117  {
1118  case ('m' - FIRST_CACHE_CHAR):
1119  p_cache->advance--;
1120  break;
1121  default:;
1122  }
1123  }
1124  }
1125  else
1126  {
1127  while (p_cache->width + p_cache->left > p_cache->advance)
1128  {
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)
1133  {
1134  p_cache->left--;
1135  }
1136  else
1137  {
1138  p_cache->advance++;
1139  }
1140  }
1141  if (chr == 1 && mg_hd_mode == NORMAL_SD && (sz_data->fnt_id & 0xff) == 31)
1142  {
1143  /* Double quote (") on SD size 31, fudges together.
1144  * So reduce the brightness of the bit between each dash */
1145  for (x = 0; x != (bheight * bwidth); x++)
1146  {
1147  if (src[x] < 0xA0)
1148  {
1149  src[x] >>= 2;
1150  }
1151  }
1152  }
1153  }
1154 
1155  /* Copy bitmap data for this glyph into cache buffer */
1156  for (y = 0; y != bheight; y++)
1157  {
1158  for (x = 0; x != bwidth; x++)
1159  {
1160  bitmaps[bmp_nx++] = src[x];
1161  }
1162  src += ptch;
1163  }
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))
1165  }
1166  else
1167  {
1168  /* Error */
1169  p_cache->width = 0;
1170  p_cache->top = 0;
1171  p_cache->left = 0;
1172  p_cache->height = 0;
1173  p_cache->advance = 0;
1174  }
1175  }
1176 
1177  /* This is a bit of a cheat for getting through the DTG test "5.10B Monospace chars", but
1178  * it is not too unreasonable. And it's only way to avoid mucking up the rendering elsewhere.
1179  */
1180  p_cache = sz_data->sbit_cache + ('0' - FIRST_CACHE_CHAR);
1181  for (chr = 0; chr != 10; chr++, p_cache++)
1182  {
1183  p_cache->advance = sz_data->figure_adv;
1184  }
1185 
1186  sz_data->cache_hit++;
1187  mg_total_cache_hits++;
1188  sz_data->cache_last = mg_total_cache_hits;
1189  }
1190  }
1191 }
1192 
1198 static void FreeFontFile( S16BIT font_index )
1199 {
1200  S_FontDetails *font_ptr;
1201  S_FontSize *fsz, *psz;
1202  TRACE(TFONT, (" ndx=%d", font_index))
1203  while (mg_font_array[font_index] != NULL)
1204  {
1205  font_ptr = mg_font_array[font_index];
1206  mg_font_array[font_index] = font_ptr->next;
1207  if (font_ptr->face)
1208  {
1209  FT_Done_Face( font_ptr->face );
1210  }
1211  fsz = font_ptr->first_sz;
1212  while (fsz != NULL)
1213  {
1214  freeCache( fsz );
1215  psz = fsz;
1216  fsz = fsz->next;
1217  FT2_MemFree( psz );
1218  }
1219  FT2_MemFree( font_ptr );
1220  }
1221 }
1222 
FT_UInt glyph_ndx_space
Definition: mg_font.h:104
FT_UInt space_horiz_adv
Definition: mg_font.h:105
struct sFontDetails * next
Definition: mg_font.h:99
U16BIT height
Definition: mg_font.h:80
S16BIT MG_FontLoadFile(const U8BIT *data, U32BIT length)
Load font data file into memory for freetype.
Definition: mg_font.c:210
struct sFontSize * next
Definition: mg_font.h:79
U16BIT top
Definition: mg_font.h:61
U16BIT out_osd_width
Definition: mg_ctxt.h:81
U8BIT bb_sd_height
Definition: mg_font.h:90
U16BIT font_ndx
Definition: mg_font.h:109
S_FontSize * first_sz
Definition: mg_font.h:103
U8BIT spxl_xleftoffset
Definition: mg_font.h:93
#define OSD_MemAlloc
Definition: glue_memory.h:96
U16BIT width
Definition: mg_font.h:81
U8BIT width
Definition: mg_font.h:73
#define FONT_STYLE_PLAIN
Definition: mg_drawtext.h:32
S32BIT minWidth
Definition: mg_fontapi.h:38
void MG_FontFreeFile(S16BIT font_index)
free memory associated with file
Definition: mg_font.c:379
U16BIT mlt
Definition: mg_ctxt.h:73
U32BIT cache_hit
Definition: mg_font.h:85
S32BIT maxWidth
Definition: mg_fontapi.h:39
S8BIT advance
Definition: mg_font.h:69
#define FT2_MemAlloc
Definition: glue_memory.h:90
const char * data
Definition: mh5gate.c:56
CacheSbit * sbit_cache
Definition: mg_font.h:84
S8BIT top
Definition: mg_font.h:70
Debug tracing.
U32BIT mem_size
Definition: mg_font.h:83
Font file handling with the Freetype.
U16BIT out_osd_height
Definition: mg_ctxt.h:82
S8BIT figure_adv
Definition: mg_font.h:89
S_FontSize * MG_GetFontSize(U16BIT fnt_index, U8BIT fnt_size, U8BIT fnt_style)
Definition: mg_font.c:600
#define BUILT_IN_FONT
Definition: mg_font.h:36
S_RATIO osd_y
Definition: mg_ctxt.h:86
Tiresias Screen Font PFR data.
#define FONT_STYLE_NO_SCALE
Definition: mg_drawtext.h:34
FT_Face face
Definition: mg_font.h:102
#define FTYPE_TTF
Definition: mg_font.h:38
U32BIT cache_last
Definition: mg_font.h:86
U16BIT height
Definition: mg_font.h:63
int16_t S16BIT
Definition: techtype.h:85
E_HDMode mg_hd_mode
Definition: mg_font.c:76
U16BIT face_type
Definition: mg_font.h:110
void MG_ReleaseFont(H_FontSize f_sz)
Allocate font of particular size from font file.
Definition: mg_font.c:506
uint8_t U8BIT
Definition: techtype.h:82
S8BIT space_adv
Definition: mg_font.h:88
U32BIT current_fnt_id
Definition: mg_font.h:111
Memory functions.
U32BIT file_size
Definition: mg_font.h:101
FT_UInt horiz_adv[CHAR_CACHE_SIZE]
Definition: mg_font.h:107
VBox bound_box
Definition: mg_font.h:82
S32BIT ascent
Definition: mg_fontapi.h:35
H_FontSize MG_AllocateFont(S16BIT fnt_index, U8BIT fnt_size, U8BIT fnt_style)
Allocate font of particular size from font file.
Definition: mg_font.c:485
This file defines the profile for the MHEG engine.
S32BIT descent
Definition: mg_fontapi.h:36
#define FTYPE_PFR
Definition: mg_font.h:39
U16BIT width
Definition: mg_font.h:62
#define MAX_FONT_OBJECTS
Definition: mg_font.c:59
U16BIT left
Definition: mg_font.h:60
U8BIT height
Definition: mg_font.h:72
void MG_FontExit(void)
Free all data associated with built-in font and terminate freetype library.
Definition: mg_font.c:185
U32BIT fnt_id
Definition: mg_font.h:87
U32BIT bmp_ndx
Definition: mg_font.h:68
BOOLEAN MG_FontInit(BOOLEAN isHD)
Initialise freetype library and load "built-in" font.
Definition: mg_font.c:92
S_MGContext mg_ctxt
Definition: mg_osd.c:144
struct _CacheSbit CacheSbit
int8_t S8BIT
Definition: techtype.h:83
#define FIRST_CACHE_CHAR
Definition: mg_font.h:34
#define FONT_STYLE_SQUARE
Definition: mg_drawtext.h:33
U8BIT pnts_xleftoffset
Definition: mg_font.h:94
int32_t S32BIT
Definition: techtype.h:87
uint16_t U16BIT
Definition: techtype.h:84
Font file handling with the Freetype.
define asserts
#define FALSE
Definition: techtype.h:68
void MG_ReleaseFontPtr(S_FontDetails *fp)
Definition: mg_font.c:412
E_HDMode
Definition: mg_font.h:45
FT_UInt glyph_ndx[CHAR_CACHE_SIZE]
Definition: mg_font.h:108
U8BIT * file_data
Definition: mg_font.h:100
FT_UInt fig_horiz_adv
Definition: mg_font.h:106
S8BIT sdleft
Definition: mg_font.h:74
U16BIT div
Definition: mg_ctxt.h:74
U8BIT bb_sd_top
Definition: mg_font.h:92
#define CHAR_CACHE_SIZE
Definition: mg_font.h:35
S_FontDetails * MG_GetFontPtr(S16BIT font_index)
Get Pointer to Font.
Definition: mg_font.c:400
S_FontDetails * MG_FindFont(H_FontSize f_sz)
Get font from size.
Definition: mg_font.c:542
U8BIT BOOLEAN
Definition: techtype.h:99
#define TRUE
Definition: techtype.h:69
void MG_CheckCache(S_FontSize *f_szdata)
Definition: mg_font.c:841
void MG_GetFontMetrics(H_FontSize f_sz, S_FontMetrics *pMetrics)
Get font Metrics.
Definition: mg_font.c:572
#define FT2_MemFree
Definition: glue_memory.h:91
Interface to OSD.
#define FONTS_CACHE_MAX
Definition: mg_font.c:52
U8BIT bb_sd_width
Definition: mg_font.h:91
FT_UInt metric_resolution
Definition: mg_font.h:112
#define FILE_DATA_PTR
#define OSD_MemFree
Definition: glue_memory.h:97
void MG_SetMaxFonts(U16BIT max)
Set Max allowable fonts for profile.
Definition: mg_font.c:164
Interface to the MHEG text render that uses Freetype font library.
S_RATIO osd_x
Definition: mg_ctxt.h:85
S8BIT left
Definition: mg_font.h:71
uint32_t U32BIT
Definition: techtype.h:86
Engine support utility functions for MHEG5.
S32BIT height
Definition: mg_fontapi.h:37
#define TRACE(t, x)
Definition: glue_debug.h:118
#define FILE_DATA_SIZE