react-x11 2.22.7 → 2.22.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -318,13 +318,22 @@ export class NodePaint {
318
318
  return false;
319
319
  }
320
320
 
321
- _paintChildren(ctx) {
321
+ /**
322
+ * The children, in paint order — or those up to and including `upTo`: an
323
+ * X11 pane over a `<glarea>` holds its own child and what is under it,
324
+ * never what is over it (src/gloverlay.js, `_paintPane`).
325
+ */
326
+ _paintChildren(ctx, upTo = null) {
322
327
  // A retained presenter replays a node's `paint` into a visual of that
323
328
  // node's own — its children have visuals of their own, so it sets this
324
329
  // for the duration of the call (src/cocoa/presenter.js, `paintSelf`).
325
330
  // Never set on the X11 or surface paths, where a frame is one walk.
326
331
  if (this._ownPaintOnly) return;
327
- const order = this.paintOrder();
332
+ let order = this.paintOrder();
333
+ if (upTo !== null) {
334
+ const at = order.indexOf(upTo);
335
+ if (at !== -1) order = order.slice(0, at + 1);
336
+ }
328
337
  if (order.length === 0) return;
329
338
  if (!this.clipsChildren()) {
330
339
  this._paintChildList(ctx, order);
package/src/nodes/text.js CHANGED
@@ -56,21 +56,6 @@ const textStripBelowFor = (app) =>
56
56
  ? textStripBelowEnv
57
57
  : TEXT_STRIP_BELOW);
58
58
 
59
- /**
60
- * Downward shift that recreates CSS "half-leading". ntk's TextLayout puts
61
- * the first baseline at exactly `ascent` and packs each line's leading
62
- * (font line gap + any lineHeight surplus) entirely *below* the glyphs, so
63
- * a layout drawn at the top of its measured box rides visually high —
64
- * most noticeable centered in buttons/inputs (fonts like Helvetica carry a
65
- * 0.5em line gap). CSS instead splits that leading evenly above and below
66
- * the ink (see seek-oss capsize for the metrics background).
67
- */
68
- function halfLeading(layout) {
69
- const last = layout.lines?.[layout.lines.length - 1];
70
- if (!last) return 0;
71
- return Math.max(0, (layout.height - (last.baseline + last.descent)) / 2);
72
- }
73
-
74
59
  /** A selected line with nothing on it still shows, so a blank line inside a
75
60
  * selection does not read as the highlight having stopped. */
76
61
  const EMPTY_LINE_BAND = 4;
@@ -469,9 +454,10 @@ export class TextNode extends Node {
469
454
  * ever optically even by luck. `lineHeight` cannot fix it: it scales the
470
455
  * box and the leading still splits evenly, so it moves both edges alike.
471
456
  *
472
- * Measured in the coordinates the layout is **drawn** in, not the ones it
473
- * reports: `halfLeading` shifts it, and deriving the baseline from the
474
- * metrics again would silently disagree the day that shift changes.
457
+ * Measured from the baselines the layout reports, which are where it
458
+ * draws them: the engine splits a line's leading above and below the
459
+ * glyphs, and deriving the baseline from the metrics again would silently
460
+ * disagree with it.
475
461
  *
476
462
  * The amounts are fractions of a pixel and stay that way — the glyphs are
477
463
  * placed from them (`_placedLayout`). What must not stay fractional is the
@@ -505,9 +491,8 @@ export class TextNode extends Node {
505
491
  // one backend and half-covers two rows on the other. Rounded, the
506
492
  // baseline sits on a pixel wherever the box does.
507
493
  const capHeight = Math.round(measured);
508
- const shift = halfLeading(layout);
509
- const firstBaseline = shift + lines[0].baseline;
510
- const lastBaseline = shift + lines[lines.length - 1].baseline;
494
+ const firstBaseline = lines[0].baseline;
495
+ const lastBaseline = lines[lines.length - 1].baseline;
511
496
  return {
512
497
  top: Math.max(0, firstBaseline - capHeight),
513
498
  bottom: Math.max(0, Math.ceil(layout.height) - lastBaseline),
@@ -530,7 +515,7 @@ export class TextNode extends Node {
530
515
  return {
531
516
  layout,
532
517
  x: content.x,
533
- y: content.y + halfLeading(layout) - (trim ? trim.top : 0),
518
+ y: content.y - (trim ? trim.top : 0),
534
519
  };
535
520
  }
536
521
 
@@ -618,15 +618,14 @@ export class TextInputNode extends Node {
618
618
  * it fills. Centred on the **capitals**, not on the line box and not on
619
619
  * the ink.
620
620
  *
621
- * The layout box carries the line's leading entirely below the glyphs, so
622
- * centring that pushes the text visually up (see `halfLeading`). Centring
623
- * ascent + descent — what this did — fixes the leading but not the
624
- * asymmetry underneath it: a font's ascent clears its capitals by
625
- * `ascent - capHeight`, which is not its descent, so a single line of
626
- * text sits off-centre by a number that belongs to the typeface. At 14px
627
- * that is 0.7px of extra space above the capitals in SF NS and 2.5px the
628
- * other way in Helvetica — visible in a field, where there is one short
629
- * line and a border close on both sides to measure it against.
621
+ * Centring the line box centres its ascent + descent, because the engine
622
+ * splits the leading evenly round them, and that is not enough: a font's
623
+ * ascent clears its capitals by `ascent - capHeight`, which is not its
624
+ * descent, so a single line of text sits off-centre by a number that
625
+ * belongs to the typeface. At 14px that is 0.7px of extra space above the
626
+ * capitals in SF NS and 2.5px the other way in Helvetica — visible in a
627
+ * field, where there is one short line and a border close on both sides
628
+ * to measure it against.
630
629
  *
631
630
  * So: put the baseline where the space above the capitals equals the
632
631
  * space under it. A `<text>` says the same thing as `textBoxTrim`, but a
@@ -486,9 +486,9 @@ export class Win32FontManager {
486
486
  );
487
487
  }
488
488
 
489
- // `descent` is what halfLeading() in nodes/text.js subtracts to recreate
490
- // CSS half-leading, and DirectWrite reports a baseline and a height per
491
- // line rather than a descent.
489
+ // Every engine answers a descent per line — a field and the edit menu
490
+ // measure a line's ink as its ascent plus its descent — and DirectWrite
491
+ // reports a baseline and a height per line rather than a descent.
492
492
  const lines = (raw.lines ?? []).map((line) => ({
493
493
  ...line,
494
494
  descent: Math.max(0, line.height - line.baseline),