deriveTextPresentationPolicy function
- WidthMeasurements measurements = const WidthMeasurements.empty(),
- Map<
String, String> environment = const <String, String>{},
Folds probe measurements and environment overrides into the one derived
ResolvedTextPresentationPolicy every geometry consumer shares
(RFC 0019 §6.2).
Per axis: an explicit FLEURY_* override wins outright; else agreeing
probe measurements decide; else the spec default stands and the axis is
recorded as WidthDecisionSource.spec — the unknown state, which
conservative consumers treat as "keep the safety net engaged".
Lowering follows RFC 0019 §6.4's two-step authorization: the observation
must be summed for every probed sequence (the measured inequality
componentSum ≤ advance ≤ componentSum + zwjCount), AND the width policy
must predict every measured component — otherwise splitting would trade
the joiner error for a component near-miss, so the action stays
ClusterLowering.preserve and the pin covers the sequence. A confidently
joined observation also records probe provenance: "this terminal
clusters" is evidence, not a default.
Implementation
ResolvedTextPresentationPolicy deriveTextPresentationPolicy({
WidthMeasurements measurements = const WidthMeasurements.empty(),
Map<String, String> environment = const <String, String>{},
}) {
final decisions = <WidthAxis, WidthDecisionSource>{};
CellWidth? agreement(WidthProbeClass probeClass) {
final widths = measurements.widthsIn(probeClass);
if (widths.isEmpty || widths.any((w) => w == null)) return null;
if (widths.every((w) => w == 1)) return CellWidth.one;
if (widths.every((w) => w! >= 2)) return CellWidth.two;
return null; // Disagreement — unknown, never a guess.
}
CellWidth resolveAxis(
WidthAxis axis,
CellWidth? override,
WidthProbeClass probeClass,
CellWidth specDefault,
) {
if (override != null) {
decisions[axis] = WidthDecisionSource.environment;
return override;
}
final measured = agreement(probeClass);
if (measured != null) {
decisions[axis] = WidthDecisionSource.probe;
return measured;
}
return specDefault;
}
final ambiguousOverride = switch (detectAmbiguousCharWidthFromEnvironment(
environment,
)) {
AmbiguousCharWidth.narrow => CellWidth.one,
AmbiguousCharWidth.wide => CellWidth.two,
null => null,
};
final widths = CellWidthPolicy(
ambiguous: resolveAxis(
WidthAxis.ambiguous,
ambiguousOverride,
WidthProbeClass.ambiguous,
CellWidth.one,
),
emojiPresentation: resolveAxis(
WidthAxis.emojiPresentation,
detectEmojiWidthFromEnvironment(environment),
WidthProbeClass.emojiPresentation,
CellWidth.two,
),
emojiVariationSequence: resolveAxis(
WidthAxis.emojiVariationSequence,
detectVs16WidthFromEnvironment(environment),
WidthProbeClass.emojiVariationSequence,
CellWidth.two,
),
);
var lowering = ClusterLowering.preserve;
final loweringOverride = detectClusterModeFromEnvironment(environment);
if (loweringOverride != null) {
lowering = loweringOverride;
decisions[WidthAxis.lowering] = WidthDecisionSource.environment;
} else {
final derived = _deriveLowering(measurements, widths);
if (derived != null) {
lowering = derived;
decisions[WidthAxis.lowering] = WidthDecisionSource.probe;
}
}
return ResolvedTextPresentationPolicy(
policy: TextPresentationPolicy(widths: widths, lowering: lowering),
decisions: Map.unmodifiable(decisions),
);
}