aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/Graphics/SvgPath.cpp6
-rw-r--r--src/platform/graphics/Geometry.cpp131
2 files changed, 83 insertions, 54 deletions
diff --git a/demos/Graphics/SvgPath.cpp b/demos/Graphics/SvgPath.cpp
index 181cb297..44524d77 100644
--- a/demos/Graphics/SvgPath.cpp
+++ b/demos/Graphics/SvgPath.cpp
@@ -1,6 +1,7 @@
#include "cru/base/io/CFileStream.h"
#include "cru/platform/Color.h"
+#include "cru/platform/Matrix.h"
#include "cru/platform/bootstrap/GraphicsBootstrap.h"
#include "cru/platform/graphics/Factory.h"
#include "cru/platform/graphics/ImageFactory.h"
@@ -23,12 +24,11 @@ M6.5 0a.5.5 0 0 0 0 1H7v1.07a7.001 7.001 0 0 0-3.273 12.474l-.602.602a.5.5 0 0 0
)");
auto geometry = geometry_builder->Build();
- auto image = graphics_factory->GetImageFactory()->CreateBitmap(1000, 1000);
+ auto image = graphics_factory->GetImageFactory()->CreateBitmap(160, 160);
auto painter = image->CreatePainter();
- painter->PushState();
+ painter->ConcatTransform(cru::platform::Matrix::Scale(10, 10));
painter->FillGeometry(geometry.get(), brush.get());
- painter->PopState();
painter->EndDraw();
cru::io::CFileStream file_stream("./svg-path-demo.png", "w");
diff --git a/src/platform/graphics/Geometry.cpp b/src/platform/graphics/Geometry.cpp
index 25dfba6e..b9503c4e 100644
--- a/src/platform/graphics/Geometry.cpp
+++ b/src/platform/graphics/Geometry.cpp
@@ -258,33 +258,50 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) {
last_is_quad = false;
switch (command) {
- case 'M':
- MoveTo(read_point());
+ case 'M': {
+ auto end = read_point();
+ MoveTo(end);
break;
- case 'm':
- RelativeMoveTo(read_point());
+ }
+ case 'm': {
+ auto offset = read_point();
+ RelativeMoveTo(offset);
break;
- case 'L':
- LineTo(read_point());
+ }
+ case 'L': {
+ auto end = read_point();
+ LineTo(end);
break;
- case 'l':
- RelativeLineTo(read_point());
+ }
+ case 'l': {
+ auto offset = read_point();
+ RelativeLineTo(offset);
break;
- case 'H':
- LineTo(read_number(), this->GetCurrentPosition().y);
+ }
+ case 'H': {
+ auto x = read_number();
+ LineTo(x, this->GetCurrentPosition().y);
break;
- case 'h':
- RelativeLineTo(read_number(), 0);
+ }
+ case 'h': {
+ auto dx = read_number();
+ RelativeLineTo(dx, 0);
break;
- case 'V':
- LineTo(GetCurrentPosition().x, read_number());
+ }
+ case 'V': {
+ auto y = read_number();
+ LineTo(GetCurrentPosition().x, y);
break;
- case 'v':
- RelativeLineTo(0, read_number());
+ }
+ case 'v': {
+ auto dy = read_number();
+ RelativeLineTo(0, dy);
break;
+ }
case 'C': {
- auto start_control_point = read_point(),
- end_control_point = read_point(), end_point = read_point();
+ auto start_control_point = read_point();
+ auto end_control_point = read_point();
+ auto end_point = read_point();
CubicBezierTo(start_control_point, end_control_point, end_point);
last_is_cubic = true;
last_control_point = end_control_point;
@@ -293,9 +310,9 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) {
}
case 'c': {
auto current_position = GetCurrentPosition();
- auto start_control_point = current_position + read_point(),
- end_control_point = current_position + read_point(),
- end_point = current_position + read_point();
+ auto start_control_point = current_position + read_point();
+ auto end_control_point = current_position + read_point();
+ auto end_point = current_position + read_point();
CubicBezierTo(start_control_point, end_control_point, end_point);
last_is_cubic = true;
last_control_point = end_control_point;
@@ -304,11 +321,12 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) {
}
case 'S': {
auto current_position = GetCurrentPosition();
- auto start_control_point = last_is_cubic ? Point{last_end_point.x * 2,
- last_end_point.y * 2} -
- last_control_point
- : current_position,
- end_control_point = read_point(), end_point = read_point();
+ auto start_control_point =
+ last_is_cubic ? Point{last_end_point.x * 2, last_end_point.y * 2} -
+ last_control_point
+ : current_position;
+ auto end_control_point = read_point();
+ auto end_point = read_point();
CubicBezierTo(start_control_point, end_control_point, end_point);
last_is_cubic = true;
last_control_point = end_control_point;
@@ -317,12 +335,12 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) {
}
case 's': {
auto current_position = GetCurrentPosition();
- auto start_control_point = last_is_cubic ? Point{last_end_point.x * 2,
- last_end_point.y * 2} -
- last_control_point
- : current_position,
- end_control_point = current_position + read_point(),
- end_point = current_position + read_point();
+ auto start_control_point =
+ last_is_cubic ? Point{last_end_point.x * 2, last_end_point.y * 2} -
+ last_control_point
+ : current_position;
+ auto end_control_point = current_position + read_point();
+ auto end_point = current_position + read_point();
CubicBezierTo(start_control_point, end_control_point, end_point);
last_is_cubic = true;
last_control_point = end_control_point;
@@ -330,7 +348,8 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) {
break;
}
case 'Q': {
- auto control_point = read_point(), end_point = read_point();
+ auto control_point = read_point();
+ auto end_point = read_point();
QuadraticBezierTo(control_point, end_point);
last_is_quad = true;
last_control_point = control_point;
@@ -339,8 +358,8 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) {
}
case 'q': {
auto current_position = GetCurrentPosition();
- auto control_point = current_position + read_point(),
- end_point = current_position + read_point();
+ auto control_point = current_position + read_point();
+ auto end_point = current_position + read_point();
QuadraticBezierTo(control_point, end_point);
last_is_quad = true;
last_control_point = control_point;
@@ -349,11 +368,11 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) {
}
case 'T': {
auto current_position = GetCurrentPosition();
- auto control_point = last_is_quad ? Point{last_end_point.x * 2,
- last_end_point.y * 2} -
- last_control_point
- : current_position,
- end_point = read_point();
+ auto control_point =
+ last_is_quad ? Point{last_end_point.x * 2, last_end_point.y * 2} -
+ last_control_point
+ : current_position;
+ auto end_point = read_point();
QuadraticBezierTo(control_point, end_point);
last_is_quad = true;
last_control_point = control_point;
@@ -362,25 +381,35 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) {
}
case 't': {
auto current_position = GetCurrentPosition();
- auto control_point = last_is_quad ? Point{last_end_point.x * 2,
- last_end_point.y * 2} -
- last_control_point
- : current_position,
- end_point = current_position + read_point();
+ auto control_point =
+ last_is_quad ? Point{last_end_point.x * 2, last_end_point.y * 2} -
+ last_control_point
+ : current_position;
+ auto end_point = current_position + read_point();
QuadraticBezierTo(control_point, end_point);
last_is_quad = true;
last_control_point = control_point;
last_end_point = end_point;
break;
}
- case 'A':
- ArcTo({read_number(), read_number()}, read_number(), read_number(),
- read_number(), read_point());
+ case 'A': {
+ Point radius(read_number(), read_number());
+ auto angle = read_number();
+ auto large_arc_flag = read_number();
+ auto sweep_flag = read_number();
+ auto end = read_point();
+ ArcTo(radius, angle, large_arc_flag, sweep_flag, end);
break;
- case 'a':
- RelativeArcTo({read_number(), read_number()}, read_number(),
- read_number(), read_number(), read_point());
+ }
+ case 'a': {
+ Point radius(read_number(), read_number());
+ auto angle = read_number();
+ auto large_arc_flag = read_number();
+ auto sweep_flag = read_number();
+ auto offset = read_point();
+ RelativeArcTo(radius, angle, large_arc_flag, sweep_flag, offset);
break;
+ }
case 'Z':
case 'z':
CloseFigure(true);