KReport

KReportUtils.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2010-2015 Jarosław Staniek <[email protected]>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18 */
19 
20 #include "KReportUtils.h"
21 #include "KReportUnit.h"
22 #include "KReportItemBase.h"
23 #include "KReportLineStyle.h"
24 
25 #include <KProperty>
26 
27 #include <QDomDocument>
28 #include <QDomElement>
29 
30 #include <float.h>
31 
32 QString KReportUtils::attr(const QDomElement &el, const QString &attrName,
33  const QString &defaultValue)
34 {
35  const QString val = el.attribute(attrName);
36  return val.isEmpty() ? defaultValue : val;
37 }
38 
39 QByteArray KReportUtils::attr(const QDomElement &el, const QString &attrName,
40  const QByteArray &defaultValue)
41 {
42  const QByteArray val = el.attribute(attrName).toLatin1();
43  return val.isEmpty() ? defaultValue : val;
44 }
45 
46 bool KReportUtils::attr(const QDomElement &el, const QString &attrName, bool defaultValue)
47 {
48  const QString val = el.attribute(attrName);
49  return val.isEmpty() ? defaultValue : QVariant(val).toBool();
50 }
51 
52 int KReportUtils::attr(const QDomElement &el, const QString &attrName, int defaultValue)
53 {
54  const QString val = el.attribute(attrName);
55  if (val.isEmpty()) {
56  return defaultValue;
57  }
58  bool ok;
59  const int result = QVariant(val).toInt(&ok);
60  return ok ? result : defaultValue;
61 }
62 
63 qreal KReportUtils::attr(const QDomElement &el, const QString &attrName, qreal defaultValue)
64 {
65  const QString val = el.attribute(attrName);
66  return KReportUnit::parseValue(val, defaultValue);
67 }
68 
69 QColor KReportUtils::attr(const QDomElement &el, const QString &attrName, const QColor &defaultValue)
70 {
71  const QString val = el.attribute(attrName);
72  if (val.isEmpty()) {
73  return defaultValue;
74  }
75  return QColor(val);
76 }
77 
78 qreal KReportUtils::attrPercent(const QDomElement& el, const QString &attrName, qreal defaultValue)
79 {
80  QString str(el.attribute(attrName));
81  if (str.isEmpty() || !str.endsWith(QLatin1Char('%'))) {
82  return defaultValue;
83  }
84  str.chop(1);
85  bool ok;
86  const qreal result = QVariant(str).toReal(&ok) / 100.0;
87  if (!ok) {
88  return defaultValue;
89  }
90  return result;
91 }
92 
93 Qt::PenStyle KReportUtils::penStyle(const QString& str, Qt::PenStyle defaultValue)
94 {
95  const QByteArray s(str.toLatin1());
96  if (s == "nopen" || s == "none") {
97  return Qt::NoPen;
98  } else if (s == "solid") {
99  return Qt::SolidLine;
100  } else if (s == "dash" || s == "wave" /*we have nothing better for now*/) {
101  return Qt::DashLine;
102  } else if (s == "dot" || s == "dotted") {
103  return Qt::DotLine;
104  } else if (s == "dashdot" || s == "dot-dash") {
105  return Qt::DashDotLine;
106  } else if (s == "dashdotdot" || s == "dot-dot-dash") {
107  return Qt::DashDotDotLine;
108  } else {
109  return defaultValue;
110  }
111 }
112 
113 Qt::Alignment KReportUtils::verticalAlignment(const QString &str, Qt::Alignment defaultValue)
114 {
115  const QByteArray s(str.toLatin1());
116  if (s == "center") {
117  return Qt::AlignVCenter;
118  } else if (s == "top") {
119  return Qt::AlignTop;
120  } else if (s == "bottom") {
121  return Qt::AlignBottom;
122  } else {
123  return defaultValue;
124  }
125 }
126 
127 Qt::Alignment KReportUtils::horizontalAlignment(const QString &str, Qt::Alignment defaultValue)
128 {
129  const QByteArray s(str.toLatin1());
130  if (s == "center") {
131  return Qt::AlignHCenter;
132  } else if (s == "right") {
133  return Qt::AlignRight;
134  } else if (s == "left") {
135  return Qt::AlignLeft;
136  } else {
137  return defaultValue;
138  }
139 }
140 
141 QString KReportUtils::verticalToString(Qt::Alignment alignment)
142 {
143  if (alignment.testFlag(Qt::AlignVCenter)) {
144  return QLatin1String("center");
145  } else if (alignment.testFlag(Qt::AlignTop)) {
146  return QLatin1String("top");
147  } else if (alignment.testFlag(Qt::AlignBottom)) {
148  return QLatin1String("bottom");
149  }
150  return QString();
151 }
152 
153 QString KReportUtils::horizontalToString(Qt::Alignment alignment)
154 {
155  if (alignment.testFlag(Qt::AlignHCenter)) {
156  return QLatin1String("center");
157  } else if (alignment.testFlag(Qt::AlignLeft)) {
158  return QLatin1String("left");
159  } else if (alignment.testFlag(Qt::AlignRight)) {
160  return QLatin1String("right");
161  }
162  return QString();
163 }
164 
165 QString KReportUtils::readNameAttribute(const QDomElement &el, const QString &defaultValue)
166 {
167  return attr(el, QLatin1String("report:name"), defaultValue);
168 }
169 
170 QSizeF KReportUtils::readSizeAttributes(const QDomElement &el, const QSizeF &defaultValue)
171 {
172  QSizeF val;
173  val.setWidth(attr(el, QLatin1String("svg:width"), defaultValue.width()));
174  if (val.width() < 0.0) {
175  val.setWidth(defaultValue.width());
176  }
177  val.setHeight(attr(el, QLatin1String("svg:height"), defaultValue.height()));
178  if (val.height() < 0.0) {
179  val.setHeight(defaultValue.height());
180  }
181  return val;
182 }
183 
184 QRectF KReportUtils::readRectAttributes(const QDomElement &el, const QRectF &defaultValue)
185 {
186  QRectF val;
187  val.setX(attr(el, QLatin1String("svg:x"), defaultValue.x()));
188  val.setY(attr(el, QLatin1String("svg:y"), defaultValue.y()));
189  val.setSize(readSizeAttributes(el, defaultValue.size()));
190  return val;
191 }
192 
193 qreal KReportUtils::readZAttribute(const QDomElement &el, qreal defaultValue)
194 {
195  return KReportUtils::attr(el, QLatin1String("report:z-index"), defaultValue);
196 }
197 
198 int KReportUtils::readPercent(const QDomElement& el, const QString &attrName, int defaultPercentValue, bool *ok)
199 {
200  QString percent(el.attribute(attrName));
201  if (percent.isEmpty()) {
202  if (ok)
203  *ok = true;
204  return defaultPercentValue;
205  }
206  if (!percent.endsWith(QLatin1Char('%'))) {
207  if (ok)
208  *ok = false;
209  return 0;
210  }
211  percent.chop(1);
212  if (ok)
213  *ok = true;
214  return percent.toInt(ok);
215 }
216 
217 QString KReportUtils::readSectionTypeNameAttribute(const QDomElement &el, const QString &defaultValue)
218 {
219  return attr(el, QLatin1String("report:section-type"), defaultValue);
220 }
221 
222 //! @return string representation of @a value, cuts of zeros; precision is set to 2
223 static QString roundValueToString(qreal value)
224 {
225  QString s(QString::number(value, 'g', 2));
226  if (s.endsWith(QLatin1String(".00")))
227  return QString::number(qRound(value));
228  return s;
229 }
230 
231 //! Used by readFontAttributes()
232 static QFont::Capitalization readFontCapitalization(const QByteArray& fontVariant, const QByteArray& textTransform)
233 {
234  if (fontVariant == "small-caps")
235  return QFont::SmallCaps;
236  if (textTransform == "uppercase")
237  return QFont::AllUppercase;
238  if (textTransform == "lowercase")
239  return QFont::AllLowercase;
240  if (textTransform == "capitalize")
241  return QFont::Capitalize;
242  // default, "normal"
243  return QFont::MixedCase;
244 }
245 
246 void KReportUtils::readFontAttributes(const QDomElement& el, QFont *font)
247 {
248  Q_ASSERT(font);
249  const QFont::Capitalization cap = readFontCapitalization(
250  attr(el, QLatin1String("fo:font-variant"), QByteArray()),
251  attr(el, QLatin1String("fo:text-transform"), QByteArray()));
252  font->setCapitalization(cap);
253 
254  // weight
255  const QByteArray fontWeight(attr(el, QLatin1String("fo:font-weight"), QByteArray()));
256  int weight = -1;
257  if (fontWeight == "bold") {
258  weight = QFont::Bold;
259  }
260  if (fontWeight == "normal") {
261  weight = QFont::Normal;
262  }
263  else if (!fontWeight.isEmpty()) {
264  // Remember : Qt and CSS/XSL doesn't have the same scale. It's 100-900 instead of Qt's 0-100
265  // See http://www.w3.org/TR/2001/REC-xsl-20011015/slice7.html#font-weight
266  // and http://www.w3.org/TR/CSS2/fonts.html#font-boldness
267  bool ok;
268  qreal boldness = fontWeight.toUInt(&ok);
269  if (ok) {
270  boldness = qMin(boldness, 900.0);
271  boldness = qMax(boldness, 100.0);
272  weight = (boldness - 100.0) * 0.12375 /*== 99/800*/; // 0..99
273  }
274  }
275  if (weight >= 0) {
276  font->setWeight(weight);
277  }
278 
279  font->setItalic(attr(el, QLatin1String("fo:font-style"), QByteArray()) == "italic");
280  font->setFixedPitch(attr(el, QLatin1String("style:font-pitch"), QByteArray()) == "fixed");
281  font->setFamily(attr(el, QLatin1String("fo:font-family"), font->family()));
282  font->setKerning(attr(el, QLatin1String("style:letter-kerning"), font->kerning()));
283 
284  // underline
285  const QByteArray underlineType(
286  attr(el, QLatin1String("style:text-underline-type"), QByteArray()));
287  font->setUnderline(!underlineType.isEmpty()
288  && underlineType
289  != "none"); // double or single (we don't recognize them)
290 
291  // stricken-out
292  const QByteArray strikeOutType(attr(el, QLatin1String("style:text-line-through-type"), QByteArray()));
293  font->setStrikeOut(!strikeOutType.isEmpty() && strikeOutType != "none"); // double or single (we don't recognize them)
294 
295 //! @todo support fo:font-size-rel?
296 //! @todo support fo:font-size in px
297  font->setPointSizeF(KReportUtils::attr(el, QLatin1String("fo:font-size"), font->pointSizeF()));
298 
299  // letter spacing
300  // §7.16.2 of [XSL] http://www.w3.org/TR/xsl11/#letter-spacing
302  100.0 * KReportUtils::attrPercent(
303  el, QLatin1String("fo:letter-spacing"), font->letterSpacing()));
304 }
305 
306 void KReportUtils::writeFontAttributes(QDomElement *el, const QFont &font)
307 {
308  Q_ASSERT(el);
309  switch (font.capitalization()) {
310  case QFont::SmallCaps:
311  el->setAttribute(QLatin1String("fo:font-variant"), QLatin1String("small-caps"));
312  break;
313  case QFont::MixedCase:
314  // default: "normal", do not save
315  break;
316  case QFont::AllUppercase:
317  el->setAttribute(QLatin1String("fo:text-transform"), QLatin1String("uppercase"));
318  break;
319  case QFont::AllLowercase:
320  el->setAttribute(QLatin1String("fo:text-transform"), QLatin1String("lowercase"));
321  break;
322  case QFont::Capitalize:
323  el->setAttribute(QLatin1String("fo:text-transform"), QLatin1String("capitalize"));
324  break;
325  }
326 
327  // Remember : Qt and CSS/XSL doesn't have the same scale. It's 100-900 instead of Qt's 0-100
328  // See http://www.w3.org/TR/2001/REC-xsl-20011015/slice7.html#font-weight
329  // and http://www.w3.org/TR/CSS2/fonts.html#font-boldness
330  if (font.weight() == QFont::Light) {
331  el->setAttribute(QLatin1String("fo:font-weight"), 200);
332  }
333  else if (font.weight() == QFont::Normal) {
334  // Default
335  //el->setAttribute("fo:font-weight", "normal"); // 400
336  }
337  else if (font.weight() == QFont::DemiBold) {
338  el->setAttribute(QLatin1String("fo:font-weight"), 600);
339  }
340  else if (font.weight() == QFont::Bold) {
341  el->setAttribute(QLatin1String("fo:font-weight"), QLatin1String("bold")); // 700
342  }
343  else if (font.weight() == QFont::Black) {
344  el->setAttribute(QLatin1String("fo:font-weight"), 900);
345  }
346  else {
347  el->setAttribute(QLatin1String("fo:font-weight"), qBound(10, font.weight(), 90) * 10);
348  }
349  // italic, default is "normal"
350  if (font.italic()) {
351  el->setAttribute(QLatin1String("fo:font-style"), QLatin1String("italic"));
352  }
353  // pitch, default is "variable"
354  if (font.fixedPitch()) {
355  el->setAttribute(QLatin1String("style:font-pitch"), QLatin1String("fixed"));
356  }
357  if (!font.family().isEmpty()) {
358  el->setAttribute(QLatin1String("fo:font-family"), font.family());
359  }
360  // kerning, default is "true"
361  KReportUtils::setAttribute(el, QLatin1String("style:letter-kerning"), font.kerning());
362  // underline, default is "none"
363  if (font.underline()) {
364  el->setAttribute(QLatin1String("style:text-underline-type"), QLatin1String("single"));
365  }
366  // stricken-out, default is "none"
367  if (font.strikeOut()) {
368  el->setAttribute(QLatin1String("style:text-line-through-type"), QLatin1String("single"));
369  }
370  el->setAttribute(QLatin1String("fo:font-size"), font.pointSize());
371 
372  // letter spacing, default is "normal"
373  // §7.16.2 of [XSL] http://www.w3.org/TR/xsl11/#letter-spacing
375  // A value of 100 will keep the spacing unchanged; a value of 200 will enlarge
376  // the spacing after a character by the width of the character itself.
377  if (font.letterSpacing() != 100.0) {
378  el->setAttribute(QLatin1String("fo:letter-spacing"), roundValueToString(font.letterSpacing()) + QLatin1Char('%'));
379  }
380  }
381  else {
382  // QFont::AbsoluteSpacing
383  // A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
384  el->setAttribute(QLatin1String("fo:letter-spacing"), roundValueToString(font.letterSpacing()));
385  }
386 }
387 
388 
389 void KReportUtils::buildXMLRect(QDomElement *entity, const QPointF &pos, const QSizeF &size)
390 {
391  Q_ASSERT(entity);
392 
393  KReportUtils::setAttribute(entity, pos);
394  KReportUtils::setAttribute(entity, size );
395 }
396 
397 void KReportUtils::buildXMLTextStyle(QDomDocument *doc, QDomElement *entity, const KReportTextStyleData &ts)
398 {
399  Q_ASSERT(doc);
400  Q_ASSERT(entity);
401  QDomElement element = doc->createElement(QLatin1String("report:text-style"));
402 
403  element.setAttribute(QLatin1String("fo:background-color"), ts.backgroundColor.name());
404  element.setAttribute(QLatin1String("fo:foreground-color"), ts.foregroundColor.name());
405  element.setAttribute(QLatin1String("fo:background-opacity"), QString::number(ts.backgroundOpacity) + QLatin1Char('%'));
406  KReportUtils::writeFontAttributes(&element, ts.font);
407 
408  entity->appendChild(element);
409 }
410 
411 void KReportUtils::buildXMLLineStyle(QDomDocument *doc, QDomElement *entity, const KReportLineStyle &ls)
412 {
413  Q_ASSERT(doc);
414  Q_ASSERT(entity);
415  QDomElement element = doc->createElement(QLatin1String("report:line-style"));
416 
417  element.setAttribute(QLatin1String("report:line-color"), ls.color().name());
418  element.setAttribute(QLatin1String("report:line-weight"), ls.weight());
419 
420  QString l;
421  switch (ls.penStyle()) {
422  case Qt::NoPen:
423  l = QLatin1String("nopen");
424  break;
425  case Qt::SolidLine:
426  l = QLatin1String("solid");
427  break;
428  case Qt::DashLine:
429  l = QLatin1String("dash");
430  break;
431  case Qt::DotLine:
432  l = QLatin1String("dot");
433  break;
434  case Qt::DashDotLine:
435  l = QLatin1String("dashdot");
436  break;
437  case Qt::DashDotDotLine:
438  l = QLatin1String("dashdotdot");
439  break;
440  default:
441  l = QLatin1String("solid");
442  }
443  element.setAttribute(QLatin1String("report:line-style"), l);
444 
445  entity->appendChild(element);
446 }
447 
448 void KReportUtils::addPropertyAsAttribute(QDomElement* e, KProperty* p)
449 {
450  Q_ASSERT(e);
451  Q_ASSERT(p);
452  const QString name = QLatin1String("report:") + QString::fromLatin1(p->name().toLower());
453 
454  switch (p->type()) {
455  case QVariant::Int:
456  e->setAttribute(name, p->value().toInt());
457  break;
458  case QVariant::Double:
459  e->setAttribute(name, p->value().toDouble());
460  break;
461  case QVariant::Bool:
462  e->setAttribute(name, p->value().toBool());
463  break;
464  default:
465  e->setAttribute(name, p->value().toString());
466  break;
467  }
468 }
469 
470 bool KReportUtils::setPropertyValue(KProperty *p, const QDomElement &e)
471 {
472  const QString name = QStringLiteral("report:") + QString::fromLatin1(p->name());
473  if (!e.hasAttribute(name)) {
474  return false;
475  }
476  QVariant value = e.attribute(name); // string
477  if (!value.convert(p->type())) {
478  return false;
479  }
480  p->setValue(value);
481  return true;
482 }
483 
484 void KReportUtils::setAttribute(QDomElement *e, const QString &attribute, double value)
485 {
486  Q_ASSERT(e);
487  QString s;
488  s.setNum(value, 'f', DBL_DIG);
489  e->setAttribute(attribute, s + QLatin1String("pt"));
490 }
491 
492 void KReportUtils::setAttribute(QDomElement *e, const QPointF &value)
493 {
494  Q_ASSERT(e);
495  KReportUtils::setAttribute(e, QLatin1String("svg:x"), value.x());
496  KReportUtils::setAttribute(e, QLatin1String("svg:y"), value.y());
497 }
498 
499 void KReportUtils::setAttribute(QDomElement *e, const QSizeF &value)
500 {
501  Q_ASSERT(e);
502  KReportUtils::setAttribute(e, QLatin1String("svg:width"), value.width());
503  KReportUtils::setAttribute(e, QLatin1String("svg:height"), value.height());
504 }
505 
506 void KReportUtils::setAttribute(QDomElement *e, const QString &attribute, bool value)
507 {
508  e->setAttribute(attribute, value ? QStringLiteral("true") : QStringLiteral("false"));
509 }
510 
511 bool KReportUtils::parseReportTextStyleData(const QDomElement & elemSource, KReportTextStyleData *ts)
512 {
513  Q_ASSERT(ts);
514  if (elemSource.tagName() != QLatin1String("report:text-style"))
515  return false;
516  ts->backgroundColor = QColor(elemSource.attribute(
517  QLatin1String("fo:background-color"), QLatin1String("#ffffff")));
518  ts->foregroundColor = QColor(elemSource.attribute(
519  QLatin1String("fo:foreground-color"), QLatin1String("#000000")));
520 
521  bool ok;
522  ts->backgroundOpacity = KReportUtils::readPercent(
523  elemSource, QLatin1String("fo:background-opacity"), 100, &ok);
524  if (!ok) {
525  return false;
526  }
527  KReportUtils::readFontAttributes(elemSource, &ts->font);
528  return true;
529 }
530 
531 bool KReportUtils::parseReportLineStyleData(const QDomElement & elemSource, KReportLineStyle *ls)
532 {
533  Q_ASSERT(ls);
534  if (elemSource.tagName() == QLatin1String("report:line-style")) {
535  ls->setColor(QColor(elemSource.attribute(QLatin1String("report:line-color"), QLatin1String("#ffffff"))));
536  ls->setWeight(elemSource.attribute(QLatin1String("report:line-weight"), QLatin1String("0.0")).toDouble());
537 
538  QString l = elemSource.attribute(QLatin1String("report:line-style"), QLatin1String("nopen"));
539  if (l == QLatin1String("nopen")) {
540  ls->setPenStyle(Qt::NoPen);
541  } else if (l == QLatin1String("solid")) {
542  ls->setPenStyle(Qt::SolidLine);
543  } else if (l == QLatin1String("dash")) {
544  ls->setPenStyle(Qt::DashLine);
545  } else if (l == QLatin1String("dot")) {
546  ls->setPenStyle(Qt::DotLine);
547  } else if (l == QLatin1String("dashdot")) {
548  ls->setPenStyle(Qt::DashDotLine);
549  } else if (l == QLatin1String("dashdotdot")) {
550  ls->setPenStyle(Qt::DashDotDotLine);
551  }
552  return true;
553  }
554  return false;
555 }
556 
557 class PageIds : private QHash<QString, QPageSize::PageSizeId>
558 {
559 public:
560  PageIds() {}
561  QPageSize::PageSizeId id(const QString &key) {
562  if (isEmpty()) {
563  for (int i = 0; i < QPageSize::LastPageSize; ++i) {
565  if (key.isEmpty()) {
566  break;
567  }
568  insert(key, static_cast<QPageSize::PageSizeId>(i));
569  }
570  }
571  return value(key);
572  }
573 };
574 
575 Q_GLOBAL_STATIC(PageIds, s_pageIds)
576 
577 QPageSize::PageSizeId KReportUtils::pageSizeId(const QString &key)
578 {
579  return s_pageIds->id(key);
580 }
581 
582 QPageSize KReportUtils::pageSize(const QString &key)
583 {
584  return QPageSize(s_pageIds->id(key));
585 }
qreal toReal(bool *ok) const const
QByteArray name() const
typedef Alignment
const T value(const Key &key) const const
qreal height() const const
QByteArray toLower() const const
The KReportLineStyle class represents line style.
QString family() const const
QString number(int n, int base)
int weight() const const
QString key() const const
QString tagName() const const
qreal x() const const
qreal y() const const
QString name() const const
int pointSize() const const
bool italic() const const
QByteArray toLatin1() const const
QDomElement createElement(const QString &tagName)
void setUnderline(bool enable)
bool kerning() const const
QHash::iterator insert(const Key &key, const T &value)
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
void setItalic(bool enable)
void setAttribute(const QString &name, const QString &value)
bool underline() const const
bool strikeOut() const const
double toDouble(bool *ok) const const
QString & setNum(short n, int base)
bool isEmpty() const const
void setX(qreal x)
void setY(qreal y)
const Key key(const T &value) const const
void setKerning(bool enable)
int toInt(bool *ok) const const
static qreal parseValue(const QString &value, qreal defaultVal=0.0)
Parses common KReport and ODF values, like "10cm", "5mm" to pt.
Capitalization
bool convert(int targetTypeId)
QFont::Capitalization capitalization() const const
PercentageSpacing
bool toBool() const const
QFont::SpacingType letterSpacingType() const const
bool setValue(const QVariant &value, ValueOptions options=ValueOptions())
int type() const
bool hasAttribute(const QString &name) const const
bool isEmpty() const const
qreal x() const const
qreal y() const const
QDomNode appendChild(const QDomNode &newChild)
QString fromLatin1(const char *str, int size)
QString name(StandardShortcut id)
void setWeight(int weight)
bool isEmpty() const const
void setCapitalization(QFont::Capitalization caps)
QVariant value() const
void setStrikeOut(bool enable)
void setLetterSpacing(QFont::SpacingType type, qreal spacing)
QSizeF size() const const
void setFixedPitch(bool enable)
void setPointSizeF(qreal pointSize)
QString attribute(const QString &name, const QString &defValue) const const
void setWidth(qreal width)
qreal letterSpacing() const const
qreal pointSizeF() const const
void setSize(const QSizeF &size)
PenStyle
void setHeight(qreal height)
QString toString() const const
qreal width() const const
void setFamily(const QString &family)
bool fixedPitch() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:17:37 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.