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.cpp264
1 files changed, 216 insertions, 48 deletions
diff --git a/noncore/apps/opie-reader/CDrawBuffer.cpp b/noncore/apps/opie-reader/CDrawBuffer.cpp
index 892456f..ca220e6 100644
--- a/noncore/apps/opie-reader/CDrawBuffer.cpp
+++ b/noncore/apps/opie-reader/CDrawBuffer.cpp
@@ -1,19 +1,25 @@
1
2#include "CDrawBuffer.h" 1#include "CDrawBuffer.h"
3#include "FontControl.h" 2#include "FontControl.h"
4#include <qfontmetrics.h> 3#include <qfontmetrics.h>
5#include <qpainter.h> 4#include <qpainter.h>
5#include <qpixmap.h>
6#include "opie.h"
7
8CDrawBuffer::~CDrawBuffer()
9{
10 while (!segs.isEmpty()) segs.erase(0);
11}
6 12
7void CDrawBuffer::setright(CDrawBuffer& rhs, int f) 13void CDrawBuffer::setright(CDrawBuffer& rhs, int f)
8{ 14{
9 int i; 15 int i;
10// qDebug("Trying 1:%d:%s", f, (const char*)toQString(rhs.data()));
11 len = rhs.len; 16 len = rhs.len;
12 m_maxstyle = rhs.m_maxstyle; 17 fc = rhs.fc;
13 m_ascent = rhs.m_ascent; 18 m_maxstyle = m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0;
14 m_descent = rhs.m_descent; 19 while (!segs.isEmpty())
15 m_lineSpacing = rhs.m_lineSpacing; 20 {
16 while (!segs.isEmpty()) segs.erase(0); 21 segs.erase(0);
22 }
17 for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); ) 23 for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); )
18 { 24 {
19 CList<textsegment>::iterator next = iter; 25 CList<textsegment>::iterator next = iter;
@@ -22,13 +28,15 @@ void CDrawBuffer::setright(CDrawBuffer& rhs, int f)
22 { 28 {
23 int st = next->start-f; 29 int st = next->start-f;
24 if (st < 0) st = 0; 30 if (st < 0) st = 0;
31
32 CStyle _style = next->style;
33
25 segs.push_back(textsegment(st,next->style)); 34 segs.push_back(textsegment(st,next->style));
26 } 35 }
27 } 36 }
28 for (i = f; rhs[i] != '\0'; i++) (*this)[i-f] = rhs[i]; 37 for (i = f; rhs[i] != '\0'; i++) (*this)[i-f] = rhs[i];
29 (*this)[i-f] = '\0'; 38 (*this)[i-f] = '\0';
30 len = i; 39 len = i;
31// qDebug("Tried 1");
32} 40}
33 41
34CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs) 42CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs)
@@ -40,7 +48,11 @@ CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs)
40 m_ascent = rhs.m_ascent; 48 m_ascent = rhs.m_ascent;
41 m_descent = rhs.m_descent; 49 m_descent = rhs.m_descent;
42 m_lineSpacing = rhs.m_lineSpacing; 50 m_lineSpacing = rhs.m_lineSpacing;
43 while (!segs.isEmpty()) segs.erase(0); 51 m_lineExtraSpacing = rhs.m_lineExtraSpacing;
52 while (!segs.isEmpty())
53 {
54 segs.erase(0);
55 }
44 for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); iter++) 56 for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); iter++)
45 { 57 {
46 segs.push_back(*iter); 58 segs.push_back(*iter);
@@ -55,7 +67,10 @@ CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs)
55CDrawBuffer& CDrawBuffer::operator=(const tchar*sztmp) 67CDrawBuffer& CDrawBuffer::operator=(const tchar*sztmp)
56{ 68{
57 int i; 69 int i;
58 while (!segs.isEmpty()) segs.erase(0); 70 while (!segs.isEmpty())
71 {
72 segs.erase(0);
73 }
59 segs.push_back(textsegment(0, CStyle())); 74 segs.push_back(textsegment(0, CStyle()));
60 for (i = 0; sztmp[i] != '\0'; i++) (*this)[i] = sztmp[i]; 75 for (i = 0; sztmp[i] != '\0'; i++) (*this)[i] = sztmp[i];
61 (*this)[i] = '\0'; 76 (*this)[i] = '\0';
@@ -67,33 +82,24 @@ void CDrawBuffer::empty()
67{ 82{
68 len = 0; 83 len = 0;
69 (*this)[0] = 0; 84 (*this)[0] = 0;
70 while (!segs.isEmpty()) segs.erase(0); 85 while (!segs.isEmpty())
86 {
87 segs.erase(0);
88 }
71 segs.push_back(textsegment(0,CStyle())); 89 segs.push_back(textsegment(0,CStyle()));
72 m_maxstyle = m_ascent = m_descent = m_lineSpacing = 0; 90 m_maxstyle = m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0;
91 m_bEof = false;
73} 92}
74 93
75void CDrawBuffer::addch(tchar ch, CStyle _style/* = ucFontBase*/) 94void CDrawBuffer::addch(tchar ch, CStyle _style/* = ucFontBase*/)
76{ 95{
77 if (len == 0) 96 if (len == 0)
78 { 97 {
79 int thissize = fc->getsize(_style);
80 m_maxstyle = thissize;
81 m_ascent = fc->ascent(_style);
82 m_descent = fc->descent(_style);
83 m_lineSpacing = fc->lineSpacing(_style);
84 segs.first().start = 0; 98 segs.first().start = 0;
85 segs.first().style = _style; 99 segs.first().style = _style;
86 } 100 }
87 else if (_style != segs.last().style) 101 else if (_style != segs.last().style)
88 { 102 {
89 int thissize = fc->getsize(_style);
90 if (thissize > m_maxstyle)
91 {
92 m_maxstyle = thissize;
93 m_ascent = fc->ascent(_style);
94 m_descent = fc->descent(_style);
95 m_lineSpacing = fc->lineSpacing(_style);
96 }
97 segs.push_back(textsegment(len, _style)); 103 segs.push_back(textsegment(len, _style));
98 } 104 }
99 (*this)[len++] = ch; 105 (*this)[len++] = ch;
@@ -120,52 +126,119 @@ int CDrawBuffer::width(int numchars)
120 end = numchars; 126 end = numchars;
121 } 127 }
122 CStyle currentstyle = textstart->style; 128 CStyle currentstyle = textstart->style;
123 QFont f(fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) ); 129 if (currentstyle.isPicture())
124 QString str = text.mid(textstart->start, end-textstart->start); 130 {
125 QFontMetrics fm(f); 131 currentx += currentstyle.getPicture()->width();
126 currentx += fm.width(str); 132 }
133 else
134 {
135 if (currentstyle.isMono() && !fc->hasCourier())
136 {
137 int cw = (7*fc->getsize(currentstyle))/10;
138 currentx += cw*(end-textstart->start);
139 }
140 else
141 {
142 QFont f(currentstyle.isMono() ? QString("courier") : fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) );
143 // f.setUnderline(currentstyle.isUnderline());
144 QString str = text.mid(textstart->start, end-textstart->start);
145 QFontMetrics fm(f);
146 currentx += fm.width(str);
147 }
148 }
127 textstart = textend; 149 textstart = textend;
128 } 150 }
129 while (textend != segs.end() && end != numchars); 151 while (textend != segs.end() && end != numchars);
130 return currentx; 152 return currentx;
131} 153}
132 154
155int CDrawBuffer::leftMargin()
156{
157 return (segs.begin()->style.getLeftMargin()*fc->getsize(segs.begin()->style))/6;
158}
159
160int CDrawBuffer::rightMargin()
161{
162 return (segs.begin()->style.getRightMargin()*fc->getsize(segs.begin()->style))/6;
163}
164
165int CDrawBuffer::offset(int scwidth)
166{
167 int currentx = BORDER;
168 switch(segs.begin()->style.getJustify())
169 {
170 case m_AlignRight:
171 {
172 currentx = scwidth - BORDER - rightMargin() - width();
173 }
174 break;
175 case m_AlignCentre:
176 {
177 currentx = (
178 scwidth +
179 leftMargin() - rightMargin()
180 - width())/2;
181 }
182 break;
183 case m_AlignJustify:
184 case m_AlignLeft:
185 currentx = BORDER + leftMargin();
186 break;
187 }
188 return currentx;
189}
190
133void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int scwidth) 191void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int scwidth)
134{ 192{
135 int currentx = 0; 193 int currentx = offset(scwidth);
136 QString text = toQString(data()); 194 QString text = toQString(data());
137 CList<textsegment>::iterator textstart = segs.begin(); 195 CList<textsegment>::iterator textstart = segs.begin();
196/*
138 StyleType align = textstart->style.getJustify(); 197 StyleType align = textstart->style.getJustify();
139 switch (align) 198 switch (align)
140 { 199 {
141 case CStyle::m_AlignRight: 200 case CStyle::m_AlignRight:
142 { 201 {
143 // int linelength = width(); 202 currentx = scwidth - width() - 2*BORDER;
144 currentx = scwidth - width();
145 } 203 }
146 break; 204 break;
147 case CStyle::m_AlignCentre: 205 case CStyle::m_AlignCentre:
148 { 206 {
149 // int linelength = width(); 207 currentx = (scwidth - width())/2 - BORDER;
150 currentx = (scwidth - width())/2;
151 } 208 }
152 break; 209 break;
153 case CStyle::m_AlignJustify: 210 case CStyle::m_AlignJustify:
154 case CStyle::m_AlignLeft: 211 case CStyle::m_AlignLeft:
155 break; 212 break;
156 } 213 }
214*/
157 CList<textsegment>::iterator textend = textstart; 215 CList<textsegment>::iterator textend = textstart;
158 do 216 do
159 { 217 {
160 textend++; 218 textend++;
161 int end = (textend != segs.end()) ? textend->start : length(); 219 int end = (textend != segs.end()) ? textend->start : length();
162 CStyle currentstyle = textstart->style; 220 CStyle currentstyle = textstart->style;
163 QFont f(fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) ); 221 QFont f((currentstyle.isMono() && fc->hasCourier()) ? QString("courier") : fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) );
222 //f.setUnderline(currentstyle.isUnderline());
223 //if (currentstyle.isUnderline()) qDebug("UNDERLINE");
164 _p->setFont(f); 224 _p->setFont(f);
165 QString str = text.mid(textstart->start, end-textstart->start); 225 QString str = text.mid(textstart->start, end-textstart->start);
166 _p->setPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue())); 226#ifdef OPIE
227 _p->setPen(QPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue()), fc->getsize(currentstyle)/100));
228#else
229 _p->setPen(QPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue()), fc->getsize(currentstyle)/10));
230#endif
167 if (_bMono) 231 if (_bMono)
168 { 232 {
233 if (currentstyle.isUnderline())
234 {
235 _p->drawLine( currentx, _y, currentx + str.length()*_charWidth, _y);
236 }
237 if (currentstyle.isStrikethru())
238 {
239 int ascent = fc->ascent(currentstyle)/3;
240 _p->drawLine( currentx, _y-ascent, currentx + str.length()*_charWidth, _y-ascent);
241 }
169 for (int i = 0; i < str.length(); i++) 242 for (int i = 0; i < str.length(); i++)
170 { 243 {
171 _p->drawText( currentx + i*_charWidth, _y, QString(str[i])); 244 _p->drawText( currentx + i*_charWidth, _y, QString(str[i]));
@@ -174,13 +247,57 @@ void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int
174 } 247 }
175 else 248 else
176 { 249 {
177 _p->drawText( currentx, _y, str); 250 if (currentstyle.isPicture())
178 QFontMetrics fm(f); 251 {
179 currentx += fm.width(str); 252 int ascent = fc->ascent(currentstyle)/2;
253 int yoffset = currentstyle.getPicture()->height()/2 + ascent;
254 _p->drawPixmap( currentx, _y-yoffset, *(currentstyle.getPicture()));
255 currentx += currentstyle.getPicture()->width();
256 }
257 else
258 {
259 if (currentstyle.isMono() && !fc->hasCourier())
260 {
261 int cw = (7*fc->getsize(currentstyle))/10;
262 int w = cw*(end-textstart->start);
263 if (currentstyle.isUnderline())
264 {
265 _p->drawLine( currentx, _y, currentx + w, _y);
266 }
267 if (currentstyle.isStrikethru())
268 {
269 int ascent = fc->ascent(currentstyle)/3;
270 _p->drawLine( currentx, _y-ascent, currentx + w, _y-ascent);
271 }
272 QString str = text.mid(textstart->start, end-textstart->start);
273
274 for (int i = 0; i < str.length(); i++)
275 {
276 _p->drawText( currentx, _y, QString(str[i]));
277 currentx += cw;
278 }
279 }
280 else
281 {
282 QFontMetrics fm(f);
283 int w = fm.width(str);
284 if (currentstyle.isUnderline())
285 {
286 _p->drawLine( currentx, _y, currentx + w, _y);
287 }
288 if (currentstyle.isStrikethru())
289 {
290 int ascent = fc->ascent(currentstyle)/3;
291 _p->drawLine( currentx, _y-ascent, currentx + w, _y-ascent);
292 }
293 _p->drawText( currentx, _y, str);
294 currentx += w;
295 }
296 }
180 } 297 }
181 textstart = textend; 298 textstart = textend;
182 } 299 }
183 while (textend != segs.end()); 300 while (textend != segs.end() && textstart->start < length()-1);
184} 301}
185 302
186CStyle CDrawBuffer::laststyle() 303CStyle CDrawBuffer::laststyle()
@@ -188,7 +305,7 @@ CStyle CDrawBuffer::laststyle()
188 return segs.last().style; 305 return segs.last().style;
189} 306}
190 307
191bool CDrawBuffer::isLink(int numchars, size_t& tgt) 308linkType CDrawBuffer::getLinkType(int numchars, size_t& tgt)
192{ 309{
193 int end = 0; 310 int end = 0;
194 CStyle currentstyle; 311 CStyle currentstyle;
@@ -198,14 +315,65 @@ bool CDrawBuffer::isLink(int numchars, size_t& tgt)
198 { 315 {
199 textend++; 316 textend++;
200 end = (textend != segs.end()) ? textend->start : length(); 317 end = (textend != segs.end()) ? textend->start : length();
201 if (numchars >= 0 && end > numchars)
202 {
203 end = numchars;
204 }
205 currentstyle = textstart->style; 318 currentstyle = textstart->style;
319/*
320 if (currentstyle.isPicture()) qDebug("Passed thru picture");
321 if (currentstyle.getLink()) qDebug("Passed thru link");
322 qDebug("islink:%d - %d", numchars, end);
323*/
206 textstart = textend; 324 textstart = textend;
207 } 325 }
208 while (textend != segs.end() && end != numchars); 326 while (textend != segs.end() && end <= numchars);
209 tgt = currentstyle.getData(); 327// if (currentstyle.isPicture()) qDebug("Clicked on picture");
210 return currentstyle.getLink(); 328 if (currentstyle.getPictureLink())
329 {
330 tgt = currentstyle.getPictureLinkData();
331 return ePicture;
332 }
333 if (currentstyle.getLink())
334 {
335 tgt = currentstyle.getData();
336 return eLink;
337 }
338 return eNone;
339}
340
341void CDrawBuffer::resize()
342{
343 int i;
344 m_maxstyle = m_ascent = m_descent = m_lineSpacing = m_lineExtraSpacing = 0;
345 for (CList<textsegment>::iterator iter = segs.begin(); iter != segs.end() && iter->start <= length(); )
346 {
347 CList<textsegment>::iterator next = iter;
348 iter++;
349 int st = next->start;
350 if (st < 0) st = 0;
351
352 CStyle _style = next->style;
353
354 int linespacing, ascent, descent, extra;
355
356 ascent = fc->ascent(_style);
357 descent = fc->descent(_style);
358 linespacing = fc->lineSpacing(_style);
359 extra = linespacing - ascent - descent;
360 if (_style.isPicture())
361 {
362 descent = (_style.getPicture()->height()-ascent)/2;
363 ascent = (_style.getPicture()->height()+ascent)/2;
364 }
365/*
366 else if (fc != NULL)
367 {
368 ascent = fc->ascent(_style);
369 descent = fc->descent(_style);
370 linespacing = fc->lineSpacing(_style);
371 extra = linespacing - ascent - descent;
372 }
373*/
374 if (ascent > m_ascent) m_ascent = ascent;
375 if (descent > m_descent) m_descent = descent;
376 if (extra > m_lineExtraSpacing) m_lineExtraSpacing = extra;
377 m_lineSpacing = m_ascent+m_descent+m_lineExtraSpacing;
378 }
211} 379}