aboutsummaryrefslogtreecommitdiffhomepage
path: root/gtk/PlatGTK.cxx
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2021-03-20 09:31:02 +1100
committerNeil <nyamatongwe@gmail.com>2021-03-20 09:31:02 +1100
commit7fe8bb0dba466798ca9efc448f772d37f360efe2 (patch)
tree9aab51a5f185e07d5ecc12ec35f3ccdf59c2f675 /gtk/PlatGTK.cxx
parent6c56011f882cdfa758898029be5cabe82fc9228c (diff)
downloadscintilla-mirror-7fe8bb0dba466798ca9efc448f772d37f360efe2.tar.gz
Implement Stadium on all platforms except for Win32 GDI.
Diffstat (limited to 'gtk/PlatGTK.cxx')
-rwxr-xr-xgtk/PlatGTK.cxx63
1 files changed, 61 insertions, 2 deletions
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx
index 0b87b8743..aa0d69477 100755
--- a/gtk/PlatGTK.cxx
+++ b/gtk/PlatGTK.cxx
@@ -47,6 +47,8 @@ namespace {
constexpr double kPi = 3.14159265358979323846;
+constexpr double degrees = kPi / 180.0;
+
// The Pango version guard for pango_units_from_double and pango_units_to_double
// is more complex than simply implementing these here.
@@ -178,6 +180,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, Point from, Surface &surfaceSource) override;
std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) override;
@@ -612,8 +615,6 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, FillStroke fillStroke) {
}
static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, double radius) noexcept {
- constexpr double degrees = kPi / 180.0;
-
cairo_new_sub_path(context);
cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees);
cairo_arc(context, left + width - radius, top + height - radius, radius, 0 * degrees, 90 * degrees);
@@ -749,6 +750,64 @@ void SurfaceImpl::Ellipse(PRectangle rc, FillStroke fillStroke) {
cairo_stroke(context);
}
+void SurfaceImpl::Stadium(PRectangle rc, FillStroke fillStroke, Ends ends) {
+ const XYPOSITION midLine = rc.Centre().y;
+ const XYPOSITION halfStroke = fillStroke.stroke.width / 2.0f;
+ const XYPOSITION radius = rc.Height() / 2.0f - halfStroke;
+ PRectangle rcInner = rc;
+ rcInner.left += radius;
+ rcInner.right -= radius;
+
+ cairo_new_sub_path(context);
+
+ 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:
+ cairo_move_to(context, rc.left + halfStroke, rc.top + halfStroke);
+ cairo_line_to(context, rc.left + halfStroke, rc.bottom - halfStroke);
+ break;
+ case Ends::leftAngle:
+ cairo_move_to(context, rcInner.left + halfStroke, rc.top + halfStroke);
+ cairo_line_to(context, rc.left + halfStroke, rc.Centre().y);
+ cairo_line_to(context, rcInner.left + halfStroke, rc.bottom - halfStroke);
+ break;
+ case Ends::semiCircles:
+ default:
+ cairo_move_to(context, rcInner.left + halfStroke, rc.top + halfStroke);
+ cairo_arc_negative(context, rcInner.left + halfStroke, midLine, radius,
+ 270 * degrees, 90 * degrees);
+ break;
+ }
+
+ switch (rightSide) {
+ case Ends::rightFlat:
+ cairo_line_to(context, rc.right - halfStroke, rc.bottom - halfStroke);
+ cairo_line_to(context, rc.right - halfStroke, rc.top + halfStroke);
+ break;
+ case Ends::rightAngle:
+ cairo_line_to(context, rcInner.right - halfStroke, rc.bottom - halfStroke);
+ cairo_line_to(context, rc.right - halfStroke, rc.Centre().y);
+ cairo_line_to(context, rcInner.right - halfStroke, rc.top + halfStroke);
+ break;
+ case Ends::semiCircles:
+ default:
+ cairo_line_to(context, rcInner.right - halfStroke, rc.bottom - halfStroke);
+ cairo_arc_negative(context, rcInner.right - halfStroke, midLine, radius,
+ 90 * degrees, 270 * degrees);
+ break;
+ }
+
+ // Close the path to enclose it for stroking and for filling, then draw it
+ cairo_close_path(context);
+ PenColourAlpha(fillStroke.fill.colour);
+ cairo_fill_preserve(context);
+
+ PenColourAlpha(fillStroke.stroke.colour);
+ cairo_set_line_width(context, fillStroke.stroke.width);
+ cairo_stroke(context);
+}
+
void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfaceSource);
const bool canDraw = surfi.psurf != nullptr;