MHEG5
15.3.0
|
00001 /******************************************************************************* 00002 * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org) 00003 * Copyright © 2008 Ocean Blue Software Ltd 00004 * 00005 * This file is part of a DTVKit Software Component 00006 * You are permitted to copy, modify or distribute this file subject to the terms 00007 * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org 00008 * 00009 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 00010 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 00011 * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 00012 * 00013 * If you or your organisation is not a member of DTVKit then you have access 00014 * to this source code outside of the terms of the licence agreement 00015 * and you are expected to delete this and any associated files immediately. 00016 * Further information on DTVKit, membership and terms can be found at www.dtvkit.org 00017 *******************************************************************************/ 00025 #ifndef RenderGlyphFn 00026 #error This file should be included from mg_drawtext.c 00027 #endif 00028 00029 static void RenderGlyphFn( TDColor *pixel, U8BIT *grey_src, U16BIT height, 00030 U8BIT width, U8BIT pitch, U16BIT stride, OSDColor full_col 00031 #ifdef _DEBUG 00032 , TDColor *cnvs_min, TDColor *cnvs_max 00033 #endif 00034 ) 00035 { 00036 U8BIT x; 00037 TDColor td_col = MakeTDColor(full_col); 00038 #ifdef CalcColorArray 00039 CalcColorArray(td_col); 00040 #endif 00041 pitch -= width; 00042 stride -= width; 00043 if (IsOpaqueColor(td_col)) 00044 { 00045 while (height--) 00046 { 00047 for (x = width; x--; grey_src++, pixel++) 00048 { 00049 U32BIT grey_val = GreyValue( *grey_src ); 00050 #ifdef _DEBUG 00051 assert((pixel >= cnvs_min) && (pixel < cnvs_max)); 00052 #endif 00053 if (grey_val == SRC_FORE_MAX) 00054 { 00055 *pixel = td_col; 00056 } 00057 else 00058 { 00059 CombineAlphaColour( *pixel, grey_val, full_col, td_col ) 00060 } 00061 } 00062 grey_src += pitch; 00063 pixel += stride; 00064 } 00065 } 00066 else 00067 { 00068 while (height--) 00069 { 00070 for (x = width; x--; grey_src++, pixel++) 00071 { 00072 U32BIT grey_val = GreyValue( *grey_src ); 00073 #ifdef _DEBUG 00074 assert((pixel >= cnvs_min) && (pixel < cnvs_max)); 00075 #endif 00076 CombineAlphaColour( *pixel, grey_val, full_col, td_col ) 00077 } 00078 grey_src += pitch; 00079 pixel += stride; 00080 } 00081 } 00082 } 00083 00084 static void TextDrawFn( LineLimit *disp_lines, CharData *char_data, S_FontSize *sz_data, 00085 FT_Face the_face, U8BIT vt_justify, U8BIT hz_justify, 00086 U16BIT line_space, S16BIT sd_top, U16BIT sd_height, 00087 U16BIT total_lines, U16BIT avail_lines, S_SURFACE *canvas ) 00088 { 00089 U32BIT m_size, pixel_line_start; 00090 TDColor *text_origin, *line_origin, *char_origin; 00091 U8BIT *src_buff; 00092 CacheSbit *c_sbit; 00093 S32BIT left, right, ctop, avail_width, hd_top; 00094 U16BIT line_num, char_ndx, cheight, buff_stride; 00095 FT_Int32 load_flags; 00096 CharData *pCharInfo; 00097 #ifdef _DEBUG 00098 TDColor *cnvs_min, *cnvs_max; 00099 #endif 00100 00101 line_num = 0; 00102 char_ndx = 0; 00103 00104 avail_width = canvas->width; 00105 text_origin = (TDColor *)canvas->col_buff; 00106 buff_stride = (U16BIT)(canvas->buff_pitch / sizeof(TDColor)); 00107 #ifdef _DEBUG 00108 cnvs_min = text_origin; 00109 m_size = buff_stride; 00110 m_size *= canvas->height; 00111 cnvs_max = &text_origin[m_size]; 00112 #endif 00113 canvas->opaque = FALSE; 00114 hd_top = (sd_top * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div; 00115 sd_top += sz_data->bb_sd_top; 00116 hd_top += sz_data->bound_box.top; 00117 switch (vt_justify) 00118 { 00119 case JUSTIFY_V_END: 00120 if (total_lines > avail_lines) 00121 { 00122 line_num = total_lines - avail_lines; 00123 while (disp_lines->line_num < line_num) 00124 { 00125 char_ndx = disp_lines->end_ndx; 00126 disp_lines++; 00127 } 00128 cheight = avail_lines - 1; 00129 } 00130 else 00131 { 00132 cheight = total_lines - 1; 00133 } 00134 cheight = (cheight * line_space) + sz_data->bb_sd_height; 00135 assert( cheight <= sd_height ); 00136 if (cheight < sd_height) 00137 { 00138 sd_top += sd_height - cheight; 00139 } 00140 break; 00141 00142 case JUSTIFY_V_CENTRE: 00143 if (total_lines > avail_lines) 00144 { 00145 total_lines = avail_lines; 00146 } 00147 cheight = ((total_lines - 1) * line_space) + sz_data->bb_sd_height; 00148 assert( cheight <= sd_height ); 00149 if (cheight < sd_height) 00150 { 00151 sd_top += (sd_height - cheight) >> 1; 00152 } 00153 break; 00154 00155 default: 00156 case JUSTIFY_V_START: 00157 if (total_lines > avail_lines) 00158 { 00159 total_lines = avail_lines; 00160 } 00161 } 00162 while (line_num != total_lines) 00163 { 00164 if (line_num == disp_lines->line_num) 00165 { 00166 pixel_line_start = (sd_top * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div; 00167 pixel_line_start -= hd_top; 00168 line_origin = text_origin + (pixel_line_start * buff_stride); 00169 switch (hz_justify) 00170 { 00171 case JUSTIFY_H_END: 00172 right = disp_lines->position + disp_lines->l_width; 00173 left = right - avail_width; 00174 break; 00175 case JUSTIFY_H_CENTRE: 00176 left = disp_lines->position; 00177 right = left; 00178 left += (disp_lines->l_width + 1 - avail_width) >> 1; 00179 right += (disp_lines->l_width + avail_width) >> 1; 00180 break; 00181 default: 00182 case JUSTIFY_H_START: 00183 left = disp_lines->position; 00184 right = left + avail_width; 00185 break; 00186 } 00187 for (char_ndx = disp_lines->start_ndx; char_ndx != disp_lines->end_ndx; char_ndx++) 00188 { 00189 pCharInfo = char_data + char_ndx; 00190 if ((pCharInfo->real_position >= left) && 00191 ((pCharInfo->real_position + pCharInfo->width) <= right) && 00192 NotTransparent(pCharInfo->colour)) 00193 { 00194 /* glyph is completely within box and visible */ 00195 ctop = sz_data->bound_box.top; 00196 if (pCharInfo->gf_ndx != 0) 00197 { 00198 load_flags = FT_LOAD_RENDER; 00199 /* Special cases to overcome a FreeType bug: for 00200 * "Latin Small Letter A With Tilde U+00E3", 00201 * "Latin Small Letter N With Tilde U+00F1" and 00202 * "Latin Small Letter O With Tilde U+00F5" the 00203 * "tilde" is rendered as a macron for small font 00204 * sizes, when auto-hinting is enabled. We cannot 00205 * always control the build options, so a special 00206 * case is required. 00207 */ 00208 if (pCharInfo->uni_chr == 0x00e3 || 00209 pCharInfo->uni_chr == 0x00f1 || 00210 pCharInfo->uni_chr == 0x00f5) 00211 { 00212 load_flags |= FT_LOAD_NO_AUTOHINT; 00213 } 00214 if (FT_Load_Glyph( the_face, pCharInfo->gf_ndx, load_flags ) != 0) 00215 { 00216 /* ERROR, so goto next glyph */ 00217 continue; 00218 } 00219 else 00220 { 00221 assert( pCharInfo->width == the_face->glyph->bitmap.width ); 00222 if (the_face->glyph->bitmap.pitch < 0) 00223 m_size = -the_face->glyph->bitmap.pitch; 00224 else 00225 m_size = the_face->glyph->bitmap.pitch; 00226 ctop -= the_face->glyph->bitmap_top; 00227 cheight = the_face->glyph->bitmap.rows; 00228 src_buff = the_face->glyph->bitmap.buffer; 00229 } 00230 } 00231 else 00232 { 00233 c_sbit = &sz_data->sbit_cache[pCharInfo->uni_chr - FIRST_CACHE_CHAR]; 00234 m_size = c_sbit->width; 00235 ctop -= c_sbit->top; 00236 src_buff = (U8BIT *)&sz_data->sbit_cache[CHAR_CACHE_SIZE]; 00237 src_buff += c_sbit->bmp_ndx; 00238 cheight = c_sbit->height; 00239 } 00240 assert( sz_data->bound_box.height >= cheight ); 00241 char_origin = line_origin; 00242 if (ctop > 0) 00243 { 00244 if ((pixel_line_start + ctop + cheight) > canvas->height) 00245 { 00246 ctop = canvas->height - (cheight + pixel_line_start); 00247 } 00248 char_origin += ctop * buff_stride; 00249 } 00250 char_origin += pCharInfo->real_position - left; 00251 00252 RenderGlyphFn( char_origin, src_buff, cheight, pCharInfo->width, (U8BIT)m_size, buff_stride, pCharInfo->colour 00253 #ifdef _DEBUG 00254 , cnvs_min, cnvs_max 00255 #endif 00256 ); 00257 } 00258 } 00259 disp_lines++; 00260 } 00261 sd_top += line_space; 00262 line_num++; 00263 } 00264 } 00265