Part 3 of 4

Creating a Cairo-Inspired Graphics Library for MetaTrader 5 (Part 3): Edges and the First Filled Shape

Creating a Cairo-Inspired Graphics Library for MetaTrader 5 (Part 3): Edges and the First Filled Shape

Why this article was written

Part 2 gave every shape the same description: points, grouped into contours, stored as one path. A rectangle, a star and a font glyph all came out as the same kind of data. What none of them could do was appear on screen.

Part 3 is where the library draws something for the first time. It takes a path and fills it — any path, however many contours, with holes where holes belong — using a single routine that does not know or care what shape it was handed.

What is inside

Scan conversion. The problem is turning a mathematical outline into a grid of pixels. The answer is sixty years old and still what everything uses: take one horizontal row at a time, find where the outline crosses that row, and paint between the crossings.

The edge. A segment stored in the form the question actually needs — top-y, bottom-y, top-x and a slope. Asking where does this cross row N then costs one multiply and one add, instead of re-deriving the line every time.

The winding number. Why alternating inside/outside — the even-odd rule — is not enough, and what counting directional crossings buys instead: shapes that overlap themselves, and holes that are holes because their contour runs the other way around.

The rasterizer, in four steps. Contours to edges; which rows the shape touches; the crossings on each row, sorted by x; then the winding number tracked across the row while the interior stretches are painted.

Vertex ambiguity. What happens when a row passes exactly through a vertex, and why half-open intervals fix the double count without a special case.

The demo. Six shapes from a rectangle to a 300-sided polygon and a letter, overlapping squares that show the winding rule doing its job, a staircase pattern that shows what is still missing, and a 2,000-edge flower for timing.

An honest note on scope

The rasterizer in this part takes one vertical sample per row, overwrites pixels instead of blending them, and implements only the non-zero fill rule. Diagonal edges come out as visible staircases.

None of that is an oversight. Each one is a separate idea that earns its own treatment: anti-aliasing and compositing arrive in Part 4, fill rules after that.

State of the library after this part:

MQL5
Color.mqh      Part 1    the ARGB color type, uint 0xAARRGGBB
Surface.mqh    Part 1    a pixel buffer bound to one chart object
Path.mqh       Part 2    points, contours, MoveTo / LineTo / Close
Raster.mqh     Part 3    edges, winding, the first filled shape   <- today

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

  1. Part 1Why the terminal needs its own 2D-rendererSeptember 3, 2026
  2. Part 2Points, Contours and the PathSeptember 10, 2026
  3. Part 3Edges and the First Filled Shape — you are hereSeptember 28, 2026
  4. Part 4Anti-Aliasing, Coverage and CompositingSeptember 28, 2026

Continue reading on MQL5.com

The full article with complete source code is published on MQL5.com.

Read the full article