Creating a Cairo-Inspired Graphics Library for MetaTrader 5 (Part 7): Arcs, Circles and Rounded Rectangles

Why this article was written
Part 6 gave the library the general tool: a cubic Bézier curve will describe any smooth shape you can draw. But interface work is not general. It is arcs and rounded rectangles, over and over — cards, tabs, pills, buttons, chat bubbles, progress bars, gauges.
You can approximate a quarter circle with a Bézier and the well-known 0.5523 magic constant. This article declines to. A circle has an exact definition, and the segment count you need falls out of it with one line of trigonometry.
What is inside
Where the segment count comes from. The error in a chord across an arc is
the sagitta — the bulge between the chord and the arc — and it is
h = r·(1 − cos(da/2)). Set h equal to the tolerance, solve for da, and you
have the step angle directly: da = 2·acos(1 − tol/r). No guessing, no constant.
The result scales the way it should. At 0.30 px tolerance: radius 4 → 9 segments, radius 24 → 20, radius 80 → 37, radius 300 → 71. A small corner stays cheap; a large one gets the detail it needs.
ArcTo, and the vertex that is easy to lose. The loop that walks the arc
starts at i = 1, which means the first vertex has to be handled separately —
and there are three different right answers depending on where the pen is: no
pen yet (MoveTo), pen already at the start point within 1e-9 (add nothing), or
pen elsewhere (LineTo first). Getting this wrong leaves a hairline gap or a
duplicate point, and the article shows exactly why.
Rounded rectangles, one radius per corner.
AddRoundRect(x, y, w, h, r_tl, r_tr, r_br, r_bl) — the corner order matches
CSS border-radius, so it reads the way you already think. There is a
single-radius overload for the common case.
The clamp that stops a bow-tie. Each radius is clamped to half the smaller
side. Without it, a radius larger than the box turns the outline inside out, and
the article shows the resulting bow-tie rather than just warning about it. The
clamp differs from CSS on purpose — CSS scales all radii together — and the
difference is stated rather than glossed over. One useful side effect:
AddRoundRect(x, y, 120, 40, 999) is the idiom for a pill.
Circles and ellipses. AddEllipse sizes its step from the larger radius,
so the flatter axis is never under-sampled, with a floor of 8 segments.
AddCircle is one line on top of it.
Rings, gauges and donuts — with no new code. A ring is two AddCircle
contours filled with the even-odd rule from Part 5. A progress band is a
single contour: arc out, line across, arc back, close, filled non-zero. This is
the moment the earlier parts pay off.
An honest note on scope
The degenerate cases are handled by stated rules rather than shown on screen: a
zero or negative radius becomes a LineTo, negative corner radii become 0, and
a negative width or height is not validated. The article says so plainly.
Only one file changes. Raster.mqh is untouched for the second article running,
and Config.mqh does not even gain a constant — Part 6's tolerance serves arcs
and curves alike.
Color.mqh Part 1 the ARGB color type
Part 4 + CairoBlendOver
Config.mqh Part 4 CairoAaSamples
Part 6 CairoFlattenTolerance - reused today, unchanged
Surface.mqh Part 1 a pixel buffer bound to one chart object
Path.mqh Part 2 points, contours, the pen
Part 3 + BuildEdges
Part 5 + AddThickLine
Part 6 + CurveTo, QuadTo, the flattener
Part 7 + ArcTo, AddCircle, AddEllipse, AddRoundRect <- today
Raster.mqh Part 3/4 the scanline fill, with coverage
Part 5 + the fill ruleAfter this article the geometry layer is finished. Everything after it is about colour.
More in this series
Building a real 2D renderer for MetaTrader 5 in pure MQL5 — anti-aliased shapes, transparency and gradients, with no DLLs and no external tools. About this series
- Part 1Why the terminal needs its own 2D-rendererSeptember 3, 2026
- Part 2Points, Contours and the PathSeptember 10, 2026
- Part 3Edges and the First Filled ShapeSeptember 28, 2026
- Part 4Anti-Aliasing, Coverage and CompositingSeptember 28, 2026
- Part 5Fill Rules, Holes and BordersOctober 1, 2026
- Part 6Curves and Adaptive FlatteningOctober 23, 2026
- Part 7Arcs, Circles and Rounded Rectangles — you are hereOctober 27, 2026
Continue reading on MQL5.com
The full article with complete source code is published on MQL5.com.


