summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/CDrawBuffer.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/CDrawBuffer.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/CDrawBuffer.cpp478
1 files changed, 398 insertions, 80 deletions
diff --git a/noncore/apps/opie-reader/CDrawBuffer.cpp b/noncore/apps/opie-reader/CDrawBuffer.cpp
index b137ac3..cd79fec 100644
--- a/noncore/apps/opie-reader/CDrawBuffer.cpp
+++ b/noncore/apps/opie-reader/CDrawBuffer.cpp
@@ -1,22 +1,26 @@
1#include "CDrawBuffer.h" 1#include "CDrawBuffer.h"
2#include "FontControl.h" 2#include "FontControl.h"
3#include <qfontmetrics.h>
3#include <qpainter.h> 4#include <qpainter.h>
5#include <qpixmap.h>
4#include <qimage.h> 6#include <qimage.h>
7#include "useqpe.h"
8#include "opie.h"
5 9
6CDrawBuffer::~CDrawBuffer() 10CDrawBuffer::~CDrawBuffer()
7{ 11{
8 while (!segs.isEmpty()) segs.erase(0); 12 while (!segs.isEmpty()) segs.erase(0);
9} 13}
10 14
11void CDrawBuffer::setright(CDrawBuffer& rhs, int f) 15void CDrawBuffer::setright(CDrawBuffer& rhs, int f)
12{ 16{
13 int i; 17 int i;
14 len = rhs.len; 18 len = rhs.len;
15 fc = rhs.fc; 19 fc = rhs.fc;
16 m_maxstyle = m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0; 20 m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0;
17 while (!segs.isEmpty()) 21 while (!segs.isEmpty())
18 { 22 {
19 segs.erase(0); 23 segs.erase(0);
20 } 24 }
21 for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); ) 25 for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); )
22 { 26 {
@@ -25,43 +29,42 @@ void CDrawBuffer::setright(CDrawBuffer& rhs, int f)
25 if (iter == rhs.segs.end() || iter->start > f) 29 if (iter == rhs.segs.end() || iter->start > f)
26 { 30 {
27 int st = next->start-f; 31 int st = next->start-f;
28 if (st < 0) st = 0; 32 if (st < 0) st = 0;
29 33
30 CStyle _style = next->style; 34 CStyle _style = next->style;
31
32 segs.push_back(textsegment(st,next->style)); 35 segs.push_back(textsegment(st,next->style));
33 } 36 }
34 } 37 }
35 for (i = f; rhs[i] != '\0'; i++) (*this)[i-f] = rhs[i]; 38 for (i = f; rhs[i] != '\0'; i++) (*this)[i-f] = rhs[i];
36 (*this)[i-f] = '\0'; 39 (*this)[i-f] = '\0';
37 len = i; 40 len = i;
38} 41}
39 42
40CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs) 43CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs)
41{ 44{
42 int i; 45 int i;
43// //odebug << "Trying 2" << oendl; 46// //qDebug("Trying 2");
44 len = rhs.len; 47 len = rhs.len;
45 m_maxstyle = rhs.m_maxstyle;
46 m_ascent = rhs.m_ascent; 48 m_ascent = rhs.m_ascent;
47 m_descent = rhs.m_descent; 49 m_descent = rhs.m_descent;
48 m_lineSpacing = rhs.m_lineSpacing; 50 m_lineSpacing = rhs.m_lineSpacing;
49 m_lineExtraSpacing = rhs.m_lineExtraSpacing; 51 m_lineExtraSpacing = rhs.m_lineExtraSpacing;
52 m_showPartial = rhs.m_showPartial;
50 while (!segs.isEmpty()) 53 while (!segs.isEmpty())
51 { 54 {
52 segs.erase(0); 55 segs.erase(0);
53 } 56 }
54 for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); iter++) 57 for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); iter++)
55 { 58 {
56 segs.push_back(*iter); 59 segs.push_back(*iter);
57 } 60 }
58 for (i = 0; rhs[i] != '\0'; i++) (*this)[i] = rhs[i]; 61 for (i = 0; rhs[i] != '\0'; i++) (*this)[i] = rhs[i];
59 (*this)[i] = '\0'; 62 (*this)[i] = '\0';
60 len = i; 63 len = i;
61// //odebug << "Tried 2" << oendl; 64// //qDebug("Tried 2");
62 return *this; 65 return *this;
63} 66}
64 67
65CDrawBuffer& CDrawBuffer::operator=(const tchar*sztmp) 68CDrawBuffer& CDrawBuffer::operator=(const tchar*sztmp)
66{ 69{
67 int i; 70 int i;
@@ -77,23 +80,34 @@ CDrawBuffer& CDrawBuffer::operator=(const tchar*sztmp)
77} 80}
78 81
79void CDrawBuffer::empty() 82void CDrawBuffer::empty()
80{ 83{
81 m_bSop = false; 84 m_bSop = false;
82 m_bEop = false; 85 m_bEop = false;
86 m_bBop = false;
83 len = 0; 87 len = 0;
84 (*this)[0] = 0; 88 (*this)[0] = 0;
85 while (!segs.isEmpty()) 89 while (!segs.isEmpty())
86 { 90 {
87 segs.erase(0); 91 segs.erase(0);
88 } 92 }
89 segs.push_back(textsegment(0,CStyle())); 93 segs.push_back(textsegment(0,CStyle()));
90 m_maxstyle = m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0; 94 m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0;
91 m_bEof = false; 95 m_bEof = false;
92} 96}
93 97
98void CDrawBuffer::setendpara(const CStyle& _style/* = ucFontBase*/)
99{
100 m_bEop = true;
101 if (len == 0)
102 {
103 segs.first().start = 0;
104 segs.first().style = _style;
105 }
106}
107
94void CDrawBuffer::addch(tchar ch, CStyle _style/* = ucFontBase*/) 108void CDrawBuffer::addch(tchar ch, CStyle _style/* = ucFontBase*/)
95{ 109{
96 if (len == 0) 110 if (len == 0)
97 { 111 {
98 segs.first().start = 0; 112 segs.first().start = 0;
99 segs.first().style = _style; 113 segs.first().style = _style;
@@ -108,13 +122,13 @@ void CDrawBuffer::addch(tchar ch, CStyle _style/* = ucFontBase*/)
108void CDrawBuffer::truncate(int n) 122void CDrawBuffer::truncate(int n)
109{ 123{
110 len = n; 124 len = n;
111 (*this)[n] = 0; 125 (*this)[n] = 0;
112} 126}
113 127
114int CDrawBuffer::width(int numchars, bool onscreen, int scwidth, unsigned char _border) 128int CDrawBuffer::width(int availht, int numchars, bool onscreen, int scwidth, unsigned short _lborder, unsigned short _rborder)
115{ 129{
116 int gzoom = fc->gzoom(); 130 int gzoom = fc->gzoom();
117 int currentx = 0, end = 0; 131 int currentx = 0, end = 0;
118 QString text = (numchars < 0) ? toQString(data()) : toQString(data(), numchars); 132 QString text = (numchars < 0) ? toQString(data()) : toQString(data(), numchars);
119 CList<textsegment>::iterator textstart = segs.begin(); 133 CList<textsegment>::iterator textstart = segs.begin();
120 int extraspace = 0; 134 int extraspace = 0;
@@ -147,13 +161,13 @@ int CDrawBuffer::width(int numchars, bool onscreen, int scwidth, unsigned char _
147 if (spaces == 0) 161 if (spaces == 0)
148 { 162 {
149 just = false; 163 just = false;
150 } 164 }
151 else 165 else
152 { 166 {
153 extraspace = (scwidth - 2*_border - rightMargin() - leftMargin() - width()); 167 extraspace = (scwidth - (_lborder+_rborder) - rightMargin() - leftMargin() - width(availht));
154 if (extraspace == 0) just = false; 168 if (extraspace == 0) just = false;
155 } 169 }
156 } 170 }
157 CList<textsegment>::iterator textend = textstart; 171 CList<textsegment>::iterator textend = textstart;
158 do 172 do
159 { 173 {
@@ -165,13 +179,19 @@ int CDrawBuffer::width(int numchars, bool onscreen, int scwidth, unsigned char _
165 } 179 }
166 CStyle currentstyle = textstart->style; 180 CStyle currentstyle = textstart->style;
167 if (currentstyle.isPicture()) 181 if (currentstyle.isPicture())
168 { 182 {
169 if (currentstyle.canScale()) 183 if (currentstyle.canScale())
170 { 184 {
171 currentx += (gzoom*currentstyle.getPicture()->width())/100; 185 int ht = (gzoom*currentstyle.getPicture()->height())/100;
186 int wt = (gzoom*currentstyle.getPicture()->width())/100;
187 if (ht > availht)
188 {
189 wt = (wt*availht)/ht;
190 }
191 currentx += wt;
172 } 192 }
173 else 193 else
174 { 194 {
175 currentx += currentstyle.getPicture()->width(); 195 currentx += currentstyle.getPicture()->width();
176 } 196 }
177 } 197 }
@@ -205,13 +225,13 @@ int CDrawBuffer::width(int numchars, bool onscreen, int scwidth, unsigned char _
205 spacesofar += nexttoadd; 225 spacesofar += nexttoadd;
206 lastspace = nsp; 226 lastspace = nsp;
207 } 227 }
208 else 228 else
209 { 229 {
210 QString nstr = str.mid(lastspace+1, nsp-lastspace); 230 QString nstr = str.mid(lastspace+1, nsp-lastspace);
211 // odebug << "str:" << str << ": last:" << lastspace << " new:" << nsp << " nstr:" << nstr << ":" << oendl; 231 // qDebug("str:%s: last:%d new:%d nstr:%s:", (const char*)str, lastspace, nsp, (const char*)nstr);
212 int lw = fm.width(nstr); 232 int lw = fm.width(nstr);
213 cx += lw; 233 cx += lw;
214 lastspace = nsp; 234 lastspace = nsp;
215 } 235 }
216 } 236 }
217 QString nstr = str.right(str.length()-1-lastspace); 237 QString nstr = str.right(str.length()-1-lastspace);
@@ -227,54 +247,181 @@ int CDrawBuffer::width(int numchars, bool onscreen, int scwidth, unsigned char _
227 textstart = textend; 247 textstart = textend;
228 } 248 }
229 while (textend != segs.end() && end != numchars && textstart->start < len); 249 while (textend != segs.end() && end != numchars && textstart->start < len);
230 return currentx; 250 return currentx;
231} 251}
232 252
253int CDrawBuffer::charwidth(int numchars, CStyle& currentstyle)
254{
255 if (currentstyle.isPicture())
256 {
257 int gzoom = fc->gzoom();
258 if (currentstyle.canScale())
259 {
260 return (gzoom*currentstyle.getPicture()->width())/100;
261 }
262 else
263 {
264 return currentstyle.getPicture()->width();
265 }
266 }
267 else
268 {
269 if (currentstyle.isMono() && !fc->hasCourier())
270 {
271 return (7*fc->getsize(currentstyle))/10;
272 }
273 else
274 {
275 QString text = QChar((data())[numchars]);
276 QFont f(currentstyle.isMono() ? QString(fc->fixedfontname()) : fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) );
277 // f.setUnderline(currentstyle.isUnderline());
278 QFontMetrics fm(f);
279 return fm.width(text);
280 }
281 }
282 return 0;
283}
284
285int CDrawBuffer::charwidth(int numchars)
286{
287 int gzoom = fc->gzoom();
288 int end = 0;
289 QString text = QChar((data())[numchars]);
290 CList<textsegment>::iterator textstart = segs.begin();
291 CList<textsegment>::iterator textend = textstart;
292 do
293 {
294 textend++;
295 end = (textend != segs.end()) ? textend->start : len;
296 if (end <= numchars)
297 {
298 textstart = textend;
299 continue;
300 }
301 if (numchars >= 0 && end > numchars)
302 {
303 end = numchars;
304 }
305 CStyle currentstyle = textstart->style;
306 if (currentstyle.isPicture())
307 {
308 if (currentstyle.canScale())
309 {
310 return (gzoom*currentstyle.getPicture()->width())/100;
311 }
312 else
313 {
314 return currentstyle.getPicture()->width();
315 }
316 }
317 else
318 {
319 if (currentstyle.isMono() && !fc->hasCourier())
320 {
321 return (7*fc->getsize(currentstyle))/10;
322 }
323 else
324 {
325 QFont f(currentstyle.isMono() ? QString(fc->fixedfontname()) : fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) );
326 // f.setUnderline(currentstyle.isUnderline());
327 QFontMetrics fm(f);
328 return fm.width(text);
329 }
330 }
331 textstart = textend;
332 }
333 while (textend != segs.end() /* && end != numchars*/ && textstart->start < len);
334 return 0;
335}
336
337
338
233int CDrawBuffer::leftMargin() 339int CDrawBuffer::leftMargin()
234{ 340{
235 return (segs.begin()->style.getLeftMargin()*fc->getsize(segs.begin()->style)+3)/6; 341 return (segs.begin()->style.getLeftMargin()*fc->getsize(segs.begin()->style)+3)/6;
236} 342}
237 343
238int CDrawBuffer::rightMargin() 344int CDrawBuffer::rightMargin()
239{ 345{
240 return (segs.begin()->style.getRightMargin()*fc->getsize(segs.begin()->style)+3)/6; 346 return (segs.begin()->style.getRightMargin()*fc->getsize(segs.begin()->style)+3)/6;
241} 347}
242 348
243int CDrawBuffer::offset(int scwidth, unsigned char _border) 349int CDrawBuffer::offset(int scwidth, unsigned short _lborder, unsigned short _rborder, int availht)
244{ 350{
245 int currentx = _border; 351 int currentx = _lborder;
246 switch(segs.begin()->style.getJustify()) 352 switch(segs.begin()->style.getJustify())
247 { 353 {
248 case m_AlignRight: 354 case m_AlignRight:
249 { 355 {
250 currentx = scwidth - _border - rightMargin() - width(); 356 currentx = scwidth - _rborder - rightMargin() - width(availht);
251 } 357 }
252 break; 358 break;
253 case m_AlignCentre: 359 case m_AlignCentre:
254 { 360 {
255 currentx = ( 361 currentx = (
256 scwidth + 362 scwidth - _lborder -_rborder +
257 leftMargin() - rightMargin() 363 leftMargin() - rightMargin()
258 - width())/2; 364 - width(availht))/2 + _lborder;
259 } 365 }
260 break; 366 break;
261 case m_AlignJustify: 367 case m_AlignJustify:
262 case m_AlignLeft: 368 case m_AlignLeft:
263 currentx = _border + leftMargin(); 369 currentx = _lborder + leftMargin();
264 break; 370 break;
265 } 371 }
266 return currentx; 372 return currentx;
267} 373}
268 374
269void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int scwidth, unsigned char _border) 375void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int scwidth, unsigned short _lborder, unsigned short _rborder, const QColor& _bg, int availht)
270{ 376{
377 CList<textsegment>::iterator textstart = segs.begin();
378 QColor paperColour = QColor(qRgb(textstart->style.pRed(),
379 textstart->style.pGreen(),
380 textstart->style.pBlue()));
381
382 Highlight(_p, !(paperColour == _bg), _lborder, _y, scwidth-(_lborder+_rborder), paperColour);
383 // Highlight(_p, true, _lborder, _y, scwidth-(_lborder+_rborder), paperColour);
271 int gzoom = fc->gzoom(); 384 int gzoom = fc->gzoom();
272 int currentx = offset(scwidth, _border); 385 int currentx = offset(scwidth, _lborder, _rborder, availht);
386 if (!m_hastext)
387 {
388 for (CList<textsegment>::iterator iter = segs.begin(); iter != segs.end(); iter++)
389 {
390 CStyle currentstyle = iter->style;
391 if (currentstyle.isPicture())
392 {
393 CStyle currentstyle = segs.begin()->style;
394 int ht = (gzoom*currentstyle.getPicture()->height())/100;
395 int wt = (gzoom*currentstyle.getPicture()->width())/100;
396 bool willscale = false;
397 if (ht > availht)
398 {
399 wt = (wt*availht)/ht;
400 ht = availht;
401 willscale = true;
402 }
403
404 QPixmap pc;
405 if ((willscale || gzoom != 100) && currentstyle.canScale())
406 {
407 QImage im = currentstyle.getPicture()->smoothScale(wt,ht);
408 pc.convertFromImage(im);
409 }
410 else
411 {
412 pc.convertFromImage(*currentstyle.getPicture());
413 }
414 int yoffset = pc.height()/2;
415 _p->drawPixmap( currentx, _y-yoffset, pc );
416 currentx += pc.width();
417 }
418 }
419 return;
420 }
273 QString text = toQString(data()); 421 QString text = toQString(data());
274 CList<textsegment>::iterator textstart = segs.begin();
275 int extraspace = 0; 422 int extraspace = 0;
276 bool just = (!m_bEop && textstart->style.getJustify() == m_AlignJustify); 423 bool just = (!m_bEop && textstart->style.getJustify() == m_AlignJustify);
277 int spaces = 0; 424 int spaces = 0;
278 int spacesofar = 0; 425 int spacesofar = 0;
279 int spacenumber = 0; 426 int spacenumber = 0;
280 int nonspace = 0; 427 int nonspace = 0;
@@ -302,35 +449,56 @@ void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int
302 if (spaces == 0) 449 if (spaces == 0)
303 { 450 {
304 just = false; 451 just = false;
305 } 452 }
306 else 453 else
307 { 454 {
308 extraspace = (scwidth - 2*_border - rightMargin() - leftMargin() - width()); 455 extraspace = (scwidth - (_lborder+_rborder) - rightMargin() - leftMargin() - width(availht));
309 if (extraspace == 0) just = false; 456 if (extraspace == 0) just = false;
310 } 457 }
311 } 458 }
312 CList<textsegment>::iterator textend = textstart; 459 CList<textsegment>::iterator textend = textstart;
460
461 bool drawBackground = false;
313 do 462 do
314 { 463 {
315 textend++; 464 textend++;
316 int end = (textend != segs.end()) ? textend->start : len; 465 int end = (textend != segs.end()) ? textend->start : len;
317 CStyle currentstyle = textstart->style; 466 CStyle currentstyle = textstart->style;
467 /*
468 bool drawBackground = (
469 currentstyle.bRed() != 255
470 ||
471 currentstyle.bGreen() != 255
472 ||
473 currentstyle.bBlue() != 255
474 );
475 */
476 QColor bgColour = QColor(qRgb(currentstyle.bRed(),
477 currentstyle.bGreen(),
478 currentstyle.bBlue()));
479 drawBackground = !(bgColour == _bg);
480
481// if (drawBackground) qDebug("Drawing background");
482
318 QFont f((currentstyle.isMono() && fc->hasCourier()) ? fc->fixedfontname() : fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) ); 483 QFont f((currentstyle.isMono() && fc->hasCourier()) ? fc->fixedfontname() : fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) );
319 //f.setUnderline(currentstyle.isUnderline()); 484 //f.setUnderline(currentstyle.isUnderline());
320 //if (currentstyle.isUnderline()) odebug << "UNDERLINE" << oendl; 485 //if (currentstyle.isUnderline()) qDebug("UNDERLINE");
321 _p->setFont(f); 486 _p->setFont(f);
322 QString str = text.mid(textstart->start, end-textstart->start); 487 QString str = text.mid(textstart->start, end-textstart->start);
323#if defined(OPIE) || !defined(USEQPE) 488#if defined(OPIE) || !defined(USEQPE)
324 _p->setPen(QPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue()), fc->getsize(currentstyle)/100)); 489 _p->setPen(QPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue()), fc->getsize(currentstyle)/100));
325#else 490#else
326 _p->setPen(QPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue()), fc->getsize(currentstyle)/10)); 491 _p->setPen(QPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue()), fc->getsize(currentstyle)/10));
327#endif 492#endif
328 int voffset = currentstyle.getVOffset()*fc->getsize(currentstyle)/2; 493 int voffset = currentstyle.getVOffset()*fc->getsize(currentstyle)/2;
494
329 if (_bMono) 495 if (_bMono)
330 { 496 {
497
498 Highlight(_p, drawBackground, currentx, _y, str.length()*_charWidth, bgColour);
331 if (currentstyle.isUnderline()) 499 if (currentstyle.isUnderline())
332 { 500 {
333 _p->drawLine( currentx, _y+voffset, currentx + str.length()*_charWidth, _y+voffset); 501 _p->drawLine( currentx, _y+voffset, currentx + str.length()*_charWidth, _y+voffset);
334 } 502 }
335 if (currentstyle.isStrikethru()) 503 if (currentstyle.isStrikethru())
336 { 504 {
@@ -346,17 +514,24 @@ void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int
346 else 514 else
347 { 515 {
348 if (currentstyle.isPicture()) 516 if (currentstyle.isPicture())
349 { 517 {
350 int ht = (gzoom*currentstyle.getPicture()->height())/100; 518 int ht = (gzoom*currentstyle.getPicture()->height())/100;
351 int wt = (gzoom*currentstyle.getPicture()->width())/100; 519 int wt = (gzoom*currentstyle.getPicture()->width())/100;
520 bool willscale = false;
521 if (ht > availht)
522 {
523 wt = (wt*availht)/ht;
524 ht = availht;
525 willscale = true;
526 }
352 int ascent = fc->ascent(currentstyle)/2; 527 int ascent = fc->ascent(currentstyle)/2;
353 int yoffset = ht/2 + ascent; 528 int yoffset = ht/2 + ascent;
354 529
355 QPixmap pc; 530 QPixmap pc;
356 if (gzoom != 100 && currentstyle.canScale()) 531 if ((willscale || gzoom != 100) && currentstyle.canScale())
357 { 532 {
358 QImage im = currentstyle.getPicture()->smoothScale(wt,ht); 533 QImage im = currentstyle.getPicture()->smoothScale(wt,ht);
359 pc.convertFromImage(im); 534 pc.convertFromImage(im);
360 } 535 }
361 else 536 else
362 { 537 {
@@ -368,12 +543,13 @@ void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int
368 else 543 else
369 { 544 {
370 if (currentstyle.isMono() && !fc->hasCourier()) 545 if (currentstyle.isMono() && !fc->hasCourier())
371 { 546 {
372 int cw = (7*fc->getsize(currentstyle))/10; 547 int cw = (7*fc->getsize(currentstyle))/10;
373 int w = cw*(end-textstart->start); 548 int w = cw*(end-textstart->start);
549 Highlight(_p, drawBackground, currentx, _y, w, bgColour);
374 if (currentstyle.isUnderline()) 550 if (currentstyle.isUnderline())
375 { 551 {
376 _p->drawLine( currentx, _y+voffset, currentx + w, _y+voffset); 552 _p->drawLine( currentx, _y+voffset, currentx + w, _y+voffset);
377 } 553 }
378 if (currentstyle.isStrikethru()) 554 if (currentstyle.isStrikethru())
379 { 555 {
@@ -405,38 +581,45 @@ void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int
405 { 581 {
406 if (nsp+textstart->start >= nonspace) 582 if (nsp+textstart->start >= nonspace)
407 { 583 {
408 spacenumber++; 584 spacenumber++;
409 int nexttoadd = (extraspace*spacenumber+spaces/2)/spaces - spacesofar; 585 int nexttoadd = (extraspace*spacenumber+spaces/2)/spaces - spacesofar;
410 QString nstr = str.mid(lastspace+1, nsp-lastspace); 586 QString nstr = str.mid(lastspace+1, nsp-lastspace);
411 // odebug << "str:" << str << ": last:" << lastspace << " new:" << nsp << " nstr:" << nstr << ":" << oendl; 587 // qDebug("str:%s: last:%d new:%d nstr:%s:", (const char*)str, lastspace, nsp, (const char*)nstr);
412 int lw = fm.width(nstr); 588 int lw = fm.width(nstr);
589 Highlight(_p, drawBackground, cx, _y, lw, bgColour);
413 _p->drawText( cx, _y+voffset, nstr); 590 _p->drawText( cx, _y+voffset, nstr);
591 Highlight(_p, drawBackground, cx+lw, _y, nexttoadd, bgColour);
414 cx += lw+nexttoadd; 592 cx += lw+nexttoadd;
415 spacesofar += nexttoadd; 593 spacesofar += nexttoadd;
416 lastspace = nsp; 594 lastspace = nsp;
417 } 595 }
418 else 596 else
419 { 597 {
420 QString nstr = str.mid(lastspace+1, nsp-lastspace); 598 QString nstr = str.mid(lastspace+1, nsp-lastspace);
421 // odebug << "str:" << str << ": last:" << lastspace << " new:" << nsp << " nstr:" << nstr << ":" << oendl; 599 // qDebug("str:%s: last:%d new:%d nstr:%s:", (const char*)str, lastspace, nsp, (const char*)nstr);
422 int lw = fm.width(nstr); 600 int lw = fm.width(nstr);
601 Highlight(_p, drawBackground, cx, _y, lw, bgColour);
423 _p->drawText( cx, _y+voffset, nstr); 602 _p->drawText( cx, _y+voffset, nstr);
424 cx += lw; 603 cx += lw;
425 lastspace = nsp; 604 lastspace = nsp;
426 } 605 }
427 } 606 }
428 QString nstr = str.right(str.length()-1-lastspace); 607 QString nstr = str.right(str.length()-1-lastspace);
608 int lw = fm.width(nstr);
609 Highlight(_p, drawBackground, cx, _y, lw, bgColour);
429 _p->drawText( cx, _y+voffset, nstr); 610 _p->drawText( cx, _y+voffset, nstr);
430 cx += fm.width(nstr); 611 cx += lw;
431 w = cx - currentx; 612 w = cx - currentx;
432 } 613 }
433 else 614 else
434 { 615 {
616 int lw = fm.width(str);
617 Highlight(_p, drawBackground, currentx, _y, lw, bgColour);
435 _p->drawText( currentx, _y+voffset, str); 618 _p->drawText( currentx, _y+voffset, str);
436 w = fm.width(str); 619 w = lw;
437 } 620 }
438 if (currentstyle.isUnderline()) 621 if (currentstyle.isUnderline())
439 { 622 {
440 _p->drawLine( currentx, _y+voffset, currentx + w, _y+voffset); 623 _p->drawLine( currentx, _y+voffset, currentx + w, _y+voffset);
441 } 624 }
442 if (currentstyle.isStrikethru()) 625 if (currentstyle.isStrikethru())
@@ -448,99 +631,234 @@ void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int
448 } 631 }
449 } 632 }
450 } 633 }
451 textstart = textend; 634 textstart = textend;
452 } 635 }
453 while (textend != segs.end() && textstart->start < len); 636 while (textend != segs.end() && textstart->start < len);
637/*
638 if (firstColour == bgColour)
639 {
640 Highlight(_p, drawBackground, currentx, _y, scwidth - (currentx + _lborder + _rborder), bgColour);
641 }
642 */
643}
644
645void CDrawBuffer::Highlight(QPainter* _p, bool drawBackground, int _x, int _y, int w, QColor bgColour)
646{
647 if (drawBackground)
648 {
649 _p->fillRect(_x, _y-m_ascent, w, m_lineSpacing, bgColour);
650 }
454} 651}
455 652
456CStyle CDrawBuffer::laststyle() 653CStyle CDrawBuffer::laststyle()
457{ 654{
458 return segs.last().style; 655 return segs.last().style;
459} 656}
460 657
461linkType CDrawBuffer::getLinkType(int numchars, size_t& tgt) 658CStyle CDrawBuffer::firststyle()
659{
660 return segs.first().style;
661}
662
663linkType CDrawBuffer::getLinkType(int numchars, size_t& tgt, size_t& offset, size_t& pictgt, QImage*& img)
462{ 664{
665 linkType ret = eNone;
463 int end = 0; 666 int end = 0;
464 CStyle currentstyle; 667 CStyle currentstyle;
465 CList<textsegment>::iterator textstart = segs.begin(); 668 CList<textsegment>::iterator textstart = segs.begin();
466 CList<textsegment>::iterator textend = textstart; 669 CList<textsegment>::iterator textend = textstart;
467 do 670 do
468 { 671 {
469 textend++; 672 textend++;
470 end = (textend != segs.end()) ? textend->start : len; 673 end = (textend != segs.end()) ? textend->start : len;
471 currentstyle = textstart->style; 674 currentstyle = textstart->style;
472/* 675/*
473 if (currentstyle.isPicture()) odebug << "Passed thru picture" << oendl; 676 if (currentstyle.isPicture()) qDebug("Passed thru picture");
474 if (currentstyle.getLink()) odebug << "Passed thru link" << oendl; 677 if (currentstyle.getLink()) qDebug("Passed thru link");
475 //odebug << "islink:" << numchars << " - " << end << "" << oendl; 678 //qDebug("islink:%d - %d", numchars, end);
476*/ 679*/
477 textstart = textend; 680 textstart = textend;
478 } 681 }
479 while (textend != segs.end() && end <= numchars); 682 while (textend != segs.end() && end <= numchars);
480// if (currentstyle.isPicture()) odebug << "Clicked on picture" << oendl; 683 img = currentstyle.getPicture();
481 if (currentstyle.getPictureLink()) 684 if (currentstyle.getPictureLink())
482 { 685 {
483 tgt = currentstyle.getPictureLinkData(); 686 pictgt = currentstyle.getPictureLinkData();
484 return ePicture; 687 ret |= ePicture;
485 } 688 }
486 if (currentstyle.getLink()) 689 if (currentstyle.getLink())
487 { 690 {
488 tgt = currentstyle.getData(); 691 tgt = currentstyle.getData();
489 return eLink; 692 offset = currentstyle.getOffset();
693 ret |= eLink;
490 } 694 }
491 return eNone; 695 return ret;
492} 696}
493 697
494void CDrawBuffer::resize() 698void CDrawBuffer::resize(int availht)
495{ 699{
496 int gzoom = fc->gzoom(); 700 int gzoom = fc->gzoom();
497 m_maxstyle = m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0; 701 m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0;
702 /*
703 int t_ascent = 0;
704 int t_descent = 0;
705 int t_lineExtraSpacing = 0;
706 */
707 int t_lineSpacing = 0;
708 m_hastext = false;
498 for (CList<textsegment>::iterator iter = segs.begin(); iter != segs.end() && iter->start <= len; ) 709 for (CList<textsegment>::iterator iter = segs.begin(); iter != segs.end() && iter->start <= len; )
499 { 710 {
500 CList<textsegment>::iterator next = iter; 711 CStyle _style = iter->style;
501 iter++; 712 if (!_style.isPicture())
502 int st = next->start; 713 {
503 if (st < 0) st = 0; 714 m_hastext = true;
715 break;
716 }
717 iter++;
718 }
719 if (m_hastext)
720 {
721
722 for (CList<textsegment>::iterator iter = segs.begin(); iter != segs.end() && iter->start <= len; )
723 {
724 CList<textsegment>::iterator next = iter;
725 iter++;
726 int st = next->start;
727 if (st < 0) st = 0;
728
729 CStyle _style = next->style;
730
731 int linespacing, ascent, descent, extra;
732
733 ascent = fc->ascent(_style);
734 descent = fc->descent(_style);
735 linespacing = fc->lineSpacing(_style);
736 extra = linespacing - ascent - descent;
737 /*
738 if (ascent > t_ascent) t_ascent = ascent;
739 if (descent > t_descent) t_descent = descent;
740 if (extra > t_lineExtraSpacing) t_lineExtraSpacing = extra;
741 t_lineSpacing = t_ascent+t_descent+t_lineExtraSpacing;
742 */
743 if (linespacing > t_lineSpacing) t_lineSpacing = linespacing;
744 if (_style.isPicture())
745 {
746 int ht = (gzoom*_style.getPicture()->height())/100;
747 int wt = (gzoom*_style.getPicture()->width())/100;
504 748
505 CStyle _style = next->style; 749 bool willscale = false;
750 if (ht > availht)
751 {
752 wt = (wt*availht)/ht;
753 ht = availht;
754 willscale = true;
755 }
756 if (willscale || _style.canScale())
757 {
758 descent = ((gzoom*_style.getPicture()->height())/100-ascent)/2;
759 ascent = ((gzoom*_style.getPicture()->height())/100+ascent)/2;
760 }
761 }
762
763 /*
764 else if (fc != NULL)
765 {
766 ascent = fc->ascent(_style);
767 descent = fc->descent(_style);
768 linespacing = fc->lineSpacing(_style);
769 extra = linespacing - ascent - descent;
770 }
771 */
772 if (ascent > m_ascent) m_ascent = ascent;
773 if (descent > m_descent) m_descent = descent;
774 if (extra > m_lineExtraSpacing) m_lineExtraSpacing = extra;
775 m_lineSpacing = m_ascent+m_descent+m_lineExtraSpacing;
776 }
777 m_showPartial = (m_lineSpacing > t_lineSpacing);
778 int lead = fc->getlead();
779 if (lead != 0)
780 {
781 int xt = (lead*t_lineSpacing+5)/10;
782 m_lineExtraSpacing += xt;
783 m_lineSpacing += xt;
784 }
785 if (m_bSop)
786 {
787 int xt = ((segs.begin()->style.getExtraSpace()+fc->getextraspace())*fc->getsize(segs.begin()->style)+5)/10;
788 //qDebug("ExtraSpace:%d", xt);
789 m_ascent += xt;
790 m_lineSpacing += xt;
791 }
792 }
793 else
794 {
795 m_showPartial = true;
796 int maxheight = 0;
797 for (CList<textsegment>::iterator iter = segs.begin(); iter != segs.end(); iter++)
798 {
799 CStyle _style = iter->style;
800 if (_style.isPicture())
801 {
802 int ht = 0;
803 if (_style.canScale())
804 {
805 ht = ((gzoom*_style.getPicture()->height())/100);
806 }
807 else
808 {
809 ht = _style.getPicture()->height();
810 }
811 if (ht > availht)
812 {
813 ht = availht;
814 }
815 if (ht > maxheight) maxheight = ht;
816 }
817 }
818 m_ascent = maxheight/2;
819 m_descent = maxheight-m_ascent;
820 m_lineExtraSpacing = 0;
821 m_lineSpacing = m_ascent+m_descent;
822 }
823}
506 824
507 int linespacing, ascent, descent, extra; 825CStyle* CDrawBuffer::getNextLink(int& offset)
826{
827 CStyle* ret = NULL;
828 for (CList<textsegment>::iterator iter = segs.begin(); iter != segs.end(); ++iter)
829 {
830 if (offset < iter->start && iter->style.getLink())
831 {
832 ret = &(iter->style);
833 offset = iter->start;
834 qDebug("Found a link at offset %d!", offset);
835 break;
836 }
837 }
838 return ret;
839}
508 840
509 ascent = fc->ascent(_style); 841int CDrawBuffer::invertLink(int offset)
510 descent = fc->descent(_style); 842{
511 linespacing = fc->lineSpacing(_style); 843 for (CList<textsegment>::iterator iter = segs.begin(); iter != segs.end(); ++iter)
512 extra = linespacing - ascent - descent; 844 {
513 if (_style.isPicture() && _style.canScale()) 845 if (offset <= iter->start && iter->style.getLink())
514 { 846 {
515 descent = ((gzoom*_style.getPicture()->height())/100-ascent)/2; 847 iter->style.invert();
516 ascent = ((gzoom*_style.getPicture()->height())/100+ascent)/2; 848 unsigned long currentvalue = iter->style.getData();
517 } 849 qDebug("Link data %u", currentvalue);
518/* 850 CList<textsegment>::iterator next = iter;
519 else if (fc != NULL) 851 ++next;
520 { 852 while (next != segs.end() && (currentvalue == next->style.getData()) && next->style.getLink())
521 ascent = fc->ascent(_style); 853 {
522 descent = fc->descent(_style); 854 next->style.invert();
523 linespacing = fc->lineSpacing(_style); 855 offset = next->start;
524 extra = linespacing - ascent - descent; 856 iter++;
525 } 857 next++;
526*/ 858 }
527 if (ascent > m_ascent) m_ascent = ascent; 859 return offset;
528 if (descent > m_descent) m_descent = descent; 860 }
529 if (extra > m_lineExtraSpacing) m_lineExtraSpacing = extra; 861 }
530 m_lineSpacing = m_ascent+m_descent+m_lineExtraSpacing; 862 qDebug("Failed to invert");
531 } 863 return offset;
532 int lead = fc->getlead();
533 if (lead != 0)
534 {
535 int xt = (lead*m_lineSpacing+5)/10;
536 m_descent += xt;
537 m_lineSpacing += xt;
538 }
539 if (m_bSop)
540 {
541 int xt = ((segs.begin()->style.getExtraSpace()+fc->getextraspace())*fc->getsize(segs.begin()->style)+5)/10;
542 //odebug << "ExtraSpace:" << xt << "" << oendl;
543 m_ascent += xt;
544 m_lineSpacing += xt;
545 }
546} 864}