Discussing the article: "Creating a Cairo-Inspired Graphics Library for MetaTrader 5 (Part 5): Fill Rules, Holes and Borders"

 

Check out the new article: Creating a Cairo-Inspired Graphics Library for MetaTrader 5 (Part 5): Fill Rules, Holes and Borders.

Part 5 adds a fill rule to the rasterizer and a stroke helper to the path. The engine now supports both non-zero and even-odd fills via a single enum parameter, enabling rings, true borders that do not repaint interiors, and glyph counters. AddThickLine() builds strokes from fills in one path and one pass, preserving uniform opacity at joints and showing why strokes require the non-zero rule.

After Part 4 the engine draws well. The renderer already does a lot: arbitrary outlines are filled with smooth anti-aliased edges and correct alpha compositing, all through a single Fill() path. But it fails when a UI needs an actual empty region inside a shape. That failure is not cosmetic — it breaks common interface elements: frame borders, donuts and gauges, the counters of letters like “A” or “O”, outlined buttons and progress tracks. The practical consequence is worse than a missing feature: callers must encode rendering semantics into vertex order or resort to opaque hacks that paint over whatever lies underneath.

What we need is a small, controllable mechanism that answers one clear question: what does “inside” mean for a given fill? With that choice available at the call site, the same geometry can either produce a solid union or guaranteed holes, and strokes can be built from fills without introducing seams or double-compositing artifacts. This article shows how to add that capability with a minimal API change and why the fill-rule choice is the right lever for both holes and stroking-by-fill.


Author: Sandro Begashvili