Ticket #9295: mythtv-0.24-stretching-cutdown-code.diff

File mythtv-0.24-stretching-cutdown-code.diff, 6.6 KB (added by savardd@…, 9 years ago)

Code of the stretching and cutdown patch

  • libs/libmythui/mythuitext.h

     
    7474    bool GetCutDown(void) const { return m_Cutdown; }
    7575    void SetMultiLine(bool multiline);
    7676    bool GetMultiLine(void) const { return m_MultiLine; }
     77    void SetStretch(bool stretch);
     78    bool GetStretch(void) const { return m_Stretch; }
    7779
    7880    void SetArea(const MythRect &rect);
    7981    void SetPosition(const MythPoint &pos);
     
    8587
    8688    bool MakeNarrow(QRect &min_rect);
    8789    void FillCutMessage(void);
    88     QString cutDown(const QString &data, MythFontProperties *font,
     90    bool IsTextFitting(const QString &text, MythFontProperties *font,
    8991                    bool multiline = false);
    9092
    9193    int m_Justification;
     
    100102
    101103    bool m_Cutdown;
    102104    bool m_MultiLine;
     105    bool m_Stretch;
     106    int m_minStretch;
     107    int m_maxStretch;
    103108
    104109    MythFontProperties* m_Font;
    105110    QMap<QString, MythFontProperties> m_FontStates;
  • libs/libmythui/mythuitext.cpp

     
    3535    m_scrolling = false;
    3636    m_scrollDirection = ScrollLeft;
    3737    m_textCase = CaseNormal;
     38    m_Stretch = false;
     39    m_minStretch = 100;
     40    m_maxStretch = 100;
    3841
    3942    m_FontStates.insert("default", MythFontProperties());
    4043    *m_Font = m_FontStates["default"];
     
    5962    m_scrolling = false;
    6063    m_scrollDirection = ScrollLeft;
    6164    m_textCase = CaseNormal;
     65    m_Stretch = false;
     66    m_minStretch = 100;
     67    m_maxStretch = 100;
    6268
    6369    SetArea(displayRect);
    6470    m_FontStates.insert("default", font);
     
    222228    SetRedraw();
    223229}
    224230
     231void MythUIText::SetStretch(bool stretch)
     232{
     233    m_Stretch = stretch;
     234    FillCutMessage();
     235    SetRedraw();
     236}
     237
    225238void MythUIText::SetArea(const MythRect &rect)
    226239{
    227240    MythUIType::SetArea(rect);
     
    380393    }
    381394}
    382395
     396bool MythUIText::IsTextFitting(const QString &text, MythFontProperties *font, bool multiline) {
     397    if (multiline) {
     398        int maxwidth = GetArea().width();
     399        int maxheight = GetArea().height();
     400        int justification = Qt::AlignLeft | Qt::TextWordWrap;
     401        QFontMetrics fm(font->face());
     402
     403        int height = fm.boundingRect(0, 0, maxwidth, maxheight,
     404                                           justification, text
     405                                           ).height();
     406        return height <= maxheight;
     407    } else {
     408        int maxwidth = GetArea().width();
     409        QFontMetrics fm = QFontMetrics(m_Font->face());
     410        int width=fm.width(text, text.length());
     411        return width <= maxwidth;
     412    }
     413}
     414
    383415void MythUIText::FillCutMessage()
    384416{
    385417    m_CutMessage.clear();
     
    445477            SetDrawRectSize(m_MinArea.width(), m_MinArea.height());
    446478    }
    447479
    448     if (m_Cutdown)
    449         m_CutMessage = cutDown(m_CutMessage, m_Font, m_MultiLine);
     480    // If we played with stretch, we need to reset to 100% before continuing
     481    // This is because sometime, the font may not resetted correctly when
     482    // switching text with SetText or other calls.
     483    int stretch = 100;
     484    if (m_Stretch)
     485        m_Font->AdjustStretch(100);
     486    bool fit = IsTextFitting(m_CutMessage, m_Font, m_MultiLine);
     487
     488    if (m_Stretch) {
     489        // Can we extend the text ?
     490        while (fit && stretch < m_maxStretch) {
     491            m_Font->AdjustStretch(++stretch);
     492            fit = IsTextFitting(m_CutMessage, m_Font, m_MultiLine);
     493        }
     494        // Can we shrink the text ?
     495        // This will correct the 'overextend' above as extend will always
     496        // extend a little to much (loop until it doesn't fit).
     497        while (!fit && stretch > m_minStretch) {
     498            m_Font->AdjustStretch(--stretch);
     499            fit = IsTextFitting(m_CutMessage, m_Font, m_MultiLine);
     500        }
     501    }
     502
     503    // Do we need to cut the text ?
     504    if (!fit && m_Cutdown) {
     505        QString dotdotdot = QString("...");
     506        for (int index=m_CutMessage.length() - 1; index>0 && !fit; index--) {
     507            m_CutMessage.truncate(index);
     508            m_CutMessage.append(dotdotdot);
     509            fit = IsTextFitting(m_CutMessage, m_Font, m_MultiLine);
     510        }
     511    }
    450512}
    451513
    452514void MythUIText::Pulse(void)
     
    540602    SetRedraw();
    541603}
    542604
    543 QString MythUIText::cutDown(const QString &data, MythFontProperties *font,
    544                             bool multiline)
    545 {
    546     int length = data.length();
    547     if (length == 0)
    548         return data;
    549 
    550     int maxwidth = GetArea().width();
    551     int maxheight = GetArea().height();
    552     int justification = Qt::AlignLeft | Qt::TextWordWrap;
    553     QFontMetrics fm(font->face());
    554 
    555     int margin = length - 1;
    556     int index = 0;
    557     int diff = 0;
    558 
    559     while (margin > 0)
    560     {
    561         if (multiline)
    562             diff = maxheight - fm.boundingRect(0, 0, maxwidth, maxheight,
    563                                                justification,
    564                                                data.left(index + margin + 1)
    565                                                ).height();
    566         else
    567             diff = maxwidth - fm.width(data, index + margin + 1);
    568         if (diff >= 0)
    569             index += margin;
    570 
    571         margin /= 2;
    572 
    573         if (index + margin >= length - 1)
    574             margin = (length - 1) - index;
    575     }
    576 
    577     if (index < length - 1)
    578     {
    579         QString tmpStr(data);
    580         tmpStr.truncate(index);
    581         if (index >= 3)
    582             tmpStr.replace(index - 3, 3, "...");
    583         return tmpStr;
    584     }
    585 
    586     return data;
    587 
    588 }
    589 
    590605bool MythUIText::ParseElement(
    591606    const QString &filename, QDomElement &element, bool showWarnings)
    592607{
     
    721736            m_textCase = CaseNormal;
    722737        FillCutMessage();
    723738    }
     739    else if (element.tagName() == "stretch")
     740    {
     741        QString stretch = getFirstText(element);
     742        if (!stretch.isEmpty())
     743            m_Stretch = parseBool(stretch);
     744        QString tmp = element.attribute("min");
     745        if (!tmp.isEmpty())
     746            m_minStretch = tmp.toInt();
     747        tmp = element.attribute("max");
     748        if (!tmp.isEmpty())
     749            m_maxStretch = tmp.toInt();
     750    }
    724751    else
    725752    {
    726753        return MythUIType::ParseElement(filename, element, showWarnings);
     
    750777
    751778    m_Cutdown = text->m_Cutdown;
    752779    m_MultiLine = text->m_MultiLine;
     780    m_Stretch = text->m_Stretch;
     781    m_minStretch = text->m_minStretch;
     782    m_maxStretch = text->m_maxStretch;
    753783
    754784    QMutableMapIterator<QString, MythFontProperties> it(text->m_FontStates);
    755785    while (it.hasNext())