Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsvgutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qsvgutils_p.h"
5#include <cmath>
6
7QT_BEGIN_NAMESPACE
8
9namespace QSvgUtils {
10
11// '0' is 0x30 and '9' is 0x39
12bool isDigit(ushort ch)
13{
14 static quint16 magic = 0x3ff;
15 return ((ch >> 4) == 3) && (magic >> (ch & 15));
16}
17
18qreal toDouble(const QChar *&str)
19{
20 const int maxLen = 255;//technically doubles can go til 308+ but whatever
21 char temp[maxLen+1];
22 int pos = 0;
23
24 if (*str == QLatin1Char('-')) {
25 temp[pos++] = '-';
26 ++str;
27 } else if (*str == QLatin1Char('+')) {
28 ++str;
29 }
30 while (isDigit(str->unicode()) && pos < maxLen) {
31 temp[pos++] = str->toLatin1();
32 ++str;
33 }
34 if (*str == QLatin1Char('.') && pos < maxLen) {
35 temp[pos++] = '.';
36 ++str;
37 }
38 while (isDigit(str->unicode()) && pos < maxLen) {
39 temp[pos++] = str->toLatin1();
40 ++str;
41 }
42 bool exponent = false;
43 if ((*str == QLatin1Char('e') || *str == QLatin1Char('E')) && pos < maxLen) {
44 exponent = true;
45 temp[pos++] = 'e';
46 ++str;
47 if ((*str == QLatin1Char('-') || *str == QLatin1Char('+')) && pos < maxLen) {
48 temp[pos++] = str->toLatin1();
49 ++str;
50 }
51 while (isDigit(str->unicode()) && pos < maxLen) {
52 temp[pos++] = str->toLatin1();
53 ++str;
54 }
55 }
56
57 temp[pos] = '\0';
58
59 qreal val;
60 if (!exponent && pos < 10) {
61 int ival = 0;
62 const char *t = temp;
63 bool neg = false;
64 if (*t == '-') {
65 neg = true;
66 ++t;
67 }
68 while (*t && *t != '.') {
69 ival *= 10;
70 ival += (*t) - '0';
71 ++t;
72 }
73 if (*t == '.') {
74 ++t;
75 int div = 1;
76 while (*t) {
77 ival *= 10;
78 ival += (*t) - '0';
79 div *= 10;
80 ++t;
81 }
82 val = ((qreal)ival)/((qreal)div);
83 } else {
84 val = ival;
85 }
86 if (neg)
87 val = -val;
88 } else {
89 val = QByteArray::fromRawData(temp, pos).toDouble();
90 // Do not tolerate values too wild to be represented normally by floats
91 if (qFpClassify(float(val)) != FP_NORMAL)
92 val = 0;
93 }
94 return val;
95
96}
97
98qreal toDouble(QStringView str, bool *ok)
99{
100 const QChar *c = str.constData();
101 qreal res = (c == nullptr ? qreal{} : toDouble(c));
102 if (ok)
103 *ok = (c == (str.constData() + str.size()));
104 return res;
105}
106
107qreal parseLength(QStringView str, LengthType *type, bool *ok)
108{
109 QStringView numStr = str.trimmed();
110
111 if (numStr.isEmpty()) {
112 if (ok)
113 *ok = false;
114 *type = LengthType::LT_OTHER;
115 return false;
116 }
117 if (numStr.endsWith(QLatin1Char('%'))) {
118 numStr.chop(1);
120 } else if (numStr.endsWith(QLatin1String("px"))) {
121 numStr.chop(2);
122 *type = LengthType::LT_PX;
123 } else if (numStr.endsWith(QLatin1String("pc"))) {
124 numStr.chop(2);
125 *type = LengthType::LT_PC;
126 } else if (numStr.endsWith(QLatin1String("pt"))) {
127 numStr.chop(2);
128 *type = LengthType::LT_PT;
129 } else if (numStr.endsWith(QLatin1String("mm"))) {
130 numStr.chop(2);
131 *type = LengthType::LT_MM;
132 } else if (numStr.endsWith(QLatin1String("cm"))) {
133 numStr.chop(2);
134 *type = LengthType::LT_CM;
135 } else if (numStr.endsWith(QLatin1String("in"))) {
136 numStr.chop(2);
137 *type = LengthType::LT_IN;
138 } else {
139 // default coordinate system
140 *type = LengthType::LT_PX;
141 }
142 qreal len = toDouble(numStr, ok);
143 return len;
144}
145
146// this should really be called convertToDefaultCoordinateSystem
147// and convert when type != QSvgHandler::defaultCoordinateSystem
148qreal convertToPixels(qreal len, bool , LengthType type)
149{
150
151 switch (type) {
153 break;
155 break;
157 break;
159 return len * 1.25;
160 break;
162 return len * 3.543307;
163 break;
165 return len * 35.43307;
166 break;
168 return len * 90;
169 break;
171 break;
172 default:
173 break;
174 }
175 return len;
176}
177
178};
179
180QT_END_NAMESPACE
bool isDigit(ushort ch)
Definition qsvgutils.cpp:12
qreal toDouble(const QChar *&str)
Definition qsvgutils.cpp:18
qreal convertToPixels(qreal len, bool, LengthType type)
qreal toDouble(QStringView str, bool *ok)
Definition qsvgutils.cpp:98
qreal parseLength(QStringView str, LengthType *type, bool *ok)