summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@trolltech.com>2009-07-28 13:49:01 (GMT)
committerGunnar Sletta <gunnar@trolltech.com>2009-07-28 14:45:48 (GMT)
commitcb04e54252e69fd794aff1ab7ab5ef6c4fbcafad (patch)
treef6081cd172b35e5cec51d64335d1ba3e783d90e6
parentaff08415dcd108cc4a3dfd9ca0d3d4a9e5f72d84 (diff)
downloadQt-cb04e54252e69fd794aff1ab7ab5ef6c4fbcafad.zip
Qt-cb04e54252e69fd794aff1ab7ab5ef6c4fbcafad.tar.gz
Qt-cb04e54252e69fd794aff1ab7ab5ef6c4fbcafad.tar.bz2
Implement perspective filling support in the raster engine...
Reviewed-by: Samuel
-rw-r--r--src/gui/painting/qdatabuffer_p.h17
-rw-r--r--src/gui/painting/qoutlinemapper.cpp59
2 files changed, 56 insertions, 20 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