layoutDimension function
The layout of a dimension of kind from world p0 to world p1, in a
group whose local-to-world transform is m, with offset its stored
local offset, on page (spec 11 D6-D8; the plan's Ruling 11-3: the
one layout every caller uses). All in world, computed relative to p0
(a far origin costs nothing beyond the points' own rounding):
u= measuringDirection,n = (−u.y, u.x); the value is|p1 − p0|for aligned and|(p1 − p0) · u|for a linear kind;h0 = 0,h1 = 0for aligned by definition and(p1 − p0) · nfor a linear kind;- the line at height
c = hi + owhenoffset's sign bit is clear andlo + owhen it is set (R-2),o = offset · m.scaleMagnitude: from the outermost measured point on the line's side (R-6);Q0 = p0 + n (c − h0),Q1 = p1 + n (c − h1); - each extension line from
P + σ n · min(g, |c − h|)toQ + σ n · v,σ−1 when the sign bit is set, else +1; - each slash
Q ∓ t,t = normalize(ur + nr) · (slash / 2),ur= readable(u),nr = (−ur.y, ur.x); - the text at
(Q0 + Q1) / 2 + nr · gap, at the world angleatan2(ur.y, ur.x).
Every paper constant is multiplied by page.scaleDenominator here, and
nowhere else.
Null when the dimension cannot be laid out in finite numbers (the one
guard every caller inherits, Ruling 11-3): when the value for kind is
not finite or is above kDimMaxValueMm, or any point, the text's height
or its angle is not finite. The value is checked before it is formatted:
formatDimension formats only a finite value (a non-finite one throws
there) and misprints one above kDimMaxValueMm. This happens for:
- a non-finite end point (an attached wall's
1e999from a file), or a non-finiteoffset; - finite points so far apart that a length overflows: an aligned pair beyond about 1.3e154 mm, where the distance's square does;
- a finite value above kDimMaxValueMm (an aligned pair across a wall 1e20 mm thick);
- a page so large that a paper constant overflows (1:1e308: the text's height, 2.5 × 1e308, is not finite, though the value is 4000).
A linear kind whose component stays finite and small still lays out: a
horizontal dimension between two points 1.5e154 apart along its local y
measures 0 and draws. generate makes no child for null, and D15 reports
the dimension dimension.broken ("it cannot be laid out in finite
numbers"): a dimension either draws its six children or is broken, never
silently empty (D7).
Implementation
DimLayout? layoutDimension(Vector2 p0, Vector2 p1, DimKind kind, Transform2 m,
double offset, PageComponent page) {
final d = p1 - p0;
final u = measuringDirection(kind, p0, p1, m);
final n = Vector2(-u.y, u.x);
final value = kind == DimKind.aligned ? d.length : d.dot(u).abs();
const h0 = 0.0;
final h1 = kind == DimKind.aligned ? 0.0 : d.dot(n);
final hi = math.max(h0, h1), lo = math.min(h0, h1);
// The side is the sign bit (R-2): one read, for the line and for σ.
final below = offset.isNegative;
final c = (below ? lo : hi) + offset * m.scaleMagnitude;
final sigma = below ? -1.0 : 1.0;
final scale = page.scaleDenominator;
final g = kDimExtGapPaperMm * scale;
final v = kDimExtOvershootPaperMm * scale;
// Relative to p0.
final r0 = n * (c - h0);
final r1 = d + n * (c - h1);
(Vector2, Vector2) ext(Vector2 r, double h, Vector2 q) => (
p0 + r + n * (sigma * math.min(g, (c - h).abs())),
p0 + q + n * (sigma * v),
);
final ur = readable(u);
final nr = Vector2(-ur.y, ur.x);
final t = (ur + nr).normalized() * (kDimSlashPaperMm * scale / 2);
final textAt = p0 + ((r0 + r1) * 0.5 + nr * (kDimTextGapPaperMm * scale));
final q0 = p0 + r0, q1 = p0 + r1;
final ext0 = ext(Vector2.zero(), h0, r0), ext1 = ext(d, h1, r1);
final slash0 = (q0 - t, q0 + t), slash1 = (q1 - t, q1 + t);
final textAngle = math.atan2(ur.y, ur.x);
final textHeight = kDimTextPaperMm * scale;
bool finite(Vector2 w) => w.x.isFinite && w.y.isFinite;
if (!value.isFinite ||
value > kDimMaxValueMm ||
!textAngle.isFinite ||
!textHeight.isFinite ||
![
q0, q1, ext0.$1, ext0.$2, ext1.$1, ext1.$2, //
slash0.$1, slash0.$2, slash1.$1, slash1.$2, textAt,
].every(finite)) {
return null;
}
return (
value: value,
u: u,
n: n,
q0: q0,
q1: q1,
ext0: ext0,
ext1: ext1,
slash0: slash0,
slash1: slash1,
textAt: textAt,
textAngle: textAngle,
textHeight: textHeight,
text: formatDimension(value, page.displayUnit,
decimalSeparator: page.decimalSeparator),
);
}