aboutsummaryrefslogtreecommitdiffhomepage
path: root/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'cocoa')
-rw-r--r--cocoa/PlatCocoa.h1
-rw-r--r--cocoa/PlatCocoa.mm55
2 files changed, 56 insertions, 0 deletions
diff --git a/cocoa/PlatCocoa.h b/cocoa/PlatCocoa.h
index 36022286c..c14ca1928 100644
--- a/cocoa/PlatCocoa.h
+++ b/cocoa/PlatCocoa.h
@@ -113,6 +113,7 @@ public:
void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) override;
void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override;
void Ellipse(PRectangle rc, FillStroke fillStroke) override;
+ void Stadium(PRectangle rc, FillStroke fillStroke, Ends ends) override;
void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource) override;
std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) override;
diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm
index 55a6ee620..7bec2d73d 100644
--- a/cocoa/PlatCocoa.mm
+++ b/cocoa/PlatCocoa.mm
@@ -1231,6 +1231,61 @@ void SurfaceImpl::Ellipse(PRectangle rc, FillStroke fillStroke) {
CGContextSetLineWidth(gc, 1.0f);
}
+void SurfaceImpl::Stadium(PRectangle rc, FillStroke fillStroke, Ends ends) {
+ const CGFloat midLine = rc.Centre().y;
+ const CGFloat piOn2 = acos(0.0);
+ const XYPOSITION halfStroke = fillStroke.stroke.width / 2.0f;
+ const float radius = rc.Height() / 2.0f - halfStroke;
+ PRectangle rcInner = rc;
+ rcInner.left += radius;
+ rcInner.right -= radius;
+
+ SetFillStroke(fillStroke);
+ CGContextBeginPath(gc);
+
+ const Ends leftSide = static_cast<Ends>(static_cast<int>(ends) & 0xf);
+ const Ends rightSide = static_cast<Ends>(static_cast<int>(ends) & 0xf0);
+ switch (leftSide) {
+ case Ends::leftFlat:
+ CGContextMoveToPoint(gc, rc.left + halfStroke, rc.top + halfStroke);
+ CGContextAddLineToPoint(gc, rc.left + halfStroke, rc.bottom - halfStroke);
+ break;
+ case Ends::leftAngle:
+ CGContextMoveToPoint(gc, rcInner.left + halfStroke, rc.top + halfStroke);
+ CGContextAddLineToPoint(gc, rc.left + halfStroke, rc.Centre().y);
+ CGContextAddLineToPoint(gc, rcInner.left + halfStroke, rc.bottom - halfStroke);
+ break;
+ case Ends::semiCircles:
+ default:
+ CGContextMoveToPoint(gc, rcInner.left + halfStroke, rc.top + halfStroke);
+ CGContextAddArc(gc, rcInner.left + halfStroke, midLine, radius, -piOn2, piOn2, 1);
+ break;
+ }
+
+ switch (rightSide) {
+ case Ends::rightFlat:
+ CGContextAddLineToPoint(gc, rc.right - halfStroke, rc.bottom - halfStroke);
+ CGContextAddLineToPoint(gc, rc.right - halfStroke, rc.top + halfStroke);
+ break;
+ case Ends::rightAngle:
+ CGContextAddLineToPoint(gc, rcInner.right - halfStroke, rc.bottom - halfStroke);
+ CGContextAddLineToPoint(gc, rc.right - halfStroke, rc.Centre().y);
+ CGContextAddLineToPoint(gc, rcInner.right - halfStroke, rc.top + halfStroke);
+ break;
+ case Ends::semiCircles:
+ default:
+ CGContextAddLineToPoint(gc, rcInner.right - halfStroke, rc.bottom - halfStroke);
+ CGContextAddArc(gc, rcInner.right - halfStroke, midLine, radius, piOn2, -piOn2, 1);
+ break;
+ }
+
+ // Close the path to enclose it for stroking and for filling, then draw it
+ CGContextClosePath(gc);
+ CGContextDrawPath(gc, kCGPathFillStroke);
+
+ CGContextSetLineWidth(gc, 1.0f);
+}
+
void SurfaceImpl::CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect) {
SurfaceImpl &source = static_cast<SurfaceImpl &>(surfaceSource);
CGImageRef image = source.CreateImage();