diff options
Diffstat (limited to 'cocoa')
-rw-r--r-- | cocoa/PlatCocoa.h | 2 | ||||
-rw-r--r-- | cocoa/PlatCocoa.mm | 60 |
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; |