( node: Node, scale: number, absLeft: number, absTop: number, )
| 2433 | } |
| 2434 | |
| 2435 | function roundLayout( |
| 2436 | node: Node, |
| 2437 | scale: number, |
| 2438 | absLeft: number, |
| 2439 | absTop: number, |
| 2440 | ): void { |
| 2441 | if (scale === 0) return |
| 2442 | const l = node.layout |
| 2443 | const nodeLeft = l.left |
| 2444 | const nodeTop = l.top |
| 2445 | const nodeWidth = l.width |
| 2446 | const nodeHeight = l.height |
| 2447 | |
| 2448 | const absNodeLeft = absLeft + nodeLeft |
| 2449 | const absNodeTop = absTop + nodeTop |
| 2450 | |
| 2451 | // Upstream YGRoundValueToPixelGrid: text nodes (has measureFunc) floor their |
| 2452 | // positions so wrapped text never starts past its allocated column. Width |
| 2453 | // uses ceil-if-fractional to avoid clipping the last glyph. Non-text nodes |
| 2454 | // use standard round. Matches yoga's PixelGrid.cpp — without this, justify |
| 2455 | // center/space-evenly positions are off-by-one vs WASM and flex-shrink |
| 2456 | // overflow places siblings at the wrong column. |
| 2457 | const isText = node.measureFunc !== null |
| 2458 | l.left = roundValue(nodeLeft, scale, false, isText) |
| 2459 | l.top = roundValue(nodeTop, scale, false, isText) |
| 2460 | |
| 2461 | // Width/height rounded via absolute edges to avoid cumulative drift |
| 2462 | const absRight = absNodeLeft + nodeWidth |
| 2463 | const absBottom = absNodeTop + nodeHeight |
| 2464 | const hasFracW = !isWholeNumber(nodeWidth * scale) |
| 2465 | const hasFracH = !isWholeNumber(nodeHeight * scale) |
| 2466 | l.width = |
| 2467 | roundValue(absRight, scale, isText && hasFracW, isText && !hasFracW) - |
| 2468 | roundValue(absNodeLeft, scale, false, isText) |
| 2469 | l.height = |
| 2470 | roundValue(absBottom, scale, isText && hasFracH, isText && !hasFracH) - |
| 2471 | roundValue(absNodeTop, scale, false, isText) |
| 2472 | |
| 2473 | for (const c of node.children) { |
| 2474 | roundLayout(c, scale, absNodeLeft, absNodeTop) |
| 2475 | } |
| 2476 | } |
| 2477 | |
| 2478 | function isWholeNumber(v: number): boolean { |
| 2479 | const frac = v - Math.floor(v) |
no test coverage detected