diff options
-rw-r--r-- | cocoa/PlatCocoa.h | 2 | ||||
-rw-r--r-- | cocoa/PlatCocoa.mm | 33 | ||||
-rwxr-xr-x | gtk/PlatGTK.cxx | 27 | ||||
-rw-r--r-- | qt/ScintillaEditBase/PlatQt.cpp | 16 | ||||
-rw-r--r-- | qt/ScintillaEditBase/PlatQt.h | 2 | ||||
-rw-r--r-- | src/Platform.h | 2 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 79 |
7 files changed, 161 insertions, 0 deletions
diff --git a/cocoa/PlatCocoa.h b/cocoa/PlatCocoa.h index c14ca1928..29a3626ce 100644 --- a/cocoa/PlatCocoa.h +++ b/cocoa/PlatCocoa.h @@ -96,6 +96,8 @@ public: int DeviceHeightFont(int points) override; void MoveTo(int x_, int y_) override; void LineTo(int x_, int y_) override; + void LineDraw(Point start, Point end, Stroke stroke) override; + void PolyLine(const Point *pts, size_t npts, Stroke stroke) override; void Polygon(Scintilla::Point *pts, size_t npts, ColourDesired fore, ColourDesired back) override; void Polygon(const Scintilla::Point *pts, size_t npts, FillStroke fillStroke) override; void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) override; diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm index 7bec2d73d..275587288 100644 --- a/cocoa/PlatCocoa.mm +++ b/cocoa/PlatCocoa.mm @@ -657,6 +657,39 @@ void SurfaceImpl::LineTo(int x_, int y_) { //-------------------------------------------------------------------------------------------------- +void SurfaceImpl::LineDraw(Point start, Point end, Stroke stroke) { + PenColourAlpha(stroke.colour); + CGContextSetLineWidth(gc, stroke.width); + + CGContextBeginPath(gc); + CGContextMoveToPoint(gc, start.x, start.y); + CGContextAddLineToPoint(gc, end.x, end.y); + CGContextStrokePath(gc); + + CGContextSetLineWidth(gc, 1.0f); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::PolyLine(const Point *pts, size_t npts, Stroke stroke) { + PLATFORM_ASSERT(gc && (npts > 1)); + if (!gc || (npts <= 1)) { + return; + } + PenColourAlpha(stroke.colour); + CGContextSetLineWidth(gc, stroke.width); + CGContextBeginPath(gc); + CGContextMoveToPoint(gc, pts[0].x, pts[0].y); + for (size_t i = 1; i < npts; i++) { + CGContextAddLineToPoint(gc, pts[i].x, pts[i].y); + } + CGContextStrokePath(gc); + + CGContextSetLineWidth(gc, 1.0f); +} + +//-------------------------------------------------------------------------------------------------- + void SurfaceImpl::Polygon(Scintilla::Point *pts, size_t npts, ColourDesired fore, ColourDesired back) { // Allocate memory for the array of points. diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index aa0d69477..5296691d1 100755 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -163,6 +163,8 @@ public: int DeviceHeightFont(int points) override; void MoveTo(int x_, int y_) override; void LineTo(int x_, int y_) override; + void LineDraw(Point start, Point end, Stroke stroke) override; + void PolyLine(const Point *pts, size_t npts, Stroke stroke) override; void Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back) override; void Polygon(const Point *pts, size_t npts, FillStroke fillStroke) override; void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) override; @@ -488,6 +490,31 @@ void SurfaceImpl::LineTo(int x_, int y_) { y = y_; } +void SurfaceImpl::LineDraw(Point start, Point end, Stroke stroke) { + PLATFORM_ASSERT(context); + if (!context) + return; + PenColourAlpha(stroke.colour); + cairo_set_line_width(context, stroke.width); + cairo_move_to(context, start.x, start.y); + cairo_line_to(context, end.x, end.y); + cairo_stroke(context); +} + +void SurfaceImpl::PolyLine(const Point *pts, size_t npts, Stroke stroke) { + // TODO: set line joins and caps + PLATFORM_ASSERT(context && npts > 1); + if (!context) + return; + PenColourAlpha(stroke.colour); + cairo_set_line_width(context, stroke.width); + cairo_move_to(context, pts[0].x, pts[0].y); + for (size_t i = 1; i < npts; i++) { + cairo_line_to(context, pts[i].x, pts[i].y); + } + cairo_stroke(context); +} + void SurfaceImpl::Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back) { PLATFORM_ASSERT(context); diff --git a/qt/ScintillaEditBase/PlatQt.cpp b/qt/ScintillaEditBase/PlatQt.cpp index 7e2fd3e98..120b75052 100644 --- a/qt/ScintillaEditBase/PlatQt.cpp +++ b/qt/ScintillaEditBase/PlatQt.cpp @@ -301,6 +301,22 @@ void SurfaceImpl::LineTo(int x_, int y_) y = y_; } +void SurfaceImpl::LineDraw(Point start, Point end, Stroke stroke) +{ + PenColourWidth(stroke.colour, stroke.width); + QLineF line(start.x, start.y, end.x, end.y); + GetPainter()->drawLine(line); +} + +void SurfaceImpl::PolyLine(const Point *pts, size_t npts, Stroke stroke) +{ + // TODO: set line joins and caps + PenColourWidth(stroke.colour, stroke.width); + std::vector<QPointF> qpts; + std::transform(pts, pts + npts, std::back_inserter(qpts), QPointFFromPoint); + GetPainter()->drawPolyline(&qpts[0], static_cast<int>(npts)); +} + void SurfaceImpl::Polygon(Point *pts, size_t npts, ColourDesired fore, diff --git a/qt/ScintillaEditBase/PlatQt.h b/qt/ScintillaEditBase/PlatQt.h index a95e1bd88..ac4bb9a69 100644 --- a/qt/ScintillaEditBase/PlatQt.h +++ b/qt/ScintillaEditBase/PlatQt.h @@ -104,6 +104,8 @@ public: int DeviceHeightFont(int points) override; void MoveTo(int x_, int y_) override; void LineTo(int x_, int y_) override; + void LineDraw(Point start, Point end, Stroke stroke) override; + void PolyLine(const Point *pts, size_t npts, Stroke stroke) override; void Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back) override; void Polygon(const Point *pts, size_t npts, FillStroke fillStroke) override; diff --git a/src/Platform.h b/src/Platform.h index 7f61967c3..3b9443cc9 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -196,6 +196,8 @@ public: virtual int DeviceHeightFont(int points)=0; virtual void MoveTo(int x_, int y_)=0; virtual void LineTo(int x_, int y_)=0; + virtual void LineDraw(Point start, Point end, Stroke stroke)=0; + virtual void PolyLine(const Point *pts, size_t npts, Stroke stroke)=0; virtual void Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back)=0; virtual void Polygon(const Point *pts, size_t npts, FillStroke fillStroke)=0; virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0; diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 673df5c2b..c902bad04 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -488,6 +488,8 @@ public: int DeviceHeightFont(int points) override; void MoveTo(int x_, int y_) override; void LineTo(int x_, int y_) override; + void LineDraw(Point start, Point end, Stroke stroke) override; + void PolyLine(const Point *pts, size_t npts, Stroke stroke) override; void Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back) override; void Polygon(const Point *pts, size_t npts, FillStroke fillStroke) override; void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) override; @@ -697,6 +699,23 @@ void SurfaceGDI::LineTo(int x_, int y_) { ::LineTo(hdc, x_, y_); } +void SurfaceGDI::LineDraw(Point start, Point end, Stroke stroke) { + PenColour(stroke.colour, stroke.width); + ::MoveToEx(hdc, std::lround(std::floor(start.x)), std::lround(std::floor(start.y)), nullptr); + ::LineTo(hdc, std::lround(std::floor(end.x)), std::lround(std::floor(end.y))); +} + +void SurfaceGDI::PolyLine(const Point *pts, size_t npts, Stroke stroke) { + PLATFORM_ASSERT(npts > 1); + if (npts <= 1) { + return; + } + PenColour(stroke.colour, stroke.width); + std::vector<POINT> outline; + std::transform(pts, pts + npts, std::back_inserter(outline), POINTFromPoint); + ::Polyline(hdc, outline.data(), static_cast<int>(npts)); +} + void SurfaceGDI::Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColour(back); @@ -1424,7 +1443,9 @@ public: int DeviceHeightFont(int points) override; void MoveTo(int x_, int y_) override; void LineTo(int x_, int y_) override; + void LineDraw(Point start, Point end, Stroke stroke) override; ID2D1PathGeometry *Geometry(const Point *pts, size_t npts, D2D1_FIGURE_BEGIN figureBegin) noexcept; + void PolyLine(const Point *pts, size_t npts, Stroke stroke) override; void Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back) override; void Polygon(const Point *pts, size_t npts, FillStroke fillStroke) override; void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) override; @@ -1686,6 +1707,31 @@ void SurfaceD2D::LineTo(int x_, int y_) { } } +void SurfaceD2D::LineDraw(Point start, Point end, Stroke stroke) { + D2DPenColourAlpha(stroke.colour); + + D2D1_STROKE_STYLE_PROPERTIES strokeProps {}; + strokeProps.startCap = D2D1_CAP_STYLE_SQUARE; + strokeProps.endCap = D2D1_CAP_STYLE_SQUARE; + strokeProps.dashCap = D2D1_CAP_STYLE_FLAT; + strokeProps.lineJoin = D2D1_LINE_JOIN_MITER; + strokeProps.miterLimit = 4.0f; + strokeProps.dashStyle = D2D1_DASH_STYLE_SOLID; + strokeProps.dashOffset = 0; + + // get the stroke style to apply + ID2D1StrokeStyle *pStrokeStyle = nullptr; + const HRESULT hr = pD2DFactory->CreateStrokeStyle( + strokeProps, nullptr, 0, &pStrokeStyle); + if (SUCCEEDED(hr)) { + pRenderTarget->DrawLine( + D2D1::Point2F(start.x, start.y), + D2D1::Point2F(end.x, end.y), pBrush, stroke.width, pStrokeStyle); + } + + ReleaseUnknown(pStrokeStyle); +} + ID2D1PathGeometry *SurfaceD2D::Geometry(const Point *pts, size_t npts, D2D1_FIGURE_BEGIN figureBegin) noexcept { ID2D1PathGeometry *geometry = nullptr; HRESULT hr = pD2DFactory->CreatePathGeometry(&geometry); @@ -1706,6 +1752,39 @@ ID2D1PathGeometry *SurfaceD2D::Geometry(const Point *pts, size_t npts, D2D1_FIGU return geometry; } +void SurfaceD2D::PolyLine(const Point *pts, size_t npts, Stroke stroke) { + PLATFORM_ASSERT(pRenderTarget && (npts > 1)); + if (!pRenderTarget || (npts <= 1)) { + return; + } + + ID2D1PathGeometry *geometry = Geometry(pts, npts, D2D1_FIGURE_BEGIN_HOLLOW); + PLATFORM_ASSERT(geometry); + if (!geometry) { + return; + } + + D2DPenColourAlpha(stroke.colour); + D2D1_STROKE_STYLE_PROPERTIES strokeProps {}; + strokeProps.startCap = D2D1_CAP_STYLE_ROUND; + strokeProps.endCap = D2D1_CAP_STYLE_ROUND; + strokeProps.dashCap = D2D1_CAP_STYLE_FLAT; + strokeProps.lineJoin = D2D1_LINE_JOIN_MITER; + strokeProps.miterLimit = 4.0f; + strokeProps.dashStyle = D2D1_DASH_STYLE_SOLID; + strokeProps.dashOffset = 0; + + // get the stroke style to apply + ID2D1StrokeStyle *pStrokeStyle = nullptr; + const HRESULT hr = pD2DFactory->CreateStrokeStyle( + strokeProps, nullptr, 0, &pStrokeStyle); + if (SUCCEEDED(hr)) { + pRenderTarget->DrawGeometry(geometry, pBrush, stroke.width, pStrokeStyle); + } + ReleaseUnknown(pStrokeStyle); + ReleaseUnknown(geometry); +} + void SurfaceD2D::Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back) { PLATFORM_ASSERT(pRenderTarget && (npts > 2)); if (pRenderTarget) { |