aboutsummaryrefslogtreecommitdiffhomepage
path: root/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'cocoa')
-rw-r--r--cocoa/PlatCocoa.h2
-rw-r--r--cocoa/PlatCocoa.mm60
2 files changed, 62 insertions, 0 deletions
diff --git a/cocoa/PlatCocoa.h b/cocoa/PlatCocoa.h
index 98a9b11ed..f50c0e7f7 100644
--- a/cocoa/PlatCocoa.h
+++ b/cocoa/PlatCocoa.h
@@ -62,6 +62,7 @@ private:
void FillColour(const ColourDesired &back);
void FillColour(ColourAlpha fill);
+ void PenColourAlpha(ColourAlpha fore);
// 24-bit RGB+A bitmap data constants
static const int BITS_PER_COMPONENT = 8;
@@ -101,6 +102,7 @@ public:
void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) override;
void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill,
ColourDesired outline, int alphaOutline, int flags) override;
+ void AlphaRectangle(PRectangle rc, XYPOSITION cornerSize, FillStroke fillStroke) override;
void GradientRectangle(PRectangle rc, const std::vector<ColourStop> &stops, GradientOptions options) override;
void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) override;
void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override;
diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm
index a4f01c5c6..714e4f484 100644
--- a/cocoa/PlatCocoa.mm
+++ b/cocoa/PlatCocoa.mm
@@ -502,6 +502,17 @@ void SurfaceImpl::FillColour(const ColourDesired &back) {
//--------------------------------------------------------------------------------------------------
+void SurfaceImpl::PenColourAlpha(ColourAlpha fore) {
+ // Set the Stroke color to match
+ CGContextSetRGBStrokeColor(gc,
+ fore.GetRedComponent(),
+ fore.GetGreenComponent(),
+ fore.GetBlueComponent(),
+ fore.GetAlphaComponent());
+}
+
+//--------------------------------------------------------------------------------------------------
+
CGImageRef SurfaceImpl::CreateImage() {
// For now, assume that CreateImage can only be called on PixMap surfaces.
if (!bitmapData)
@@ -895,6 +906,55 @@ void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, Colou
}
}
+void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, XYPOSITION cornerSize, FillStroke fillStroke) {
+ if (gc) {
+ const XYPOSITION halfStroke = fillStroke.stroke.width / 2.0f;
+ // Set the Fill color to match
+ FillColour(fillStroke.fill.colour);
+ PenColourAlpha(fillStroke.stroke.colour);
+ PRectangle rcFill = rc;
+ if (cornerSize == 0) {
+ // A simple rectangle, no rounded corners
+ if (fillStroke.fill.colour == fillStroke.stroke.colour) {
+ // Optimization for simple case
+ CGRect rect = PRectangleToCGRect(rcFill);
+ CGContextFillRect(gc, rect);
+ } else {
+ rcFill.left += fillStroke.stroke.width;
+ rcFill.top += fillStroke.stroke.width;
+ rcFill.right -= fillStroke.stroke.width;
+ rcFill.bottom -= fillStroke.stroke.width;
+ CGRect rect = PRectangleToCGRect(rcFill);
+ CGContextFillRect(gc, rect);
+ CGContextAddRect(gc, CGRectMake(rc.left + halfStroke, rc.top + halfStroke,
+ rc.Width() - fillStroke.stroke.width, rc.Height() - fillStroke.stroke.width));
+ CGContextStrokeRectWithWidth(gc,
+ CGRectMake(rc.left + halfStroke, rc.top + halfStroke,
+ rc.Width() - fillStroke.stroke.width, rc.Height() - fillStroke.stroke.width),
+ fillStroke.stroke.width);
+ }
+ } else {
+ // Approximate rounded corners with 45 degree chamfers.
+ // Drawing real circular arcs often leaves some over- or under-drawn pixels.
+ if (fillStroke.fill.colour == fillStroke.stroke.colour) {
+ // Specializing this case avoids a few stray light/dark pixels in corners.
+ rcFill.left -= halfStroke;
+ rcFill.top -= halfStroke;
+ rcFill.right += halfStroke;
+ rcFill.bottom += halfStroke;
+ DrawChamferedRectangle(gc, rcFill, cornerSize, kCGPathFill);
+ } else {
+ rcFill.left += halfStroke;
+ rcFill.top += halfStroke;
+ rcFill.right -= halfStroke;
+ rcFill.bottom -= halfStroke;
+ DrawChamferedRectangle(gc, rcFill, cornerSize-fillStroke.stroke.width, kCGPathFill);
+ DrawChamferedRectangle(gc, rc, cornerSize, kCGPathStroke);
+ }
+ }
+ }
+}
+
void Scintilla::SurfaceImpl::GradientRectangle(PRectangle rc, const std::vector<ColourStop> &stops, GradientOptions options) {
if (!gc) {
return;