47 #include <QPainterPath>
51 static quint16 magic = 0x3ff;
52 return ((ch >> 4) == 3) && (magic >> (ch & 15));
57 const int maxLen = 255;
61 if (*str == QLatin1Char(
'-')) {
64 }
else if (*str == QLatin1Char(
'+')) {
67 while (
isDigit(str->unicode()) && pos < maxLen) {
68 temp[pos++] = str->toLatin1();
71 if (*str == QLatin1Char(
'.') && pos < maxLen) {
75 while (
isDigit(str->unicode()) && pos < maxLen) {
76 temp[pos++] = str->toLatin1();
79 bool exponent =
false;
80 if ((*str == QLatin1Char(
'e') || *str == QLatin1Char(
'E')) && pos < maxLen) {
84 if ((*str == QLatin1Char(
'-') || *str == QLatin1Char(
'+')) && pos < maxLen) {
85 temp[pos++] = str->toLatin1();
88 while (
isDigit(str->unicode()) && pos < maxLen) {
89 temp[pos++] = str->toLatin1();
97 if (!exponent && pos < 10) {
105 while(*t && *t !=
'.') {
119 val =
static_cast<qreal
> (ival)/
static_cast<qreal
> (div);
126 val = QByteArray::fromRawData(temp, pos).toDouble();
134 while (str->isSpace())
136 while (
isDigit(str->unicode()) ||
137 *str == QLatin1Char(
'-') || *str == QLatin1Char(
'+') ||
138 *str == QLatin1Char(
'.')) {
142 while (str->isSpace())
144 if (*str == QLatin1Char(
','))
148 while (str->isSpace())
154 qreal th0, qreal th1,
155 qreal rx, qreal ry, qreal xAxisRotation)
158 qreal a00, a01, a10, a11;
159 qreal x1, y1, x2, y2, x3, y3;
163 sinTh = qSin(xAxisRotation * (3.141592653589793 / 180.0));
164 cosTh = qCos(xAxisRotation * (3.141592653589793 / 180.0));
171 thHalf = 0.5 * (th1 - th0);
172 t = (8.0 / 3.0) * qSin(thHalf * 0.5) * qSin(thHalf * 0.5) / qSin(thHalf);
173 x1 = xc + qCos(th0) - t * qSin(th0);
174 y1 = yc + qSin(th0) + t * qCos(th0);
177 x2 = x3 + t * qSin(th1);
178 y2 = y3 - t * qCos(th1);
180 path.cubicTo(a00 * x1 + a01 * y1, a10 * x1 + a11 * y1,
181 a00 * x2 + a01 * y2, a10 * x2 + a11 * y2,
182 a00 * x3 + a01 * y3, a10 * x3 + a11 * y3);
214 qreal x_axis_rotation,
219 qreal curx, qreal cury)
221 qreal sin_th, cos_th;
222 qreal a00, a01, a10, a11;
223 qreal x0, y0, x1, y1, xc, yc;
224 qreal
d, sfactor, sfactor_sq;
225 qreal th0, th1, th_arc;
227 qreal dx, dy, dx1, dy1, Pr1, Pr2, Px, Py, check;
232 sin_th = qSin(x_axis_rotation * (3.141592653589793 / 180.0));
233 cos_th = qCos(x_axis_rotation * (3.141592653589793 / 180.0));
235 dx = (curx -
x) / 2.0;
236 dy = (cury - y) / 2.0;
237 dx1 = cos_th * dx + sin_th * dy;
238 dy1 = -sin_th * dx + cos_th * dy;
244 check = Px / Pr1 + Py / Pr2;
246 rx = rx * qSqrt(check);
247 ry = ry * qSqrt(check);
254 x0 = a00 * curx + a01 * cury;
255 y0 = a10 * curx + a11 * cury;
256 x1 = a00 *
x + a01 * y;
257 y1 = a10 *
x + a11 * y;
263 d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
264 sfactor_sq = 1.0 /
d - 0.25;
265 if (sfactor_sq < 0) sfactor_sq = 0;
266 sfactor = qSqrt(sfactor_sq);
267 if (sweep_flag == large_arc_flag) sfactor = -sfactor;
268 xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
269 yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
272 th0 = qAtan2(y0 - yc, x0 - xc);
273 th1 = qAtan2(y1 - yc, x1 - xc);
276 if (th_arc < 0 && sweep_flag)
277 th_arc += 2 * 3.141592653589793;
278 else if (th_arc > 0 && !sweep_flag)
279 th_arc -= 2 * 3.141592653589793;
281 n_segs = qCeil(qAbs(th_arc / (3.141592653589793 * 0.5 + 0.001)));
283 for (i = 0; i < n_segs; i++) {
285 th0 + i * th_arc / n_segs,
286 th0 + (i + 1) * th_arc / n_segs,
287 rx, ry, x_axis_rotation);
297 const QChar *str = value.constData();
298 const QChar *end = str + value.length();
301 if (str->isSpace() || *str == QLatin1Char(
',')) {
314 if (*str == QLatin1Char(
'm')) {
315 const char *ident =
"atrix";
316 for (
int i = 0; i < 5; ++i)
317 if (*(++str) != QLatin1Char(ident[i]))
321 }
else if (*str == QLatin1Char(
't')) {
322 const char *ident =
"ranslate";
323 for (
int i = 0; i < 8; ++i)
324 if (*(++str) != QLatin1Char(ident[i]))
328 }
else if (*str == QLatin1Char(
'r')) {
329 const char *ident =
"otate";
330 for (
int i = 0; i < 5; ++i)
331 if (*(++str) != QLatin1Char(ident[i]))
335 }
else if (*str == QLatin1Char(
's')) {
337 if (*str == QLatin1Char(
'c')) {
338 const char *ident =
"ale";
339 for (
int i = 0; i < 3; ++i)
340 if (*(++str) != QLatin1Char(ident[i]))
344 }
else if (*str == QLatin1Char(
'k')) {
345 if (*(++str) != QLatin1Char(
'e'))
347 if (*(++str) != QLatin1Char(
'w'))
350 if (*str == QLatin1Char(
'X'))
352 else if (*str == QLatin1Char(
'Y'))
365 while (str < end && str->isSpace())
367 if (*str != QLatin1Char(
'('))
370 QVarLengthArray<qreal, 8> points;
372 if (*str != QLatin1Char(
')'))
377 if(points.count() != 6)
379 matrix = QTransform(points[0], points[1],
380 points[2], points[3],
381 points[4], points[5]) * matrix;
382 }
else if (
state == Translate) {
383 if (points.count() == 1)
384 matrix.translate(points[0], 0);
385 else if (points.count() == 2)
386 matrix.translate(points[0], points[1]);
389 }
else if (
state == Rotate) {
390 if(points.count() == 1) {
391 matrix.rotate(points[0]);
392 }
else if (points.count() == 3) {
393 matrix.translate(points[1], points[2]);
394 matrix.rotate(points[0]);
395 matrix.translate(-points[1], -points[2]);
399 }
else if (
state == Scale) {
400 if (points.count() < 1 || points.count() > 2)
402 qreal sx = points[0];
404 if(points.count() == 2)
406 matrix.scale(sx, sy);
407 }
else if (
state == SkewX) {
408 if (points.count() != 1)
410 const qreal deg2rad = qreal(0.017453292519943295769);
411 matrix.shear(qTan(points[0]*deg2rad), 0);
412 }
else if (
state == SkewY) {
413 if (points.count() != 1)
415 const qreal deg2rad = qreal(0.017453292519943295769);
416 matrix.shear(0, qTan(points[0]*deg2rad));
425 qreal x0 = 0, y0 = 0;
429 const QChar *str = dataStr.constData();
430 const QChar *end = str + dataStr.size();
433 while (str->isSpace() && (str + 1) != end)
435 QChar pathElem = *str;
438 *
const_cast<QChar *
>(end) = 0;
439 QVarLengthArray<qreal, 8> arg;
441 *
const_cast<QChar *
>(end) = endc;
442 if (pathElem == QLatin1Char(
'z') || pathElem == QLatin1Char(
'Z'))
444 const qreal *num = arg.constData();
445 int count = arg.count();
449 switch (pathElem.unicode()) {
456 x = x0 = num[0] + offsetX;
457 y = y0 = num[1] + offsetY;
465 pathElem = QLatin1Char(
'l');
483 pathElem = QLatin1Char(
'L');
501 x = num[0] + offsetX;
502 y = num[1] + offsetY;
523 x = num[0] + offsetX;
537 y = num[0] + offsetY;
556 QPointF c1(num[0] + offsetX, num[1] + offsetY);
557 QPointF c2(num[2] + offsetX, num[3] + offsetY);
558 QPointF e(num[4] + offsetX, num[5] + offsetY);
561 path.cubicTo(c1, c2, e);
573 QPointF c1(num[0], num[1]);
574 QPointF c2(num[2], num[3]);
575 QPointF e(num[4], num[5]);
578 path.cubicTo(c1, c2, e);
591 if (lastMode ==
'c' || lastMode ==
'C' ||
592 lastMode ==
's' || lastMode ==
'S')
593 c1 = QPointF(2*
x-ctrlPt.x(), 2*y-ctrlPt.y());
596 QPointF c2(num[0] + offsetX, num[1] + offsetY);
597 QPointF e(num[2] + offsetX, num[3] + offsetY);
600 path.cubicTo(c1, c2, e);
613 if (lastMode ==
'c' || lastMode ==
'C' ||
614 lastMode ==
's' || lastMode ==
'S')
615 c1 = QPointF(2*
x-ctrlPt.x(), 2*y-ctrlPt.y());
618 QPointF c2(num[0], num[1]);
619 QPointF e(num[2], num[3]);
622 path.cubicTo(c1, c2, e);
634 QPointF c(num[0] + offsetX, num[1] + offsetY);
635 QPointF e(num[2] + offsetX, num[3] + offsetY);
650 QPointF c(num[0], num[1]);
651 QPointF e(num[2], num[3]);
666 QPointF e(num[0] + offsetX, num[1] + offsetY);
670 if (lastMode ==
'q' || lastMode ==
'Q' ||
671 lastMode ==
't' || lastMode ==
'T')
672 c = QPointF(2*
x-ctrlPt.x(), 2*y-ctrlPt.y());
687 QPointF e(num[0], num[1]);
691 if (lastMode ==
'q' || lastMode ==
'Q' ||
692 lastMode ==
't' || lastMode ==
'T')
693 c = QPointF(2*
x-ctrlPt.x(), 2*y-ctrlPt.y());
710 qreal xAxisRotation = (*num++);
711 qreal largeArcFlag = (*num++);
712 qreal sweepFlag = (*num++);
713 qreal ex = (*num++) + offsetX;
714 qreal ey = (*num++) + offsetY;
718 pathArc(path, rx, ry, xAxisRotation,
int(largeArcFlag),
719 int(sweepFlag), ex, ey, curx, cury);
733 qreal xAxisRotation = (*num++);
734 qreal largeArcFlag = (*num++);
735 qreal sweepFlag = (*num++);
741 pathArc(path, rx, ry, xAxisRotation,
int(largeArcFlag),
742 int(sweepFlag), ex, ey, curx, cury);
751 lastMode = pathElem.toLatin1();
void error(const char *fmt,...)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
static bool isDigit(ushort ch)
static void pathArc(QPainterPath &path, qreal rx, qreal ry, qreal x_axis_rotation, int large_arc_flag, int sweep_flag, qreal x, qreal y, qreal curx, qreal cury)
static qreal toDouble(const QChar *&str)
static void pathArcSegment(QPainterPath &path, qreal xc, qreal yc, qreal th0, qreal th1, qreal rx, qreal ry, qreal xAxisRotation)
static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
static QTransform parseTransformationMatrix(const QStringRef &value)
static void parseNumbersArray(const QChar *&str, QVarLengthArray< qreal, 8 > &points)
static uint32_t state[624]