summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/painting/qdatabuffer_p.h17
-rw-r--r--src/gui/painting/qoutlinemapper.cpp59
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp89
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpaintengineex.cpp68
-rw-r--r--src/gui/painting/qpainterpath.cpp2
-rw-r--r--src/gui/painting/qvectorpath_p.h2
7 files changed, 122 insertions, 117 deletions
diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h
index 275ec13..b568f43 100644
--- a/src/gui/painting/qdatabuffer_p.h
+++ b/src/gui/painting/qdatabuffer_p.h
@@ -114,6 +114,23 @@ public:
qSwap(buffer, other.buffer);
}
+ inline void insertBlank(int pos, int count) {
+ Q_ASSERT(pos >= 0);
+ Q_ASSERT(pos < siz);
+ reserve(siz + count);
+ for (int i = siz - pos - 1; i >= 0; --i)
+ buffer[pos + count + i] = buffer[pos + i];
+ siz += count;
+ }
+
+ inline void removeAndShift(int pos, int count) {
+ Q_ASSERT(pos >= 0);
+ Q_ASSERT(pos < siz);
+ for (int i=pos; i<siz-count; ++i)
+ buffer[i] = buffer[i+count];
+ siz -= count;
+ }
+
inline QDataBuffer &operator<<(const Type &t) { add(t); return *this; }
private:
diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp
index 401fad9..9c073f2 100644
--- a/src/gui/painting/qoutlinemapper.cpp
+++ b/src/gui/painting/qoutlinemapper.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qoutlinemapper_p.h"
+#include "qbezier_p.h"
#include "qmath.h"
@@ -199,51 +200,69 @@ void QOutlineMapper::endOutline()
}
} else {
// ## TODO: this case needs to be plain code polygonal paths
- QPainterPath path;
+ QTransform matrix(m_m11, m_m12, m_m13, m_m21, m_m22, m_m23, m_dx, m_dy, m_m33);
+
if (m_element_types.isEmpty()) {
if (!m_elements.isEmpty())
- path.moveTo(m_elements.at(0));
+ m_elements_dev << m_elements.at(0) * matrix;
for (int i=1; i<m_elements.size(); ++i)
- path.lineTo(m_elements.at(i));
+ m_elements_dev << m_elements.at(i) * matrix;
+
} else {
- for (int i=0; i<m_elements.size(); ++i) {
- switch (m_element_types.at(i)) {
+ for (int i=0, t=0; i<m_elements.size(); ++i) {
+ switch (m_element_types.at(t)) {
case QPainterPath::MoveToElement:
- path.moveTo(m_elements.at(i));
+ m_elements_dev << m_elements.at(i) * matrix;
+ ++t;
break;
case QPainterPath::LineToElement:
- path.lineTo(m_elements.at(i));
+ m_elements_dev << m_elements.at(i) * matrix;
+ ++t;
break;
- case QPainterPath::CurveToElement:
- path.cubicTo(m_elements.at(i), m_elements.at(i+1), m_elements.at(i+2));
+ case QPainterPath::CurveToElement: {
+ QPolygonF segment = QBezier::fromPoints(m_elements.at(i-1),
+ m_elements.at(i),
+ m_elements.at(i+1),
+ m_elements.at(i+2)).toPolygon();
+ if (segment.size() > 3)
+ m_element_types.insertBlank(t, segment.size() - 3);
+ else if (segment.size() < 3)
+ m_element_types.removeAndShift(t, 3 - segment.size());
+
+ for (QPolygonF::const_iterator it = segment.constBegin();
+ it < segment.constEnd(); ++it, ++t) {
+ m_elements_dev << *it * matrix;
+ m_element_types.at(t) = QPainterPath::LineToElement;
+ }
i += 2;
- break;
+ } break;
default:
Q_ASSERT(false);
break;
}
}
+ element_count = m_elements_dev.size();
}
- path = QTransform(m_m11, m_m12, m_m13, m_m21, m_m22, m_m23, m_dx, m_dy, m_m33).map(path);
- uint old_txop = m_txop;
- m_txop = QTransform::TxNone;
- if (path.isEmpty())
- m_valid = false;
- else
- convertPath(path);
- m_txop = old_txop;
- return;
}
elements = m_elements_dev.data();
}
if (m_round_coords) {
// round coordinates to match outlines drawn with drawLine_midpoint_i
- for (int i = 0; i < m_elements.size(); ++i)
+ for (int i = 0; i < element_count; ++i)
elements[i] = QPointF(qFloor(elements[i].x() + aliasedCoordinateDelta),
qFloor(elements[i].y() + aliasedCoordinateDelta));
}
+#ifdef QT_DEBUG_CONVERT
+ for (int i=0; i<element_count; ++i) {
+ printf("%d: (%.2f, %.2f)\n",
+ !m_element_types.isEmpty() ? m_element_types.at(i) : -1,
+ elements[i].x(),
+ elements[i].y());
+ }
+#endif
+
controlPointRect = boundingRect(elements, element_count);
#ifdef QT_DEBUG_CONVERT
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index dfd3e16..69e490a 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1672,34 +1672,6 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
QPaintEngineEx::drawRects(rects, rectCount);
}
-void QRasterPaintEnginePrivate::strokeProjective(const QPainterPath &path)
-{
- Q_Q(QRasterPaintEngine);
- QRasterPaintEngineState *s = q->state();
-
- const QPen &pen = s->lastPen;
- QPainterPathStroker pathStroker;
- pathStroker.setWidth(pen.width() == 0 ? qreal(1) : pen.width());
- pathStroker.setCapStyle(pen.capStyle());
- pathStroker.setJoinStyle(pen.joinStyle());
- pathStroker.setMiterLimit(pen.miterLimit());
- pathStroker.setDashOffset(pen.dashOffset());
-
- if (qpen_style(pen) == Qt::CustomDashLine)
- pathStroker.setDashPattern(pen.dashPattern());
- else
- pathStroker.setDashPattern(qpen_style(pen));
-
- outlineMapper->setMatrix(QTransform());
- const QPainterPath stroke = pen.isCosmetic()
- ? pathStroker.createStroke(s->matrix.map(path))
- : s->matrix.map(pathStroker.createStroke(path));
-
- rasterize(outlineMapper->convertPath(stroke), s->penData.blend, &s->penData, rasterBuffer);
- outlinemapper_xform_dirty = true;
-}
-
-
/*!
\internal
@@ -1969,67 +1941,6 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color)
fillRect(r, &d->solid_color_filler);
}
-/*!
- \reimp
-*/
-void QRasterPaintEngine::drawPath(const QPainterPath &path)
-{
-#ifdef QT_DEBUG_DRAW
- QRectF bounds = path.boundingRect();
- qDebug(" - QRasterPaintEngine::drawPath(), [%.2f, %.2f, %.2f, %.2f]",
- bounds.x(), bounds.y(), bounds.width(), bounds.height());
-#endif
-
- if (path.isEmpty())
- return;
-
- // Filling..,
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
-
- ensureBrush();
- if (s->brushData.blend) {
- ensureOutlineMapper();
- fillPath(path, &s->brushData);
- }
-
- // Stroking...
- ensurePen();
- if (!s->penData.blend)
- return;
- {
- if (s->matrix.type() >= QTransform::TxProject) {
- d->strokeProjective(path);
- } else {
- Q_ASSERT(s->stroker);
- d->outlineMapper->beginOutline(Qt::WindingFill);
- qreal txscale = 1;
- if (s->pen.isCosmetic() || (qt_scaleForTransform(s->matrix, &txscale) && txscale != 1)) {
- const qreal strokeWidth = d->basicStroker.strokeWidth();
- const QRectF clipRect = d->dashStroker ? d->dashStroker->clipRect() : QRectF();
- if (d->dashStroker)
- d->dashStroker->setClipRect(d->deviceRect);
- d->basicStroker.setStrokeWidth(strokeWidth * txscale);
- d->outlineMapper->setMatrix(QTransform());
- s->stroker->strokePath(path, d->outlineMapper, s->matrix);
- d->outlinemapper_xform_dirty = true;
- d->basicStroker.setStrokeWidth(strokeWidth);
- if (d->dashStroker)
- d->dashStroker->setClipRect(clipRect);
- } else {
- ensureOutlineMapper();
- s->stroker->strokePath(path, d->outlineMapper, QTransform());
- }
- d->outlineMapper->endOutline();
-
- ProcessSpans blend = d->getPenFunc(d->outlineMapper->controlPointRect,
- &s->penData);
- d->rasterize(d->outlineMapper->outline(), blend, &s->penData, d->rasterBuffer);
- }
- }
-
-}
-
static inline bool isAbove(const QPointF *a, const QPointF *b)
{
return a->y() < b->y();
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 283c442..3dab491 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -165,7 +165,6 @@ public:
void updateMatrix(const QTransform &matrix);
- void drawPath(const QPainterPath &path);
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
void fillPath(const QPainterPath &path, QSpanData *fillData);
@@ -327,7 +326,6 @@ public:
inline const QClipData *clip() const;
- void strokeProjective(const QPainterPath &path);
void initializeRasterizer(QSpanData *data);
void recalculateFastImages();
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 797a5ab..8ec881e 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -42,6 +42,7 @@
#include "qpaintengineex_p.h"
#include "qpainter_p.h"
#include "qstroker_p.h"
+#include "qbezier_p.h"
#include <private/qpainterpath_p.h>
#include <qvarlengtharray.h>
@@ -91,6 +92,40 @@ QRectF QVectorPath::controlPointRect() const
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
}
+QPainterPath QVectorPath::convertToPainterPath() const
+{
+ QPainterPath path;
+
+ if (m_count == 0)
+ return path;
+
+ const QPointF *points = (const QPointF *) m_points;
+
+ if (m_elements) {
+ for (int i=0; i<m_count; ++i) {
+ switch (m_elements[i]) {
+ case QPainterPath::MoveToElement:
+ path.moveTo(points[i]);
+ break;
+ case QPainterPath::LineToElement:
+ path.lineTo(points[i]);
+ break;
+ case QPainterPath::CurveToElement:
+ path.cubicTo(points[i], points[i+1], points[i+2]);
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ path.moveTo(points[0]);
+ for (int i=1; i<m_count; ++i)
+ path.lineTo(points[i]);
+ }
+
+ return path;
+}
+
const QVectorPath &qtVectorPathForPath(const QPainterPath &path)
{
Q_ASSERT(path.d_func());
@@ -450,13 +485,14 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
QVectorPath strokePath(d->strokeHandler->pts.data(),
d->strokeHandler->types.size(),
d->strokeHandler->types.data(),
- QVectorPath::WindingFill);
+ flags);
fill(strokePath, pen.brush());
} else {
const qreal strokeWidth = d->stroker.strokeWidth();
d->stroker.setStrokeWidth(strokeWidth * txscale);
// For cosmetic pens we need a bit of trickery... We to process xform the input points
if (types) {
+ bool isProject = state()->matrix.type() >= QTransform::TxProject;
while (points < lastPoint) {
switch (*types) {
case QPainterPath::MoveToElement: {
@@ -474,10 +510,30 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
break;
}
case QPainterPath::CurveToElement: {
- QPointF c1 = ((QPointF *) points)[0] * state()->matrix;
- QPointF c2 = ((QPointF *) points)[1] * state()->matrix;
- QPointF e = ((QPointF *) points)[2] * state()->matrix;
- d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
+ // Convert projective xformed curves to line
+ // segments so they can be transformed more
+ // accurately
+ if (isProject) {
+ // -1 access here is safe because there is
+ // always an element prior to the cubicTo, we
+ // just need the value..
+ QPolygonF segment =
+ QBezier::fromPoints(*(((QPointF *) points) - 1),
+ *((QPointF *) points),
+ *(((QPointF *) points) + 1),
+ *(((QPointF *) points) + 2)).toPolygon();
+
+ for (QPolygonF::const_iterator it = segment.constBegin();
+ it < segment.constEnd(); ++it) {
+ const QPointF pt = *it * state()->matrix;
+ d->activeStroker->lineTo(pt.x(), pt.y());
+ }
+ } else {
+ QPointF c1 = ((QPointF *) points)[0] * state()->matrix;
+ QPointF c2 = ((QPointF *) points)[1] * state()->matrix;
+ QPointF e = ((QPointF *) points)[2] * state()->matrix;
+ d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
+ }
points += 6;
types += 3;
flags |= QVectorPath::CurvedShapeHint;
@@ -512,7 +568,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
QVectorPath strokePath(d->strokeHandler->pts.data(),
d->strokeHandler->types.size(),
d->strokeHandler->types.data(),
- QVectorPath::WindingFill);
+ flags);
QTransform xform = state()->matrix;
state()->matrix = QTransform();
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index ea86cf5..09972b0 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -3271,6 +3271,8 @@ void QPainterPath::setDirty(bool dirty)
{
d_func()->dirtyBounds = dirty;
d_func()->dirtyControlBounds = dirty;
+ delete d_func()->pathConverter;
+ d_func()->pathConverter = 0;
}
void QPainterPath::computeBoundingRect() const
diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h
index b6b85fa..9264c9c 100644
--- a/src/gui/painting/qvectorpath_p.h
+++ b/src/gui/painting/qvectorpath_p.h
@@ -130,6 +130,8 @@ public:
static inline uint polygonFlags(QPaintEngine::PolygonDrawMode mode);
+ QPainterPath convertToPainterPath() const;
+
private:
Q_DISABLE_COPY(QVectorPath)