|
22 | 22 |
|
23 | 23 | #include <algorithm> |
24 | 24 | // IWYU pragma: no_include <array> |
| 25 | +#include <cstddef> |
25 | 26 | // IWYU pragma: no_include <initializer_list> |
26 | 27 | #include <limits> |
27 | 28 | #include <memory> |
|
40 | 41 | #include <QDir> |
41 | 42 | #include <QFile> |
42 | 43 | #include <QFileInfo> |
| 44 | +#include <QFlags> |
43 | 45 | #include <QIODevice> |
44 | 46 | #include <QLatin1Char> |
45 | 47 | #include <QLatin1String> |
46 | 48 | #include <QMetaObject> |
| 49 | +#include <QMetaType> |
47 | 50 | #include <QPageSize> |
48 | 51 | #include <QPoint> |
49 | 52 | #include <QPointF> |
@@ -1228,6 +1231,8 @@ struct TestOcdFileImport : public OcdFileImport |
1228 | 1231 | } |
1229 | 1232 |
|
1230 | 1233 | using OcdFileImport::getObjectText; |
| 1234 | + using OcdFileImport::fillPathCoords; |
| 1235 | + using OcdFileImport::OcdImportedPathObject; |
1231 | 1236 | }; |
1232 | 1237 |
|
1233 | 1238 | void FileFormatTest::ocdTextImportTest_data() |
@@ -1306,6 +1311,314 @@ void FileFormatTest::ocdTextImportTest() |
1306 | 1311 | } |
1307 | 1312 |
|
1308 | 1313 |
|
| 1314 | +struct OcdPointsView { |
| 1315 | + const Ocd::OcdPoint32* data = nullptr; |
| 1316 | + int size = 0; |
| 1317 | + |
| 1318 | + OcdPointsView() = default; |
| 1319 | + |
| 1320 | + template <class T, std::size_t n> |
| 1321 | + explicit OcdPointsView(T(& t)[n]) |
| 1322 | + : data { t } |
| 1323 | + , size { int(n) } |
| 1324 | + {} |
| 1325 | +}; |
| 1326 | +Q_DECLARE_METATYPE(OcdPointsView) |
| 1327 | + |
| 1328 | +struct FlagsView { |
| 1329 | + const int* data = nullptr; |
| 1330 | + int size = 0; |
| 1331 | + |
| 1332 | + FlagsView() = default; |
| 1333 | + |
| 1334 | + template <class T, std::size_t n> |
| 1335 | + explicit FlagsView(T(& t)[n], int size) |
| 1336 | + : data { t } |
| 1337 | + , size { size } |
| 1338 | + {} |
| 1339 | + |
| 1340 | + template <class T, std::size_t n> |
| 1341 | + explicit FlagsView(T(& t)[n]) |
| 1342 | + : data { t } |
| 1343 | + , size { int(n) } |
| 1344 | + {} |
| 1345 | +}; |
| 1346 | +Q_DECLARE_METATYPE(FlagsView) |
| 1347 | + |
| 1348 | +enum OcdPathPersonality { |
| 1349 | + Line = 0, |
| 1350 | + Area = 1 |
| 1351 | +}; |
| 1352 | +Q_DECLARE_METATYPE(OcdPathPersonality) |
| 1353 | + |
| 1354 | +void FileFormatTest::ocdPathImportTest_data() |
| 1355 | +{ |
| 1356 | + #define C(x) ((int)((unsigned int)(x)<<8)) // FIXME: Not the same as in export |
| 1357 | + constexpr auto ocd_flag_gap = 8; // TODO: implement as Ocd::OcdPoint32::FlagGap |
| 1358 | + |
| 1359 | + QTest::addColumn<OcdPointsView>("points"); |
| 1360 | + QTest::addColumn<OcdPathPersonality>("personality"); |
| 1361 | + QTest::addColumn<FlagsView>("expected"); |
| 1362 | + |
| 1363 | + { |
| 1364 | + // bezier curve |
| 1365 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1366 | + { C(-1109), C(212) }, |
| 1367 | + { C(-1035) | Ocd::OcdPoint32::FlagCtl1, C(302) }, |
| 1368 | + { C(-1008) | Ocd::OcdPoint32::FlagCtl2, C(519) }, |
| 1369 | + { C(-926), C(437) } // different from first point |
| 1370 | + }; |
| 1371 | + static int expected_flags[] = { |
| 1372 | + MapCoord::CurveStart, |
| 1373 | + 0, |
| 1374 | + 0, |
| 1375 | + 0, |
| 1376 | + MapCoord::ClosePoint // injected by Mapper |
| 1377 | + }; |
| 1378 | + QTest::newRow("bezier, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags); |
| 1379 | + QTest::newRow("bezier, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags, 4); |
| 1380 | + } |
| 1381 | + |
| 1382 | + { |
| 1383 | + // straight segments, corner flag |
| 1384 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1385 | + { C(-589), C(432) }, |
| 1386 | + { C(-269), C(845) | Ocd::OcdPoint32::FlagCorner }, |
| 1387 | + { C(267), C(279) }, // different from first point |
| 1388 | + }; |
| 1389 | + static int expected_flags[] = { |
| 1390 | + 0, |
| 1391 | + MapCoord::DashPoint, |
| 1392 | + 0, |
| 1393 | + MapCoord::ClosePoint // injected by Mapper |
| 1394 | + }; |
| 1395 | + QTest::newRow("straight, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags); |
| 1396 | + QTest::newRow("straight, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags, 3); |
| 1397 | + } |
| 1398 | + |
| 1399 | + { |
| 1400 | + // straight segments, virtual gap |
| 1401 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1402 | + { C(-972), C(-264) }, |
| 1403 | + { C(-836) | Ocd::OcdPoint32::FlagLeft | ocd_flag_gap, C(-151) | Ocd::OcdPoint32::FlagRight }, |
| 1404 | + { C(-677), C(-19) }, |
| 1405 | + { C(-518), C(112) } // different from first point |
| 1406 | + }; |
| 1407 | + static int expected_flags[] = { |
| 1408 | + 0, |
| 1409 | + 0, |
| 1410 | + 0, |
| 1411 | + 0, |
| 1412 | + MapCoord::ClosePoint // injected by Mapper |
| 1413 | + }; |
| 1414 | + QTest::newRow("virtual gap, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags); |
| 1415 | + QTest::newRow("virtual gap, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags, 4); |
| 1416 | + } |
| 1417 | + |
| 1418 | + { |
| 1419 | + // straight segments, one hole |
| 1420 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1421 | + { C(100), C(-250) }, |
| 1422 | + { C(150), C(-260) }, |
| 1423 | + { C(100), C(-250) }, // same as first point |
| 1424 | + { C(200), C(-350) | Ocd::OcdPoint32::FlagHole }, |
| 1425 | + { C(220), C(-400) }, |
| 1426 | + { C(200), C(-350) } // same as first point of hole |
| 1427 | + }; |
| 1428 | + static int expected_flags_area[] = { |
| 1429 | + 0, |
| 1430 | + 0, |
| 1431 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1432 | + 0, |
| 1433 | + 0, |
| 1434 | + MapCoord::ClosePoint |
| 1435 | + }; |
| 1436 | + QTest::newRow("hole, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1437 | + static int expected_flags_line[6] = {}; |
| 1438 | + QTest::newRow("hole, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1439 | + } |
| 1440 | + |
| 1441 | + { |
| 1442 | + // straight segments, with an "empty" hole |
| 1443 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1444 | + { C(100), C(-250) }, |
| 1445 | + { C(150), C(-260) }, |
| 1446 | + { C(100), C(-250) }, // same as first point |
| 1447 | + { C(120), C(-200) | Ocd::OcdPoint32::FlagHole }, |
| 1448 | + { C(200), C(-350) | Ocd::OcdPoint32::FlagHole }, |
| 1449 | + { C(220), C(-400) }, |
| 1450 | + { C(200), C(-350) } // same as second FlagHole point |
| 1451 | + }; |
| 1452 | + static int expected_flags_area[] = { |
| 1453 | + 0, |
| 1454 | + 0, |
| 1455 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1456 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1457 | + 0, |
| 1458 | + 0, |
| 1459 | + MapCoord::ClosePoint |
| 1460 | + }; |
| 1461 | + QTest::newRow("empty hole, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1462 | + static int expected_flags_line[7] = {}; |
| 1463 | + QTest::newRow("empty hole, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1464 | + } |
| 1465 | + |
| 1466 | + { |
| 1467 | + // straight segments, with two "empty" holes |
| 1468 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1469 | + { C(100), C(-250) }, |
| 1470 | + { C(150), C(-260) }, |
| 1471 | + { C(100), C(-250) }, // same as first point |
| 1472 | + { C(120), C(-200) | Ocd::OcdPoint32::FlagHole }, |
| 1473 | + { C(140), C(-300) | Ocd::OcdPoint32::FlagHole }, |
| 1474 | + { C(200), C(-350) | Ocd::OcdPoint32::FlagHole }, |
| 1475 | + { C(220), C(-400) }, |
| 1476 | + { C(200), C(-350) }, // same as third FlagHole point |
| 1477 | + }; |
| 1478 | + static int expected_flags_area[] = { |
| 1479 | + 0, |
| 1480 | + 0, |
| 1481 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1482 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1483 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1484 | + 0, |
| 1485 | + 0, |
| 1486 | + MapCoord::ClosePoint |
| 1487 | + }; |
| 1488 | + QTest::newRow("two empty holes, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1489 | + static int expected_flags_line[8] = {}; |
| 1490 | + QTest::newRow("two empty holes, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1491 | + } |
| 1492 | + |
| 1493 | + { |
| 1494 | + // straight segments, one hole, not actual areas |
| 1495 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1496 | + { C(100), C(-250) }, |
| 1497 | + { C(150), C(-260) }, |
| 1498 | + { C(200), C(-350) | Ocd::OcdPoint32::FlagHole }, |
| 1499 | + { C(220), C(-400) } |
| 1500 | + }; |
| 1501 | + static int expected_flags_area[] = { |
| 1502 | + 0, |
| 1503 | + 0, |
| 1504 | + MapCoord::ClosePoint | MapCoord::HolePoint, // injected by Mapper |
| 1505 | + 0, |
| 1506 | + 0, |
| 1507 | + MapCoord::ClosePoint // injected by Mapper |
| 1508 | + }; |
| 1509 | + QTest::newRow("open areas with hole, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1510 | + static int expected_flags_line[4] = {}; |
| 1511 | + QTest::newRow("open areas with hole, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1512 | + } |
| 1513 | + |
| 1514 | + { |
| 1515 | + // area with hole in hole |
| 1516 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1517 | + { C(-405), C(-167) }, |
| 1518 | + { C(-348) | Ocd::OcdPoint32::FlagCtl1, C(22) }, |
| 1519 | + { C(-113) | Ocd::OcdPoint32::FlagCtl2, C(667) }, |
| 1520 | + { C(54), C(687) }, |
| 1521 | + { C(184) | Ocd::OcdPoint32::FlagCtl1, C(702) }, |
| 1522 | + { C(836) | Ocd::OcdPoint32::FlagCtl2, C(418) }, |
| 1523 | + { C(889), C(298) }, |
| 1524 | + { C(599), C(117) }, |
| 1525 | + { C(137), C(93) | Ocd::OcdPoint32::FlagDash}, // different from first point |
| 1526 | + { C(-25), C(79) | Ocd::OcdPoint32::FlagHole}, |
| 1527 | + { C(-208) | Ocd::OcdPoint32::FlagCtl1, C(259) }, |
| 1528 | + { C(90) | Ocd::OcdPoint32::FlagCtl2, C(652) }, |
| 1529 | + { C(559), C(322) }, // different from first point of hole |
| 1530 | + { C(78), C(326) | Ocd::OcdPoint32::FlagHole}, |
| 1531 | + { C(100) | Ocd::OcdPoint32::FlagCtl1, C(341) }, |
| 1532 | + { C(157) | Ocd::OcdPoint32::FlagCtl2, C(354) }, |
| 1533 | + { C(198), C(339) | Ocd::OcdPoint32::FlagCorner }, |
| 1534 | + { C(227) | Ocd::OcdPoint32::FlagCtl1, C(329) }, |
| 1535 | + { C(247) | Ocd::OcdPoint32::FlagCtl2, C(304) }, |
| 1536 | + { C(242), C(256) }, |
| 1537 | + { C(144), C(243) }, // different from first point of hole |
| 1538 | + }; |
| 1539 | + static int expected_flags_area[] = { |
| 1540 | + MapCoord::CurveStart, |
| 1541 | + 0, |
| 1542 | + 0, |
| 1543 | + MapCoord::CurveStart, |
| 1544 | + 0, |
| 1545 | + 0, |
| 1546 | + 0, |
| 1547 | + 0, |
| 1548 | + MapCoord::DashPoint, |
| 1549 | + MapCoord::ClosePoint | MapCoord::HolePoint, // injected by Mapper |
| 1550 | + MapCoord::CurveStart, |
| 1551 | + 0, |
| 1552 | + 0, |
| 1553 | + 0, |
| 1554 | + MapCoord::ClosePoint | MapCoord::HolePoint, // injected by Mapper |
| 1555 | + MapCoord::CurveStart, |
| 1556 | + 0, |
| 1557 | + 0, |
| 1558 | + MapCoord::DashPoint | MapCoord::CurveStart, |
| 1559 | + 0, |
| 1560 | + 0, |
| 1561 | + 0, |
| 1562 | + 0, |
| 1563 | + MapCoord::ClosePoint // injected by Mapper |
| 1564 | + }; |
| 1565 | + QTest::newRow("area with nested holes, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1566 | + static int expected_flags_line[] = { |
| 1567 | + MapCoord::CurveStart, |
| 1568 | + 0, |
| 1569 | + 0, |
| 1570 | + MapCoord::CurveStart, |
| 1571 | + 0, |
| 1572 | + 0, |
| 1573 | + 0, |
| 1574 | + 0, |
| 1575 | + MapCoord::DashPoint, |
| 1576 | + MapCoord::CurveStart, |
| 1577 | + 0, |
| 1578 | + 0, |
| 1579 | + 0, |
| 1580 | + MapCoord::CurveStart, |
| 1581 | + 0, |
| 1582 | + 0, |
| 1583 | + MapCoord::DashPoint | MapCoord::CurveStart, |
| 1584 | + 0, |
| 1585 | + 0, |
| 1586 | + 0, |
| 1587 | + 0 |
| 1588 | + }; |
| 1589 | + QTest::newRow("area with nested holes, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1590 | + } |
| 1591 | +} |
| 1592 | + |
| 1593 | +void FileFormatTest::ocdPathImportTest() |
| 1594 | +{ |
| 1595 | + QFETCH(OcdPointsView, points); |
| 1596 | + QFETCH(OcdPathPersonality, personality); |
| 1597 | + QFETCH(FlagsView, expected); |
| 1598 | + |
| 1599 | + TestOcdFileImport ocd_v12_import{12}; |
| 1600 | + |
| 1601 | + TestOcdFileImport::OcdImportedPathObject path_object; |
| 1602 | + ocd_v12_import.fillPathCoords(&path_object, personality == Area, points.size, points.data); |
| 1603 | + QVERIFY(path_object.getRawCoordinateVector().size() > 0); |
| 1604 | + |
| 1605 | + QCOMPARE(path_object.getRawCoordinateVector().size(), expected.size); |
| 1606 | + for (int i = 0; i < expected.size; ++i) |
| 1607 | + { |
| 1608 | + // Provide the current index when failing. |
| 1609 | + if (path_object.getCoordinate(i).flags() != MapCoord::Flags(expected.data[i])) |
| 1610 | + { |
| 1611 | + auto err = QString::fromLatin1("Compared flags are not the same at index %1\n" |
| 1612 | + " Actual : %2\n" |
| 1613 | + " Expected: %3" |
| 1614 | + ).arg(QString::number(i), |
| 1615 | + QString::number(path_object.getCoordinate(i).flags()), |
| 1616 | + QString::number(expected.data[i]) |
| 1617 | + ); |
| 1618 | + QFAIL(qPrintable(err)); |
| 1619 | + } |
| 1620 | + } |
| 1621 | +} |
1309 | 1622 |
|
1310 | 1623 | /* |
1311 | 1624 | * We don't need a real GUI window. |
|
0 commit comments