Permalink
Browse files

MeterShape: Added 'Winding' fill mode for path shapes.

Usage: Shape=Path1 myPath | ...
1 parent 639c1ba commit b4e0f985c5348c487687ed153084f19bcbf26fdf @TheAzack9 TheAzack9 committed with brianferguson Jan 9, 2017
Showing with 22 additions and 8 deletions.
  1. +5 −3 Common/Gfx/Shapes/Path.cpp
  2. +2 −1 Common/Gfx/Shapes/Path.h
  3. +14 −3 Library/MeterShape.cpp
  4. +1 −1 Library/MeterShape.h
@@ -12,8 +12,9 @@
namespace Gfx {
-Path::Path(FLOAT x, FLOAT y, bool isCloned) : Shape(ShapeType::Path),
- m_StartPoint(D2D1::Point2F(x, y))
+Path::Path(FLOAT x, FLOAT y, D2D1_FILL_MODE fillMode, bool isCloned) : Shape(ShapeType::Path),
+ m_StartPoint(D2D1::Point2F(x, y)),
+ m_FillMode(fillMode)
{
// If cloned, copy |m_Path| instead of re-creating it.
if (isCloned) return;
@@ -24,6 +25,7 @@ Path::Path(FLOAT x, FLOAT y, bool isCloned) : Shape(ShapeType::Path),
hr = m_Path->Open(m_Sink.GetAddressOf());
if (SUCCEEDED(hr))
{
+ m_Sink->SetFillMode(m_FillMode);
m_Sink->BeginFigure(m_StartPoint, D2D1_FIGURE_BEGIN_FILLED);
return;
}
@@ -44,7 +46,7 @@ void Path::Dispose()
Shape* Path::Clone()
{
- Path* newShape = new Path(m_StartPoint.x, m_StartPoint.y, true);
+ Path* newShape = new Path(m_StartPoint.x, m_StartPoint.y, m_FillMode, true);
m_Shape.CopyTo(newShape->m_Shape.GetAddressOf());
@@ -15,7 +15,7 @@ namespace Gfx {
class Path final : public Shape
{
public:
- Path(FLOAT x, FLOAT y, bool isCloned = false);
+ Path(FLOAT x, FLOAT y, D2D1_FILL_MODE fillMode, bool isCloned = false);
~Path();
void AddLine(FLOAT x, FLOAT y);
@@ -35,6 +35,7 @@ class Path final : public Shape
void Dispose();
D2D1_POINT_2F m_StartPoint;
+ D2D1_FILL_MODE m_FillMode;
Microsoft::WRL::ComPtr<ID2D1GeometrySink> m_Sink;
Microsoft::WRL::ComPtr<ID2D1PathGeometry> m_Path;
@@ -385,10 +385,21 @@ bool MeterShape::CreateShape(std::vector<std::wstring>& args, ConfigParser& pars
return true;
}
}
+ else if (StringUtil::CaseInsensitiveCompareN(shapeName, L"PATH1"))
+ {
+ auto opt = parser.ReadString(section, shapeName.c_str(), L"");
+ if (opt.empty() || !ParsePath(opt, D2D1_FILL_MODE_WINDING))
+ {
+ LogErrorF(this, L"Path shape has invalid parameters: %s", opt.c_str());
+ return false;
+ }
+
+ return true;
+ }
else if (StringUtil::CaseInsensitiveCompareN(shapeName, L"PATH"))
{
auto opt = parser.ReadString(section, shapeName.c_str(), L"");
- if (opt.empty() || !ParsePath(opt))
+ if (opt.empty() || !ParsePath(opt, D2D1_FILL_MODE_ALTERNATE))
{
LogErrorF(this, L"Path shape has invalid parameters: %s", opt.c_str());
return false;
@@ -963,7 +974,7 @@ bool MeterShape::ParseGradient(Gfx::BrushType type, const WCHAR* options, bool a
return false;
}
-bool MeterShape::ParsePath(std::wstring& options)
+bool MeterShape::ParsePath(std::wstring& options, D2D1_FILL_MODE fillMode)
{
auto createSegmentFlags = [](bool stroke, bool round) -> D2D1_PATH_SEGMENT
{
@@ -984,7 +995,7 @@ bool MeterShape::ParsePath(std::wstring& options)
FLOAT startX = (FLOAT)ConfigParser::ParseDouble(stPoint[0].c_str(), 0.0);
FLOAT startY = (FLOAT)ConfigParser::ParseDouble(stPoint[1].c_str(), 0.0);
- Gfx::Path* shape = new Gfx::Path(startX, startY);
+ Gfx::Path* shape = new Gfx::Path(startX, startY, fillMode);
bool error = false;
bool open = true;
@@ -40,7 +40,7 @@ class MeterShape : public Meter
void ParseModifiers(std::vector<std::wstring>& args, ConfigParser& parser, const WCHAR* section, bool recursive = false);
bool ParseTransformModifers(Gfx::Shape* shape, std::wstring& transform);
bool ParseGradient(Gfx::BrushType type, const WCHAR* options, bool altGamma, bool isStroke);
- bool ParsePath(std::wstring& options);
+ bool ParsePath(std::wstring& options, D2D1_FILL_MODE fillMode);
std::vector<Gfx::Shape*> m_Shapes;
};

0 comments on commit b4e0f98

Please sign in to comment.