File indexing completed on 2025-02-02 04:14:58
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2006 Thorsten Zachmann <zachmann@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #include "TestPathShape.h" 0007 0008 #include <QPainterPath> 0009 #include "KoPathShape.h" 0010 #include "KoPathPoint.h" 0011 #include "KoPathPointData.h" 0012 #include "KoPathSegment.h" 0013 0014 #include <simpletest.h> 0015 0016 void TestPathShape::close() 0017 { 0018 KoPathShape path; 0019 path.lineTo(QPointF(10, 0)); 0020 path.lineTo(QPointF(10, 10)); 0021 0022 QPainterPath ppath(QPointF(0, 0)); 0023 ppath.lineTo(QPointF(10, 0)); 0024 ppath.lineTo(10, 10); 0025 0026 QVERIFY(ppath == path.outline()); 0027 0028 path.close(); 0029 ppath.closeSubpath(); 0030 0031 QVERIFY(ppath == path.outline()); 0032 0033 path.lineTo(QPointF(0, 10)); 0034 ppath.lineTo(0, 10); 0035 0036 QVERIFY(ppath == path.outline()); 0037 } 0038 0039 void TestPathShape::moveTo() 0040 { 0041 KoPathShape path; 0042 path.moveTo(QPointF(10, 10)); 0043 QPainterPath ppath(QPointF(10, 10)); 0044 path.lineTo(QPointF(20, 20)); 0045 ppath.lineTo(20, 20); 0046 QVERIFY(ppath == path.outline()); 0047 path.moveTo(QPointF(30, 30)); 0048 ppath.moveTo(30, 30); 0049 path.lineTo(QPointF(40, 40)); 0050 ppath.lineTo(QPointF(40, 40)); 0051 QVERIFY(ppath == path.outline()); 0052 } 0053 0054 void TestPathShape::normalize() 0055 { 0056 KoPathShape path; 0057 path.moveTo(QPointF(10, 10)); 0058 path.lineTo(QPointF(20, 20)); 0059 path.normalize(); 0060 QPainterPath ppath(QPointF(0, 0)); 0061 ppath.lineTo(10, 10); 0062 QVERIFY(ppath == path.outline()); 0063 } 0064 0065 void TestPathShape::pathPointIndex() 0066 { 0067 KoPathShape path; 0068 KoPathPoint * point1 = path.moveTo(QPointF(10, 10)); 0069 KoPathPointIndex p1Index(0, 0); 0070 KoPathPoint * point2 = path.lineTo(QPointF(20, 20)); 0071 KoPathPointIndex p2Index(0, 1); 0072 KoPathPoint * point3 = path.moveTo(QPointF(30, 30)); 0073 KoPathPointIndex p3Index(1, 0); 0074 KoPathPoint * point4 = path.lineTo(QPointF(40, 40)); 0075 KoPathPointIndex p4Index(1, 1); 0076 KoPathPoint * point5 = 0; 0077 KoPathPointIndex p5Index(-1, -1); 0078 0079 QCOMPARE(p1Index, path.pathPointIndex(point1)); 0080 QCOMPARE(p2Index, path.pathPointIndex(point2)); 0081 QCOMPARE(p3Index, path.pathPointIndex(point3)); 0082 QCOMPARE(p4Index, path.pathPointIndex(point4)); 0083 QCOMPARE(p5Index, path.pathPointIndex(point5)); 0084 0085 QVERIFY(p1Index == path.pathPointIndex(point1)); 0086 QVERIFY(p2Index == path.pathPointIndex(point2)); 0087 QVERIFY(p3Index == path.pathPointIndex(point3)); 0088 QVERIFY(p4Index == path.pathPointIndex(point4)); 0089 QVERIFY(p5Index == path.pathPointIndex(point5)); 0090 } 0091 0092 void TestPathShape::pointByIndex() 0093 { 0094 KoPathShape path; 0095 KoPathPoint * point1 = path.moveTo(QPointF(10, 10)); 0096 KoPathPoint * point2 = path.lineTo(QPointF(20, 20)); 0097 KoPathPoint * point3 = path.moveTo(QPointF(30, 30)); 0098 KoPathPoint * point4 = path.lineTo(QPointF(40, 40)); 0099 KoPathPoint * point5 = 0; 0100 0101 QVERIFY(point1 == path.pointByIndex(path.pathPointIndex(point1))); 0102 QVERIFY(point2 == path.pointByIndex(path.pathPointIndex(point2))); 0103 QVERIFY(point3 == path.pointByIndex(path.pathPointIndex(point3))); 0104 QVERIFY(point4 == path.pointByIndex(path.pathPointIndex(point4))); 0105 QVERIFY(point5 == path.pointByIndex(path.pathPointIndex(point5))); 0106 } 0107 0108 void TestPathShape::segmentByIndex() 0109 { 0110 KoPathShape path; 0111 KoPathPoint * point1 = path.moveTo(QPointF(20, 20)); 0112 KoPathPoint * point2 = path.lineTo(QPointF(15, 25)); 0113 path.lineTo(QPointF(10, 20)); 0114 path.close(); 0115 path.moveTo(QPointF(20, 30)); 0116 KoPathPoint * point3 = path.lineTo(QPointF(20, 30)); 0117 path.moveTo(QPointF(30, 30)); 0118 path.lineTo(QPointF(40, 30)); 0119 path.lineTo(QPointF(40, 40)); 0120 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0121 KoPathPoint * point4 = path.moveTo(QPointF(50, 50)); 0122 path.lineTo(QPointF(60, 50)); 0123 path.lineTo(QPointF(60, 60)); 0124 KoPathPoint * point5 = path.curveTo(QPointF(60, 65), QPointF(50, 65), QPointF(50, 60)); 0125 path.close(); 0126 0127 QVERIFY(KoPathSegment(point1, point2) == path.segmentByIndex(path.pathPointIndex(point1))); 0128 // test last point in a open path 0129 QVERIFY(KoPathSegment(0, 0) == path.segmentByIndex(path.pathPointIndex(point3))); 0130 // test last point in a closed path 0131 QVERIFY(KoPathSegment(point5, point4) == path.segmentByIndex(path.pathPointIndex(point5))); 0132 // test out of bounds 0133 QVERIFY(KoPathSegment(0, 0) == path.segmentByIndex(KoPathPointIndex(3, 4))); 0134 QVERIFY(KoPathSegment(0, 0) == path.segmentByIndex(KoPathPointIndex(4, 0))); 0135 } 0136 0137 void TestPathShape::pointCount() 0138 { 0139 KoPathShape path; 0140 path.moveTo(QPointF(20, 20)); 0141 path.lineTo(QPointF(15, 25)); 0142 path.lineTo(QPointF(10, 20)); 0143 path.close(); 0144 0145 QVERIFY(path.pointCount() == 3); 0146 0147 path.moveTo(QPointF(20, 30)); 0148 path.lineTo(QPointF(20, 30)); 0149 path.moveTo(QPointF(30, 30)); 0150 path.lineTo(QPointF(40, 30)); 0151 path.lineTo(QPointF(40, 40)); 0152 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0153 0154 QVERIFY(path.pointCount() == 9); 0155 0156 path.moveTo(QPointF(50, 50)); 0157 path.lineTo(QPointF(60, 50)); 0158 path.lineTo(QPointF(60, 60)); 0159 path.curveTo(QPointF(60, 65), QPointF(50, 65), QPointF(50, 60)); 0160 path.close(); 0161 0162 QVERIFY(path.pointCount() == 13); 0163 } 0164 0165 void TestPathShape::subpathPointCount() 0166 { 0167 KoPathShape path; 0168 path.moveTo(QPointF(20, 20)); 0169 path.lineTo(QPointF(15, 25)); 0170 path.lineTo(QPointF(10, 20)); 0171 path.close(); 0172 path.moveTo(QPointF(20, 30)); 0173 path.lineTo(QPointF(20, 30)); 0174 path.moveTo(QPointF(30, 30)); 0175 path.lineTo(QPointF(40, 30)); 0176 path.lineTo(QPointF(40, 40)); 0177 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0178 path.moveTo(QPointF(50, 50)); 0179 path.lineTo(QPointF(60, 50)); 0180 path.lineTo(QPointF(60, 60)); 0181 path.curveTo(QPointF(60, 65), QPointF(50, 65), QPointF(50, 60)); 0182 path.close(); 0183 0184 QVERIFY(path.subpathPointCount(0) == 3); 0185 QVERIFY(path.subpathPointCount(1) == 2); 0186 QVERIFY(path.subpathPointCount(2) == 4); 0187 QVERIFY(path.subpathPointCount(3) == 4); 0188 QVERIFY(path.subpathPointCount(4) == -1); 0189 } 0190 0191 void TestPathShape::isClosedSubpath() 0192 { 0193 KoPathShape path; 0194 path.moveTo(QPointF(20, 20)); 0195 path.lineTo(QPointF(15, 25)); 0196 path.lineTo(QPointF(10, 20)); 0197 path.close(); 0198 path.moveTo(QPointF(20, 30)); 0199 path.lineTo(QPointF(20, 30)); 0200 path.moveTo(QPointF(30, 30)); 0201 path.lineTo(QPointF(40, 30)); 0202 path.lineTo(QPointF(40, 40)); 0203 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0204 path.close(); 0205 path.moveTo(QPointF(50, 50)); 0206 path.lineTo(QPointF(60, 50)); 0207 path.lineTo(QPointF(60, 60)); 0208 path.curveTo(QPointF(60, 65), QPointF(50, 65), QPointF(50, 60)); 0209 path.close(); 0210 0211 QVERIFY(path.isClosedSubpath(0) == true); 0212 QVERIFY(path.isClosedSubpath(1) == false); 0213 QVERIFY(path.isClosedSubpath(2) == true); 0214 QVERIFY(path.isClosedSubpath(3) == true); 0215 } 0216 0217 void TestPathShape::insertPoint() 0218 { 0219 KoPathShape path; 0220 path.moveTo(QPointF(10, 10)); 0221 path.lineTo(QPointF(20, 20)); 0222 path.moveTo(QPointF(30, 30)); 0223 path.lineTo(QPointF(40, 40)); 0224 path.close(); 0225 0226 // add before the first point of a open subpath 0227 KoPathPoint *point1 = new KoPathPoint(&path, QPointF(5, 5), KoPathPoint::Normal); 0228 KoPathPointIndex p1Index(0, 0); 0229 QVERIFY(path.insertPoint(point1, p1Index) == true); 0230 QVERIFY(point1->parent() == &path); 0231 0232 KoPathPoint *point2 = new KoPathPoint(&path, QPointF(15, 15), KoPathPoint::Normal); 0233 KoPathPointIndex p2Index(0, 2); 0234 QVERIFY(path.insertPoint(point2, p2Index) == true); 0235 QVERIFY(point2->parent() == &path); 0236 0237 // add after last point of a open subpath 0238 KoPathPoint *point3 = new KoPathPoint(&path, QPointF(25, 25), KoPathPoint::Normal); 0239 KoPathPointIndex p3Index(0, 4); 0240 QVERIFY(path.insertPoint(point3, p3Index) == true); 0241 QVERIFY(point3->parent() == &path); 0242 0243 KoPathPoint *point4 = new KoPathPoint(&path, QPointF(40, 30), KoPathPoint::Normal); 0244 KoPathPointIndex p4Index(1, 1); 0245 QVERIFY(path.insertPoint(point4, p4Index) == true); 0246 QVERIFY(point4->parent() == &path); 0247 0248 // add before the first point of a closed subpath 0249 KoPathPoint *point5 = new KoPathPoint(&path, QPointF(30, 35), KoPathPoint::Normal); 0250 KoPathPointIndex p5Index(1, 0); 0251 QVERIFY(path.insertPoint(point5, p5Index) == true); 0252 QVERIFY(point5->parent() == &path); 0253 0254 // add after last point of a closed subpath 0255 KoPathPoint *point6 = new KoPathPoint(&path, QPointF(35, 40), KoPathPoint::Normal); 0256 KoPathPointIndex p6Index(1, 4); 0257 QVERIFY(path.insertPoint(point6, p6Index) == true); 0258 QVERIFY(point6->parent() == &path); 0259 0260 // test out of bounds 0261 KoPathPoint *point7 = new KoPathPoint(&path, QPointF(0, 0), KoPathPoint::Normal); 0262 // subpath index out of bounds 0263 KoPathPointIndex p7Index(2, 0); 0264 QVERIFY(path.insertPoint(point7, p7Index) == false); 0265 // position in subpath out of bounds 0266 p7Index.second = 6; 0267 QVERIFY(path.insertPoint(point7, p7Index) == false); 0268 0269 QPainterPath ppath(QPointF(5, 5)); 0270 ppath.lineTo(10, 10); 0271 ppath.lineTo(15, 15); 0272 ppath.lineTo(20, 20); 0273 ppath.lineTo(25, 25); 0274 ppath.moveTo(30, 35); 0275 ppath.lineTo(30, 30); 0276 ppath.lineTo(40, 30); 0277 ppath.lineTo(40, 40); 0278 ppath.lineTo(35, 40); 0279 ppath.closeSubpath(); 0280 0281 QVERIFY(ppath == path.outline()); 0282 0283 KoPathShape path2; 0284 path2.moveTo(QPointF(0, 0)); 0285 KoPathPoint * p = new KoPathPoint(0, QPointF(100, 100)); 0286 QVERIFY(path2.insertPoint(p, KoPathPointIndex(0, 1)) == true); 0287 QVERIFY(p->parent() == &path2); 0288 } 0289 0290 void TestPathShape::removePoint() 0291 { 0292 KoPathShape path; 0293 KoPathPoint *point1 = path.moveTo(QPointF(10, 10)); 0294 path.lineTo(QPointF(20, 10)); 0295 KoPathPoint *point3 = path.lineTo(QPointF(20, 20)); 0296 path.lineTo(QPointF(15, 25)); 0297 KoPathPoint *point5 = path.lineTo(QPointF(10, 20)); 0298 KoPathPoint *point6 = path.moveTo(QPointF(30, 30)); 0299 path.lineTo(QPointF(40, 30)); 0300 KoPathPoint *point8 = path.lineTo(QPointF(40, 40)); 0301 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0302 KoPathPoint *point10 = path.lineTo(QPointF(30, 35)); 0303 path.close(); 0304 0305 // remove from beginning of a open subpath 0306 QVERIFY(path.removePoint(path.pathPointIndex(point1)) == point1); 0307 // remove from middle of a open subpath 0308 QVERIFY(path.removePoint(path.pathPointIndex(point3)) == point3); 0309 // remove from end of a open subpath 0310 QVERIFY(path.removePoint(path.pathPointIndex(point5)) == point5); 0311 0312 // remove from beginning of a closed subpath 0313 QVERIFY(path.removePoint(path.pathPointIndex(point6)) == point6); 0314 // remove from middle of a closed subpath 0315 QVERIFY(path.removePoint(path.pathPointIndex(point8)) == point8); 0316 // remove from end of a closed subpath 0317 QVERIFY(path.removePoint(path.pathPointIndex(point10)) == point10); 0318 0319 QPainterPath ppath(QPointF(20, 10)); 0320 ppath.lineTo(15, 25); 0321 ppath.moveTo(40, 30); 0322 ppath.quadTo(30, 45, 30, 40); 0323 ppath.closeSubpath(); 0324 0325 QVERIFY(ppath == path.outline()); 0326 } 0327 0328 void TestPathShape::splitAfter() 0329 { 0330 KoPathShape path; 0331 path.moveTo(QPointF(10, 10)); 0332 path.lineTo(QPointF(20, 10)); 0333 path.lineTo(QPointF(20, 20)); 0334 path.lineTo(QPointF(15, 25)); 0335 path.lineTo(QPointF(10, 20)); 0336 path.moveTo(QPointF(30, 30)); 0337 path.lineTo(QPointF(40, 30)); 0338 path.lineTo(QPointF(40, 40)); 0339 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0340 path.close(); 0341 0342 QVERIFY(path.breakAfter(KoPathPointIndex(0, 1)) == true); 0343 // try to break at the last point in the subpath 0344 QVERIFY(path.breakAfter(KoPathPointIndex(1, 2)) == false); 0345 // try to break a closed subpath 0346 QVERIFY(path.breakAfter(KoPathPointIndex(2, 1)) == false); 0347 0348 QPainterPath ppath(QPointF(10, 10)); 0349 ppath.lineTo(20, 10); 0350 ppath.moveTo(20, 20); 0351 ppath.lineTo(15, 25); 0352 ppath.lineTo(10, 20); 0353 ppath.moveTo(30, 30); 0354 ppath.lineTo(40, 30); 0355 ppath.lineTo(40, 40); 0356 ppath.cubicTo(40, 45, 30, 45, 30, 40); 0357 ppath.closeSubpath(); 0358 0359 QVERIFY(ppath == path.outline()); 0360 } 0361 0362 void TestPathShape::join() 0363 { 0364 KoPathShape path; 0365 path.moveTo(QPointF(10, 10)); 0366 path.lineTo(QPointF(20, 10)); 0367 path.moveTo(QPointF(20, 20)); 0368 path.lineTo(QPointF(15, 25)); 0369 path.lineTo(QPointF(10, 20)); 0370 path.moveTo(QPointF(30, 30)); 0371 path.lineTo(QPointF(40, 30)); 0372 path.lineTo(QPointF(40, 40)); 0373 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0374 path.close(); 0375 path.moveTo(QPointF(50, 50)); 0376 path.lineTo(QPointF(60, 60)); 0377 0378 QVERIFY(path.join(0) == true); 0379 // try to join to a closed subpath 0380 QVERIFY(path.join(0) == false); 0381 // try to join from a closed subpath 0382 QVERIFY(path.join(1) == false); 0383 // try to join last subpath 0384 QVERIFY(path.join(2) == false); 0385 0386 QPainterPath ppath(QPointF(10, 10)); 0387 ppath.lineTo(20, 10); 0388 ppath.lineTo(20, 20); 0389 ppath.lineTo(15, 25); 0390 ppath.lineTo(10, 20); 0391 ppath.moveTo(30, 30); 0392 ppath.lineTo(40, 30); 0393 ppath.lineTo(40, 40); 0394 ppath.cubicTo(40, 45, 30, 45, 30, 40); 0395 ppath.closeSubpath(); 0396 ppath.moveTo(50, 50); 0397 ppath.lineTo(60, 60); 0398 0399 QVERIFY(ppath == path.outline()); 0400 } 0401 0402 void TestPathShape::moveSubpath() 0403 { 0404 KoPathShape path; 0405 path.moveTo(QPointF(10, 10)); 0406 path.lineTo(QPointF(20, 10)); 0407 path.moveTo(QPointF(20, 20)); 0408 path.lineTo(QPointF(15, 25)); 0409 path.lineTo(QPointF(10, 20)); 0410 path.moveTo(QPointF(30, 30)); 0411 path.lineTo(QPointF(40, 30)); 0412 path.lineTo(QPointF(40, 40)); 0413 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0414 path.close(); 0415 0416 QVERIFY(path.moveSubpath(0, 1) == true); 0417 QVERIFY(path.moveSubpath(1, 0) == true); 0418 QVERIFY(path.moveSubpath(2, 1) == true); 0419 QVERIFY(path.moveSubpath(0, 2) == true); 0420 QVERIFY(path.moveSubpath(3, 1) == false); 0421 QVERIFY(path.moveSubpath(1, 3) == false); 0422 0423 QPainterPath ppath(QPointF(30, 30)); 0424 ppath.lineTo(40, 30); 0425 ppath.lineTo(40, 40); 0426 ppath.cubicTo(40, 45, 30, 45, 30, 40); 0427 ppath.closeSubpath(); 0428 ppath.moveTo(20, 20); 0429 ppath.lineTo(15, 25); 0430 ppath.lineTo(10, 20); 0431 ppath.moveTo(10, 10); 0432 ppath.lineTo(20, 10); 0433 0434 QVERIFY(ppath == path.outline()); 0435 } 0436 0437 void TestPathShape::openSubpath() 0438 { 0439 KoPathShape path; 0440 path.moveTo(QPointF(20, 20)); 0441 KoPathPoint *point1 = path.lineTo(QPointF(15, 25)); 0442 path.lineTo(QPointF(10, 20)); 0443 path.close(); 0444 KoPathPoint *point2 = path.moveTo(QPointF(30, 30)); 0445 path.lineTo(QPointF(40, 30)); 0446 path.lineTo(QPointF(40, 40)); 0447 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0448 path.close(); 0449 path.moveTo(QPointF(50, 50)); 0450 path.lineTo(QPointF(60, 50)); 0451 path.lineTo(QPointF(60, 60)); 0452 KoPathPoint *point3 = path.curveTo(QPointF(60, 65), QPointF(50, 65), QPointF(50, 60)); 0453 path.close(); 0454 KoPathPoint *point4 = path.moveTo(QPointF(100, 100)); 0455 point4->setControlPoint2(QPointF(120, 120)); 0456 path.lineTo(QPointF(140, 140)); 0457 KoPathPoint *point5 = path.lineTo(QPointF(140, 100)); 0458 path.close(); 0459 0460 // open at middle point in subpath 0461 QVERIFY(path.openSubpath(path.pathPointIndex(point1)) == KoPathPointIndex(0, 2)); 0462 QVERIFY(path.pointByIndex(KoPathPointIndex(0,0))->properties() & KoPathPoint::StartSubpath); 0463 QVERIFY(path.pointByIndex(KoPathPointIndex(0,2))->properties() & KoPathPoint::StopSubpath); 0464 // open at first point in subpath 0465 QVERIFY(path.openSubpath(path.pathPointIndex(point2)) == KoPathPointIndex(1, 0)); 0466 QVERIFY(path.pointByIndex(KoPathPointIndex(1,0))->properties() & KoPathPoint::StartSubpath); 0467 QVERIFY(path.pointByIndex(KoPathPointIndex(1,3))->properties() & KoPathPoint::StopSubpath); 0468 // open at last point in subpath 0469 QVERIFY(path.openSubpath(path.pathPointIndex(point3)) == KoPathPointIndex(2, 1)); 0470 QVERIFY(path.pointByIndex(KoPathPointIndex(2,0))->properties() & KoPathPoint::StartSubpath); 0471 QVERIFY(path.pointByIndex(KoPathPointIndex(2,3))->properties() & KoPathPoint::StopSubpath); 0472 // try to open subpath 0473 QVERIFY(path.openSubpath(path.pathPointIndex(point3)) == KoPathPointIndex(-1, -1)); 0474 // open if the first path is a curve 0475 QVERIFY(path.openSubpath(path.pathPointIndex(point5)) == KoPathPointIndex(3, 1)); 0476 QVERIFY(path.pointByIndex(KoPathPointIndex(3,0))->properties() & KoPathPoint::StartSubpath); 0477 QVERIFY(path.pointByIndex(KoPathPointIndex(3,2))->properties() & KoPathPoint::StopSubpath); 0478 // try to open none existing subpath 0479 QVERIFY(path.openSubpath(KoPathPointIndex(4, 1)) == KoPathPointIndex(-1, -1)); 0480 0481 QPainterPath ppath(QPointF(15, 25)); 0482 ppath.lineTo(10, 20); 0483 ppath.lineTo(20, 20); 0484 ppath.moveTo(30, 30); 0485 ppath.lineTo(40, 30); 0486 ppath.lineTo(40, 40); 0487 ppath.cubicTo(40, 45, 30, 45, 30, 40); 0488 ppath.moveTo(50, 60); 0489 ppath.lineTo(50, 50); 0490 ppath.lineTo(60, 50); 0491 ppath.lineTo(60, 60); 0492 ppath.moveTo(140, 100); 0493 ppath.lineTo(100, 100); 0494 ppath.quadTo(120, 120, 140, 140); 0495 0496 QVERIFY(ppath == path.outline()); 0497 } 0498 0499 void TestPathShape::closeSubpath() 0500 { 0501 KoPathShape path; 0502 path.moveTo(QPointF(20, 20)); 0503 KoPathPoint *point1 = path.lineTo(QPointF(15, 25)); 0504 path.lineTo(QPointF(10, 20)); 0505 KoPathPoint *point2 = path.moveTo(QPointF(30, 30)); 0506 path.lineTo(QPointF(40, 30)); 0507 path.lineTo(QPointF(40, 40)); 0508 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0509 path.moveTo(QPointF(50, 50)); 0510 path.lineTo(QPointF(60, 50)); 0511 path.lineTo(QPointF(60, 60)); 0512 KoPathPoint *point3 = path.curveTo(QPointF(60, 65), QPointF(50, 65), QPointF(50, 60)); 0513 0514 // open at middle point in subpath 0515 QVERIFY(path.closeSubpath(path.pathPointIndex(point1)) == KoPathPointIndex(0, 2)); 0516 // open at first point in subpath 0517 QVERIFY(path.closeSubpath(path.pathPointIndex(point2)) == KoPathPointIndex(1, 0)); 0518 // open at last point in subpath 0519 QVERIFY(path.closeSubpath(path.pathPointIndex(point3)) == KoPathPointIndex(2, 1)); 0520 // try to close a closed subpath 0521 QVERIFY(path.closeSubpath(path.pathPointIndex(point3)) == KoPathPointIndex(-1, -1)); 0522 // try to close a none existing subpath 0523 QVERIFY(path.closeSubpath(KoPathPointIndex(3, 1)) == KoPathPointIndex(-1, -1)); 0524 // try to close at a none existing position in a subpath 0525 QVERIFY(path.closeSubpath(KoPathPointIndex(2, 4)) == KoPathPointIndex(-1, -1)); 0526 0527 QPainterPath ppath(QPointF(15, 25)); 0528 ppath.lineTo(10, 20); 0529 ppath.lineTo(20, 20); 0530 ppath.closeSubpath(); 0531 ppath.moveTo(30, 30); 0532 ppath.lineTo(40, 30); 0533 ppath.lineTo(40, 40); 0534 ppath.cubicTo(40, 45, 30, 45, 30, 40); 0535 ppath.closeSubpath(); 0536 ppath.moveTo(50, 60); 0537 ppath.lineTo(50, 50); 0538 ppath.lineTo(60, 50); 0539 ppath.lineTo(60, 60); 0540 ppath.cubicTo(60, 65, 50, 65, 50, 60); 0541 ppath.closeSubpath(); 0542 0543 QVERIFY(ppath == path.outline()); 0544 } 0545 0546 void TestPathShape::openCloseSubpath() 0547 { 0548 KoPathShape path; 0549 path.moveTo(QPointF(20, 20)); 0550 KoPathPoint *point1 = path.lineTo(QPointF(15, 25)); 0551 path.lineTo(QPointF(10, 20)); 0552 path.close(); 0553 KoPathPoint *point2 = path.moveTo(QPointF(30, 30)); 0554 path.lineTo(QPointF(40, 30)); 0555 path.lineTo(QPointF(40, 40)); 0556 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0557 0558 KoPathPointIndex p1Index = path.pathPointIndex(point1); 0559 KoPathPointIndex p1OldIndex = path.openSubpath(p1Index); 0560 QVERIFY(path.closeSubpath(p1OldIndex) == p1Index); 0561 0562 KoPathPointIndex p2Index = path.pathPointIndex(point2); 0563 KoPathPointIndex p2OldIndex = path.closeSubpath(p2Index); 0564 QVERIFY(path.openSubpath(p2OldIndex) == p2Index); 0565 0566 QPainterPath ppath(QPointF(20, 20)); 0567 ppath.lineTo(15, 25); 0568 ppath.lineTo(10, 20); 0569 ppath.closeSubpath(); 0570 ppath.moveTo(30, 30); 0571 ppath.lineTo(40, 30); 0572 ppath.lineTo(40, 40); 0573 ppath.cubicTo(40, 45, 30, 45, 30, 40); 0574 0575 QVERIFY(ppath == path.outline()); 0576 } 0577 0578 void TestPathShape::reverseSubpath() 0579 { 0580 KoPathShape path; 0581 path.moveTo(QPointF(10, 10)); 0582 path.lineTo(QPointF(20, 10)); 0583 path.moveTo(QPointF(20, 20)); 0584 path.lineTo(QPointF(15, 25)); 0585 path.lineTo(QPointF(10, 20)); 0586 path.moveTo(QPointF(30, 30)); 0587 path.lineTo(QPointF(40, 30)); 0588 path.lineTo(QPointF(40, 40)); 0589 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0590 path.close(); 0591 0592 QVERIFY(path.reverseSubpath(0) == true); 0593 QVERIFY(path.reverseSubpath(1) == true); 0594 QVERIFY(path.reverseSubpath(1) == true); 0595 QVERIFY(path.reverseSubpath(2) == true); 0596 QVERIFY(path.reverseSubpath(3) == false); 0597 0598 QPainterPath ppath(QPointF(20, 10)); 0599 ppath.lineTo(10, 10); 0600 ppath.moveTo(20, 20); 0601 ppath.lineTo(15, 25); 0602 ppath.lineTo(10, 20); 0603 ppath.moveTo(30, 40); 0604 ppath.cubicTo(30, 45, 40, 45, 40, 40); 0605 ppath.lineTo(40, 30); 0606 ppath.lineTo(30, 30); 0607 ppath.closeSubpath(); 0608 0609 QVERIFY(ppath == path.outline()); 0610 0611 QVERIFY(path.reverseSubpath(2) == true); 0612 QVERIFY(path.reverseSubpath(2) == true); 0613 0614 QVERIFY(ppath == path.outline()); 0615 } 0616 0617 void TestPathShape::removeSubpath() 0618 { 0619 #if 0 0620 // enable again when point groups work 0621 KoPathShape path; 0622 path.moveTo(QPointF(10, 10)); 0623 path.lineTo(QPointF(20, 10)); 0624 path.lineTo(QPointF(20, 20)); 0625 path.close(); 0626 path.lineTo(QPointF(15, 25)); 0627 path.lineTo(QPointF(10, 20)); 0628 path.moveTo(QPointF(30, 30)); 0629 path.lineTo(QPointF(40, 30)); 0630 path.lineTo(QPointF(40, 40)); 0631 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0632 path.close(); 0633 0634 QVERIFY(path.removeSubpath(0) != 0); 0635 QVERIFY(path.removeSubpath(1) != 0); 0636 QVERIFY(path.removeSubpath(1) == 0); 0637 0638 QPainterPath ppath(QPointF(10, 20)); 0639 ppath.lineTo(15, 25); 0640 ppath.lineTo(10, 20); 0641 0642 path.debugPath(); 0643 0644 QVERIFY(ppath == path.outline()); 0645 #endif 0646 0647 KoPathShape path; 0648 path.moveTo(QPointF(10, 10)); 0649 path.lineTo(QPointF(20, 10)); 0650 path.lineTo(QPointF(20, 20)); 0651 path.close(); 0652 path.moveTo(QPointF(15, 25)); 0653 path.lineTo(QPointF(10, 20)); 0654 path.moveTo(QPointF(30, 30)); 0655 path.lineTo(QPointF(40, 30)); 0656 path.lineTo(QPointF(40, 40)); 0657 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0658 path.close(); 0659 0660 QVERIFY(path.removeSubpath(0) != 0); 0661 QVERIFY(path.removeSubpath(1) != 0); 0662 QVERIFY(path.removeSubpath(1) == 0); 0663 0664 QPainterPath ppath(QPointF(15, 25)); 0665 ppath.lineTo(10, 20); 0666 0667 QVERIFY(ppath == path.outline()); 0668 } 0669 0670 void TestPathShape::addSubpath() 0671 { 0672 KoPathShape path; 0673 path.moveTo(QPointF(10, 10)); 0674 path.lineTo(QPointF(20, 10)); 0675 path.lineTo(QPointF(20, 20)); 0676 path.close(); 0677 path.moveTo(QPointF(15, 25)); 0678 path.lineTo(QPointF(10, 20)); 0679 path.moveTo(QPointF(30, 30)); 0680 path.lineTo(QPointF(40, 30)); 0681 path.lineTo(QPointF(40, 40)); 0682 path.curveTo(QPointF(40, 45), QPointF(30, 45), QPointF(30, 40)); 0683 path.close(); 0684 0685 KoSubpath * sp1 = path.removeSubpath(0); 0686 QVERIFY(path.addSubpath(sp1, 0) == true); 0687 0688 KoSubpath * sp2 = path.removeSubpath(1); 0689 QVERIFY(path.addSubpath(sp2, 1) == true); 0690 0691 QVERIFY(path.addSubpath(sp2, 4) == false); 0692 0693 QPainterPath ppath(QPointF(10, 10)); 0694 ppath.lineTo(20, 10); 0695 ppath.lineTo(20, 20); 0696 ppath.closeSubpath(); 0697 ppath.moveTo(15, 25); 0698 ppath.lineTo(10, 20); 0699 ppath.moveTo(30, 30); 0700 ppath.lineTo(40, 30); 0701 ppath.lineTo(40, 40); 0702 ppath.cubicTo(40, 45, 30, 45, 30, 40); 0703 ppath.closeSubpath(); 0704 0705 QVERIFY(ppath == path.outline()); 0706 } 0707 0708 void TestPathShape::koPathPointDataLess() 0709 { 0710 QList<KoPathPointData> v; 0711 v.push_back(KoPathPointData((KoPathShape*)1, KoPathPointIndex(1, 1))); 0712 v.push_back(KoPathPointData((KoPathShape*)1, KoPathPointIndex(1, 2))); 0713 v.push_back(KoPathPointData((KoPathShape*)1, KoPathPointIndex(1, 3))); 0714 v.push_back(KoPathPointData((KoPathShape*)1, KoPathPointIndex(1, 6))); 0715 v.push_back(KoPathPointData((KoPathShape*)2, KoPathPointIndex(2, 1))); 0716 v.push_back(KoPathPointData((KoPathShape*)2, KoPathPointIndex(2, 3))); 0717 v.push_back(KoPathPointData((KoPathShape*)2, KoPathPointIndex(3, 3))); 0718 v.push_back(KoPathPointData((KoPathShape*)3, KoPathPointIndex(1, 1))); 0719 v.push_back(KoPathPointData((KoPathShape*)3, KoPathPointIndex(1, 2))); 0720 0721 QList<KoPathPointData> l; 0722 l.push_back(v[8]); 0723 l.push_back(v[0]); 0724 l.push_back(v[1]); 0725 l.push_back(v[7]); 0726 l.push_back(v[6]); 0727 l.push_back(v[2]); 0728 l.push_back(v[5]); 0729 l.push_back(v[3]); 0730 l.push_back(v[4]); 0731 0732 std::sort(l.begin(), l.end()); 0733 for (int i = 0; i < v.size(); ++i) { 0734 KoPathPointData ld = l.at(i); 0735 KoPathPointData vd = v[i]; 0736 QVERIFY(ld.pathShape == vd.pathShape); 0737 QVERIFY(ld.pointIndex.first == vd.pointIndex.first); 0738 QVERIFY(ld.pointIndex.second == vd.pointIndex.second); 0739 } 0740 } 0741 0742 void TestPathShape::closeMerge() 0743 { 0744 KoPathShape path; 0745 KoPathPoint *p1 = path.moveTo(QPointF(0, 0)); 0746 KoPathPoint *p2 = path.curveTo(QPointF(50, 0), QPointF(100, 50), QPointF(100, 100)); 0747 KoPathPoint *p3 = path.curveTo(QPointF(50, 100), QPointF(0, 50), QPointF(0, 0)); 0748 QVERIFY(p1->properties() & KoPathPoint::StartSubpath); 0749 QVERIFY((p1->properties() & KoPathPoint::CloseSubpath) == 0); 0750 QVERIFY(p1->activeControlPoint1() == false); 0751 QVERIFY(p1->activeControlPoint2()); 0752 QVERIFY(p2->activeControlPoint1()); 0753 QVERIFY(p2->activeControlPoint2()); 0754 QVERIFY((p3->properties() & KoPathPoint::CloseSubpath) == 0); 0755 QVERIFY(p3->activeControlPoint1()); 0756 QCOMPARE(path.pointCount(), 3); 0757 0758 path.closeMerge(); 0759 QCOMPARE(path.pointCount(), 2); 0760 QVERIFY(p1->properties() & KoPathPoint::CloseSubpath); 0761 QVERIFY(p1->activeControlPoint1()); 0762 QVERIFY(p2->properties() & KoPathPoint::CloseSubpath); 0763 QVERIFY(p2->activeControlPoint2()); 0764 0765 QPainterPath ppath(QPointF(0, 0)); 0766 ppath.cubicTo(50, 0, 100, 50, 100, 100); 0767 ppath.cubicTo(50, 100, 0, 50, 0, 0); 0768 0769 QVERIFY(path.outline() == ppath); 0770 } 0771 0772 SIMPLE_TEST_MAIN(TestPathShape)