Ticket #6004: osd_rtl.patch

File osd_rtl.patch, 12.0 KB (added by Tony Arie Kolev <kolevtony@…>, 12 years ago)

patch file to applay to mythtv-0-21-fixes (rev. 192.89)

  • libs/libmythtv/libmythtv.pro

    ===== OSD RTL Languages fix by Tony Arie Kolev
    ===== store this file (osd_rtl.patch) in mythtv-0-21-fixes/mythtv
    ===== patch -p0 < osd_rtl.patch
    
     
    243243
    244244    # On screen display (video output overlay)
    245245    using_fribidi:DEFINES += USING_FRIBIDI
    246     HEADERS += osd.h                    osdtypes.h
     246    HEADERS += osd.h                    osdtypes.h rtl.h
    247247    HEADERS += osdsurface.h             osdlistbtntype.h
    248248    HEADERS += osdimagecache.h          osdtypeteletext.h
    249249    HEADERS += udpnotify.h
    250     SOURCES += osd.cpp                  osdtypes.cpp
     250    SOURCES += osd.cpp                  osdtypes.cpp rtl.cpp
    251251    SOURCES += osdsurface.cpp           osdlistbtntype.cpp
    252252    SOURCES += osdimagecache.cpp        osdtypeteletext.cpp
    253253    SOURCES += udpnotify.cpp
  • libs/libmythtv/osdtypes.h

     
    1212#include <qcolor.h>
    1313#include "cc708window.h"
    1414#include "osdimagecache.h"
     15#include "rtl.h"
    1516
    1617using namespace std;
    1718
     
    238239    void SetButton(bool is_button)      { m_button = is_button;     }
    239240    void SetEntryNum(int entrynum)      { m_entrynum = entrynum;    }
    240241
    241     QString ConvertFromRtoL(const QString &text) const;
    242 
    243     static QString BasicConvertFromRtoL(const QString &text);
    244242
    245243  protected:
    246244    ~OSDTypeText();
     
    292290    mutable uint    m_draw_info_len;
    293291    mutable vector<DrawInfo> m_draw_info;
    294292
    295     mutable QMutex      fribidi_lock;
    296     mutable QTextCodec *codeci;
     293    RTL *rtl;
    297294};
    298295   
    299296class OSDTypeImage : public OSDType
  • libs/libmythtv/osdtypes.cpp

     
    1717#include "mythcontext.h"
    1818#include "mythdialogs.h"
    1919
    20 #ifdef USING_FRIBIDI
    21     #include "fribidi/fribidi.h"
    22     #include <qtextcodec.h>
    23 #endif // USING_FRIBIDI
    2420
    2521/// Shared OSD image cache
    2622OSDImageCache OSDTypeImage::c_cache;
     
    707703    m_linespacing(1.5f),
    708704
    709705    m_draw_info_str(""),
    710     m_draw_info_len(0),
    711 
    712     codeci(NULL)
     706    m_draw_info_len(0)
    713707{
     708  rtl=new RTL();
    714709}
    715710
    716711OSDTypeText::OSDTypeText(const OSDTypeText &other) :
     
    745740    m_linespacing(1.5f),
    746741
    747742    m_draw_info_str(""),
    748     m_draw_info_len(0),
     743    m_draw_info_len(0)
    749744
    750     codeci(NULL)
    751745{
    752746    QMutexLocker locker(&other.m_lock);
    753747
     
    779773    m_scrollinit = other.m_scrollinit;
    780774
    781775    m_linespacing = other.m_linespacing;
     776    rtl=new RTL();
    782777}
    783778
    784779OSDTypeText::~OSDTypeText()
     
    791786    m_altfont = font;
    792787}
    793788
    794 QString OSDTypeText::BasicConvertFromRtoL(const QString &text)
    795 {
    796     QStringList rtl_string_composer;
    797     bool handle_rtl = false;
    798     QChar prev_char;
    799 
    800     // Handling Right-to-Left languages.
    801     // Left-to-Right languages are not affected.
    802     for (int i = (int)text.length() - 1; i >= 0; i--)
    803     {
    804         QChar::Direction text_dir = text[i].direction();
    805         if (text_dir != QChar::DirR &&
    806             text_dir != QChar::DirRLE &&
    807             text_dir != QChar::DirRLO)
    808         {
    809             if (handle_rtl || rtl_string_composer.empty())
    810                 rtl_string_composer.append(QString());
    811 
    812             if (text[i].isSpace() && !prev_char.isNull()
    813                     && prev_char.isDigit() && handle_rtl)
    814                 rtl_string_composer.back().append(text[i]);
    815             else
    816                 rtl_string_composer.back().prepend(text[i]);
    817 
    818             prev_char = text[i];
    819 
    820             handle_rtl = false;
    821         }
    822         else
    823         {
    824             if (!handle_rtl)
    825             {
    826                 rtl_string_composer.append(QString());
    827                 handle_rtl = true;
    828                 prev_char = QChar();
    829             }
    830             rtl_string_composer.back().append(text[i]);
    831         }
    832     }
    833 
    834     QString output = rtl_string_composer.join("");
    835 
    836     return QDeepCopy<QString>(output);
    837 }
    838 
    839 QString OSDTypeText::ConvertFromRtoL(const QString &text) const
    840 {
    841     QString output = BasicConvertFromRtoL(text);
    842 
    843 #ifdef USING_FRIBIDI
    844     QMutexLocker locker(&fribidi_lock);
    845     if (!codeci)
    846         codeci = QTextCodec::codecForName("utf8");
    847 
    848     if (!codeci)
    849         return output;
    850 
    851     QCString temp = codeci->fromUnicode(output);
    852 
    853     FriBidiCharType base;
    854     size_t len;
    855 
    856     bool fribidi_flip_commas = true;
    857     base = (fribidi_flip_commas) ? FRIBIDI_TYPE_ON : FRIBIDI_TYPE_L;
    858 
    859     const char *ip = temp;
    860     FriBidiChar logical[strlen(ip) + 1], visual[strlen(ip) + 1];
    861 
    862     int char_set_num = fribidi_parse_charset("UTF-8");
    863 
    864     len = fribidi_charset_to_unicode(
    865         (FriBidiCharSet) char_set_num, ip, strlen(ip), logical);
    866 
    867     bool log2vis = fribidi_log2vis(
    868         logical, len, &base, visual, NULL, NULL, NULL); // output
    869 
    870     if (log2vis)
    871         len = fribidi_remove_bidi_marks(visual, len, NULL, NULL, NULL);
    872  
    873     output = "";
    874     for (size_t i = 0; i < len ; i++)
    875         output += QChar(visual[i]);
    876 #endif // USING_FRIBIDI
    877 
    878     return output;
    879 }
    880789
    881790void OSDTypeText::SetText(const QString &text)
    882791{
    883792    QMutexLocker locker(&m_lock);
    884     m_message    = ConvertFromRtoL(text);
     793    m_message    = text;
    885794    m_cursorpos  = m_message.length();
    886795    m_scrollinit = false;
    887796}
     
    895804void OSDTypeText::SetDefaultText(const QString &text)
    896805{
    897806    QMutexLocker locker(&m_lock);
    898     m_message     = ConvertFromRtoL(text);
     807    m_message     = text;
    899808    m_default_msg = QDeepCopy<QString>(m_message);
    900809    m_scrollinit  = false;
    901810}
     
    12191128{
    12201129    QMutexLocker locker(&m_lock);
    12211130
     1131    bool isRTL=false;
     1132    QString msg    = rtl->ConvertFromRtoL(text,&isRTL);
     1133    if (isRTL) m_right=true;
     1134
    12221135    if (m_centered || m_right)
    12231136    {
    12241137        int textlength = 0;
     
    12441157    if ((m_usingalt || m_selected) && m_altfont)
    12451158        font = m_altfont;
    12461159
    1247     font->DrawString(surface, rect.left(), rect.top(), text,
     1160    font->DrawString(surface, rect.left(), rect.top(), msg,
    12481161                     rect.right(), rect.bottom(), alphamod, doubl);
    12491162
    12501163    // draw cursor
  • libs/libmythtv/osdlistbtntype.h

     
    3737#include "osdtypes.h"
    3838#include "ttfont.h"
    3939#include "generictree.h"
     40#include "rtl.h"
    4041
    4142class OSDListBtnType;
    4243class OSDListBtnTypeItem;
     
    313314    QRect           m_arrowRect;
    314315    QRect           m_pixmapRect;
    315316    QRect           m_textRect;
     317    RTL            *rtl;
    316318};
    317319
    318320
  • libs/libmythtv/osdlistbtntype.cpp

     
    767767    tw -= (m_showArrow) ? m_arrowRect.width()  + margin : 0;
    768768    tw -= (m_pixmap)    ? m_pixmapRect.width() + margin : 0;
    769769    m_textRect = QRect(tx, 0, tw, height);
     770    rtl=new RTL();
    770771
    771772    m_parent->InsertItem(this);
    772773}
     
    828829    QRect tr(m_textRect);
    829830    tr.moveBy(x, y);
    830831    tr.moveBy(0, font->Size() / 4);
    831     font->DrawString(surface, tr.x(), tr.y(), m_text, tr.right(), tr.bottom());
     832    bool isRTL=false;
     833    QString m_message = rtl->ConvertFromRtoL(m_text,&isRTL);
     834    if (isRTL)
     835    {
     836        int textlength = 0;
     837        font->CalcWidth(m_text, &textlength);
     838        int xoffset = tr.width() - textlength;
     839        if (xoffset > 0)
     840            tr.moveBy(xoffset, 0);
     841    }
     842    font->DrawString(surface, tr.x(), tr.y(), m_message, tr.right(), tr.bottom());
    832843}
  • libs/libmythtv/rtl.h

     
     1#ifndef RTL_H_
     2#define RTL_H_
     3class RTL {
     4  private:
     5    mutable QMutex      fribidi_lock;
     6    mutable QTextCodec *codeci;
     7  public:
     8    RTL();
     9   ~RTL();
     10    QString ConvertFromRtoL(const QString &text,bool *isRTL) const;
     11    static QString BasicConvertFromRtoL(const QString &text,bool *isRTL);
     12};
     13#endif
  • libs/libmythtv/rtl.cpp

     
     1/*
     2 * Right To Left Languages manipulation for OSD
     3 * Tony Arie Kolev 14-Dec-2008
     4 * RTL conversion taken from previously implemented patches:
     5 * release 0.21-192.89
     6 * #4885: patch: multi line BiDi support in OSD
     7 * (some corrections made to fix double conversion when fribidi-devel is installed)
     8 * and a new RTL class introduced to integrate unsuccessful attempts
     9 * to make RTL conversion in osdtypes.cpp and later in ttfont.cpp
     10 * now it may be used everywhere when needed
     11 *
     12 */
     13#include <qimage.h>
     14#include <qmap.h>
     15#include <qregexp.h>
     16#include <qdeepcopy.h>
     17
     18#include <iostream>
     19#include <algorithm>
     20using namespace std;
     21
     22#include "yuv2rgb.h"
     23#include "osdtypes.h"
     24#include "ttfont.h"
     25#include "osdsurface.h"
     26#include "osdlistbtntype.h"
     27#include "osdtypeteletext.h"
     28
     29#include "mythcontext.h"
     30#include "mythdialogs.h"
     31
     32#ifdef USING_FRIBIDI
     33    #include "fribidi/fribidi.h"
     34    #include <qtextcodec.h>
     35#endif // USING_FRIBIDI
     36
     37#include "rtl.h"
     38
     39RTL::RTL() :     codeci(NULL)
     40{
     41}
     42RTL::~RTL() {
     43}
     44 
     45QString RTL::BasicConvertFromRtoL(const QString &text,bool *isRTL)
     46{
     47    QStringList rtl_string_composer;
     48    bool handle_rtl = false;
     49    QChar prev_char;
     50
     51    // Handling Right-to-Left languages.
     52    // Left-to-Right languages are not affected.
     53    for (int i = (int)text.length() - 1; i >= 0; i--)
     54    {
     55        QChar::Direction text_dir = text[i].direction();
     56        if (text_dir != QChar::DirR &&
     57            text_dir != QChar::DirRLE &&
     58            text_dir != QChar::DirRLO)
     59        {
     60            if (handle_rtl || rtl_string_composer.empty())
     61                rtl_string_composer.append(QString());
     62
     63            if (text[i].isSpace() && !prev_char.isNull()
     64                    && prev_char.isDigit() && handle_rtl)
     65                rtl_string_composer.back().append(text[i]);
     66            else
     67                rtl_string_composer.back().prepend(text[i]);
     68
     69            prev_char = text[i];
     70
     71            handle_rtl = false;
     72        }
     73        else
     74        {
     75            if (!handle_rtl)
     76            {
     77                rtl_string_composer.append(QString());
     78                handle_rtl = true;
     79                prev_char = QChar();
     80            }
     81            rtl_string_composer.back().append(text[i]);
     82            *isRTL=true;
     83        }
     84    }
     85
     86    QString output = rtl_string_composer.join("");
     87
     88    return QDeepCopy<QString>(output);
     89}
     90
     91QString RTL::ConvertFromRtoL(const QString &text,bool *isRTL) const
     92{
     93    *isRTL=false;
     94#ifndef USING_FRIBIDI
     95    QString output = BasicConvertFromRtoL(text,isRTL);
     96#endif
     97#ifdef USING_FRIBIDI
     98    QString output = text;
     99    QMutexLocker locker(&fribidi_lock);
     100    if (!codeci)
     101        codeci = QTextCodec::codecForName("utf8");
     102
     103    if (!codeci)
     104        return output;
     105
     106    QCString temp = codeci->fromUnicode(output);
     107
     108    FriBidiCharType base;
     109    size_t len;
     110   
     111
     112    bool fribidi_flip_commas = true;
     113    base = (fribidi_flip_commas) ? FRIBIDI_TYPE_ON : FRIBIDI_TYPE_L;
     114
     115    const char *ip = temp;
     116    FriBidiChar logical[strlen(ip) + 1], visual[strlen(ip) + 1];
     117
     118    int char_set_num = fribidi_parse_charset("UTF-8");
     119
     120    len = fribidi_charset_to_unicode(
     121        (FriBidiCharSet) char_set_num, ip, strlen(ip), logical);
     122
     123    FriBidiLevel embedding_level_list[len];
     124    FriBidiStrIndex position_L_to_V_list[len];
     125    FriBidiStrIndex position_V_to_L_list[len];
     126
     127    bool log2vis = fribidi_log2vis(
     128        logical, len, &base, visual, position_L_to_V_list, position_V_to_L_list, embedding_level_list); // output
     129
     130    if (log2vis) {
     131        len = fribidi_remove_bidi_marks(visual, len, NULL, NULL, NULL);
     132        for (int i=0;i<(int)len;i++) {
     133          if (embedding_level_list[i]%2==1) {
     134            *isRTL=true;
     135            break;
     136          }
     137        }
     138    }
     139    output = "";
     140    for (size_t i = 0; i < len ; i++)
     141        output += QChar(visual[i]);
     142#endif // USING_FRIBIDI
     143
     144    return output;
     145}
     146