MHEG5  15.3.0
source/graphics/src/textdrawfn.h
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Defines