MHEG  17.9.0
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
textdrawfn.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2008 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 #ifndef RenderGlyphFn
26 #error This file should be included from mg_drawtext.c
27 #endif
28 
29 static void RenderGlyphFn( TDColor *pixel, U8BIT *grey_src, U16BIT height,
30  U8BIT width, U8BIT pitch, U16BIT stride, OSDColor full_col
31  #ifdef _DEBUG
32  , TDColor *cnvs_min, TDColor *cnvs_max
33  #endif
34  )
35 {
36  U8BIT x;
37  TDColor td_col = MakeTDColor(full_col);
38 #ifdef CalcColorArray
39  CalcColorArray(td_col);
40 #endif
41  pitch -= width;
42  stride -= width;
43  if (IsOpaqueColor(td_col))
44  {
45  while (height--)
46  {
47  for (x = width; x--; grey_src++, pixel++)
48  {
49  U32BIT grey_val = GreyValue( *grey_src );
50  #ifdef _DEBUG
51  assert((pixel >= cnvs_min) && (pixel < cnvs_max));
52  #endif
53  if (grey_val == SRC_FORE_MAX)
54  {
55  *pixel = td_col;
56  }
57  else
58  {
59  CombineAlphaColour( *pixel, grey_val, full_col, td_col )
60  }
61  }
62  grey_src += pitch;
63  pixel += stride;
64  }
65  }
66  else
67  {
68  while (height--)
69  {
70  for (x = width; x--; grey_src++, pixel++)
71  {
72  U32BIT grey_val = GreyValue( *grey_src );
73  #ifdef _DEBUG
74  assert((pixel >= cnvs_min) && (pixel < cnvs_max));
75  #endif
76  CombineAlphaColour( *pixel, grey_val, full_col, td_col )
77  }
78  grey_src += pitch;
79  pixel += stride;
80  }
81  }
82 }
83 
84 static void TextDrawFn( LineLimit *disp_lines, CharData *char_data, S_FontSize *sz_data,
85  FT_Face the_face, U8BIT vt_justify, U8BIT hz_justify,
86  U16BIT line_space, S16BIT sd_top, U16BIT sd_height,
87  U16BIT total_lines, U16BIT avail_lines, S_SURFACE *canvas )
88 {
89  U32BIT m_size, pixel_line_start;
90  TDColor *text_origin, *line_origin, *char_origin;
91  U8BIT *src_buff;
92  CacheSbit *c_sbit;
93  S32BIT left, right, ctop, avail_width, hd_top;
94  U16BIT line_num, char_ndx, cheight, buff_stride;
95  FT_Int32 load_flags;
96  CharData *pCharInfo;
97 #ifdef _DEBUG
98  TDColor *cnvs_min, *cnvs_max;
99 #endif
100 
101  line_num = 0;
102  char_ndx = 0;
103 
104  avail_width = canvas->width;
105  text_origin = (TDColor *)canvas->col_buff;
106  buff_stride = (U16BIT)(canvas->buff_pitch / sizeof(TDColor));
107 #ifdef _DEBUG
108  cnvs_min = text_origin;
109  m_size = buff_stride;
110  m_size *= canvas->height;
111  cnvs_max = &text_origin[m_size];
112 #endif
113  canvas->opaque = FALSE;
114  hd_top = (sd_top * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div;
115  sd_top += sz_data->bb_sd_top;
116  hd_top += sz_data->bound_box.top;
117  switch (vt_justify)
118  {
119  case JUSTIFY_V_END:
120  if (total_lines > avail_lines)
121  {
122  line_num = total_lines - avail_lines;
123  while (disp_lines->line_num < line_num)
124  {
125  char_ndx = disp_lines->end_ndx;
126  disp_lines++;
127  }
128  cheight = avail_lines - 1;
129  }
130  else
131  {
132  cheight = total_lines - 1;
133  }
134  cheight = (cheight * line_space) + sz_data->bb_sd_height;
135  assert( cheight <= sd_height );
136  if (cheight < sd_height)
137  {
138  sd_top += sd_height - cheight;
139  }
140  break;
141 
142  case JUSTIFY_V_CENTRE:
143  if (total_lines > avail_lines)
144  {
145  total_lines = avail_lines;
146  }
147  cheight = ((total_lines - 1) * line_space) + sz_data->bb_sd_height;
148  assert( cheight <= sd_height );
149  if (cheight < sd_height)
150  {
151  sd_top += (sd_height - cheight) >> 1;
152  }
153  break;
154 
155  default:
156  case JUSTIFY_V_START:
157  if (total_lines > avail_lines)
158  {
159  total_lines = avail_lines;
160  }
161  }
162  while (line_num != total_lines)
163  {
164  if (line_num == disp_lines->line_num)
165  {
166  pixel_line_start = (sd_top * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div;
167  pixel_line_start -= hd_top;
168  line_origin = text_origin + (pixel_line_start * buff_stride);
169  switch (hz_justify)
170  {
171  case JUSTIFY_H_END:
172  right = disp_lines->position + disp_lines->l_width;
173  left = right - avail_width;
174  break;
175  case JUSTIFY_H_CENTRE:
176  left = disp_lines->position;
177  right = left;
178  left += (disp_lines->l_width + 1 - avail_width) >> 1;
179  right += (disp_lines->l_width + avail_width) >> 1;
180  break;
181  default:
182  case JUSTIFY_H_START:
183  left = disp_lines->position;
184  right = left + avail_width;
185  break;
186  }
187  for (char_ndx = disp_lines->start_ndx; char_ndx != disp_lines->end_ndx; char_ndx++)
188  {
189  pCharInfo = char_data + char_ndx;
190  if ((pCharInfo->real_position >= left) &&
191  ((pCharInfo->real_position + pCharInfo->width) <= right) &&
192  NotTransparent(pCharInfo->colour))
193  {
194  /* glyph is completely within box and visible */
195  ctop = sz_data->bound_box.top;
196  if (pCharInfo->gf_ndx != 0)
197  {
198  load_flags = FT_LOAD_RENDER;
199  /* Special cases to overcome a FreeType bug: for
200  * "Latin Small Letter A With Tilde U+00E3",
201  * "Latin Small Letter N With Tilde U+00F1" and
202  * "Latin Small Letter O With Tilde U+00F5" the
203  * "tilde" is rendered as a macron for small font
204  * sizes, when auto-hinting is enabled. We cannot
205  * always control the build options, so a special
206  * case is required.
207  */
208  if (pCharInfo->uni_chr == 0x00e3 ||
209  pCharInfo->uni_chr == 0x00f1 ||
210  pCharInfo->uni_chr == 0x00f5)
211  {
212  load_flags |= FT_LOAD_NO_AUTOHINT;
213  }
214  if (FT_Load_Glyph( the_face, pCharInfo->gf_ndx, load_flags ) != 0)
215  {
216  /* ERROR, so goto next glyph */
217  continue;
218  }
219  else
220  {
221  assert( pCharInfo->width == the_face->glyph->bitmap.width );
222  if (the_face->glyph->bitmap.pitch < 0)
223  m_size = -the_face->glyph->bitmap.pitch;
224  else
225  m_size = the_face->glyph->bitmap.pitch;
226  ctop -= the_face->glyph->bitmap_top;
227  cheight = the_face->glyph->bitmap.rows;
228  src_buff = the_face->glyph->bitmap.buffer;
229  }
230  }
231  else
232  {
233  c_sbit = &sz_data->sbit_cache[pCharInfo->uni_chr - FIRST_CACHE_CHAR];
234  m_size = c_sbit->width;
235  ctop -= c_sbit->top;
236  src_buff = (U8BIT *)&sz_data->sbit_cache[CHAR_CACHE_SIZE];
237  src_buff += c_sbit->bmp_ndx;
238  cheight = c_sbit->height;
239  }
240  assert( sz_data->bound_box.height >= cheight );
241  char_origin = line_origin;
242  if (ctop > 0)
243  {
244  if ((pixel_line_start + ctop + cheight) > canvas->height)
245  {
246  ctop = canvas->height - (cheight + pixel_line_start);
247  }
248  char_origin += ctop * buff_stride;
249  }
250  char_origin += pCharInfo->real_position - left;
251 
252  RenderGlyphFn( char_origin, src_buff, cheight, pCharInfo->width, (U8BIT)m_size, buff_stride, pCharInfo->colour
253  #ifdef _DEBUG
254  , cnvs_min, cnvs_max
255  #endif
256  );
257  }
258  }
259  disp_lines++;
260  }
261  sd_top += line_space;
262  line_num++;
263  }
264 }
265 
Definition: mg_font.h:66
Definition: mg_font.h:77
Definition: mg_osd.h:37