Qt 4.8
qgl2pexvertexarray.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtOpenGL 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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qgl2pexvertexarray_p.h"
43 
44 #include <private/qbezier_p.h>
45 
47 
49 {
52  boundingRectDirty = true;
53 }
54 
55 
57 {
59  return QGLRect(0.0, 0.0, 0.0, 0.0);
60  else
61  return QGLRect(minX, minY, maxX, maxY);
62 }
63 
65 {
66  QPointF point(vertexArray.at(index));
67  if (point != QPointF(vertexArray.last()))
68  vertexArray.add(point);
69 }
70 
71 void QGL2PEXVertexArray::addCentroid(const QVectorPath &path, int subPathIndex)
72 {
73  const QPointF *const points = reinterpret_cast<const QPointF *>(path.points());
74  const QPainterPath::ElementType *const elements = path.elements();
75 
76  QPointF sum = points[subPathIndex];
77  int count = 1;
78 
79  for (int i = subPathIndex + 1; i < path.elementCount() && (!elements || elements[i] != QPainterPath::MoveToElement); ++i) {
80  sum += points[i];
81  ++count;
82  }
83 
84  const QPointF centroid = sum / qreal(count);
85  vertexArray.add(centroid);
86 }
87 
88 void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline)
89 {
90  const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
91  const QPainterPath::ElementType* const elements = path.elements();
92 
93  if (boundingRectDirty) {
94  minX = maxX = points[0].x();
95  minY = maxY = points[0].y();
96  boundingRectDirty = false;
97  }
98 
99  if (!outline && !path.isConvex())
100  addCentroid(path, 0);
101 
102  int lastMoveTo = vertexArray.size();
103  vertexArray.add(points[0]); // The first element is always a moveTo
104 
105  do {
106  if (!elements) {
107 // qDebug("QVectorPath has no elements");
108  // If the path has a null elements pointer, the elements implicitly
109  // start with a moveTo (already added) and continue with lineTos:
110  for (int i=1; i<path.elementCount(); ++i)
111  lineToArray(points[i].x(), points[i].y());
112 
113  break;
114  }
115 // qDebug("QVectorPath has element types");
116 
117  for (int i=1; i<path.elementCount(); ++i) {
118  switch (elements[i]) {
120  if (!outline)
121  addClosingLine(lastMoveTo);
122 // qDebug("element[%d] is a MoveToElement", i);
124  if (!outline) {
125  if (!path.isConvex()) addCentroid(path, i);
126  lastMoveTo = vertexArray.size();
127  }
128  lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex
129  break;
131 // qDebug("element[%d] is a LineToElement", i);
132  lineToArray(points[i].x(), points[i].y());
133  break;
135  QBezier b = QBezier::fromPoints(*(((const QPointF *) points) + i - 1),
136  points[i],
137  points[i+1],
138  points[i+2]);
139  QRectF bounds = b.bounds();
140  // threshold based on same algorithm as in qtriangulatingstroker.cpp
141  int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6));
142  if (threshold < 3) threshold = 3;
143  qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1);
144  for (int t=0; t<threshold; ++t) {
145  QPointF pt = b.pointAt(t * one_over_threshold_minus_1);
146  lineToArray(pt.x(), pt.y());
147  }
148  i += 2;
149  break; }
150  default:
151  break;
152  }
153  }
154  } while (0);
155 
156  if (!outline)
157  addClosingLine(lastMoveTo);
159 }
160 
161 void QGL2PEXVertexArray::lineToArray(const GLfloat x, const GLfloat y)
162 {
163  vertexArray.add(QGLPoint(x, y));
164 
165  if (x > maxX)
166  maxX = x;
167  else if (x < minX)
168  minX = x;
169  if (y > maxY)
170  maxY = y;
171  else if (y < minY)
172  minY = y;
173 }
174 
ElementType
This enum describes the types of elements used to connect vertices in subpaths.
Definition: qpainterpath.h:70
double qreal
Definition: qglobal.h:1193
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
int elementCount() const
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
QPointF pointAt(qreal t) const
Definition: qbezier_p.h:163
const QPainterPath::ElementType * elements() const
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
static QBezier fromPoints(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
Definition: qbezier.cpp:71
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QGLRect boundingRect() const
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
Type & at(int i)
Definition: qdatabuffer_p.h:86
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
void add(const Type &t)
Definition: qdatabuffer_p.h:93
void addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline=true)
void lineToArray(const GLfloat x, const GLfloat y)
QRectF bounds() const
Definition: qbezier.cpp:223
void addCentroid(const QVectorPath &path, int subPathIndex)
Type & last()
Definition: qdatabuffer_p.h:88
const qreal * points() const
bool isConvex() const
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
quint16 index
static const QTextHtmlElement elements[Html_NumElements]
QDataBuffer< QGLPoint > vertexArray
QDataBuffer< int > vertexArrayStops
void addClosingLine(int index)
void reset()
Definition: qdatabuffer_p.h:79
int size() const
Definition: qdatabuffer_p.h:83