19 #include "kwordwrap.h"
21 #include <kstringhandler.h>
22 #include <tqpainter.h>
24 class KWordWrapPrivate {
26 TQRect m_constrainingRect;
29 KWordWrap::KWordWrap(
const TQRect & r) {
30 d =
new KWordWrapPrivate;
31 d->m_constrainingRect = r;
41 int height = fm.height();
45 kw->m_text = str.left( len );
54 bool isBreakable =
false;
55 bool wasBreakable =
false;
56 bool isParens =
false;
57 bool wasParens =
false;
59 for (
int i = 0 ; i < len; ++i )
62 int ww = fm.charWidth( str, i );
64 isParens = ( c ==
'(' || c ==
'[' || c ==
'{' );
66 isBreakable = ( c.isSpace() || c.isPunct() || c.isSymbol() ) & !isParens;
69 if ( !isBreakable && i < len-1 ) {
70 TQChar nextc = str[i+1];
71 isBreakable = ( nextc ==
'(' || nextc ==
'[' || nextc ==
'{' );
76 if ( c ==
'/' && (wasBreakable || wasParens) )
83 if ( x + ww > w && lastBreak != -1 )
85 if ( x + ww > w - 4 && lastBreak == -1 )
87 if ( i == len - 2 && x + ww + fm.charWidth( str, i+1 ) > w )
88 breakAt = lastBreak == -1 ? i - 1 : lastBreak;
91 if ( breakAt == -1 && lastBreak != -1)
97 kw->m_text.remove(i, 1);
103 kw->m_breakPositions.append( breakAt );
104 int thisLineWidth = lastBreak == -1 ? x + ww : lineWidth;
105 kw->m_lineWidths.append( thisLineWidth );
106 textwidth = TQMAX( textwidth, thisLineWidth );
111 if ( lastBreak != -1 )
118 }
else if ( isBreakable )
124 wasBreakable = isBreakable;
125 wasParens = isParens;
127 textwidth = TQMAX( textwidth, x );
128 kw->m_lineWidths.append( x );
131 if ( r.height() >= 0 && y > r.height() )
132 textwidth = r.width();
134 if ( r.height() >= 0 )
136 while ( realY > r.height() )
138 realY = TQMAX( realY, 0 );
140 kw->m_boundingRect.setRect( 0, 0, textwidth, realY );
153 TQValueList<int>::ConstIterator it = m_breakPositions.begin();
154 for ( ; it != m_breakPositions.end() ; ++it )
157 ws += m_text.mid( start, end - start + 1 ) +
'\n';
160 ws += m_text.mid( start );
166 if ( m_breakPositions.isEmpty() )
169 TQString ts = m_text.left( m_breakPositions.first() + 1 );
175 static TQColor mixColors(
double p1, TQColor c1, TQColor c2) {
176 return TQColor(
int(c1.red() * p1 + c2.red() * (1.0-p1)),
177 int(c1.green() * p1 + c2.green() * (1.0-p1)),
178 int(c1.blue() * p1 + c2.blue() * (1.0-p1)));
183 TQFontMetrics fm = p->fontMetrics();
184 TQColor bgColor = p->backgroundColor();
185 TQColor textColor = p->pen().color();
187 if ( ( fm.boundingRect( t ).width() > maxW ) && ( t.length() > 1 ) ) {
190 while ( tl < t.length() ) {
191 w += fm.charWidth( t, tl );
198 p->drawText( x, y, t.left( tl - 3 ) );
199 x += fm.width( t.left( tl - 3 ) );
201 int n = TQMIN( tl, 3);
202 for (
int i = 0; i < n; i++) {
203 p->setPen( mixColors( 0.70 - i * 0.25, textColor, bgColor ) );
204 TQString s( t.at( tl - n + i ) );
205 p->drawText( x, y, s );
210 p->drawText( x, y, t );
216 p->drawText( x, y, tmpText, maxW );
225 TQFontMetrics fm = painter->fontMetrics();
226 int height = fm.height();
227 int ascent = fm.ascent();
228 int maxwidth = m_boundingRect.width();
229 TQValueList<int>::ConstIterator it = m_breakPositions.begin();
230 TQValueList<int>::ConstIterator itw = m_lineWidths.begin();
231 for ( ; it != m_breakPositions.end() ; ++it, ++itw )
234 if ( (d->m_constrainingRect.height() >= 0) &&
235 ((y + 2 * height) > d->m_constrainingRect.height()) )
239 if ( flags & TQt::AlignHCenter )
240 x += ( maxwidth - *itw ) / 2;
241 else if ( flags & TQt::AlignRight )
242 x += maxwidth - *itw;
243 painter->drawText( x, textY + y + ascent, m_text.mid( start, end - start + 1 ) );
249 if ( flags & TQt::AlignHCenter )
250 x += ( maxwidth - *itw ) / 2;
251 else if ( flags & TQt::AlignRight )
252 x += maxwidth - *itw;
253 if ( (d->m_constrainingRect.height() < 0) ||
254 ((y + height) <= d->m_constrainingRect.height()) ) {
255 if ( it == m_breakPositions.end() )
256 painter->drawText( x, textY + y + ascent, m_text.mid( start ) );
257 else if (flags & FadeOut)
259 d->m_constrainingRect.width(),
260 m_text.mid( start ) );
261 else if (flags & Truncate)
263 d->m_constrainingRect.width(),
264 m_text.mid( start ) );
266 painter->drawText( x, textY + y + ascent,
267 m_text.mid( start, (*it) - start + 1 ) );
static TQString rPixelSqueeze(const TQString &name, const TQFontMetrics &fontMetrics, uint maxPixels)
Word-wrap algorithm that takes into account beautifulness ;)
TQString truncatedString(bool dots=true) const
static void drawFadeoutText(TQPainter *p, int x, int y, int maxW, const TQString &t)
Draws the string t at the given coordinates, if it does not fit into maxW the text will be faded out.
static KWordWrap * formatText(TQFontMetrics &fm, const TQRect &r, int flags, const TQString &str, int len=-1)
Main method for wrapping text.
void drawText(TQPainter *painter, int x, int y, int flags=TQt::AlignAuto) const
Draw the text that has been previously wrapped, at position x,y.
static void drawTruncateText(TQPainter *p, int x, int y, int maxW, const TQString &t)
Draws the string t at the given coordinates, if it does not fit into maxW the text will be truncated.
TQString wrappedString() const