GlyphAutoTrace.h header
#include <ew/app/GlyphAutoTrace.h>
Namespace ew::app
TraceBitmap struct
struct ew::app::TraceBitmap
A greyscale bitmap for the tracer to read: width by height samples, row-major, 0 black and 255 white.
Deliberately not an image type. The tracer is geometry, not presentation, and taking a plain buffer keeps it testable without a window system and leaves the desktop free to hand it a photograph, a scan, or a region a user dragged out of one.
Members
int ew::app::script::TraceBitmap::width = 0
Samples across.
int ew::app::script::TraceBitmap::height = 0
Samples down.
std::vector<std::uint8_t> ew::app::script::TraceBitmap::luminance
The samples, row-major, width * height of them.
bool ew::app::script::TraceBitmap::isValid() const
Whether the buffer's size matches its dimensions, so a caller cannot trace a truncated image and get silently wrong geometry from the rows that are missing.
std::uint8_t ew::app::script::TraceBitmap::at(int x, int y) const
The sample at (x, y), or 255 (blank) outside the image – so the edge of the picture behaves like paper rather than like ink.
TraceOptions struct
struct ew::app::TraceOptions
How a bitmap is turned into strokes.
Members
int ew::app::script::TraceOptions::threshold = 128
Samples at or beyond this distance from the paper colour count as ink (0-255).
bool ew::app::script::TraceOptions::inkIsDark = true
Whether the drawing is dark on light. False traces light marks on a dark ground, which is what a photograph of chalk or a negative scan gives.
double ew::app::script::TraceOptions::simplifyTolerance = 0.01
How far, in glyph-box units, a point may sit from the line before it is kept. Larger leaves fewer points.
int ew::app::script::TraceOptions::minimumPoints = 3
Strokes with fewer points than this are dropped, which removes the specks a photograph of paper always has without touching a real mark.
bool ew::app::script::TraceOptions::fitToInk = true
Whether the traced result is scaled so the INK fills the glyph box.
On by default because a photograph is mostly margin: tracing a letter that occupies a tenth of the frame and placing it at a tenth of the box would make every traced glyph tiny and the feature useless. The aspect ratio is kept, so the letter is not stretched.
Functions
std::vector< bool > ew::app::script::inkMask(const TraceBitmap &bitmap, const TraceOptions &options)
bitmap reduced to the samples that are ink, as a mask the size of the image.
Exposed so a preview can show what the threshold selected. A user who cannot see what counts as ink can only adjust the slider by trial.
std::vector< bool > ew::app::script::thinned(const std::vector< bool > &mask, int width, int height)
mask thinned to single-sample centrelines (Zhang-Suen), the same size as the input.
std::vector< ew::core::conlang::Stroke > ew::app::script::traceBitmap(const TraceBitmap &bitmap, const TraceOptions &options)
The strokes bitmap's drawn lines reduce to.
Threshold, thin to single-sample centrelines, trace those into polylines splitting at every junction so a crossing becomes separate strokes rather than one path that doubles back, then simplify. The result is an ordinary editable glyph – a very good first draft, not a final answer, which is the whole point: manual tracing of complex curves is the difference between an afternoon and a week for a user with a page of drawings.