diff options
Diffstat (limited to 'kdeui/kwordwrap.cpp')
-rw-r--r-- | kdeui/kwordwrap.cpp | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/kdeui/kwordwrap.cpp b/kdeui/kwordwrap.cpp deleted file mode 100644 index b7eeaff7c..000000000 --- a/kdeui/kwordwrap.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001 David Faure <david@mandrakesoft.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kwordwrap.h" -#include <kdebug.h> -#include <kstringhandler.h> -#include <tqpainter.h> - -class KWordWrapPrivate { -public: - TQRect m_constrainingRect; -}; - -KWordWrap::KWordWrap(const TQRect & r) { - d = new KWordWrapPrivate; - d->m_constrainingRect = r; -} - -KWordWrap* KWordWrap::formatText( TQFontMetrics &fm, const TQRect & r, int /*flags*/, const TQString & str, int len ) -{ - KWordWrap* kw = new KWordWrap( r ); - // The wordwrap algorithm - // The variable names and the global tqshape of the algorithm are inspired - // from QTextFormatterBreakWords::format(). - //kdDebug() << "KWordWrap::formatText " << str << " r=" << r.x() << "," << r.y() << " " << r.width() << "x" << r.height() << endl; - int height = fm.height(); - if ( len == -1 ) - kw->m_text = str; - else - kw->m_text = str.left( len ); - if ( len == -1 ) - len = str.length(); - int lastBreak = -1; - int lineWidth = 0; - int x = 0; - int y = 0; - int w = r.width(); - int textwidth = 0; - bool isBreakable = false; - bool wasBreakable = false; // value of isBreakable for last char (i-1) - bool isParens = false; // true if one of ({[ - bool wasParens = false; // value of isParens for last char (i-1) - - for ( int i = 0 ; i < len; ++i ) - { - TQChar c = str[i]; - int ww = fm.charWidth( str, i ); - - isParens = ( c == '(' || c == '[' || c == '{' ); - // isBreakable is true when we can break _after_ this character. - isBreakable = ( c.isSpace() || c.isPunct() || c.isSymbol() ) & !isParens; - - // Special case for '(', '[' and '{': we want to break before them - if ( !isBreakable && i < len-1 ) { - TQChar nextc = str[i+1]; // look at next char - isBreakable = ( nextc == '(' || nextc == '[' || nextc == '{' ); - } - // Special case for '/': after normal chars it's breakable (e.g. inside a path), - // but after another breakable char it's not (e.g. "mounted at /foo") - // Same thing after a parenthesis (e.g. "dfaure [/fool]") - if ( c == '/' && (wasBreakable || wasParens) ) - isBreakable = false; - - /*kdDebug() << "c='" << TQString(c) << "' i=" << i << "/" << len - << " x=" << x << " ww=" << ww << " w=" << w - << " lastBreak=" << lastBreak << " isBreakable=" << isBreakable << endl;*/ - int breakAt = -1; - if ( x + ww > w && lastBreak != -1 ) // time to break and we know where - breakAt = lastBreak; - if ( x + ww > w - 4 && lastBreak == -1 ) // time to break but found nowhere [-> break here] - breakAt = i; - if ( i == len - 2 && x + ww + fm.charWidth( str, i+1 ) > w ) // don't leave the last char alone - breakAt = lastBreak == -1 ? i - 1 : lastBreak; - if ( c == '\n' ) // Forced break here - { - if ( breakAt == -1 && lastBreak != -1) // only break if not already breaking - { - breakAt = i - 1; - lastBreak = -1; - } - // remove the line feed from the string - kw->m_text.remove(i, 1); - len--; - } - if ( breakAt != -1 ) - { - //kdDebug() << "KWordWrap::formatText breaking after " << breakAt << endl; - kw->m_breakPositions.append( breakAt ); - int thisLineWidth = lastBreak == -1 ? x + ww : lineWidth; - kw->m_lineWidths.append( thisLineWidth ); - textwidth = QMAX( textwidth, thisLineWidth ); - x = 0; - y += height; - wasBreakable = true; - wasParens = false; - if ( lastBreak != -1 ) - { - // Breakable char was found, restart from there - i = lastBreak; - lastBreak = -1; - continue; - } - } else if ( isBreakable ) - { - lastBreak = i; - lineWidth = x + ww; - } - x += ww; - wasBreakable = isBreakable; - wasParens = isParens; - } - textwidth = QMAX( textwidth, x ); - kw->m_lineWidths.append( x ); - y += height; - //kdDebug() << "KWordWrap::formatText boundingRect:" << r.x() << "," << r.y() << " " << textwidth << "x" << y << endl; - if ( r.height() >= 0 && y > r.height() ) - textwidth = r.width(); - int realY = y; - if ( r.height() >= 0 ) - { - while ( realY > r.height() ) - realY -= height; - realY = QMAX( realY, 0 ); - } - kw->m_boundingRect.setRect( 0, 0, textwidth, realY ); - return kw; -} - -KWordWrap::~KWordWrap() { - delete d; -} - -TQString KWordWrap::wrappedString() const -{ - // We use the calculated break positions to insert '\n' into the string - TQString ws; - int start = 0; - TQValueList<int>::ConstIterator it = m_breakPositions.begin(); - for ( ; it != m_breakPositions.end() ; ++it ) - { - int end = (*it); - ws += m_text.mid( start, end - start + 1 ) + '\n'; - start = end + 1; - } - ws += m_text.mid( start ); - return ws; -} - -TQString KWordWrap::truncatedString( bool dots ) const -{ - if ( m_breakPositions.isEmpty() ) - return m_text; - - TQString ts = m_text.left( m_breakPositions.first() + 1 ); - if ( dots ) - ts += "..."; - return ts; -} - -static TQColor mixColors(double p1, TQColor c1, TQColor c2) { - return TQColor(int(c1.red() * p1 + c2.red() * (1.0-p1)), - int(c1.green() * p1 + c2.green() * (1.0-p1)), - int(c1.blue() * p1 + c2.blue() * (1.0-p1))); -} - -void KWordWrap::drawFadeoutText(TQPainter *p, int x, int y, int maxW, - const TQString &t) { - TQFontMetrics fm = p->fontMetrics(); - TQColor bgColor = p->backgroundColor(); - TQColor textColor = p->pen().color(); - - if ( ( fm.boundingRect( t ).width() > maxW ) && ( t.length() > 1 ) ) { - unsigned int tl = 0; - int w = 0; - while ( tl < t.length() ) { - w += fm.charWidth( t, tl ); - if ( w >= maxW ) - break; - tl++; - } - - if (tl > 3) { - p->drawText( x, y, t.left( tl - 3 ) ); - x += fm.width( t.left( tl - 3 ) ); - } - int n = TQMIN( tl, 3); - for (int i = 0; i < n; i++) { - p->setPen( mixColors( 0.70 - i * 0.25, textColor, bgColor ) ); - TQString s( t.tqat( tl - n + i ) ); - p->drawText( x, y, s ); - x += fm.width( s ); - } - } - else - p->drawText( x, y, t ); -} - -void KWordWrap::drawTruncateText(TQPainter *p, int x, int y, int maxW, - const TQString &t) { - TQString tmpText = KStringHandler::rPixelSqueeze( t, p->fontMetrics(), maxW ); - p->drawText( x, y, tmpText, maxW ); -} - -void KWordWrap::drawText( TQPainter *painter, int textX, int textY, int flags ) const -{ - //kdDebug() << "KWordWrap::drawText text=" << wrappedString() << " x=" << textX << " y=" << textY << endl; - // We use the calculated break positions to draw the text line by line using QPainter - int start = 0; - int y = 0; - TQFontMetrics fm = painter->fontMetrics(); - int height = fm.height(); // line height - int ascent = fm.ascent(); - int maxwidth = m_boundingRect.width(); - TQValueList<int>::ConstIterator it = m_breakPositions.begin(); - TQValueList<int>::ConstIterator itw = m_lineWidths.begin(); - for ( ; it != m_breakPositions.end() ; ++it, ++itw ) - { - // if this is the last line, leave the loop - if ( (d->m_constrainingRect.height() >= 0) && - ((y + 2 * height) > d->m_constrainingRect.height()) ) - break; - int end = (*it); - int x = textX; - if ( flags & Qt::AlignHCenter ) - x += ( maxwidth - *itw ) / 2; - else if ( flags & Qt::AlignRight ) - x += maxwidth - *itw; - painter->drawText( x, textY + y + ascent, m_text.mid( start, end - start + 1 ) ); - y += height; - start = end + 1; - } - // Draw the last line - int x = textX; - if ( flags & Qt::AlignHCenter ) - x += ( maxwidth - *itw ) / 2; - else if ( flags & Qt::AlignRight ) - x += maxwidth - *itw; - if ( (d->m_constrainingRect.height() < 0) || - ((y + height) <= d->m_constrainingRect.height()) ) { - if ( it == m_breakPositions.end() ) - painter->drawText( x, textY + y + ascent, m_text.mid( start ) ); - else if (flags & FadeOut) - drawFadeoutText( painter, textX, textY + y + ascent, - d->m_constrainingRect.width(), - m_text.mid( start ) ); - else if (flags & Truncate) - drawTruncateText( painter, textX, textY + y + ascent, - d->m_constrainingRect.width(), - m_text.mid( start ) ); - else - painter->drawText( x, textY + y + ascent, - m_text.mid( start, (*it) - start + 1 ) ); - } -} |