Articulation.h header

#include <ew/core/Articulation.h>

Namespace ew::core

ArticulationChannel struct

struct ew::core::ArticulationChannel

One articulatory channel: something about the sound, plotted as a free 2D path.

A PATH, not a function of time. The distinction is the single most important correction from prototyping: a value-over-time graph can only rise and fall, so every channel looks alike and the glyphs derived from them come out flat and near-identical. A free path can double back on itself – a breath that draws in before pushing out – and can close into a shape, because a mouth that rounds is an oval and not a height.

Members

QString ew::core::conlang::ArticulationChannel::name

What this channel tracks (e.g. "breath", "tongue", "aperture"). User-defined: four is not a magic number, and a whistled or signed language wants different ones entirely.

QString ew::core::conlang::ArticulationChannel::colour

The colour to draw it in while deriving, so the user can see which line is which.

std::vector<StrokePoint> ew::core::conlang::ArticulationChannel::path

The path, in glyph-box coordinates.

bool ew::core::conlang::ArticulationChannel::closed = false

Whether the path closes back on itself.

std::vector<ArticulationMark> ew::core::conlang::ArticulationChannel::marks

The qualitative marks laid along it.

bool ew::core::conlang::ArticulationChannel::operator==(const ArticulationChannel &other) const =default

Value equality over all fields.

ArticulationMark struct

struct ew::core::ArticulationMark

One qualitative mark on a stretch of a channel.

Members

ArticulationMarkKind ew::core::conlang::ArticulationMark::kind =

What the mark is.

double ew::core::conlang::ArticulationMark::from = 0.0

Where the stretch begins, 0..1 along the channel.

double ew::core::conlang::ArticulationMark::to = 1.0

Where it ends, 0..1 along the channel.

double ew::core::conlang::ArticulationMark::amount = 0.05

How strongly it deforms the path, as a fraction of the glyph box.

bool ew::core::conlang::ArticulationMark::operator==(const ArticulationMark &other) const =default

Value equality over all fields.

GlyphArticulation struct

struct ew::core::GlyphArticulation

The articulation a glyph was derived from: the channels, how the route was walked, and whether it was anchored.

Kept with the script and saved with it. The prototype this comes from lost an afternoon of work because it persisted the generator's inputs and the drawn glyphs separately, and the save path covered only one of them – so the rule here is that the whole model travels together.

Members

QString ew::core::conlang::GlyphArticulation::glyphName

The glyph this derives, by Glyph::name.

std::vector<ArticulationChannel> ew::core::conlang::GlyphArticulation::channels

The channels, in drawing order.

RouteStrategy ew::core::conlang::GlyphArticulation::strategy =

How the route is walked through the nodes.

bool ew::core::conlang::GlyphArticulation::anchored = false

Whether the route starts and ends at fixed anchors rather than at whichever node happens to be first, so every glyph of the script begins and ends in the same places and a connected script joins.

StrokePoint ew::core::conlang::GlyphArticulation::startAnchor {.x = 0.0, .y = 1.0, .pressure = 1.0, .corner = false}

Where an anchored route starts.

StrokePoint ew::core::conlang::GlyphArticulation::endAnchor {.x = 1.0, .y = 1.0, .pressure = 1.0, .corner = false}

Where an anchored route ends.

bool ew::core::conlang::GlyphArticulation::operator==(const GlyphArticulation &other) const =default

Value equality over all fields.

Enumerations

enum class ArticulationMarkKind { Ripple, Jagged, Split, Break, Circle }

A qualitative feature laid along a stretch of an articulation channel.

These are what make otherwise-similar sounds produce genuinely different letterforms. Two phonemes differing only in voicing trace nearly the same paths, so the glyphs derived from them would be nearly the same shape; a mark changes the GEOMETRY that gets intersected, so a ripple on one of them yields a different set of crossings and a different letter. A ring struck on a line crosses its neighbours four times where the bare line crossed twice.

Serialized as a stable lowercase token, and deliberately open: a language modelling something the five below cannot say needs a sixth, and the set is expected to grow.

enum class RouteStrategy { NearestUnclaimed, ByTime, ConvexOrder }

How the route is walked through the nodes.

Functions

std::optional< ArticulationMarkKind > ew::core::conlang::articulationMarkKindFromToken(QStringView token)

Parses an articulation mark kind from its token; std::nullopt if unrecognized.

std::optional< RouteStrategy > ew::core::conlang::routeStrategyFromToken(QStringView token)

Parses a route strategy from its token; std::nullopt if unrecognized.

QString ew::core::conlang::toToken(ArticulationMarkKind kind)

The stable serialization token for kind (e.g. "ripple").

QString ew::core::conlang::toToken(RouteStrategy strategy)

The stable serialization token for strategy (e.g. "nearest").