diff options
author | Gunnar Sletta <gunnar@trolltech.com> | 2009-07-28 13:49:01 (GMT) |
---|---|---|
committer | Gunnar Sletta <gunnar@trolltech.com> | 2009-07-28 14:45:48 (GMT) |
commit | cb04e54252e69fd794aff1ab7ab5ef6c4fbcafad (patch) | |
tree | f6081cd172b35e5cec51d64335d1ba3e783d90e6 /src/gui/painting | |
parent | aff08415dcd108cc4a3dfd9ca0d3d4a9e5f72d84 (diff) | |
download | Qt-cb04e54252e69fd794aff1ab7ab5ef6c4fbcafad.zip Qt-cb04e54252e69fd794aff1ab7ab5ef6c4fbcafad.tar.gz Qt-cb04e54252e69fd794aff1ab7ab5ef6c4fbcafad.tar.bz2 |
Implement perspective filling support in the raster engine...
Reviewed-by: Samuel
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qdatabuffer_p.h | 17 | ||||
-rw-r--r-- | src/gui/painting/qoutlinemapper.cpp | 59 |
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 |