summaryrefslogtreecommitdiffstats
path: root/src/opengl/qopengl2pexvertexarray.cpp
blob: aa8bae0282c9e03e39edb2413cf68e966860ba8c (plain)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
// Copyright (C) 2016 The Qt Company Ltd.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#include"qopengl2pexvertexarray_p.h"#include <private/qbezier_p.h> QT_BEGIN_NAMESPACE voidQOpenGL2PEXVertexArray::clear(){ vertexArray.reset(); vertexArrayStops.reset(); boundingRectDirty =true;} QOpenGLRect QOpenGL2PEXVertexArray::boundingRect()const{if(boundingRectDirty)returnQOpenGLRect(0.0,0.0,0.0,0.0);elsereturnQOpenGLRect(minX, minY, maxX, maxY);}voidQOpenGL2PEXVertexArray::addClosingLine(int index){ QPointF point(vertexArray.at(index));if(point !=QPointF(vertexArray.last())) vertexArray.add(point);}voidQOpenGL2PEXVertexArray::addCentroid(const QVectorPath &path,int subPathIndex){const QPointF *const points =reinterpret_cast<const QPointF *>(path.points());constQPainterPath::ElementType *const elements = path.elements(); QPointF sum = points[subPathIndex];int count =1;for(int i = subPathIndex +1; i < path.elementCount() && (!elements || elements[i] !=QPainterPath::MoveToElement); ++i) { sum += points[i];++count;}const QPointF centroid = sum /qreal(count); vertexArray.add(centroid);}voidQOpenGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale,bool outline){const QPointF*const points =reinterpret_cast<const QPointF*>(path.points());constQPainterPath::ElementType*const elements = path.elements();if(boundingRectDirty) { minX = maxX = points[0].x(); minY = maxY = points[0].y(); boundingRectDirty =false;}if(!outline && !path.isConvex())addCentroid(path,0);int lastMoveTo = vertexArray.size(); vertexArray.add(points[0]);// The first element is always a moveTodo{if(!elements) {// qDebug("QVectorPath has no elements");// If the path has a null elements pointer, the elements implicitly// start with a moveTo (already added) and continue with lineTos:for(int i=1; i<path.elementCount(); ++i)lineToArray(points[i].x(), points[i].y());break;}// qDebug("QVectorPath has element types");for(int i=1; i<path.elementCount(); ++i) {switch(elements[i]) {caseQPainterPath::MoveToElement:if(!outline)addClosingLine(lastMoveTo);// qDebug("element[%d] is a MoveToElement", i); vertexArrayStops.add(vertexArray.size());if(!outline) {if(!path.isConvex())addCentroid(path, i); lastMoveTo = vertexArray.size();}lineToArray(points[i].x(), points[i].y());// Add the moveTo as a new vertexbreak;caseQPainterPath::LineToElement:// qDebug("element[%d] is a LineToElement", i);lineToArray(points[i].x(), points[i].y());break;caseQPainterPath::CurveToElement: { QBezier b =QBezier::fromPoints(*(((const QPointF *) points) + i -1), points[i], points[i+1], points[i+2]); QRectF bounds = b.bounds();// threshold based on same algorithm as in qtriangulatingstroker.cppint threshold = qMin<float>(64,qMax(bounds.width(), bounds.height()) *3.14f / (curveInverseScale *6));if(threshold <3) threshold =3; qreal one_over_threshold_minus_1 =qreal(1) / (threshold -1);for(int t=0; t<threshold; ++t) { QPointF pt = b.pointAt(t * one_over_threshold_minus_1);lineToArray(pt.x(), pt.y());} i +=2;break; }default:break;}}}while(0);if(!outline)addClosingLine(lastMoveTo); vertexArrayStops.add(vertexArray.size());}voidQOpenGL2PEXVertexArray::lineToArray(const GLfloat x,const GLfloat y){ vertexArray.add(QOpenGLPoint(x, y));if(x > maxX) maxX = x;else if(x < minX) minX = x;if(y > maxY) maxY = y;else if(y < minY) minY = y;} QT_END_NAMESPACE 
close