Changeset 846 for trunk/src/gui/painting/qstroker.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/painting/qstroker.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 121 121 { 122 122 public: 123 QSubpathFlatIterator(const QDataBuffer<QStrokerOps::Element> *path )124 : m_path(path), m_pos(0), m_curve_index(-1) { }123 QSubpathFlatIterator(const QDataBuffer<QStrokerOps::Element> *path, qreal threshold) 124 : m_path(path), m_pos(0), m_curve_index(-1), m_curve_threshold(threshold) { } 125 125 126 126 inline bool hasNext() const { return m_curve_index >= 0 || m_pos < m_path->size(); } … … 153 153 qt_fixed_to_real(m_path->at(m_pos+1).y)), 154 154 QPointF(qt_fixed_to_real(m_path->at(m_pos+2).x), 155 qt_fixed_to_real(m_path->at(m_pos+2).y))).toPolygon( );155 qt_fixed_to_real(m_path->at(m_pos+2).y))).toPolygon(m_curve_threshold); 156 156 m_curve_index = 1; 157 157 e.type = QPainterPath::LineToElement; … … 170 170 QPolygonF m_curve; 171 171 int m_curve_index; 172 qreal m_curve_threshold; 172 173 }; 173 174 … … 188 189 189 190 QStrokerOps::QStrokerOps() 190 : m_customData(0), m_moveTo(0), m_lineTo(0), m_cubicTo(0) 191 : m_elements(0) 192 , m_curveThreshold(qt_real_to_fixed(0.25)) 193 , m_dashThreshold(qt_real_to_fixed(0.25)) 194 , m_customData(0) 195 , m_moveTo(0) 196 , m_lineTo(0) 197 , m_cubicTo(0) 191 198 { 192 199 } … … 195 202 { 196 203 } 197 198 204 199 205 /*! … … 239 245 return; 240 246 247 setCurveThresholdFromTransform(QTransform()); 241 248 begin(customData); 242 249 int count = path.elementCount(); … … 309 316 if (!pointCount) 310 317 return; 318 319 setCurveThresholdFromTransform(QTransform()); 311 320 begin(data); 312 321 if (matrix.isIdentity()) { … … 349 358 } 350 359 360 setCurveThresholdFromTransform(QTransform()); 351 361 begin(data); 352 362 moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y())); … … 367 377 m_strokeWidth = qt_real_to_fixed(1); 368 378 m_miterLimit = qt_real_to_fixed(2); 369 m_curveThreshold = qt_real_to_fixed(0.25);370 379 } 371 380 372 381 QStroker::~QStroker() 373 382 { 374 375 383 } 376 384 … … 603 611 QLineF miterLine(QPointF(qt_fixed_to_real(focal_x), 604 612 qt_fixed_to_real(focal_y)), isect); 605 if ( miterLine.length() > qt_fixed_to_real(m_strokeWidth * m_miterLimit) / 2) {613 if (type == QLineF::NoIntersection || miterLine.length() > qt_fixed_to_real(m_strokeWidth * m_miterLimit) / 2) { 606 614 emitLineTo(qt_real_to_fixed(nextLine.x1()), 607 615 qt_real_to_fixed(nextLine.y1())); … … 1044 1052 } 1045 1053 1054 static inline bool lineRectIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br) 1055 { 1056 return ((p1.x > tl.x || p2.x > tl.x) && (p1.x < br.x || p2.x < br.x) 1057 && (p1.y > tl.y || p2.y > tl.y) && (p1.y < br.y || p2.y < br.y)); 1058 } 1059 1060 // If the line intersects the rectangle, this function will return true. 1061 static bool lineIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br) 1062 { 1063 if (!lineRectIntersectsRect(p1, p2, tl, br)) 1064 return false; 1065 if (p1.x == p2.x || p1.y == p2.y) 1066 return true; 1067 1068 if (p1.y > p2.y) 1069 qSwap(p1, p2); // make p1 above p2 1070 qfixed2d u; 1071 qfixed2d v; 1072 qfixed2d w = {p2.x - p1.x, p2.y - p1.y}; 1073 if (p1.x < p2.x) { 1074 // backslash 1075 u.x = tl.x - p1.x; u.y = br.y - p1.y; 1076 v.x = br.x - p1.x; v.y = tl.y - p1.y; 1077 } else { 1078 // slash 1079 u.x = tl.x - p1.x; u.y = tl.y - p1.y; 1080 v.x = br.x - p1.x; v.y = br.y - p1.y; 1081 } 1082 #if defined(QFIXED_IS_26_6) || defined(QFIXED_IS_16_16) 1083 qint64 val1 = qint64(u.x) * qint64(w.y) - qint64(u.y) * qint64(w.x); 1084 qint64 val2 = qint64(v.x) * qint64(w.y) - qint64(v.y) * qint64(w.x); 1085 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0); 1086 #elif defined(QFIXED_IS_32_32) 1087 // Cannot do proper test because it may overflow. 1088 return true; 1089 #else 1090 qreal val1 = u.x * w.y - u.y * w.x; 1091 qreal val2 = v.x * w.y - v.y * w.x; 1092 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0); 1093 #endif 1094 } 1046 1095 1047 1096 void QDashStroker::processCurrentSubpath() … … 1068 1117 return; 1069 1118 1119 qreal invSumLength = qreal(1) / sumLength; 1120 1070 1121 Q_ASSERT(dashCount > 0); 1071 1122 1072 dashCount = (dashCount / 2) *2; // Round down to even number1123 dashCount = dashCount & -2; // Round down to even number 1073 1124 1074 1125 int idash = 0; // Index to current dash … … 1078 1129 1079 1130 // make sure doffset is in range [0..sumLength) 1080 doffset -= qFloor(doffset / sumLength) * sumLength;1131 doffset -= qFloor(doffset * invSumLength) * sumLength; 1081 1132 1082 1133 while (doffset >= dashes[idash]) { 1083 1134 doffset -= dashes[idash]; 1084 idash = (idash + 1) % dashCount; 1135 if (++idash >= dashCount) 1136 idash = 0; 1085 1137 } 1086 1138 … … 1092 1144 QPainterPath dashPath; 1093 1145 1094 QSubpathFlatIterator it(&m_elements );1146 QSubpathFlatIterator it(&m_elements, m_dashThreshold); 1095 1147 qfixed2d prev = it.next(); 1096 1148 … … 1120 1172 1121 1173 bool done = pos >= estop; 1174 1175 if (clipping) { 1176 // Check if the entire line can be clipped away. 1177 if (!lineIntersectsRect(prev, e, clip_tl, clip_br)) { 1178 // Cut away full dash sequences. 1179 elen -= qFloor(elen * invSumLength) * sumLength; 1180 // Update dash offset. 1181 while (!done) { 1182 qreal dpos = pos + dashes[idash] - doffset - estart; 1183 1184 Q_ASSERT(dpos >= 0); 1185 1186 if (dpos > elen) { // dash extends this line 1187 doffset = dashes[idash] - (dpos - elen); // subtract the part already used 1188 pos = estop; // move pos to next path element 1189 done = true; 1190 } else { // Dash is on this line 1191 pos = dpos + estart; 1192 done = pos >= estop; 1193 if (++idash >= dashCount) 1194 idash = 0; 1195 doffset = 0; // full segment so no offset on next. 1196 } 1197 } 1198 hasMoveTo = false; 1199 move_to_pos = e; 1200 } 1201 } 1202 1122 1203 // Dash away... 1123 1204 while (!done) { 1124 1205 QPointF p2; 1125 1206 1126 int idash_incr = 0;1127 1207 bool has_offset = doffset > 0; 1208 bool evenDash = (idash & 1) == 0; 1128 1209 qreal dpos = pos + dashes[idash] - doffset - estart; 1129 1210 … … 1139 1220 pos = dpos + estart; 1140 1221 done = pos >= estop; 1141 idash_incr = 1; 1222 if (++idash >= dashCount) 1223 idash = 0; 1142 1224 doffset = 0; // full segment so no offset on next. 1143 1225 } 1144 1226 1145 if ( idash % 2 == 0) {1227 if (evenDash) { 1146 1228 line_to_pos.x = qt_real_to_fixed(p2.x()); 1147 1229 line_to_pos.y = qt_real_to_fixed(p2.y()); 1148 1230 1149 // If we have an offset, we're continuing a dash 1150 // from a previous element and should only 1151 // continue the current dash, without starting a 1152 // new subpath. 1153 if (!has_offset || !hasMoveTo) { 1154 emitMoveTo(move_to_pos.x, move_to_pos.y); 1155 hasMoveTo = true; 1231 if (!clipping 1232 || lineRectIntersectsRect(move_to_pos, line_to_pos, clip_tl, clip_br)) 1233 { 1234 // If we have an offset, we're continuing a dash 1235 // from a previous element and should only 1236 // continue the current dash, without starting a 1237 // new subpath. 1238 if (!has_offset || !hasMoveTo) { 1239 emitMoveTo(move_to_pos.x, move_to_pos.y); 1240 hasMoveTo = true; 1241 } 1242 1243 emitLineTo(line_to_pos.x, line_to_pos.y); 1244 } else { 1245 hasMoveTo = false; 1156 1246 } 1157 1158 if (!clipping 1159 // if move_to is inside... 1160 || (move_to_pos.x > clip_tl.x && move_to_pos.x < clip_br.x 1161 && move_to_pos.y > clip_tl.y && move_to_pos.y < clip_br.y) 1162 // Or if line_to is inside... 1163 || (line_to_pos.x > clip_tl.x && line_to_pos.x < clip_br.x 1164 && line_to_pos.y > clip_tl.y && line_to_pos.y < clip_br.y)) 1165 { 1166 emitLineTo(line_to_pos.x, line_to_pos.y); 1167 } 1247 move_to_pos = line_to_pos; 1168 1248 } else { 1169 1249 move_to_pos.x = qt_real_to_fixed(p2.x()); 1170 1250 move_to_pos.y = qt_real_to_fixed(p2.y()); 1171 1251 } 1172 1173 idash = (idash + idash_incr) % dashCount;1174 1252 } 1175 1253
Note:
See TracChangeset
for help on using the changeset viewer.