|
10 | 10 |
|
11 | 11 | #include <algorithm> |
12 | 12 | // IWYU pragma: no_include <array> |
| 13 | +#include <cstddef> |
13 | 14 | // IWYU pragma: no_include <initializer_list> |
14 | 15 | #include <limits> |
15 | 16 | #include <memory> |
|
28 | 29 | #include <QDir> |
29 | 30 | #include <QFile> |
30 | 31 | #include <QFileInfo> |
| 32 | +#include <QFlags> |
31 | 33 | #include <QIODevice> |
32 | 34 | #include <QLatin1Char> |
33 | 35 | #include <QLatin1String> |
34 | 36 | #include <QMetaObject> |
| 37 | +#include <QMetaType> |
35 | 38 | #include <QPageSize> |
36 | 39 | #include <QPoint> |
37 | 40 | #include <QPointF> |
@@ -1428,6 +1431,8 @@ struct TestOcdFileImport : public OcdFileImport |
1428 | 1431 | } |
1429 | 1432 |
|
1430 | 1433 | using OcdFileImport::getObjectText; |
| 1434 | + using OcdFileImport::fillPathCoords; |
| 1435 | + using OcdFileImport::OcdImportedPathObject; |
1431 | 1436 | }; |
1432 | 1437 |
|
1433 | 1438 | void FileFormatTest::ocdTextImportTest_data() |
@@ -1506,6 +1511,314 @@ void FileFormatTest::ocdTextImportTest() |
1506 | 1511 | } |
1507 | 1512 |
|
1508 | 1513 |
|
| 1514 | +struct OcdPointsView { |
| 1515 | + const Ocd::OcdPoint32* data = nullptr; |
| 1516 | + int size = 0; |
| 1517 | + |
| 1518 | + OcdPointsView() = default; |
| 1519 | + |
| 1520 | + template <class T, std::size_t n> |
| 1521 | + explicit OcdPointsView(T(& t)[n]) |
| 1522 | + : data { t } |
| 1523 | + , size { int(n) } |
| 1524 | + {} |
| 1525 | +}; |
| 1526 | +Q_DECLARE_METATYPE(OcdPointsView) |
| 1527 | + |
| 1528 | +struct FlagsView { |
| 1529 | + const int* data = nullptr; |
| 1530 | + int size = 0; |
| 1531 | + |
| 1532 | + FlagsView() = default; |
| 1533 | + |
| 1534 | + template <class T, std::size_t n> |
| 1535 | + explicit FlagsView(T(& t)[n], int size) |
| 1536 | + : data { t } |
| 1537 | + , size { size } |
| 1538 | + {} |
| 1539 | + |
| 1540 | + template <class T, std::size_t n> |
| 1541 | + explicit FlagsView(T(& t)[n]) |
| 1542 | + : data { t } |
| 1543 | + , size { int(n) } |
| 1544 | + {} |
| 1545 | +}; |
| 1546 | +Q_DECLARE_METATYPE(FlagsView) |
| 1547 | + |
| 1548 | +enum OcdPathPersonality { |
| 1549 | + Line = 0, |
| 1550 | + Area = 1 |
| 1551 | +}; |
| 1552 | +Q_DECLARE_METATYPE(OcdPathPersonality) |
| 1553 | + |
| 1554 | +void FileFormatTest::ocdPathImportTest_data() |
| 1555 | +{ |
| 1556 | + #define C(x) ((int)((unsigned int)(x)<<8)) // FIXME: Not the same as in export |
| 1557 | + constexpr auto ocd_flag_gap = 8; // TODO: implement as Ocd::OcdPoint32::FlagGap |
| 1558 | + |
| 1559 | + QTest::addColumn<OcdPointsView>("points"); |
| 1560 | + QTest::addColumn<OcdPathPersonality>("personality"); |
| 1561 | + QTest::addColumn<FlagsView>("expected"); |
| 1562 | + |
| 1563 | + { |
| 1564 | + // bezier curve |
| 1565 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1566 | + { C(-1109), C(212) }, |
| 1567 | + { C(-1035) | Ocd::OcdPoint32::FlagCtl1, C(302) }, |
| 1568 | + { C(-1008) | Ocd::OcdPoint32::FlagCtl2, C(519) }, |
| 1569 | + { C(-926), C(437) } // different from first point |
| 1570 | + }; |
| 1571 | + static int expected_flags[] = { |
| 1572 | + MapCoord::CurveStart, |
| 1573 | + 0, |
| 1574 | + 0, |
| 1575 | + 0, |
| 1576 | + MapCoord::ClosePoint // injected by Mapper |
| 1577 | + }; |
| 1578 | + QTest::newRow("bezier, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags); |
| 1579 | + QTest::newRow("bezier, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags, 4); |
| 1580 | + } |
| 1581 | + |
| 1582 | + { |
| 1583 | + // straight segments, corner flag |
| 1584 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1585 | + { C(-589), C(432) }, |
| 1586 | + { C(-269), C(845) | Ocd::OcdPoint32::FlagCorner }, |
| 1587 | + { C(267), C(279) }, // different from first point |
| 1588 | + }; |
| 1589 | + static int expected_flags[] = { |
| 1590 | + 0, |
| 1591 | + MapCoord::DashPoint, |
| 1592 | + 0, |
| 1593 | + MapCoord::ClosePoint // injected by Mapper |
| 1594 | + }; |
| 1595 | + QTest::newRow("straight, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags); |
| 1596 | + QTest::newRow("straight, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags, 3); |
| 1597 | + } |
| 1598 | + |
| 1599 | + { |
| 1600 | + // straight segments, virtual gap |
| 1601 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1602 | + { C(-972), C(-264) }, |
| 1603 | + { C(-836) | Ocd::OcdPoint32::FlagLeft | ocd_flag_gap, C(-151) | Ocd::OcdPoint32::FlagRight }, |
| 1604 | + { C(-677), C(-19) }, |
| 1605 | + { C(-518), C(112) } // different from first point |
| 1606 | + }; |
| 1607 | + static int expected_flags[] = { |
| 1608 | + 0, |
| 1609 | + 0, |
| 1610 | + 0, |
| 1611 | + 0, |
| 1612 | + MapCoord::ClosePoint // injected by Mapper |
| 1613 | + }; |
| 1614 | + QTest::newRow("virtual gap, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags); |
| 1615 | + QTest::newRow("virtual gap, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags, 4); |
| 1616 | + } |
| 1617 | + |
| 1618 | + { |
| 1619 | + // straight segments, one hole |
| 1620 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1621 | + { C(100), C(-250) }, |
| 1622 | + { C(150), C(-260) }, |
| 1623 | + { C(100), C(-250) }, // same as first point |
| 1624 | + { C(200), C(-350) | Ocd::OcdPoint32::FlagHole }, |
| 1625 | + { C(220), C(-400) }, |
| 1626 | + { C(200), C(-350) } // same as first point of hole |
| 1627 | + }; |
| 1628 | + static int expected_flags_area[] = { |
| 1629 | + 0, |
| 1630 | + 0, |
| 1631 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1632 | + 0, |
| 1633 | + 0, |
| 1634 | + MapCoord::ClosePoint |
| 1635 | + }; |
| 1636 | + QTest::newRow("hole, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1637 | + static int expected_flags_line[6] = {}; |
| 1638 | + QTest::newRow("hole, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1639 | + } |
| 1640 | + |
| 1641 | + { |
| 1642 | + // straight segments, with an "empty" hole |
| 1643 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1644 | + { C(100), C(-250) }, |
| 1645 | + { C(150), C(-260) }, |
| 1646 | + { C(100), C(-250) }, // same as first point |
| 1647 | + { C(120), C(-200) | Ocd::OcdPoint32::FlagHole }, |
| 1648 | + { C(200), C(-350) | Ocd::OcdPoint32::FlagHole }, |
| 1649 | + { C(220), C(-400) }, |
| 1650 | + { C(200), C(-350) } // same as second FlagHole point |
| 1651 | + }; |
| 1652 | + static int expected_flags_area[] = { |
| 1653 | + 0, |
| 1654 | + 0, |
| 1655 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1656 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1657 | + 0, |
| 1658 | + 0, |
| 1659 | + MapCoord::ClosePoint |
| 1660 | + }; |
| 1661 | + QTest::newRow("empty hole, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1662 | + static int expected_flags_line[7] = {}; |
| 1663 | + QTest::newRow("empty hole, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1664 | + } |
| 1665 | + |
| 1666 | + { |
| 1667 | + // straight segments, with two "empty" holes |
| 1668 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1669 | + { C(100), C(-250) }, |
| 1670 | + { C(150), C(-260) }, |
| 1671 | + { C(100), C(-250) }, // same as first point |
| 1672 | + { C(120), C(-200) | Ocd::OcdPoint32::FlagHole }, |
| 1673 | + { C(140), C(-300) | Ocd::OcdPoint32::FlagHole }, |
| 1674 | + { C(200), C(-350) | Ocd::OcdPoint32::FlagHole }, |
| 1675 | + { C(220), C(-400) }, |
| 1676 | + { C(200), C(-350) }, // same as third FlagHole point |
| 1677 | + }; |
| 1678 | + static int expected_flags_area[] = { |
| 1679 | + 0, |
| 1680 | + 0, |
| 1681 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1682 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1683 | + MapCoord::ClosePoint | MapCoord::HolePoint, |
| 1684 | + 0, |
| 1685 | + 0, |
| 1686 | + MapCoord::ClosePoint |
| 1687 | + }; |
| 1688 | + QTest::newRow("two empty holes, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1689 | + static int expected_flags_line[8] = {}; |
| 1690 | + QTest::newRow("two empty holes, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1691 | + } |
| 1692 | + |
| 1693 | + { |
| 1694 | + // straight segments, one hole, not actual areas |
| 1695 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1696 | + { C(100), C(-250) }, |
| 1697 | + { C(150), C(-260) }, |
| 1698 | + { C(200), C(-350) | Ocd::OcdPoint32::FlagHole }, |
| 1699 | + { C(220), C(-400) } |
| 1700 | + }; |
| 1701 | + static int expected_flags_area[] = { |
| 1702 | + 0, |
| 1703 | + 0, |
| 1704 | + MapCoord::ClosePoint | MapCoord::HolePoint, // injected by Mapper |
| 1705 | + 0, |
| 1706 | + 0, |
| 1707 | + MapCoord::ClosePoint // injected by Mapper |
| 1708 | + }; |
| 1709 | + QTest::newRow("open areas with hole, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1710 | + static int expected_flags_line[4] = {}; |
| 1711 | + QTest::newRow("open areas with hole, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1712 | + } |
| 1713 | + |
| 1714 | + { |
| 1715 | + // area with hole in hole |
| 1716 | + static Ocd::OcdPoint32 ocd_points[] = { |
| 1717 | + { C(-405), C(-167) }, |
| 1718 | + { C(-348) | Ocd::OcdPoint32::FlagCtl1, C(22) }, |
| 1719 | + { C(-113) | Ocd::OcdPoint32::FlagCtl2, C(667) }, |
| 1720 | + { C(54), C(687) }, |
| 1721 | + { C(184) | Ocd::OcdPoint32::FlagCtl1, C(702) }, |
| 1722 | + { C(836) | Ocd::OcdPoint32::FlagCtl2, C(418) }, |
| 1723 | + { C(889), C(298) }, |
| 1724 | + { C(599), C(117) }, |
| 1725 | + { C(137), C(93) | Ocd::OcdPoint32::FlagDash}, // different from first point |
| 1726 | + { C(-25), C(79) | Ocd::OcdPoint32::FlagHole}, |
| 1727 | + { C(-208) | Ocd::OcdPoint32::FlagCtl1, C(259) }, |
| 1728 | + { C(90) | Ocd::OcdPoint32::FlagCtl2, C(652) }, |
| 1729 | + { C(559), C(322) }, // different from first point of hole |
| 1730 | + { C(78), C(326) | Ocd::OcdPoint32::FlagHole}, |
| 1731 | + { C(100) | Ocd::OcdPoint32::FlagCtl1, C(341) }, |
| 1732 | + { C(157) | Ocd::OcdPoint32::FlagCtl2, C(354) }, |
| 1733 | + { C(198), C(339) | Ocd::OcdPoint32::FlagCorner }, |
| 1734 | + { C(227) | Ocd::OcdPoint32::FlagCtl1, C(329) }, |
| 1735 | + { C(247) | Ocd::OcdPoint32::FlagCtl2, C(304) }, |
| 1736 | + { C(242), C(256) }, |
| 1737 | + { C(144), C(243) }, // different from first point of hole |
| 1738 | + }; |
| 1739 | + static int expected_flags_area[] = { |
| 1740 | + MapCoord::CurveStart, |
| 1741 | + 0, |
| 1742 | + 0, |
| 1743 | + MapCoord::CurveStart, |
| 1744 | + 0, |
| 1745 | + 0, |
| 1746 | + 0, |
| 1747 | + 0, |
| 1748 | + MapCoord::DashPoint, |
| 1749 | + MapCoord::ClosePoint | MapCoord::HolePoint, // injected by Mapper |
| 1750 | + MapCoord::CurveStart, |
| 1751 | + 0, |
| 1752 | + 0, |
| 1753 | + 0, |
| 1754 | + MapCoord::ClosePoint | MapCoord::HolePoint, // injected by Mapper |
| 1755 | + MapCoord::CurveStart, |
| 1756 | + 0, |
| 1757 | + 0, |
| 1758 | + MapCoord::DashPoint | MapCoord::CurveStart, |
| 1759 | + 0, |
| 1760 | + 0, |
| 1761 | + 0, |
| 1762 | + 0, |
| 1763 | + MapCoord::ClosePoint // injected by Mapper |
| 1764 | + }; |
| 1765 | + QTest::newRow("area with nested holes, area") << OcdPointsView(ocd_points) << Area << FlagsView(expected_flags_area); |
| 1766 | + static int expected_flags_line[] = { |
| 1767 | + MapCoord::CurveStart, |
| 1768 | + 0, |
| 1769 | + 0, |
| 1770 | + MapCoord::CurveStart, |
| 1771 | + 0, |
| 1772 | + 0, |
| 1773 | + 0, |
| 1774 | + 0, |
| 1775 | + MapCoord::DashPoint, |
| 1776 | + MapCoord::CurveStart, |
| 1777 | + 0, |
| 1778 | + 0, |
| 1779 | + 0, |
| 1780 | + MapCoord::CurveStart, |
| 1781 | + 0, |
| 1782 | + 0, |
| 1783 | + MapCoord::DashPoint | MapCoord::CurveStart, |
| 1784 | + 0, |
| 1785 | + 0, |
| 1786 | + 0, |
| 1787 | + 0 |
| 1788 | + }; |
| 1789 | + QTest::newRow("area with nested holes, line") << OcdPointsView(ocd_points) << Line << FlagsView(expected_flags_line); |
| 1790 | + } |
| 1791 | +} |
| 1792 | + |
| 1793 | +void FileFormatTest::ocdPathImportTest() |
| 1794 | +{ |
| 1795 | + QFETCH(OcdPointsView, points); |
| 1796 | + QFETCH(OcdPathPersonality, personality); |
| 1797 | + QFETCH(FlagsView, expected); |
| 1798 | + |
| 1799 | + TestOcdFileImport ocd_v12_import{12}; |
| 1800 | + |
| 1801 | + TestOcdFileImport::OcdImportedPathObject path_object; |
| 1802 | + ocd_v12_import.fillPathCoords(&path_object, personality == Area, points.size, points.data); |
| 1803 | + QVERIFY(path_object.getRawCoordinateVector().size() > 0); |
| 1804 | + |
| 1805 | + QCOMPARE(path_object.getRawCoordinateVector().size(), expected.size); |
| 1806 | + for (int i = 0; i < expected.size; ++i) |
| 1807 | + { |
| 1808 | + // Provide the current index when failing. |
| 1809 | + if (path_object.getCoordinate(i).flags() != MapCoord::Flags(expected.data[i])) |
| 1810 | + { |
| 1811 | + auto err = QString::fromLatin1("Compared flags are not the same at index %1\n" |
| 1812 | + " Actual : %2\n" |
| 1813 | + " Expected: %3" |
| 1814 | + ).arg(QString::number(i), |
| 1815 | + QString::number(path_object.getCoordinate(i).flags()), |
| 1816 | + QString::number(expected.data[i]) |
| 1817 | + ); |
| 1818 | + QFAIL(qPrintable(err)); |
| 1819 | + } |
| 1820 | + } |
| 1821 | +} |
1509 | 1822 |
|
1510 | 1823 | /* |
1511 | 1824 | * We don't need a real GUI window. |
|
0 commit comments