KHtml

render_generated.cpp
1 /**
2  * This file is part of the HTML rendering engine for KDE.
3  *
4  * Copyright (C) 2004-2005 Allan Sandfeld Jensen ([email protected])
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "rendering/render_generated.h"
24 #include "rendering/render_style.h"
25 #include "rendering/enumerate.h"
26 #include "rendering/counter_tree.h"
27 #include "css/css_valueimpl.h"
28 
29 using namespace khtml;
30 using namespace Enumerate;
31 
32 // -------------------------------------------------------------------------
33 
34 RenderCounterBase::RenderCounterBase(DOM::NodeImpl *node)
35  : RenderText(node, nullptr), m_counterNode(nullptr)
36 {
37 }
38 
39 void RenderCounterBase::layout()
40 {
41  KHTMLAssert(needsLayout());
42 
43  if (!minMaxKnown()) {
44  calcMinMaxWidth();
45  }
46 
47  RenderText::layout();
48 }
49 
50 void RenderCounterBase::calcMinMaxWidth()
51 {
52  KHTMLAssert(!minMaxKnown());
53 
54  generateContent();
55 
56  if (str) {
57  str->deref();
58  }
59  str = new DOM::DOMStringImpl(m_item.unicode(), m_item.length());
60  str->ref();
61 
62  RenderText::calcMinMaxWidth();
63 }
64 
65 void RenderCounterBase::updateContent()
66 {
67  setMinMaxKnown(false);
68 }
69 
70 // -------------------------------------------------------------------------
71 
72 RenderCounter::RenderCounter(DOM::NodeImpl *node, const DOM::CounterImpl *counter)
73  : RenderCounterBase(node), m_counter(counter)
74 {
75 }
76 
77 QString RenderCounter::toListStyleType(int value, int total, EListStyleType type)
78 {
79  QString item;
80  switch (type) {
81  case LNONE:
82  break;
83 // Glyphs: (these values are not really used and instead handled by RenderGlyph)
84  case LDISC:
85  item = QChar(0x2022);
86  break;
87  case LCIRCLE:
88  item = QChar(0x25e6);
89  break;
90  case LSQUARE:
91  item = QChar(0x25a0);
92  break;
93  case LBOX:
94  item = QChar(0x25a1);
95  break;
96  case LDIAMOND:
97  item = QChar(0x25c6);
98  break;
99 // Numeric:
100  case LDECIMAL:
101  item.setNum(value);
102  break;
103  case DECIMAL_LEADING_ZERO: {
104  int decimals = 2;
105  int t = total / 100;
106  while (t > 0) {
107  t = t / 10;
108  decimals++;
109  }
110  decimals = qMax(decimals, 2);
111  QString num = QString::number(value);
112  item.fill('0', decimals - num.length());
113  item.append(num);
114  break;
115  }
116  case ARABIC_INDIC:
117  item = toArabicIndic(value);
118  break;
119  case LAO:
120  item = toLao(value);
121  break;
122  case PERSIAN:
123  case URDU:
124  item = toPersianUrdu(value);
125  break;
126  case THAI:
127  item = toThai(value);
128  break;
129  case TIBETAN:
130  item = toTibetan(value);
131  break;
132 // Algoritmic:
133  case LOWER_ROMAN:
134  item = toRoman(value, false);
135  break;
136  case UPPER_ROMAN:
137  item = toRoman(value, true);
138  break;
139  case HEBREW:
140  item = toHebrew(value);
141  break;
142  case ARMENIAN:
143  item = toArmenian(value);
144  break;
145  case GEORGIAN:
146  item = toGeorgian(value);
147  break;
148 // Alphabetic:
149  case LOWER_ALPHA:
150  case LOWER_LATIN:
151  item = toLowerLatin(value);
152  break;
153  case UPPER_ALPHA:
154  case UPPER_LATIN:
155  item = toUpperLatin(value);
156  break;
157  case LOWER_GREEK:
158  item = toLowerGreek(value);
159  break;
160  case UPPER_GREEK:
161  item = toUpperGreek(value);
162  break;
163  case HIRAGANA:
164  item = toHiragana(value);
165  break;
166  case HIRAGANA_IROHA:
167  item = toHiraganaIroha(value);
168  break;
169  case KATAKANA:
170  item = toKatakana(value);
171  break;
172  case KATAKANA_IROHA:
173  item = toKatakanaIroha(value);
174  break;
175 // Ideographic:
176  case JAPANESE_FORMAL:
177  item = toJapaneseFormal(value);
178  break;
179  case JAPANESE_INFORMAL:
180  item = toJapaneseInformal(value);
181  break;
182  case SIMP_CHINESE_FORMAL:
183  item = toSimpChineseFormal(value);
184  break;
185  case SIMP_CHINESE_INFORMAL:
186  item = toSimpChineseInformal(value);
187  break;
188  case TRAD_CHINESE_FORMAL:
189  item = toTradChineseFormal(value);
190  break;
191  case CJK_IDEOGRAPHIC:
192  // CSS 3 List says treat as trad-chinese-informal
193  case TRAD_CHINESE_INFORMAL:
194  item = toTradChineseInformal(value);
195  break;
196  default:
197  item.setNum(value);
198  break;
199  }
200  return item;
201 }
202 
203 void RenderCounter::generateContent()
204 {
205  bool counters;
206  counters = !m_counter->separator().isNull();
207 
208  if (!m_counterNode) {
209  m_counterNode = getCounter(m_counter->identifier(), true, counters);
210  }
211 
212  int value = m_counterNode->count();
213  if (m_counterNode->isReset()) {
214  value = m_counterNode->value();
215  }
216  int total = value;
217  if (m_counterNode->parent()) {
218  total = m_counterNode->parent()->total();
219  }
220  m_item = toListStyleType(value, total, (EListStyleType)m_counter->listStyle());
221 
222  if (counters) {
223  CounterNode *counter = m_counterNode->parent();
224  // we deliberately do not render the root counter-node
225  while (counter->parent() && !(counter->isReset() && counter->parent()->isRoot())) {
226  value = counter->count();
227  total = counter->parent()->total();
228  m_item = toListStyleType(value, total, (EListStyleType)m_counter->listStyle()) + m_counter->separator().string() + m_item;
229  counter = counter->parent();
230  };
231  }
232 
233 }
234 
235 // -------------------------------------------------------------------------
236 
237 RenderQuote::RenderQuote(DOM::NodeImpl *node, EQuoteContent type)
238  : RenderCounterBase(node), m_quoteType(type)
239 {
240 }
241 
242 int RenderQuote::quoteCount() const
243 {
244  switch (m_quoteType) {
245  case OPEN_QUOTE:
246  case NO_OPEN_QUOTE:
247  return 1;
248  case CLOSE_QUOTE:
249  case NO_CLOSE_QUOTE:
250  return -1;
251  case NO_QUOTE:
252  return 0;
253  }
254  assert(false);
255  return 0;
256 }
257 
258 void RenderQuote::generateContent()
259 {
260  bool visual;
261  if (m_quoteType == NO_CLOSE_QUOTE || m_quoteType == NO_OPEN_QUOTE) {
262  visual = false;
263  } else {
264  visual = true;
265  }
266 
267  if (!m_counterNode) {
268  m_counterNode = getCounter("-khtml-quotes", visual, false);
269  }
270 
271  int value = m_counterNode->count();
272  if (m_counterNode->isReset()) {
273  value = m_counterNode->value();
274  }
275  switch (m_quoteType) {
276  case OPEN_QUOTE:
277  m_item = style()->openQuote(value);
278  break;
279  case CLOSE_QUOTE:
280  m_item = style()->closeQuote(value);
281  break;
282  case NO_OPEN_QUOTE:
283  case NO_CLOSE_QUOTE:
284  case NO_QUOTE:
285  m_item.clear();
286  }
287 }
288 
289 // -------------------------------------------------------------------------
290 
291 RenderGlyph::RenderGlyph(DOM::NodeImpl *node, EListStyleType type)
292  : RenderBox(node), m_type(type)
293 {
294  setInline(true);
295 // setReplaced(true);
296 }
297 
298 void RenderGlyph::setStyle(RenderStyle *_style)
299 {
300  RenderBox::setStyle(_style);
301 
302  const QFontMetrics &fm = style()->fontMetrics();
303  QRect xSize = fm.boundingRect('x');
304  m_height = xSize.height();
305  m_width = xSize.width();
306 
307  switch (m_type) {
308  // Glyphs:
309  case LDISC:
310  case LCIRCLE:
311  case LSQUARE:
312  case LBOX:
313  case LDIAMOND:
314  case LNONE:
315  break;
316  default:
317  // not a glyph !
318  assert(false);
319  break;
320  }
321 }
322 
323 void RenderGlyph::calcMinMaxWidth()
324 {
325  m_minWidth = m_width;
326  m_maxWidth = m_width;
327 
328  setMinMaxKnown();
329 }
330 
331 short RenderGlyph::lineHeight(bool /*b*/) const
332 {
333  return height();
334 }
335 
336 short RenderGlyph::baselinePosition(bool /*b*/) const
337 {
338  return height();
339 }
340 
341 void RenderGlyph::paint(PaintInfo &paintInfo, int _tx, int _ty)
342 {
343  if (paintInfo.phase != PaintActionForeground) {
344  return;
345  }
346 
347  if (style()->visibility() != VISIBLE) {
348  return;
349  }
350 
351  _tx += m_x;
352  _ty += m_y;
353 
354  if ((_ty > paintInfo.r.bottom()) || (_ty + m_height <= paintInfo.r.top())) {
355  return;
356  }
357 
358  QPainter *p = paintInfo.p;
359 
360  const QColor color(style()->color());
361  p->setPen(color);
362 
363  int xHeight = m_height;
364  int bulletWidth = (xHeight + 1) / 2;
365  int yoff = (xHeight - 1) / 4;
366  QRect marker(_tx, _ty + yoff, bulletWidth, bulletWidth);
367 
368  switch (m_type) {
369  case LDISC:
370  p->setBrush(color);
371  p->drawEllipse(marker);
372  return;
373  case LCIRCLE:
374  p->setBrush(Qt::NoBrush);
375  p->drawEllipse(marker);
376  return;
377  case LSQUARE:
378  p->setBrush(color);
379  p->drawRect(marker);
380  return;
381  case LBOX:
382  p->setBrush(Qt::NoBrush);
383  p->drawRect(marker);
384  return;
385  case LDIAMOND: {
386  static QPolygon diamond(4);
387  int x = marker.x();
388  int y = marker.y();
389  int s = bulletWidth / 2;
390  diamond[0] = QPoint(x + s, y);
391  diamond[1] = QPoint(x + 2 * s, y + s);
392  diamond[2] = QPoint(x + s, y + 2 * s);
393  diamond[3] = QPoint(x, y + s);
394  p->setBrush(color);
395  p->drawConvexPolygon(diamond.constData(), 4);
396  return;
397  }
398  case LNONE:
399  return;
400  default:
401  // not a glyph
402  assert(false);
403  }
404 }
405 
QString & append(QChar ch)
QString & fill(QChar ch, int size)
This file is part of the HTML rendering engine for KDE.
int height() const const
bool isNull() const const
void drawRect(const QRectF &rectangle)
QRect boundingRect(QChar ch) const const
QString number(int n, int base)
void setPen(const QColor &color)
void drawEllipse(const QRectF &rectangle)
void setBrush(const QBrush &brush)
int width() const const
QString & setNum(short n, int base)
void drawConvexPolygon(const QPointF *points, int pointCount)
int length() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 25 2021 22:48:20 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.