Ticket #1899: 1899-v3.patch

File 1899-v3.patch, 35.4 KB (added by pholmes@…, 19 years ago)

Now uses the OSD to request a redraw of the data. This works fine for subtitles. For teletext pages the Header update has been disabled since this causes an excessive load.

  • libs/libmythtv/osdtypeteletext.h

     
    1515
    1616#include "osdtypes.h"
    1717#include "teletextdecoder.h"
     18#include "osd.h"
    1819
    1920class TTFFont;
    2021class OSDType;
     
    8182    int flof;                 ///< page has FastText links
    8283    int floflink[6];          ///< FastText links (FLOF)
    8384    bool subtitle;            ///< page is subtitle page
     85    bool active;
    8486};
    8587
    8688class TeletextPage
     
    9698class TeletextMagazine
    9799{
    98100  public:
    99     QMutex lock;
     101    mutable QMutex lock;
    100102    int current_page;
    101103    int current_subpage;
     104    TeletextSubPage             loadingpage;
    102105    std::map<int, TeletextPage> pages;
    103106};
    104107
     
    107110    Q_OBJECT
    108111  public:
    109112    OSDTypeTeletext(const QString &name, TTFFont *font,
    110                     QRect displayrect, float wmult, float hmult);
     113                    QRect displayrect, float wmult, float hmult, OSD *osd);
    111114    OSDTypeTeletext(const OSDTypeTeletext &other)
    112115        : OSDType(other.m_name), TeletextViewer() {}
    113116    virtual ~OSDTypeTeletext() {}
    114117
    115 
    116118    void Reinit(float wmult, float hmult);
    117119
     120    // Teletext Drawing methods
    118121    void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
     122    void DrawBackground(OSDSurface *surface, int x, int y) const;
     123    void DrawRect(OSDSurface *surface, const QRect) const;
     124    void DrawCharacter(OSDSurface *surface, int x, int y,
     125                       QChar ch, int doubleheight = 0) const;
     126    void DrawMosaic(OSDSurface *surface, int x, int y,
     127                    int code, int doubleheight) const;
     128    void DrawLine(OSDSurface *surface, const uint8_t *page,
     129                  uint row, int lang) const;
     130    void DrawHeader(OSDSurface *surface, const uint8_t *page, int lang) const;
     131    void DrawStatus(OSDSurface *surface) const;
     132    void DrawPage(OSDSurface *surface) const;
    119133
    120     void SetForegroundColor(int color);
    121     void SetBackgroundColor(int color);
    122 
    123     void DrawBackground(int x, int y);
    124     void DrawRect(int x, int y, int dx, int dy);
    125     void DrawCharacter(int x, int y, QChar ch, int doubleheight = 0);
    126     void DrawMosaic(int x, int y, int code, int doubleheight);
    127 
    128     void DrawLine(const uint8_t* page, uint row, int lang);
    129     void DrawHeader(const uint8_t* page, int lang);
    130     void DrawPage(void);
    131 
    132     void NewsFlash(void) {};
    133 
    134     void PageUpdated(int page, int subpage);
    135     void HeaderUpdated(uint8_t* page, int lang);
    136     void StatusUpdated(void);
    137 
    138     // Teletext Viewer methods
     134    // TeletextViewer interface methods
    139135    void KeyPress(uint key);
    140136    void SetPage(int page, int subpage);
    141137    void SetDisplaying(bool display) { m_displaying = display; };
     
    146142    void AddTeletextData(int magazine, int row,
    147143                         const uint8_t* buf, int vbimode);
    148144
     145    static const QColor kColorBlack;
     146    static const QColor kColorRed;
     147    static const QColor kColorGreen;
     148    static const QColor kColorYellow;
     149    static const QColor kColorBlue;
     150    static const QColor kColorMagenta;
     151    static const QColor kColorCyan;
     152    static const QColor kColorWhite;
     153    static const int    kTeletextColumns;
     154    static const int    kTeletextRows;
     155
    149156  private:
    150     char CharConversion(char ch, int lang);
    151     TeletextSubPage *FindSubPage(int page, int subpage, int direction = 0);
    152     TeletextPage    *FindPage(int page, int direction = 0);
     157    // Internal Teletext Sets
     158    void SetForegroundColor(int color) const;
     159    void SetBackgroundColor(int color) const;
    153160
     161    // Internal Teletext Commands
     162    void NewsFlash(void) {};
     163    void PageUpdated(int page, int subpage);
     164    void HeaderUpdated(uint8_t *page, int lang);
     165
     166    const TeletextSubPage *FindSubPagec(int page,int subpage,int dir = 0) const;
     167    const TeletextPage *FindPagec(int page, int direction = 0) const;
     168
     169    TeletextSubPage *FindSubPage(int page, int subpage, int direction = 0)
     170        { return (TeletextSubPage*) FindSubPagec(page, subpage, direction);}
     171    TeletextPage *FindPage(int page, int direction = 0)
     172          { return (TeletextPage*) FindPagec(page, direction);}
     173
    154174  private:
    155175    QMutex       m_lock;
    156176    QRect        m_displayrect;
    157177    QRect        m_unbiasedrect;
    158178
    159     TTFFont     *m_font;
    160     OSDSurface  *m_surface;
    161179    OSDTypeBox  *m_box;
    162180
    163181    int          m_tt_colspace;
    164182    int          m_tt_rowspace;
    165183
    166     uint8_t      m_bgcolor_y;
    167     uint8_t      m_bgcolor_u;
    168     uint8_t      m_bgcolor_v;
    169     uint8_t      m_bgcolor_a;
    170 
    171184    // last fetched page
    172185    int          m_fetchpage;
    173186    int          m_fetchsubpage;
    174187
     188    // needs to mutable so we can change color character by character.
     189    mutable TTFFont *m_font;
     190
     191    // current character background
     192    mutable uint8_t  m_bgcolor_y;
     193    mutable uint8_t  m_bgcolor_u;
     194    mutable uint8_t  m_bgcolor_v;
     195    mutable uint8_t  m_bgcolor_a;
     196
    175197    // currently displayed page:
    176     int          m_curpage;
    177     int          m_cursubpage;
     198    mutable int  m_curpage;
     199    mutable int  m_cursubpage;
     200    mutable bool m_curpage_showheader;
     201    mutable bool m_curpage_issubtitle;
     202
    178203    int          m_pageinput[3];
    179     bool         m_curpage_showheader;
    180     bool         m_curpage_issubtitle;
    181204
    182205    bool         m_transparent;
    183206    bool         m_revealHidden;
    184207
    185208    bool         m_displaying;
    186209
     210    OSD          *m_osd;
     211    uint8_t      m_header[40];
     212    mutable bool m_header_changed;
     213    mutable bool m_page_changed;
     214
    187215    TeletextMagazine m_magazines[8];
    188216    unsigned char    bitswap[256];
    189 
    190     static const QColor kColorBlack;
    191     static const QColor kColorRed;
    192     static const QColor kColorGreen;
    193     static const QColor kColorYellow;
    194     static const QColor kColorBlue;
    195     static const QColor kColorMagenta;
    196     static const QColor kColorCyan;
    197     static const QColor kColorWhite;
    198     static const int    kTeletextColumns;
    199     static const int    kTeletextRows;
    200217};
    201218
    202219#endif
  • libs/libmythtv/osd.h

     
    154154
    155155    void SetTextSubtitles(const QStringList&);
    156156    void ClearTextSubtitles(void);
     157
     158    void UpdateTeletext(void);
    157159 private:
    158160    bool InitDefaults(void);
    159161    bool InitCC608(void);
  • libs/libmythtv/osdtypeteletext.cpp

     
    4747
    4848/*****************************************************************************/
    4949OSDTypeTeletext::OSDTypeTeletext(const QString &name, TTFFont *font,
    50                                  QRect displayrect, float wmult, float hmult)
     50                                 QRect displayrect, float wmult, float hmult, OSD *osd)
    5151    : OSDType(name),
    5252      m_displayrect(displayrect),       m_unbiasedrect(0,0,0,0),
    53       m_font(font),                     m_surface(NULL),
    5453      m_box(NULL),
    5554
    5655      m_tt_colspace(m_displayrect.width()  / kTeletextColumns),
    5756      m_tt_rowspace(m_displayrect.height() / kTeletextRows),
    5857
     58      // last fetched page
     59      m_fetchpage(0),                   m_fetchsubpage(0),
     60
     61      // current font
     62      m_font(font),
     63
     64      // current character background
    5965      m_bgcolor_y(0),                   m_bgcolor_u(0),
    6066      m_bgcolor_v(0),                   m_bgcolor_a(0),
    61       // last fetched page
    62       m_fetchpage(0),                   m_fetchsubpage(0),
    63       // currently displayed page:
     67
     68      // currently displayed page
    6469      m_curpage(0x100),                 m_cursubpage(-1),
    6570      m_curpage_showheader(true),       m_curpage_issubtitle(false),
    6671
    6772      m_transparent(false),             m_revealHidden(false),
    68       m_displaying(false)
     73      m_displaying(false),              m_osd(osd),
     74      m_header_changed(false),          m_page_changed(false)
    6975{
    7076    m_unbiasedrect  = bias(m_displayrect, wmult, hmult);
    7177
     
    104110        m_magazines[mag].pages.clear();
    105111        m_magazines[mag].current_page = 0;
    106112        m_magazines[mag].current_subpage = 0;
     113        m_magazines[mag].loadingpage.active = false;
    107114    }
     115    memset(m_header, ' ', 40);
    108116
    109117    m_curpage    = 0x100;
    110118    m_cursubpage = -1;
     
    115123    m_pageinput[2] = '0';
    116124}
    117125
    118 /** \fn OSDTypeTeletext::CharConversion(char, int)
    119  *  \brief converts the given character to the given language
    120  */
    121 char OSDTypeTeletext::CharConversion(char ch, int lang)
    122 {
    123     int c = 0;
    124     for (int j = 0; j < 14; j++)
    125     {
    126         c = ch & 0x7F;
    127         if (c == lang_chars[0][j])
    128             ch = lang_chars[lang + 1][j];
    129     }
    130     return ch;
    131 }
    132 
    133126/** \fn OSDTypeTeletext::AddPageHeader(int,int,const unsigned char*,int,int,int)
    134  *  \brief Adds a new page header 
     127 *  \brief Adds a new page header
    135128 *         (page=0 if none)
    136129 */
    137130void OSDTypeTeletext::AddPageHeader(int page, int subpage,
     
    144137    int lastPage = m_magazines[magazine - 1].current_page;
    145138    int lastSubPage = m_magazines[magazine - 1].current_subpage;
    146139
    147     // update the last fetched page if the magazine is the same 
     140    // update the last fetched page if the magazine is the same
    148141    // and the page no. is different
    149     if (page != lastPage || subpage != lastSubPage)
     142
     143    if ((page != lastPage || subpage != lastSubPage) &&
     144        m_magazines[magazine - 1].loadingpage.active == true)
     145    {
     146        TeletextSubPage *ttpage = FindSubPage(lastPage, lastSubPage);
     147        if (ttpage == NULL)
     148        {
     149            ttpage = &m_magazines[magazine - 1].pages[lastPage].subpages[lastSubPage];
     150            m_magazines[magazine - 1].pages[lastPage].pagenum = lastPage;
     151            ttpage->subpagenum = lastSubPage;
     152        }
     153        memcpy(ttpage, &m_magazines[magazine - 1].loadingpage, sizeof(TeletextSubPage));
     154        m_magazines[magazine - 1].loadingpage.active = false;
     155
    150156        PageUpdated(lastPage, lastSubPage);
     157    }
    151158
    152159    m_fetchpage = page;
    153160    m_fetchsubpage = subpage;
    154161
    155     TeletextSubPage *ttpage = FindSubPage(page, subpage);
     162    TeletextSubPage *ttpage = &m_magazines[magazine - 1].loadingpage;
    156163
    157     if (ttpage == NULL)
    158     {
    159         ttpage = &m_magazines[magazine - 1].pages[page].subpages[subpage];
    160         m_magazines[magazine - 1].pages[page].pagenum = page;
    161         ttpage->subpagenum = subpage;
    162 
    163         for (int i=0; i < 6; i++)
    164             ttpage->floflink[i] = 0;
    165     }
    166 
    167164    m_magazines[magazine - 1].current_page = page;
    168165    m_magazines[magazine - 1].current_subpage = subpage;
    169166
     167    memset(ttpage->data, ' ', sizeof(ttpage->data));
     168
     169    ttpage->active = true;
     170    ttpage->subpagenum = subpage;
     171
     172    for (int i=0; i < 6; i++)
     173        ttpage->floflink[i] = 0;
     174
    170175    ttpage->lang = lang;
    171176    ttpage->flags = flags;
    172177    ttpage->flof = 0;
     
    174179    ttpage->subtitle = (vbimode == VBI_DVB_SUBTITLE);
    175180
    176181    for (int j = 0; j < 8; j++)
     182    {
    177183        ttpage->data[0][j] = 32;
     184    }
    178185
    179186    if (vbimode == VBI_DVB || vbimode == VBI_DVB_SUBTITLE)
    180187    {
     
    184191    else
    185192    {
    186193        memcpy(ttpage->data[0]+0, buf, 40);
    187         memset(ttpage->data[0]+40, ' ', sizeof(ttpage->data)-40);
    188194    }
    189195   
    190196    if ( !(ttpage->flags & TP_INTERRUPTED_SEQ))
     197    {
     198        memcpy(m_header, ttpage->data[0], 40);
    191199        HeaderUpdated(ttpage->data[0],ttpage->lang);
     200    }
    192201}
    193202
    194203/** \fn OSDTypeTeletext::AddTeletextData(int,int,const unsigned char*,int)
     
    207216    if (currentpage == 0)
    208217        return;
    209218
    210     TeletextSubPage *ttpage = FindSubPage(currentpage, currentsubpage);
     219    TeletextSubPage *ttpage = &m_magazines[magazine - 1].loadingpage;
    211220
    212     if (ttpage == NULL)
    213         return;
    214 
    215221    switch (row)
    216222    {
    217223        case 1 ... 24: // Page Data
     
    298304    }
    299305}
    300306
    301 /** \fn OSDTypeTeletext::PageUpdated(int)
     307/** \fn OSDTypeTeletext::PageUpdated(int,int)
    302308 *  \brief Updates the page, if given pagenumber is the same
    303309 *         as the current shown page
    304310 */
     
    313319    if (subpage != m_cursubpage && m_cursubpage != -1)
    314320        return;
    315321
    316 
    317     if (m_surface != NULL)
    318     {
    319         m_surface->SetChanged(true);
    320         m_surface->ClearUsed();
    321         DrawPage();
    322     }
     322    m_page_changed = true;
     323    m_osd->UpdateTeletext();
    323324}
    324325
    325326/** \fn OSDTypeTeletext::HeaderUpdated(unsigned char*,int)
     
    331332 */
    332333void OSDTypeTeletext::HeaderUpdated(unsigned char *page, int lang)
    333334{
     335    (void)lang;
     336
    334337    if (!m_displaying)
    335338        return;
    336339
     
    340343    if (m_curpage_showheader == false)
    341344        return;
    342345
    343     if (m_surface != NULL)
    344         DrawHeader(page, lang);
     346    m_header_changed = true;
     347// Cannot use the OSD to trigger a draw for this. If it does it
     348// takes too much time drawing the page each time the data changes
     349// (the OSD erases the surface before doing a redraw so the entire
     350//  teletext contents must be re-displayed).
     351//   m_osd->UpdateTeletext();
     352#if 0
     353    if (surface != NULL)
     354        DrawHeader(surface, page, lang);
     355#endif
    345356}
    346357
    347358/** \fn OSDTypeTeletext::FindPage(int, int)
     
    351362 *  \param direction find page before or after the given page
    352363 *  \return TeletextPage (NULL if not found)
    353364 */
    354 TeletextPage* OSDTypeTeletext::FindPage(int page, int direction)
     365const TeletextPage *OSDTypeTeletext::FindPagec(int page, int direction) const
    355366{
    356     TeletextPage *res = NULL;
    357367    int mag = MAGAZINE(page);
    358368
    359369    if (mag > 8 || mag < 1)
     
    361371
    362372    QMutexLocker lock(&m_magazines[mag - 1].lock);
    363373
    364     std::map<int, TeletextPage>::iterator pageIter;
     374    std::map<int, TeletextPage>::const_iterator pageIter;
    365375    pageIter = m_magazines[mag - 1].pages.find(page);
    366376    if (pageIter == m_magazines[mag - 1].pages.end())
    367377        return NULL;
    368378
    369     res = &pageIter->second;
     379    const TeletextPage *res = &pageIter->second;
    370380    if (direction == -1)
    371381    {
    372382        --pageIter;
    373383        if (pageIter == m_magazines[mag - 1].pages.end())
    374384        {
    375             std::map<int, TeletextPage>::reverse_iterator iter;
     385            std::map<int, TeletextPage>::const_reverse_iterator iter;
    376386            iter = m_magazines[mag - 1].pages.rbegin();
    377387            res = &iter->second;
    378388        }
     
    395405    return res;
    396406}
    397407
    398 /** \fn OSDTypeTeletext::FindSubPage(int, int, int)
     408/** \fn OSDTypeTeletext::FindSubPage(int, int, int) const
    399409 *  \brief Finds the given page
    400410 *
    401411 *  \param page Page number
     
    404414 *         (only if Subpage is not -1)
    405415 *  \return TeletextSubPage (NULL if not found)
    406416 */
    407 TeletextSubPage* OSDTypeTeletext::FindSubPage(int page, int subpage, int direction)
     417const TeletextSubPage *OSDTypeTeletext::FindSubPagec(int page, int subpage,
     418                                                    int direction) const
    408419{
    409     TeletextSubPage *res = NULL;
    410420    int mag = MAGAZINE(page);
    411421
    412422    if (mag > 8 || mag < 1)
     
    414424
    415425    QMutexLocker lock(&m_magazines[mag - 1].lock);
    416426
    417     if (subpage == -1)
    418     {
    419         // return the first subpage found
    420         std::map<int, TeletextPage>::iterator pageIter;
    421         pageIter = m_magazines[mag - 1].pages.find(page);
    422         if (pageIter == m_magazines[mag - 1].pages.end())
    423             return NULL;
     427    std::map<int, TeletextPage>::const_iterator pageIter;
     428    pageIter = m_magazines[mag - 1].pages.find(page);
     429    if (pageIter == m_magazines[mag - 1].pages.end())
     430        return NULL;
    424431
    425         TeletextPage *page = &pageIter->second;
    426         std::map<int, TeletextSubPage>::iterator subpageIter;
    427         subpageIter = page->subpages.begin();
    428         if (subpageIter == page->subpages.end())
    429             return NULL;
     432    const TeletextPage *ttpage = &(pageIter->second);
     433    std::map<int, TeletextSubPage>::const_iterator subpageIter =
     434        ttpage->subpages.begin();
    430435
    431         return &subpageIter->second;
    432     }
    433     else
    434     {
    435         // try to find the subpage given
    436         std::map<int, TeletextPage>::iterator pageIter;
    437         pageIter = m_magazines[mag - 1].pages.find(page);
    438         if (pageIter == m_magazines[mag - 1].pages.end())
    439             return NULL;
     436    // try to find the subpage given, or first if subpage == -1
     437    if (subpage != -1)
     438        subpageIter = ttpage->subpages.find(subpage);
    440439
    441         TeletextPage *page = &pageIter->second;
    442         std::map<int, TeletextSubPage>::iterator subpageIter;
    443         subpageIter = page->subpages.find(subpage);
    444         if (subpageIter == page->subpages.end())
    445             return NULL;
     440    if (subpageIter == ttpage->subpages.end())
     441        return NULL;
    446442
    447         res = &subpageIter->second;
    448         if (direction == -1)
    449         {
    450             --subpageIter;
    451             if (subpageIter == page->subpages.end())
    452             {
    453                 std::map<int, TeletextSubPage>::reverse_iterator iter;
    454                 iter = page->subpages.rbegin();
    455                 res = &iter->second;
    456             }
    457             else
    458                 res = &subpageIter->second;
    459         }
     443    if (subpage == -1)
     444        return &(subpageIter->second);
    460445
    461         if (direction == 1)
     446    const TeletextSubPage *res = &(subpageIter->second);
     447    if (direction == -1)
     448    {
     449        --subpageIter;
     450        if (subpageIter == ttpage->subpages.end())
    462451        {
    463             ++subpageIter;
    464             if (subpageIter == page->subpages.end())
    465             {
    466                 subpageIter = page->subpages.begin();
    467                 res = &subpageIter->second;
    468             }
    469             else
    470                 res = &subpageIter->second;
     452            std::map<int, TeletextSubPage>::const_reverse_iterator iter =
     453                ttpage->subpages.rbegin();
     454            res = &(iter->second);
    471455        }
     456        else
     457            res = &(subpageIter->second);
    472458    }
    473459
     460    if (direction == 1)
     461    {
     462        ++subpageIter;
     463        if (subpageIter == ttpage->subpages.end())
     464            subpageIter = ttpage->subpages.begin();
     465
     466        res = &(subpageIter->second);
     467    }
     468
    474469    return res;
    475470}
    476471
     
    677672    PageUpdated(m_curpage, m_cursubpage);
    678673}
    679674
    680 /** \fn OSDTypeTeletext::SetForegroundColor(int)
     675QColor color_tt2qt(int ttcolor)
     676{
     677    QColor color;
     678
     679    switch (ttcolor & ~TTColor::TRANSPARENT)
     680    {
     681        case TTColor::BLACK:   color = OSDTypeTeletext::kColorBlack;   break;
     682        case TTColor::RED:     color = OSDTypeTeletext::kColorRed;     break;
     683        case TTColor::GREEN:   color = OSDTypeTeletext::kColorGreen;   break;
     684        case TTColor::YELLOW:  color = OSDTypeTeletext::kColorYellow;  break;
     685        case TTColor::BLUE:    color = OSDTypeTeletext::kColorBlue;    break;
     686        case TTColor::MAGENTA: color = OSDTypeTeletext::kColorMagenta; break;
     687        case TTColor::CYAN:    color = OSDTypeTeletext::kColorCyan;    break;
     688        case TTColor::WHITE:   color = OSDTypeTeletext::kColorWhite;   break;
     689    }
     690
     691    return color;
     692}
     693
     694/** \fn OSDTypeTeletext::SetForegroundColor(int) const
    681695 *  \brief Set the font color to the given color.
    682696 *
    683697 *   NOTE: TTColor::TRANSPARENT does not do anything!
    684698 *  \sa TTColor
    685699 */
    686 void OSDTypeTeletext::SetForegroundColor(int color)
     700void OSDTypeTeletext::SetForegroundColor(int ttcolor) const
    687701{
    688     switch (color & ~TTColor::TRANSPARENT)
    689     {
    690         case TTColor::BLACK:   m_font->setColor(kColorBlack);   break;
    691         case TTColor::RED:     m_font->setColor(kColorRed);     break;
    692         case TTColor::GREEN:   m_font->setColor(kColorGreen);   break;
    693         case TTColor::YELLOW:  m_font->setColor(kColorYellow);  break;
    694         case TTColor::BLUE:    m_font->setColor(kColorBlue);    break;
    695         case TTColor::MAGENTA: m_font->setColor(kColorMagenta); break;
    696         case TTColor::CYAN:    m_font->setColor(kColorCyan);    break;
    697         case TTColor::WHITE:   m_font->setColor(kColorWhite);   break;
    698     }
    699 
     702    m_font->setColor(color_tt2qt(ttcolor));
    700703    m_font->setShadow(0,0);
    701704    m_font->setOutline(0);
    702705}
    703706
    704 /** \fn OSDTypeTeletext:SetBackgroundColor(int)
     707/** \fn OSDTypeTeletext:SetBackgroundColor(int) const
    705708 *  \brief Set the background color to the given color
    706709 *
    707710 *  \sa TTColor
    708711 */
    709 void OSDTypeTeletext::SetBackgroundColor(int ttcolor)
     712void OSDTypeTeletext::SetBackgroundColor(int ttcolor) const
    710713{
    711     QColor color;
     714    const QColor color = color_tt2qt(ttcolor);
    712715
    713     switch (ttcolor & ~TTColor::TRANSPARENT)
    714     {
    715         case TTColor::BLACK:   color = kColorBlack;   break;
    716         case TTColor::RED:     color = kColorRed;     break;
    717         case TTColor::GREEN:   color = kColorGreen;   break;
    718         case TTColor::YELLOW:  color = kColorYellow;  break;
    719         case TTColor::BLUE:    color = kColorBlue;    break;
    720         case TTColor::MAGENTA: color = kColorMagenta; break;
    721         case TTColor::CYAN:    color = kColorCyan;    break;
    722         case TTColor::WHITE:   color = kColorWhite;   break;
    723     }
     716    const int r = color.red();
     717    const int g = color.green();
     718    const int b = color.blue();
    724719
    725     int r = color.red();
    726     int g = color.green();
    727     int b = color.blue();
     720    const float y = (0.299*r) + (0.587*g) + (0.114*b);
     721    const float u = (0.564*(b - y)); // = -0.169R-0.331G+0.500B
     722    const float v = (0.713*(r - y)); // = 0.500R-0.419G-0.081B
    728723
    729     float y = (0.299*r) + (0.587*g) + (0.114*b);
    730     float u = (0.564*(b - y)); // = -0.169R-0.331G+0.500B
    731     float v = (0.713*(r - y)); // = 0.500R-0.419G-0.081B
    732 
    733724    m_bgcolor_y = (uint8_t)(y);
    734725    m_bgcolor_u = (uint8_t)(127 + u);
    735726    m_bgcolor_v = (uint8_t)(127 + v);
     727
    736728    m_bgcolor_a = (ttcolor & TTColor::TRANSPARENT) ? 0x00 : 0xff;
    737729}
    738730
    739 /** \fn OSDTypeTeletext::DrawBackground(int, int)
    740  *  \brief draws background in the color set in setBackgroundColor
     731/** \fn OSDTypeTeletext::DrawBackground(OSDSurface*,int,int) const
     732 *  \brief draws background in the color set in SetBackgroundColor().
    741733 *
    742734 *  \param x X position (40 cols)
    743735 *  \param y Y position (25 rows)
    744736 */
    745 void OSDTypeTeletext::DrawBackground(int x, int y)
     737void OSDTypeTeletext::DrawBackground(OSDSurface *surface, int x, int y) const
    746738{
    747739    x *= m_tt_colspace;
    748740    x += m_displayrect.left();
     
    750742    y *= m_tt_rowspace;
    751743    y += m_displayrect.top();
    752744
    753     DrawRect(x, y, m_tt_colspace, m_tt_rowspace);
     745    DrawRect(surface, QRect(x, y, m_tt_colspace, m_tt_rowspace));
    754746}
    755747
    756 /** \fn OSDTypeteletext::drawRect(int, int, int, int)
    757  *  \brief draws a Rectangle at position x and y (width dx, height dy)
    758  *         with the color set in setBackgroundColor
    759  *
    760  *  \param x X position at the screen
    761  *  \param y Y position at the screen
    762  *  \param dx width
    763  *  \param dy height
     748/** \fn OSDTypeteletext::DrawRect(OSDSurface*,const QRect) const
     749 *  \brief Draws a Rectangle with the color set in SetBackgroundColor().
    764750 */
    765 void OSDTypeTeletext::DrawRect(int x, int y, int dx, int dy)
     751void OSDTypeTeletext::DrawRect(OSDSurface *surface, const QRect rect) const
    766752{
    767     QRect all(x, y, dx, dy);
    768     m_surface->AddRect(all);
     753    QRect tmp = rect;
     754    surface->AddRect(tmp);
    769755
    770     int luma_stride = m_surface->width;
    771     int chroma_stride = m_surface->width >> 1;
    772     int ye = y + dy;
     756    const int luma_stride   = surface->width;
     757    const int chroma_stride = surface->width >> 1;
     758    const int y  = rect.top(),    x  = rect.left();
     759    const int dy = rect.height(), dx = rect.width();
     760    const int ye = y + dy;
    773761
    774     unsigned char *buf_y = m_surface->y + (luma_stride * y) + x;
    775     unsigned char *buf_u = m_surface->u + (chroma_stride * (y>>1)) + (x>>1);
    776     unsigned char *buf_v = m_surface->v + (chroma_stride * (y>>1)) + (x>>1);
    777     unsigned char *buf_a = m_surface->alpha + (luma_stride * y) + x;
     762    unsigned char *buf_y = surface->y + (luma_stride * y) + x;
     763    unsigned char *buf_u = surface->u + (chroma_stride * (y>>1)) + (x>>1);
     764    unsigned char *buf_v = surface->v + (chroma_stride * (y>>1)) + (x>>1);
     765    unsigned char *buf_a = surface->alpha + (luma_stride * y) + x;
    778766
    779     for (; y<ye; ++y)
     767    for (int j = y; j < ye; j++)
    780768    {
    781         for (int i=0; i<dx; ++i)
     769        for (int i = 0; i < dx; i++)
    782770        {
    783771            buf_y[i] = m_bgcolor_y;
    784772            buf_a[i] = m_bgcolor_a;
    785773        }
    786774
    787         if ((y & 1) == 0)
     775        if (!(y & 1))
    788776        {
    789             for (int i=0; i<dx; ++i)
     777            for (int k = 0; k < dx; k++)
    790778            {
    791                 buf_u[i>>1] = m_bgcolor_u;
    792                 buf_v[i>>1] = m_bgcolor_v;
     779                buf_u[k>>1] = m_bgcolor_u;
     780                buf_v[k>>1] = m_bgcolor_v;
    793781            }
    794782
    795783            buf_u += chroma_stride;
     
    801789    }
    802790}
    803791
    804 /** \fn OSDTypeTeletext::DrawCharacter(int, int, QChar, int)
     792/** \fn OSDTypeTeletext::DrawCharacter(OSDSurface*,int,int,QChar,int) const
    805793 *  \brief Draws a character at posistion x, y
    806794 *
    807795 *  \param x X position (40 cols)
     
    809797 *  \param ch Character
    810798 *  \param doubleheight if different to 0, draw doubleheighted character
    811799 */
    812 void OSDTypeTeletext::DrawCharacter(int x, int y, QChar ch, int doubleheight)
     800void OSDTypeTeletext::DrawCharacter(OSDSurface *surface,
     801                                    int x, int y,
     802                                    QChar ch, int doubleheight) const
    813803{
    814804    if (!m_font)
    815805        return;
     
    822812    y *= m_tt_rowspace;
    823813    y += m_displayrect.top();
    824814
    825     m_font->DrawString(m_surface, x, y, line,
    826                        m_surface->width, m_surface->height,
     815    m_font->DrawString(surface, x, y, line,
     816                       surface->width, surface->height,
    827817                       255, doubleheight);
    828818}
    829819
     
    833823 *  \param x X position (40 cols)
    834824 *  \param y Y position (25 rows)
    835825 *  \param code Code
    836  *  \param doubleheight if different to 0, draw doubleheighted mosaic)
     826 *  \param doubleheight if different to 0, draw doubleheighted mosaic) const
    837827 */
    838 void OSDTypeTeletext::DrawMosaic(int x, int y, int code, int doubleheight)
     828void OSDTypeTeletext::DrawMosaic(OSDSurface *surface, int x, int y,
     829                                 int code, int doubleheight) const
    839830{
    840     (void)x;
    841     (void)y;
    842     (void)code;
    843 
    844831    x *= m_tt_colspace;
    845832    x += m_displayrect.left();
    846833
    847834    y *= m_tt_rowspace;
    848835    y += m_displayrect.top();
    849836
    850     int dx = (int)round(m_tt_colspace / 2)+1;
    851     int dy = (int)round(m_tt_rowspace / 3)+1;
     837    int dx = (int)round(m_tt_colspace / 2) + 1;
     838    int dy = (int)round(m_tt_rowspace / 3) + 1;
     839    dy = (doubleheight) ? (2 * dy) : dy;
    852840
    853     if (doubleheight != 0)
    854         dy *= 2;
     841    if (code & 0x10)
     842        DrawRect(surface, QRect(x,      y + 2*dy, dx, dy));
     843    if (code & 0x40)
     844        DrawRect(surface, QRect(x + dx, y + 2*dy, dx, dy));
     845    if (code & 0x01)
     846        DrawRect(surface, QRect(x,      y,        dx, dy));
     847    if (code & 0x02)
     848        DrawRect(surface, QRect(x + dx, y,        dx, dy));
     849    if (code & 0x04)
     850        DrawRect(surface, QRect(x,      y + dy,   dx, dy));
     851    if (code & 0x08)
     852        DrawRect(surface, QRect(x + dx, y + dy,   dx, dy));
     853}
    855854
    856     if (code & 0x10) DrawRect(x,      y + 2*dy, dx, dy);
    857     if (code & 0x40) DrawRect(x + dx, y + 2*dy, dx, dy);
    858     if (code & 0x01) DrawRect(x,      y,        dx, dy);
    859     if (code & 0x02) DrawRect(x + dx, y,        dx, dy);
    860     if (code & 0x04) DrawRect(x,      y + dy,   dx, dy);
    861     if (code & 0x08) DrawRect(x + dx, y + dy,   dx, dy);
     855/** \fn cvt_char(char,int)
     856 *  \brief converts the given character to the given language
     857 */
     858static char cvt_char(char ch, int lang)
     859{
     860    int c = 0;
     861    for (int j = 0; j < 14; j++)
     862    {
     863        c = ch & 0x7F;
     864        if (c == lang_chars[0][j])
     865            ch = lang_chars[lang + 1][j];
     866    }
     867    return ch;
    862868}
    863869
    864 void OSDTypeTeletext::DrawLine(const unsigned char* page, uint row, int lang)
     870void OSDTypeTeletext::DrawLine(OSDSurface *surface, const unsigned char *page,
     871                               uint row, int lang) const
    865872{
    866873    bool mosaic;
    867874    bool conceal;
     
    903910    if (row == 1)
    904911    {
    905912        for (uint x = 0; x < 8; x++)
    906             DrawBackground(x, 1);
     913            DrawBackground(surface, x, 1);
    907914    }
    908915
    909916    for (uint x = (row == 1 ? 8 : 0); x < (uint)kTeletextColumns; ++x)
     
    10061013            if (m_transparent)
    10071014                SetBackgroundColor(TTColor::TRANSPARENT);
    10081015
    1009             DrawBackground(x, row);
     1016            DrawBackground(surface, x, row);
    10101017            if (doubleheight && row < (uint)kTeletextRows)
    1011                 DrawBackground(x, row + 1);
     1018                DrawBackground(surface, x, row + 1);
    10121019
    10131020            if ((mosaic) && (ch < 0x40 || ch > 0x5F))
    10141021            {
    10151022                SetBackgroundColor(newfgcolor);
    1016                 DrawMosaic(x, row, ch, doubleheight);
     1023                DrawMosaic(surface, x, row, ch, doubleheight);
    10171024            }
    1018             else 
     1025            else
    10191026            {
    1020                 char c2 = CharConversion(ch, lang);
     1027                char c2 = cvt_char(ch, lang);
    10211028                bool dh = doubleheight && row < (uint)kTeletextRows;
    10221029                int  rw = (dh) ? row + 1 : row;
    1023                 DrawCharacter(x, rw, c2, dh);
     1030                DrawCharacter(surface, x, rw, c2, dh);
    10241031            }
    10251032        }
    10261033    }
    10271034}
    10281035
    1029 void OSDTypeTeletext::DrawHeader(const unsigned char* page, int lang)
     1036void OSDTypeTeletext::DrawHeader(OSDSurface *surface,
     1037                                 const unsigned char* page, int lang) const
    10301038{
    10311039    if (!m_displaying)
    10321040        return;
    10331041
    10341042    if (page != NULL)
    1035         DrawLine(page, 1, lang);
    1036    
    1037     StatusUpdated();
     1043        DrawLine(surface, page, 1, lang);
     1044
     1045    DrawStatus(surface);
    10381046}
    10391047
    1040 void OSDTypeTeletext::DrawPage(void)
     1048void OSDTypeTeletext::DrawPage(OSDSurface *surface) const
    10411049{
    10421050    if (!m_displaying)
    10431051        return;
    10441052
    1045     TeletextSubPage *ttpage = FindSubPage(m_curpage, m_cursubpage);
     1053    const TeletextSubPage *ttpage = FindSubPagec(m_curpage, m_cursubpage);
    10461054
    1047     if (ttpage == NULL)
     1055    if (!ttpage)
    10481056    {
    1049         DrawHeader(NULL,0);
     1057        DrawHeader(surface, NULL, 0);                               // no page selected so show the header and a list of available pages
    10501058        return;
    10511059    }
    10521060
    10531061    m_cursubpage = ttpage->subpagenum;
    10541062
    10551063    int a = 0;
    1056     if ((ttpage->subtitle) || (ttpage->flags &
    1057             (TP_SUPPRESS_HEADER + TP_NEWSFLASH + TP_SUBTITLE)))
     1064    if ((ttpage->subtitle) ||
     1065        (ttpage->flags & (TP_SUPPRESS_HEADER | TP_NEWSFLASH | TP_SUBTITLE)))
    10581066    {
    1059         a = 1;
     1067        a = 1;                                                      // when showing subtitles we don't want to
     1068                                                                    // see the teletext header line, so skip it when displaying
    10601069        m_curpage_showheader = false;
    10611070        m_curpage_issubtitle = true;
    10621071    }
     
    10641073    {
    10651074        m_curpage_issubtitle = false;
    10661075        m_curpage_showheader = true;
    1067         DrawHeader(ttpage->data[0], ttpage->lang);
     1076//        DrawHeader(surface, ttpage->data[0], ttpage->lang);
     1077//        if (m_header_changed == true)
     1078        {
     1079            DrawHeader(surface, m_header, ttpage->lang);
     1080            m_header_changed = false;
     1081        }
    10681082    }
    10691083
    1070     for (int y = kTeletextRows-a; y >= 2; y--)
    1071         DrawLine(ttpage->data[y-1], y, ttpage->lang);
     1084//    if (m_page_changed == true)
     1085    {
     1086        m_page_changed = false;
     1087        for (int y = kTeletextRows - a; y >= 2; y--)
     1088            DrawLine(surface, ttpage->data[y-1], y, ttpage->lang);
     1089    }
    10721090}
    10731091
    10741092void OSDTypeTeletext::Reinit(float wmult, float hmult)
     
    10781096    m_tt_rowspace = m_displayrect.height() / kTeletextRows;
    10791097}
    10801098
    1081 void OSDTypeTeletext::Draw(OSDSurface *surface, int fade, int maxfade,
    1082                            int xoff, int yoff)
     1099void OSDTypeTeletext::Draw(OSDSurface *surface,
     1100                           int /*fade*/, int /*maxfade*/,
     1101                           int /*xoff*/, int /*yoff*/)
    10831102{
    1084     (void)surface;
    1085     (void)fade;
    1086     (void)maxfade;
    1087     (void)xoff;
    1088     (void)yoff;
    1089 
    1090     m_surface = surface;
    1091     DrawPage();
     1103    DrawPage(surface);
    10921104}
    10931105
    1094 void OSDTypeTeletext::StatusUpdated(void)
     1106void OSDTypeTeletext::DrawStatus(OSDSurface *surface) const
    10951107{
    10961108    SetForegroundColor(TTColor::WHITE);
    10971109    SetBackgroundColor(TTColor::BLACK);
    10981110
    10991111    if (!m_transparent)
    11001112        for (int i = 0; i < 40; ++i)
    1101             DrawBackground(i, 0);
     1113            DrawBackground(surface, i, 0);
    11021114
    1103     DrawCharacter(1, 0, 'P', 0);
    1104     DrawCharacter(2, 0, m_pageinput[0], 0);
    1105     DrawCharacter(3, 0, m_pageinput[1], 0);
    1106     DrawCharacter(4, 0, m_pageinput[2], 0);
     1115    DrawCharacter(surface, 1, 0, 'P', 0);
     1116    DrawCharacter(surface, 2, 0, m_pageinput[0], 0);
     1117    DrawCharacter(surface, 3, 0, m_pageinput[1], 0);
     1118    DrawCharacter(surface, 4, 0, m_pageinput[2], 0);
    11071119
    1108     TeletextSubPage *ttpage = FindSubPage(m_curpage, m_cursubpage);
     1120    const TeletextSubPage *ttpage = FindSubPagec(m_curpage, m_cursubpage);
    11091121
    11101122    if (!ttpage)
    11111123    {
     
    11141126
    11151127        if (!m_transparent)
    11161128            for (int i = 7; i < 40; i++)
    1117                 DrawBackground(i, 0);
     1129                DrawBackground(surface, i, 0);
    11181130
    11191131        char *str = "Page Not Available";
    11201132        for (unsigned int i = 0; i < strlen(str); ++i)
    1121             DrawCharacter(i+10, 0, str[i], 0);
     1133            DrawCharacter(surface, i+10, 0, str[i], 0);
    11221134
    11231135        return;
    11241136    }
     
    11261138    // get list of available sub pages
    11271139    QString str = "";
    11281140    int count = 1, selected = 0;
    1129     TeletextPage *page = FindPage(m_curpage);
     1141    const TeletextPage *page = FindPagec(m_curpage);
    11301142    if (page)
    11311143    {
    1132         std::map<int, TeletextSubPage>::iterator subpageIter;
     1144        std::map<int, TeletextSubPage>::const_iterator subpageIter;
    11331145        subpageIter = page->subpages.begin();
    11341146        while (subpageIter != page->subpages.end())
    11351147        {
    1136             TeletextSubPage *subpage = &subpageIter->second;
     1148            const TeletextSubPage *subpage = &subpageIter->second;
    11371149
    11381150            if (subpage->subpagenum == m_cursubpage)
    11391151            {
     
    11801192        else
    11811193            SetBackgroundColor(TTColor::BLACK);
    11821194
    1183         DrawBackground(x * 3 + 7, 0);
     1195        DrawBackground(surface, x * 3 + 7, 0);
    11841196
    11851197        if (str[x * 3] == '*')
    11861198        {
     
    11881200            SetBackgroundColor(TTColor::RED);
    11891201        }
    11901202
    1191         DrawBackground(x * 3 + 8, 0);
    1192         DrawBackground(x * 3 + 9, 0);
     1203        DrawBackground(surface, x * 3 + 8, 0);
     1204        DrawBackground(surface, x * 3 + 9, 0);
    11931205
    1194         DrawCharacter(x * 3 + 7, 0, str[x * 3], 0);
    1195         DrawCharacter(x * 3 + 8, 0, str[x * 3 + 1], 0);
    1196         DrawCharacter(x * 3 + 9, 0, str[x * 3 + 2], 0);
     1206        DrawCharacter(surface, x * 3 + 7, 0, str[x * 3], 0);
     1207        DrawCharacter(surface, x * 3 + 8, 0, str[x * 3 + 1], 0);
     1208        DrawCharacter(surface, x * 3 + 9, 0, str[x * 3 + 2], 0);
    11971209    }
    11981210}
    11991211
  • libs/libmythtv/osd.cpp

     
    269269    }
    270270
    271271    OSDTypeTeletext *ttpage = new OSDTypeTeletext(
    272         name, font, area, wmult, hmult);
     272        name, font, area, wmult, hmult, this);
    273273 
     274    container->SetPriority(30);                         // set draw priority to 30.
    274275    container->AddType(ttpage);
    275276    return true;
    276277}   
    277278
     279void OSD::UpdateTeletext(void)
     280{
     281    QMutexLocker locker(&osdlock);
     282
     283    OSDSet *container = GetSet("teletext");
     284    if (!container)
     285        return;
     286
     287    OSDType *type = container->GetType("teletext");
     288    OSDTypeTeletext *ttpage = dynamic_cast<OSDTypeTeletext*>(type);
     289    if (ttpage)
     290    {
     291        container->Display(1);
     292        m_setsvisible = true;
     293        changed = true;
     294    }
     295}
     296
    278297void OSD::SetTextSubtitles(const QStringList &lines)
    279298{
    280299    const uint SUBTITLE_FONT_SIZE     = 18;