GNU Octave  8.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
octave-qsvghandler.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt SVG module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 // --------------------------------------------------------------------------
41 // Build a QPainterPath from the "d" attribute of a path element
42 // These functions are extracted from Qt-5.12 sources (qtsvghandler.cpp)
43 // Modifications:
44 // * use static_cast<qreal> to avoid old style cast warning.
45 // --------------------------------------------------------------------------
46 
47 #include <QPainterPath>
48 
49 static inline bool isDigit(ushort ch)
50 {
51  static quint16 magic = 0x3ff;
52  return ((ch >> 4) == 3) && (magic >> (ch & 15));
53 }
54 
55 static qreal toDouble(const QChar *&str)
56 {
57  const int maxLen = 255;//technically doubles can go til 308+ but whatever
58  char temp[maxLen+1];
59  int pos = 0;
60 
61  if (*str == QLatin1Char('-')) {
62  temp[pos++] = '-';
63  ++str;
64  } else if (*str == QLatin1Char('+')) {
65  ++str;
66  }
67  while (isDigit(str->unicode()) && pos < maxLen) {
68  temp[pos++] = str->toLatin1();
69  ++str;
70  }
71  if (*str == QLatin1Char('.') && pos < maxLen) {
72  temp[pos++] = '.';
73  ++str;
74  }
75  while (isDigit(str->unicode()) && pos < maxLen) {
76  temp[pos++] = str->toLatin1();
77  ++str;
78  }
79  bool exponent = false;
80  if ((*str == QLatin1Char('e') || *str == QLatin1Char('E')) && pos < maxLen) {
81  exponent = true;
82  temp[pos++] = 'e';
83  ++str;
84  if ((*str == QLatin1Char('-') || *str == QLatin1Char('+')) && pos < maxLen) {
85  temp[pos++] = str->toLatin1();
86  ++str;
87  }
88  while (isDigit(str->unicode()) && pos < maxLen) {
89  temp[pos++] = str->toLatin1();
90  ++str;
91  }
92  }
93 
94  temp[pos] = '\0';
95 
96  qreal val;
97  if (!exponent && pos < 10) {
98  int ival = 0;
99  const char *t = temp;
100  bool neg = false;
101  if(*t == '-') {
102  neg = true;
103  ++t;
104  }
105  while(*t && *t != '.') {
106  ival *= 10;
107  ival += (*t) - '0';
108  ++t;
109  }
110  if(*t == '.') {
111  ++t;
112  int div = 1;
113  while(*t) {
114  ival *= 10;
115  ival += (*t) - '0';
116  div *= 10;
117  ++t;
118  }
119  val = static_cast<qreal> (ival)/static_cast<qreal> (div);
120  } else {
121  val = ival;
122  }
123  if (neg)
124  val = -val;
125  } else {
126  val = QByteArray::fromRawData(temp, pos).toDouble();
127  }
128  return val;
129 
130 }
131 
132 static inline void parseNumbersArray(const QChar *&str, QVarLengthArray<qreal, 8> &points)
133 {
134  while (str->isSpace())
135  ++str;
136  while (isDigit(str->unicode()) ||
137  *str == QLatin1Char('-') || *str == QLatin1Char('+') ||
138  *str == QLatin1Char('.')) {
139 
140  points.append(toDouble(str));
141 
142  while (str->isSpace())
143  ++str;
144  if (*str == QLatin1Char(','))
145  ++str;
146 
147  //eat the rest of space
148  while (str->isSpace())
149  ++str;
150  }
151 }
152 static void pathArcSegment(QPainterPath &path,
153  qreal xc, qreal yc,
154  qreal th0, qreal th1,
155  qreal rx, qreal ry, qreal xAxisRotation)
156 {
157  qreal sinTh, cosTh;
158  qreal a00, a01, a10, a11;
159  qreal x1, y1, x2, y2, x3, y3;
160  qreal t;
161  qreal thHalf;
162 
163  sinTh = qSin(xAxisRotation * (3.141592653589793 / 180.0));
164  cosTh = qCos(xAxisRotation * (3.141592653589793 / 180.0));
165 
166  a00 = cosTh * rx;
167  a01 = -sinTh * ry;
168  a10 = sinTh * rx;
169  a11 = cosTh * ry;
170 
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);
175  x3 = xc + qCos(th1);
176  y3 = yc + qSin(th1);
177  x2 = x3 + t * qSin(th1);
178  y2 = y3 - t * qCos(th1);
179 
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);
183 }
184 
185 // the arc handling code underneath is from XSVG (BSD license)
186 /*
187  * Copyright 2002 USC/Information Sciences Institute
188  *
189  * Permission to use, copy, modify, distribute, and sell this software
190  * and its documentation for any purpose is hereby granted without
191  * fee, provided that the above copyright notice appear in all copies
192  * and that both that copyright notice and this permission notice
193  * appear in supporting documentation, and that the name of
194  * Information Sciences Institute not be used in advertising or
195  * publicity pertaining to distribution of the software without
196  * specific, written prior permission. Information Sciences Institute
197  * makes no representations about the suitability of this software for
198  * any purpose. It is provided "as is" without express or implied
199  * warranty.
200  *
201  * INFORMATION SCIENCES INSTITUTE DISCLAIMS ALL WARRANTIES WITH REGARD
202  * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
203  * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INFORMATION SCIENCES
204  * INSTITUTE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
205  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
206  * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
207  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
208  * PERFORMANCE OF THIS SOFTWARE.
209  *
210  */
211 static void pathArc(QPainterPath &path,
212  qreal rx,
213  qreal ry,
214  qreal x_axis_rotation,
215  int large_arc_flag,
216  int sweep_flag,
217  qreal x,
218  qreal y,
219  qreal curx, qreal cury)
220 {
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;
226  int i, n_segs;
227  qreal dx, dy, dx1, dy1, Pr1, Pr2, Px, Py, check;
228 
229  rx = qAbs(rx);
230  ry = qAbs(ry);
231 
232  sin_th = qSin(x_axis_rotation * (3.141592653589793 / 180.0));
233  cos_th = qCos(x_axis_rotation * (3.141592653589793 / 180.0));
234 
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;
239  Pr1 = rx * rx;
240  Pr2 = ry * ry;
241  Px = dx1 * dx1;
242  Py = dy1 * dy1;
243  /* Spec : check if radii are large enough */
244  check = Px / Pr1 + Py / Pr2;
245  if (check > 1) {
246  rx = rx * qSqrt(check);
247  ry = ry * qSqrt(check);
248  }
249 
250  a00 = cos_th / rx;
251  a01 = sin_th / rx;
252  a10 = -sin_th / ry;
253  a11 = cos_th / ry;
254  x0 = a00 * curx + a01 * cury;
255  y0 = a10 * curx + a11 * cury;
256  x1 = a00 * x + a01 * y;
257  y1 = a10 * x + a11 * y;
258  /* (x0, y0) is current point in transformed coordinate space.
259  (x1, y1) is new point in transformed coordinate space.
260 
261  The arc fits a unit-radius circle in this space.
262  */
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);
270  /* (xc, yc) is center of the circle. */
271 
272  th0 = qAtan2(y0 - yc, x0 - xc);
273  th1 = qAtan2(y1 - yc, x1 - xc);
274 
275  th_arc = th1 - th0;
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;
280 
281  n_segs = qCeil(qAbs(th_arc / (3.141592653589793 * 0.5 + 0.001)));
282 
283  for (i = 0; i < n_segs; i++) {
284  pathArcSegment(path, xc, yc,
285  th0 + i * th_arc / n_segs,
286  th0 + (i + 1) * th_arc / n_segs,
287  rx, ry, x_axis_rotation);
288  }
289 }
290 
291 static QTransform parseTransformationMatrix(const QStringRef &value)
292 {
293  if (value.isEmpty())
294  return QTransform();
295 
296  QTransform matrix;
297  const QChar *str = value.constData();
298  const QChar *end = str + value.length();
299 
300  while (str < end) {
301  if (str->isSpace() || *str == QLatin1Char(',')) {
302  ++str;
303  continue;
304  }
305  enum State {
306  Matrix,
307  Translate,
308  Rotate,
309  Scale,
310  SkewX,
311  SkewY
312  };
313  State state = Matrix;
314  if (*str == QLatin1Char('m')) { //matrix
315  const char *ident = "atrix";
316  for (int i = 0; i < 5; ++i)
317  if (*(++str) != QLatin1Char(ident[i]))
318  goto error;
319  ++str;
320  state = Matrix;
321  } else if (*str == QLatin1Char('t')) { //translate
322  const char *ident = "ranslate";
323  for (int i = 0; i < 8; ++i)
324  if (*(++str) != QLatin1Char(ident[i]))
325  goto error;
326  ++str;
327  state = Translate;
328  } else if (*str == QLatin1Char('r')) { //rotate
329  const char *ident = "otate";
330  for (int i = 0; i < 5; ++i)
331  if (*(++str) != QLatin1Char(ident[i]))
332  goto error;
333  ++str;
334  state = Rotate;
335  } else if (*str == QLatin1Char('s')) { //scale, skewX, skewY
336  ++str;
337  if (*str == QLatin1Char('c')) {
338  const char *ident = "ale";
339  for (int i = 0; i < 3; ++i)
340  if (*(++str) != QLatin1Char(ident[i]))
341  goto error;
342  ++str;
343  state = Scale;
344  } else if (*str == QLatin1Char('k')) {
345  if (*(++str) != QLatin1Char('e'))
346  goto error;
347  if (*(++str) != QLatin1Char('w'))
348  goto error;
349  ++str;
350  if (*str == QLatin1Char('X'))
351  state = SkewX;
352  else if (*str == QLatin1Char('Y'))
353  state = SkewY;
354  else
355  goto error;
356  ++str;
357  } else {
358  goto error;
359  }
360  } else {
361  goto error;
362  }
363 
364 
365  while (str < end && str->isSpace())
366  ++str;
367  if (*str != QLatin1Char('('))
368  goto error;
369  ++str;
370  QVarLengthArray<qreal, 8> points;
371  parseNumbersArray(str, points);
372  if (*str != QLatin1Char(')'))
373  goto error;
374  ++str;
375 
376  if(state == Matrix) {
377  if(points.count() != 6)
378  goto error;
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]);
387  else
388  goto error;
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]);
396  } else {
397  goto error;
398  }
399  } else if (state == Scale) {
400  if (points.count() < 1 || points.count() > 2)
401  goto error;
402  qreal sx = points[0];
403  qreal sy = sx;
404  if(points.count() == 2)
405  sy = points[1];
406  matrix.scale(sx, sy);
407  } else if (state == SkewX) {
408  if (points.count() != 1)
409  goto error;
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)
414  goto error;
415  const qreal deg2rad = qreal(0.017453292519943295769);
416  matrix.shear(0, qTan(points[0]*deg2rad));
417  }
418  }
419  error:
420  return matrix;
421 }
422 
423 static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
424 {
425  qreal x0 = 0, y0 = 0; // starting point
426  qreal x = 0, y = 0; // current point
427  char lastMode = 0;
428  QPointF ctrlPt;
429  const QChar *str = dataStr.constData();
430  const QChar *end = str + dataStr.size();
431 
432  while (str != end) {
433  while (str->isSpace() && (str + 1) != end)
434  ++str;
435  QChar pathElem = *str;
436  ++str;
437  QChar endc = *end;
438  *const_cast<QChar *>(end) = 0; // parseNumbersArray requires 0-termination that QStringRef cannot guarantee
439  QVarLengthArray<qreal, 8> arg;
440  parseNumbersArray(str, arg);
441  *const_cast<QChar *>(end) = endc;
442  if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z'))
443  arg.append(0);//dummy
444  const qreal *num = arg.constData();
445  int count = arg.count();
446  while (count > 0) {
447  qreal offsetX = x; // correction offsets
448  qreal offsetY = y; // for relative commands
449  switch (pathElem.unicode()) {
450  case 'm': {
451  if (count < 2) {
452  num++;
453  count--;
454  break;
455  }
456  x = x0 = num[0] + offsetX;
457  y = y0 = num[1] + offsetY;
458  num += 2;
459  count -= 2;
460  path.moveTo(x0, y0);
461 
462  // As per 1.2 spec 8.3.2 The "moveto" commands
463  // If a 'moveto' is followed by multiple pairs of coordinates without explicit commands,
464  // the subsequent pairs shall be treated as implicit 'lineto' commands.
465  pathElem = QLatin1Char('l');
466  }
467  break;
468  case 'M': {
469  if (count < 2) {
470  num++;
471  count--;
472  break;
473  }
474  x = x0 = num[0];
475  y = y0 = num[1];
476  num += 2;
477  count -= 2;
478  path.moveTo(x0, y0);
479 
480  // As per 1.2 spec 8.3.2 The "moveto" commands
481  // If a 'moveto' is followed by multiple pairs of coordinates without explicit commands,
482  // the subsequent pairs shall be treated as implicit 'lineto' commands.
483  pathElem = QLatin1Char('L');
484  }
485  break;
486  case 'z':
487  case 'Z': {
488  x = x0;
489  y = y0;
490  count--; // skip dummy
491  num++;
492  path.closeSubpath();
493  }
494  break;
495  case 'l': {
496  if (count < 2) {
497  num++;
498  count--;
499  break;
500  }
501  x = num[0] + offsetX;
502  y = num[1] + offsetY;
503  num += 2;
504  count -= 2;
505  path.lineTo(x, y);
506 
507  }
508  break;
509  case 'L': {
510  if (count < 2) {
511  num++;
512  count--;
513  break;
514  }
515  x = num[0];
516  y = num[1];
517  num += 2;
518  count -= 2;
519  path.lineTo(x, y);
520  }
521  break;
522  case 'h': {
523  x = num[0] + offsetX;
524  num++;
525  count--;
526  path.lineTo(x, y);
527  }
528  break;
529  case 'H': {
530  x = num[0];
531  num++;
532  count--;
533  path.lineTo(x, y);
534  }
535  break;
536  case 'v': {
537  y = num[0] + offsetY;
538  num++;
539  count--;
540  path.lineTo(x, y);
541  }
542  break;
543  case 'V': {
544  y = num[0];
545  num++;
546  count--;
547  path.lineTo(x, y);
548  }
549  break;
550  case 'c': {
551  if (count < 6) {
552  num += count;
553  count = 0;
554  break;
555  }
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);
559  num += 6;
560  count -= 6;
561  path.cubicTo(c1, c2, e);
562  ctrlPt = c2;
563  x = e.x();
564  y = e.y();
565  break;
566  }
567  case 'C': {
568  if (count < 6) {
569  num += count;
570  count = 0;
571  break;
572  }
573  QPointF c1(num[0], num[1]);
574  QPointF c2(num[2], num[3]);
575  QPointF e(num[4], num[5]);
576  num += 6;
577  count -= 6;
578  path.cubicTo(c1, c2, e);
579  ctrlPt = c2;
580  x = e.x();
581  y = e.y();
582  break;
583  }
584  case 's': {
585  if (count < 4) {
586  num += count;
587  count = 0;
588  break;
589  }
590  QPointF c1;
591  if (lastMode == 'c' || lastMode == 'C' ||
592  lastMode == 's' || lastMode == 'S')
593  c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
594  else
595  c1 = QPointF(x, y);
596  QPointF c2(num[0] + offsetX, num[1] + offsetY);
597  QPointF e(num[2] + offsetX, num[3] + offsetY);
598  num += 4;
599  count -= 4;
600  path.cubicTo(c1, c2, e);
601  ctrlPt = c2;
602  x = e.x();
603  y = e.y();
604  break;
605  }
606  case 'S': {
607  if (count < 4) {
608  num += count;
609  count = 0;
610  break;
611  }
612  QPointF c1;
613  if (lastMode == 'c' || lastMode == 'C' ||
614  lastMode == 's' || lastMode == 'S')
615  c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
616  else
617  c1 = QPointF(x, y);
618  QPointF c2(num[0], num[1]);
619  QPointF e(num[2], num[3]);
620  num += 4;
621  count -= 4;
622  path.cubicTo(c1, c2, e);
623  ctrlPt = c2;
624  x = e.x();
625  y = e.y();
626  break;
627  }
628  case 'q': {
629  if (count < 4) {
630  num += count;
631  count = 0;
632  break;
633  }
634  QPointF c(num[0] + offsetX, num[1] + offsetY);
635  QPointF e(num[2] + offsetX, num[3] + offsetY);
636  num += 4;
637  count -= 4;
638  path.quadTo(c, e);
639  ctrlPt = c;
640  x = e.x();
641  y = e.y();
642  break;
643  }
644  case 'Q': {
645  if (count < 4) {
646  num += count;
647  count = 0;
648  break;
649  }
650  QPointF c(num[0], num[1]);
651  QPointF e(num[2], num[3]);
652  num += 4;
653  count -= 4;
654  path.quadTo(c, e);
655  ctrlPt = c;
656  x = e.x();
657  y = e.y();
658  break;
659  }
660  case 't': {
661  if (count < 2) {
662  num += count;
663  count = 0;
664  break;
665  }
666  QPointF e(num[0] + offsetX, num[1] + offsetY);
667  num += 2;
668  count -= 2;
669  QPointF c;
670  if (lastMode == 'q' || lastMode == 'Q' ||
671  lastMode == 't' || lastMode == 'T')
672  c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
673  else
674  c = QPointF(x, y);
675  path.quadTo(c, e);
676  ctrlPt = c;
677  x = e.x();
678  y = e.y();
679  break;
680  }
681  case 'T': {
682  if (count < 2) {
683  num += count;
684  count = 0;
685  break;
686  }
687  QPointF e(num[0], num[1]);
688  num += 2;
689  count -= 2;
690  QPointF c;
691  if (lastMode == 'q' || lastMode == 'Q' ||
692  lastMode == 't' || lastMode == 'T')
693  c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
694  else
695  c = QPointF(x, y);
696  path.quadTo(c, e);
697  ctrlPt = c;
698  x = e.x();
699  y = e.y();
700  break;
701  }
702  case 'a': {
703  if (count < 7) {
704  num += count;
705  count = 0;
706  break;
707  }
708  qreal rx = (*num++);
709  qreal ry = (*num++);
710  qreal xAxisRotation = (*num++);
711  qreal largeArcFlag = (*num++);
712  qreal sweepFlag = (*num++);
713  qreal ex = (*num++) + offsetX;
714  qreal ey = (*num++) + offsetY;
715  count -= 7;
716  qreal curx = x;
717  qreal cury = y;
718  pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag),
719  int(sweepFlag), ex, ey, curx, cury);
720 
721  x = ex;
722  y = ey;
723  }
724  break;
725  case 'A': {
726  if (count < 7) {
727  num += count;
728  count = 0;
729  break;
730  }
731  qreal rx = (*num++);
732  qreal ry = (*num++);
733  qreal xAxisRotation = (*num++);
734  qreal largeArcFlag = (*num++);
735  qreal sweepFlag = (*num++);
736  qreal ex = (*num++);
737  qreal ey = (*num++);
738  count -= 7;
739  qreal curx = x;
740  qreal cury = y;
741  pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag),
742  int(sweepFlag), ex, ey, curx, cury);
743 
744  x = ex;
745  y = ey;
746  }
747  break;
748  default:
749  return false;
750  }
751  lastMode = pathElem.toLatin1();
752  }
753  }
754  return true;
755 }
Definition: dMatrix.h:42
void error(const char *fmt,...)
Definition: error.cc:979
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
class OCTAVE_API Matrix
Definition: mx-fwd.h:31
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]
Definition: randmtzig.cc:193