Ticket #4885: osd_rtl.patch

File osd_rtl.patch, 11.9 KB (added by Ran Nachmany, 12 years ago)

This patch is built on top of Ido's bidi fix. It fixes the OSD and menu behavior, as well as some right alignment. The results of this patch can be seen in previously attached screenshots.

  • mythtv/libs/libmythtv/osdlistbtntype.cpp

     
    6565    m_hmult        = (hmult == 0.0f) ? 1.0f : hmult;
    6666    m_unbiasedarea = unbias(area,      wmult, hmult);
    6767    m_unbiasedsize = unbias(levelsize, wmult, hmult);
     68    if (gContext->GetLanguage()=="he")
     69        m_isRtl = true;
     70    else
     71        m_isRtl = false;
    6872}
    6973
    7074OSDListTreeType::~OSDListTreeType()
     
    7478        delete *it;   
    7579}
    7680
     81void OSDListTreeType::SetRtl (bool isRtl)
     82{
     83/***
     84        m_isRtl = isRtl;
     85if (gContext->GetLanguage()=="he")
     86        m_isRtl = true;
     87    else
     88        m_isRtl = false;
     89***/
     90}
     91
    7792void OSDListTreeType::Reinit(float wmult, float hmult)
    7893{
    7994    m_wmult     = (wmult == 0.0f) ? 1.0f : wmult;
     
    140155    {
    141156        QString levelname = QString("level%1").arg(i + 1);
    142157        QRect curlevelarea = m_levelsize;
    143         curlevelarea.moveBy(m_totalarea.x(), m_totalarea.y());
    144         curlevelarea.moveBy((m_levelsize.width() + m_levelspacing) * i, 0);
    145 
     158       
     159// if we are left to right
     160        if (false == m_isRtl)
     161        {
     162                curlevelarea.moveBy(m_totalarea.x(), m_totalarea.y()); 
     163                curlevelarea.moveBy((m_levelsize.width() + m_levelspacing) * i, 0);
     164        }
     165       
     166// if we are right to left
     167        else
     168        {
     169                curlevelarea.moveBy(m_totalarea.width(), m_totalarea.y());
     170                curlevelarea.moveBy( ((-1 - i) * m_levelsize.width()) - m_levelspacing,0);
     171        }
    146172        OSDListBtnType *newlevel = new OSDListBtnType(
    147173            levelname, curlevelarea, m_wmult, m_hmult, true);
    148174
     
    214240        GetLevel(m_levelnum)->MovePageDown();
    215241        EnterItem();
    216242    }
    217     else if (has_action("LEFT", actions) && (m_levelnum > 0))
     243    else if (!m_isRtl && has_action("LEFT", actions) && (m_levelnum > 0))
    218244    {
     245
    219246        GetLevel(m_levelnum)->Reset();
    220247        GetLevel(m_levelnum)->SetVisible(false);
    221248
    222249        m_levelnum--;
    223250        EnterItem();
    224251    }
    225     else if ((has_action("LEFT", actions) && m_arrowAccel) ||
     252
     253    else if (m_isRtl && has_action("LEFT",actions))
     254        {
     255                // Right to left - left acts as select / advance one stage
     256                if ((m_levelnum + 1 < m_depth) &&
     257                    (currentpos->childCount() > 0))     
     258                {
     259                        GetLevel(m_levelnum)->SetActive(false);
     260                        m_levelnum++;
     261               
     262                        FillLevelFromTree(currentpos, m_levelnum);
     263                        GetLevel(m_levelnum)->SetVisible(true);
     264                        EnterItem();
     265                }
     266                else
     267                {
     268                        SelectItem();
     269                }
     270        }       
     271    else if ((!m_isRtl &&  has_action("LEFT", actions) && m_arrowAccel) ||
    226272             has_action("ESCAPE",   actions) ||
    227273             has_action("CLEAROSD", actions) ||
    228274             has_action("MENU",     actions))
    229275    {
    230276        m_visible = false;
    231277    }
    232     else if (has_action("RIGHT", actions) &&
     278    else if (!m_isRtl && has_action("RIGHT", actions) &&
    233279             (m_levelnum + 1 < m_depth) &&
    234280             (currentpos->childCount() > 0))
    235281    {
     
    240286        GetLevel(m_levelnum)->SetVisible(true);
    241287        EnterItem();
    242288    }
    243     else if ((has_action("RIGHT", actions) && m_arrowAccel) ||
     289    else if ((!m_isRtl && has_action("RIGHT", actions) && m_arrowAccel) ||
    244290             has_action("SELECT", actions))
    245291    {
    246292        SelectItem();
    247293    }
     294    else if ((true ==m_isRtl) && has_action("RIGHT",actions) && (m_levelnum > 0))
     295        {
     296                GetLevel(m_levelnum)->Reset();
     297                GetLevel(m_levelnum)->SetVisible(false);
     298       
     299                m_levelnum--;
     300                EnterItem();
     301        }
     302
    248303    else
    249304    {
    250305        return false;
     
    662717    LoadPixmap(m_checkNonePix, "check-empty");
    663718    LoadPixmap(m_checkHalfPix, "check-half");
    664719    LoadPixmap(m_checkFullPix, "check-full");
    665     LoadPixmap(m_arrowPix, "arrow");
     720    if (gContext->GetLanguage()=="he")
     721       LoadPixmap(m_arrowPix, "ltarrow");
     722    else
     723       LoadPixmap(m_arrowPix, "arrow");
    666724
    667725    uint itemWidth = (m_rect.width() + 1) & (~1);
    668726
     
    751809    if (m_checkable)
    752810        m_checkRect  = QRect(margin, (height - ch)/2, cw, ch);
    753811
    754     if (m_showArrow)
    755         m_arrowRect  = QRect(width - aw - margin, (height - ah)/2, aw, ah);
     812    if (m_showArrow)
     813        if (gContext->GetLanguage() == "he")
     814                m_arrowRect  = QRect(m_parent->m_contentsRect.x() + margin, (height - ah)/2, aw, ah);
     815        else
     816                m_arrowRect  = QRect(width - aw - margin, (height - ah)/2, aw, ah);
     817       
    756818
    757819    if (m_pixmap)
    758820    {
     
    764826    tx += (m_checkable) ? m_checkRect.width()  + margin : 0;
    765827    tx += (m_pixmap)    ? m_pixmapRect.width() + margin : 0;
    766828    tw -= (m_checkable) ? m_checkRect.width()  + margin : 0;
     829   
    767830    tw -= (m_showArrow) ? m_arrowRect.width()  + margin : 0;
     831   
     832    if (gContext->GetLanguage()=="he")
     833        tx += (m_showArrow) ? m_arrowRect.width()  + margin : 0;
     834
    768835    tw -= (m_pixmap)    ? m_pixmapRect.width() + margin : 0;
    769836    m_textRect = QRect(tx, 0, tw, height);
    770837
  • mythtv/libs/libmythtv/ttfont.h

     
    88#include <qstring.h>
    99#include <qmap.h>
    1010#include <qcolor.h>
    11 
     11#include <qmutex.h>
    1212#include "config.h"
    1313
    1414#ifdef HAVE_STDINT_H
     
    6767                     int offset_y, int xstart, int ystart, int width,
    6868                     int height, int alphamod, kTTF_Color k = kTTF_Normal);
    6969     bool cache_glyph(unsigned short c);
    70 
     70       
     71         QString ConvertFromRtoL(const QString &text) const;
     72                 
     73         static QString BasicConvertFromRtoL(const QString &text);
     74       
     75       
     76       
    7177     bool         valid;
    7278     FT_Library   library;
    7379     FT_Face      face;
     
    104110     int loadedfontsize;
    105111     float m_wscale;
    106112     float m_hmult;
     113       
     114        mutable QMutex      fribidi_lock;
     115        mutable QTextCodec *codeci;
    107116};
    108117
    109118#endif
  • mythtv/libs/libmythtv/osdlistbtntype.h

     
    108108    bool HandleKeypress(QKeyEvent *e);
    109109    void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
    110110
     111    void SetRtl (bool isRtl);
     112
    111113  signals:
    112114    void itemSelected(OSDListTreeType *parent, OSDGenericTree *item);
    113115    void itemEntered(OSDListTreeType *parent, OSDGenericTree *item);
     
    151153    int       m_levelnum;
    152154    bool      m_visible;
    153155    bool      m_arrowAccel;
     156    bool      m_isRtl;
    154157};
    155158 
    156159class OSDListBtnType : public OSDType
  • mythtv/libs/libmythtv/ttfont.cpp

     
    2121
    2222#include <iostream>
    2323
     24#ifdef USING_FRIBIDI
     25#include "fribidi/fribidi.h"
     26#include <qtextcodec.h> 
     27#endif // USING_FRIBIDI
     28
    2429using namespace std;
    2530
    2631#include <cstdio>
     
    3035
    3136#include "osdtypes.h"
    3237#include "osdsurface.h"
     38#include "mythcontext.h"
    3339
    3440static int          have_library = 0;
    3541static FT_Library   the_library;
     
    430436                               surface->pow_lut);
    431437}
    432438
     439QString TTFFont::BasicConvertFromRtoL(const QString &text)
     440        {
     441            QStringList rtl_string_composer;
     442            bool handle_rtl = false;
     443            QChar prev_char;
     444                 
     445            // Handling Right-to-Left languages.
     446            // Left-to-Right languages are not affected.
     447
     448            // first,we need to ignore all the spaces in the end of the string
     449            int lastCharIdx = (int)text.length() - 1;
     450            while (text[lastCharIdx].isSpace())
     451                lastCharIdx--;
     452            for (int i = lastCharIdx; i >= 0; i--)
     453            {
     454                QChar::Direction text_dir = text[i].direction();
     455                if (text_dir != QChar::DirR && 
     456                    text_dir != QChar::DirRLE &&
     457                    text_dir != QChar::DirRLO)
     458                        {
     459                            if (handle_rtl || rtl_string_composer.empty())
     460                                rtl_string_composer.append(QString());
     461                 
     462                            if (text[i].isSpace() && !prev_char.isNull()
     463                                    && prev_char.isDigit() && handle_rtl)
     464                                rtl_string_composer.back().append(text[i]);
     465                            else
     466                                rtl_string_composer.back().prepend(text[i]);
     467                 
     468                            prev_char = text[i];
     469                 
     470                            handle_rtl = false;
     471                        }
     472                        else
     473                        {
     474                            if (!handle_rtl)
     475                            {
     476                                rtl_string_composer.append(QString());
     477                                handle_rtl = true;
     478                                prev_char = QChar();
     479                            }
     480                            rtl_string_composer.back().append(text[i]);
     481                        }
     482                    }
     483                 
     484                    QString output = rtl_string_composer.join("");
     485                 
     486                //    return QDeepCopy<QString>(output);
     487                    return output;
     488                }
     489                 
     490QString TTFFont::ConvertFromRtoL(const QString &text) const
     491{
     492        QString output = BasicConvertFromRtoL(text);
     493// cout<< output;
     494#ifdef USING_FRIBIDI
     495                cout<<"fribidi";
     496        QMutexLocker locker(&fribidi_lock);
     497        if (!codeci)
     498                codeci = QTextCodec::codecForName("utf8");
     499 
     500        if (!codeci)
     501                return output;
     502 
     503        QCString temp = codeci->fromUnicode(text);
     504 
     505        FriBidiCharType base;
     506        size_t len;
     507 
     508        bool fribidi_flip_commas = true;
     509        base = (fribidi_flip_commas) ? FRIBIDI_TYPE_ON : FRIBIDI_TYPE_L;
     510 
     511        const char *ip = temp;
     512        FriBidiChar logical[strlen(ip) + 1], visual[strlen(ip) + 1];
     513 
     514        int char_set_num = fribidi_parse_charset("UTF-8");
     515
     516        len = fribidi_charset_to_unicode(
     517        (FriBidiCharSet) char_set_num, (char *)ip, strlen(ip), logical);
     518
     519        bool log2vis = fribidi_log2vis(
     520        logical, len, &base, visual, NULL, NULL, NULL); // output
     521
     522        if (log2vis)
     523        len = fribidi_remove_bidi_marks(visual, len, NULL, NULL, NULL);
     524
     525        output = "";
     526        for (size_t i = 1; i < len ; i++)
     527            output += QChar(visual[i]);
     528       
     529       
     530        #endif // USING_FRIBIDI
     531
     532        return output;
     533}
     534
     535
    433536void TTFFont::DrawString(OSDSurface *surface, int x, int y,
    434537                         const QString &text, int maxx, int maxy,
    435538                         int alphamod, bool double_size)
     
    452555   }
    453556   rmap = create_font_raster(w, h);
    454557
    455    render_text(rmap, rtmp, text, &inx, &iny, double_size);
     558   render_text(rmap, rtmp, ConvertFromRtoL(text), &inx, &iny, double_size);
    456559
    457560   is_pixmap = 1;
    458561
     
    496599       return;
    497600   }
    498601
     602        if (gContext->GetLanguage()=="he")
     603        {
     604                x = maxx - width;
     605        }
     606
    499607   if (m_shadowxoff != 0 || m_shadowyoff != 0)
    500608   {
    501609       merge_text(surface, rmap, clipx, clipy, x + m_shadowxoff,
    502610                  y + m_shadowyoff, width, height, alphamod, kTTF_Shadow);
    503611   }
    504612
     613       
     614
    505615   if (m_outline)
    506616   {
    507617       merge_text(surface, rmap, clipx, clipy, x - 1, y - 1, width, height,
     
    514624                  alphamod, kTTF_Outline);
    515625   }
    516626
     627   
    517628   merge_text(surface, rmap, clipx, clipy, x, y, width, height, alphamod);
    518629
    519630   destroy_font_raster(rmap);
  • mythtv/libs/libmythtv/osd.cpp

     
    12981298    uint    grSelectedAlpha(255);
    12991299    int     spacing = 2;
    13001300    int     margin = 3;
     1301    bool    isRtl = false;     
    13011302
    13021303    QString name = element.attribute("name", "");
    13031304    if (name.isNull() || name.isEmpty())
     
    13121313        QDomElement info = child.toElement();
    13131314        if (!info.isNull())
    13141315        {
    1315             if (info.tagName() == "area")
     1316            if (info.tagName() == "RTL")
     1317                {
     1318                        if (getFirstText(info) == "yes")
     1319                        {
     1320                                isRtl = true;
     1321                        }
     1322                        else if (getFirstText(info) == "no")
     1323                        {
     1324                                isRtl = false;
     1325                        }
     1326                }       
     1327            else if (info.tagName() == "area")
    13161328            {
    13171329                area = parseRect(getFirstText(info));
    13181330                normalizeRect(area);
     
    14281440    lb->SetSpacing(spacing);
    14291441    lb->SetMargin(margin);
    14301442
     1443    lb->SetRtl(isRtl);
     1444
    14311445    container->AddType(lb);
    14321446}
    14331447