Diffstat (limited to 'noncore/apps/opie-reader/CDrawBuffer.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/opie-reader/CDrawBuffer.cpp | 264 |
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,49 +1,61 @@ | |||
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 | |||
8 | CDrawBuffer::~CDrawBuffer() | ||
9 | { | ||
10 | while (!segs.isEmpty()) segs.erase(0); | ||
11 | } | ||
6 | 12 | ||
7 | void CDrawBuffer::setright(CDrawBuffer& rhs, int f) | 13 | void 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; |
20 | iter++; | 26 | iter++; |
21 | if (iter == rhs.segs.end() || iter->start > f) | 27 | if (iter == rhs.segs.end() || iter->start > 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 | ||
34 | CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs) | 42 | CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs) |
35 | { | 43 | { |
36 | int i; | 44 | int i; |
37 | // qDebug("Trying 2"); | 45 | // qDebug("Trying 2"); |
38 | len = rhs.len; | 46 | len = rhs.len; |
39 | m_maxstyle = rhs.m_maxstyle; | 47 | m_maxstyle = rhs.m_maxstyle; |
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); |
47 | } | 59 | } |
48 | for (i = 0; rhs[i] != '\0'; i++) (*this)[i] = rhs[i]; | 60 | for (i = 0; rhs[i] != '\0'; i++) (*this)[i] = rhs[i]; |
49 | (*this)[i] = '\0'; | 61 | (*this)[i] = '\0'; |
@@ -52,51 +64,45 @@ CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs) | |||
52 | return *this; | 64 | return *this; |
53 | } | 65 | } |
54 | 66 | ||
55 | CDrawBuffer& CDrawBuffer::operator=(const tchar*sztmp) | 67 | CDrawBuffer& 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'; |
62 | len = i; | 77 | len = i; |
63 | return *this; | 78 | return *this; |
64 | } | 79 | } |
65 | 80 | ||
66 | void CDrawBuffer::empty() | 81 | 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 | ||
75 | void CDrawBuffer::addch(tchar ch, CStyle _style/* = ucFontBase*/) | 94 | void 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; |
100 | } | 106 | } |
101 | 107 | ||
102 | void CDrawBuffer::truncate(int n) | 108 | void CDrawBuffer::truncate(int n) |
@@ -117,95 +123,257 @@ int CDrawBuffer::width(int numchars) | |||
117 | end = (textend != segs.end()) ? textend->start : length(); | 123 | end = (textend != segs.end()) ? textend->start : length(); |
118 | if (numchars >= 0 && end > numchars) | 124 | if (numchars >= 0 && end > numchars) |
119 | { | 125 | { |
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 | ||
155 | int CDrawBuffer::leftMargin() | ||
156 | { | ||
157 | return (segs.begin()->style.getLeftMargin()*fc->getsize(segs.begin()->style))/6; | ||
158 | } | ||
159 | |||
160 | int CDrawBuffer::rightMargin() | ||
161 | { | ||
162 | return (segs.begin()->style.getRightMargin()*fc->getsize(segs.begin()->style))/6; | ||
163 | } | ||
164 | |||
165 | int 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 | |||
133 | void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int scwidth) | 191 | void 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])); |
172 | } | 245 | } |
173 | currentx += str.length()*_charWidth; | 246 | currentx += str.length()*_charWidth; |
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 | ||
186 | CStyle CDrawBuffer::laststyle() | 303 | CStyle CDrawBuffer::laststyle() |
187 | { | 304 | { |
188 | return segs.last().style; | 305 | return segs.last().style; |
189 | } | 306 | } |
190 | 307 | ||
191 | bool CDrawBuffer::isLink(int numchars, size_t& tgt) | 308 | linkType CDrawBuffer::getLinkType(int numchars, size_t& tgt) |
192 | { | 309 | { |
193 | int end = 0; | 310 | int end = 0; |
194 | CStyle currentstyle; | 311 | CStyle currentstyle; |
195 | CList<textsegment>::iterator textstart = segs.begin(); | 312 | CList<textsegment>::iterator textstart = segs.begin(); |
196 | CList<textsegment>::iterator textend = textstart; | 313 | CList<textsegment>::iterator textend = textstart; |
197 | do | 314 | do |
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 | |||
341 | void 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 | } |