From a46477cdcf78383ff9a0ee908f92ce532f93de95 Mon Sep 17 00:00:00 2001 From: jmsgrogan Date: Fri, 20 Jan 2023 17:30:05 +0000 Subject: [PATCH] Start dx path support. --- .../circuits/test/TestElectronicCircuit.cpp | 4 +- src/base/geometry/path/Arc.cpp | 10 ++- .../geometry/path/PathPostScriptConverter.cpp | 18 +++--- .../graphics/directx/DirectX2dPainter.cpp | 63 ++++++++++++++++--- .../graphics/directx/DirectX2dPainter.h | 18 +++++- 5 files changed, 91 insertions(+), 22 deletions(-) diff --git a/plugins/circuits/test/TestElectronicCircuit.cpp b/plugins/circuits/test/TestElectronicCircuit.cpp index 75c081d..f0fd27c 100644 --- a/plugins/circuits/test/TestElectronicCircuit.cpp +++ b/plugins/circuits/test/TestElectronicCircuit.cpp @@ -9,7 +9,7 @@ TEST_CASE(TestElectronicCircuit, "circuits") { - TestRenderer renderer(100, 100); + TestRenderer renderer(800, 800); auto circuit = std::make_unique(); @@ -68,4 +68,6 @@ TEST_CASE(TestElectronicCircuit, "circuits") renderer.getScene()->addNode(circuit_node.get()); renderer.writeSvg(TestUtils::getTestOutputDir(__FILE__) / "circuit.svg"); + + renderer.write(TestUtils::getTestOutputDir(__FILE__) / "circuit.png"); } diff --git a/src/base/geometry/path/Arc.cpp b/src/base/geometry/path/Arc.cpp index 68492a1..e66c2fc 100644 --- a/src/base/geometry/path/Arc.cpp +++ b/src/base/geometry/path/Arc.cpp @@ -34,9 +34,15 @@ std::string Arc::toPostScriptString(std::size_t precision) const { sstr.precision(precision); } - sstr << (mPostscriptPositioning == PostscriptPositioning::RELATIVE_TO) ? "a" : "A"; + if (mPostscriptPositioning == PostscriptPositioning::RELATIVE_TO) + { + sstr << "a"; + } + else + { + sstr << "A"; + } sstr << mRx << " " << mRy << " " << mRotation << " " << large << " " << sweep << " "; - if (mPostscriptPositioning == PostscriptPositioning::RELATIVE_TO) { sstr << PointParser::toStringRelative(mEndPoint, mStartPoint, 2, " ", precision); diff --git a/src/base/geometry/path/PathPostScriptConverter.cpp b/src/base/geometry/path/PathPostScriptConverter.cpp index 8b92ade..acbbf58 100644 --- a/src/base/geometry/path/PathPostScriptConverter.cpp +++ b/src/base/geometry/path/PathPostScriptConverter.cpp @@ -11,6 +11,8 @@ #include "QuadraticBezierCurve.h" #include "CubicBezierCurve.h" +#include "PointParser.h" + void PathPostScriptConverter::fromPostScript(GeometryPath* targetPath, const std::string& postScriptPath) { mCurrentPoint = Point(); @@ -266,7 +268,7 @@ PathElementPtr PathPostScriptConverter::onQuadraticBezier() double control_x = mPointBuffer[0]; double control_y = mPointBuffer[1]; double end_x = mPointBuffer[2]; - bool end_y = mPointBuffer[3]; + double end_y = mPointBuffer[3]; if (mPositionState == PositionState::RELATIVE) { const auto control_point = Point(mCurrentPoint.getX() + control_x, mCurrentPoint.getY() + control_y); @@ -286,14 +288,14 @@ PathElementPtr PathPostScriptConverter::onQuadraticBezier() PathElementPtr PathPostScriptConverter::onCubicBezier() { PathElementPtr element; - if (mPointBuffer.size() == 4) + if (mPointBuffer.size() == 6) { double control0_x = mPointBuffer[0]; double control0_y = mPointBuffer[1]; - double control1_x = mPointBuffer[0]; - double control1_y = mPointBuffer[1]; - double end_x = mPointBuffer[2]; - bool end_y = mPointBuffer[3]; + double control1_x = mPointBuffer[2]; + double control1_y = mPointBuffer[3]; + double end_x = mPointBuffer[4]; + double end_y = mPointBuffer[5]; if (mPositionState == PositionState::RELATIVE) { const auto control_point0 = Point(mCurrentPoint.getX() + control0_x, mCurrentPoint.getY() + control0_y); @@ -318,11 +320,11 @@ std::string PathPostScriptConverter::toPostScript(const GeometryPath* targetPath for (const auto& feature : targetPath->getFeatures()) { auto start_loc = feature->getLocation(); - path += "M " + std::to_string(start_loc.getX()) + " " + std::to_string(start_loc.getY()); + path += "M" + PointParser::toString(start_loc, 2, " ", mPrecision); for (const auto& path_element : feature->getElements()) { - path += " " + path_element->toPostScriptString(mPrecision); + path += path_element->toPostScriptString(mPrecision); } path += "Z "; } diff --git a/src/rendering/graphics/directx/DirectX2dPainter.cpp b/src/rendering/graphics/directx/DirectX2dPainter.cpp index 867ee41..c885be2 100644 --- a/src/rendering/graphics/directx/DirectX2dPainter.cpp +++ b/src/rendering/graphics/directx/DirectX2dPainter.cpp @@ -11,6 +11,11 @@ #include "Line.h" #include "Path.h" +#include "Curve.h" +#include "Arc.h" +#include "QuadraticBezierCurve.h" +#include "CubicBezierCurve.h" + #include "FileLogger.h" #include "SceneModel.h" @@ -152,18 +157,27 @@ void DirectX2dPainter::paintPath(SceneModel* model) { if (element->getType() == AbstractGeometricItem::Type::LINE) { - for (const auto& point : dynamic_cast(element.get())->getPoints().getPoints()) - { - MLOG_INFO("Adding line entry at: " << point.getX() << " " << point.getY()); - path_sink->AddLine(toD2dPoint(point)); - } - MLOG_INFO("Finished line"); + onLine(element.get(), path_sink.Get()); } else if (element->getType() == AbstractGeometricItem::Type::LINE_SEGMENT) { - const auto loc = element->getEndPoint(); - MLOG_INFO("Adding segment entry at: " << loc.getX() << " " << loc.getY()); - path_sink->AddLine(toD2dPoint(loc)); + onLineSegment(element.get(), path_sink.Get()); + } + else if (element->getType() == AbstractGeometricItem::Type::CURVE) + { + auto curve = dynamic_cast(element.get()); + if (curve->getCurveType() == Curve::CurveType::ARC) + { + onArc(curve, path_sink.Get()); + } + else if (curve->getCurveType() == Curve::CurveType::CUBIC_BEZIER) + { + onCubicBezier(curve, path_sink.Get()); + } + else if (curve->getCurveType() == Curve::CurveType::QUADRATIC_BEZIER) + { + onQuadraticBezier(curve, path_sink.Get()); + } } } path_sink->EndFigure(D2D1_FIGURE_END_CLOSED); @@ -183,6 +197,37 @@ void DirectX2dPainter::paintPath(SceneModel* model) } } +void DirectX2dPainter::onArc(Curve* element, ID2D1GeometrySink* sink) +{ + +} + +void DirectX2dPainter::onQuadraticBezier(Curve* element, ID2D1GeometrySink* sink) +{ + +} + +void DirectX2dPainter::onCubicBezier(Curve* element, ID2D1GeometrySink* sink) +{ + +} + +void DirectX2dPainter::onLine(PathElement* element, ID2D1GeometrySink* sink) +{ + for (const auto& point : dynamic_cast(element)->getPoints().getPoints()) + { + MLOG_INFO("Adding line entry at: " << point.getX() << " " << point.getY()); + sink->AddLine(toD2dPoint(point)); + } + MLOG_INFO("Finished line"); +} + +void DirectX2dPainter::onLineSegment(PathElement* element, ID2D1GeometrySink* sink) +{ + const auto loc = element->getEndPoint(); + MLOG_INFO("Adding segment entry at: " << loc.getX() << " " << loc.getY()); + sink->AddLine(toD2dPoint(loc)); +} void DirectX2dPainter::setD2dInterface(DirectX2dInterface* d2dIterface) { diff --git a/src/rendering/graphics/directx/DirectX2dPainter.h b/src/rendering/graphics/directx/DirectX2dPainter.h index 0d8fe14..621c9ea 100644 --- a/src/rendering/graphics/directx/DirectX2dPainter.h +++ b/src/rendering/graphics/directx/DirectX2dPainter.h @@ -8,7 +8,11 @@ class SceneModel; class Point; class DirectX2dInterface; +class PathElement; +class Curve; + struct ID2D1SolidColorBrush; +struct ID2D1GeometrySink; namespace D2D1 { @@ -30,9 +34,15 @@ public: void setD2dInterface(DirectX2dInterface* d2dIterface); private: - static D2D1::ColorF toD2dColor(const Color& color); + void onLine(PathElement* element, ID2D1GeometrySink* sink); - static D2D_POINT_2F toD2dPoint(const Point& point); + void onLineSegment(PathElement* element, ID2D1GeometrySink* sink); + + void onArc(Curve* element, ID2D1GeometrySink* sink); + + void onQuadraticBezier(Curve* element, ID2D1GeometrySink* sink); + + void onCubicBezier(Curve* element, ID2D1GeometrySink* sink); void paintRect(SceneModel* model); @@ -40,6 +50,10 @@ private: void paintPath(SceneModel* model); + static D2D1::ColorF toD2dColor(const Color& color); + + static D2D_POINT_2F toD2dPoint(const Point& point); + Microsoft::WRL::ComPtr mSolidBrush; DirectX2dInterface* mD2dInterface{ nullptr };