Files
eepp/bin/unit_tests/assets/html/background_atlas.html
Martín Lucas Golini e94550a049 ui: Full HTML background property support + whitespace collapsing rewrite
Part 1: CSS background properties (UINodeDrawable, LayerDrawable)
Add `BackgroundMode` (Native / Html) to `UINodeDrawable`. When Html mode
is active, background rendering follows CSS/HTML semantics (repeat defaults
to repeat, clip plane always enabled, etc.). Native mode preserves the
original eepp behavior (no-repeat by default, clip only when repeating).
Add per-layer `background-origin`, `background-clip`, `background-attachment`
with `fromText` parsers and CSS property registration. `background-origin`
controls the reference box for position/percentage resolution.
`background-clip` enables per-layer content-box clipping.
`background-attachment: fixed` anchors the background to the scene root;
`local` is stubbed (needs per-widget scroll offset plumbing).
Replace the single `Repeat` enum with `RepeatX` / `RepeatY` enums supporting
two-value repeat (e.g. "repeat no-repeat", "space round"). Implement space
and round repeat rendering in `LayerDrawable::draw()`.
Fix `background-size: contain` to scale up (not just down) like HTML.
Rewrite the comma-separated multi-layer `background` shorthand parser with
`/size` separator, box keyword disambiguation, and attachment keywords.
UINode::{getBackground} detects `UI_HTML_ELEMENT` flag and lazily sets
`BackgroundMode::Html`.
Add golden image test: 20-tile image atlas via
`background: url(bnp.png) pos / size no-repeat` with browser-comparable HTML.
Part 2: HTML whitespace collapsing (HTMLFormatter → UIRichText)
Move whitespace collapsing from parse time to layout time. Previously
`HTMLFormatter::collapseXmlWhitespace` ran on the pugixml DOM before
CSS was resolved, using tag-name heuristics for inline/block detection.
This caused whitespace between elements with `display: inline-block`
(via CSS) to be incorrectly stripped.
The new pipeline preserves raw whitespace in `UITextNode` widgets (after
internal whitespace collapsing via `UIRichText::collapseInternalWhitespace`)
and defers boundary stripping to `UIRichText::rebuildRichText`, where every
widget's computed `CSSDisplay` is available via `UIWidget::isInlineDisplay()`.
- `UIWidget::isInlineDisplay()` returns true for text nodes and widgets
  with `CSSDisplay::Inline | InlineBlock`, used by boundary logic.
- `UITextNode::isWhitespaceOnly()` identifies collapsible text nodes.
- `findLogicalPrev/Next` walks up through inline ancestors to find the
  correct boundary element, matching HTML's whitespace transparency rule.
- Boundary stripping: leading/trailing spaces removed at block edges,
  preserved between inline-level siblings.
- Double-space prevention: when adding text that starts with a space,
  peeks at the last `SpanBlock` in RichText if it ends with a space,
  the leading space is stripped. This prevents consecutive spaces when
  whitespace nodes are separated by empty inline elements.
- `UITextNode::mLayoutCharCount` syncs the character index between
  `rebuildRichText` (where boundary-stripped text is added) and
  `positionRichTextChildren` (where widgets are mapped to render spans),
  fixing hitbox alignment for all text-bearing widgets.
Remove `HTMLFormatter::collapseXmlWhitespace`, `isInlineNode`,
`hasSignificantText`, `getLogicalPrev`, `getLogicalNext`, and the
`precomputeDisplayStyles` hack (~200 lines removed). `HTMLFormatter`
now only exposes `HTMLtoXML`.
Other fixes
- Remove `@import url(https://fonts.googleapis.com/css?family=Lato)`
  from ensoft.css (async HTTP use-after-free in test suite).
- `BlockLayouter::positionRichTextChildren` skips whitespace-only text
  nodes when advancing the character index.
- Fix in DrawableSearcher not finding already loaded textures.
2026-05-08 22:13:07 -03:00

30 lines
2.5 KiB
HTML

<!DOCTYPE html>
<html>
<head><style>
body { margin:0; padding:0; background:white; }
.tile { display:inline-block; width:32px; height:32px; }
</style></head>
<body>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) 0px 0px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -33px 0px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -66px 0px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -99px 0px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -132px 0px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) 0px -33px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -33px -33px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -66px -33px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -99px -33px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -132px -33px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) 0px -66px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -33px -66px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -66px -66px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -99px -66px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -132px -66px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) 0px -99px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -33px -99px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -66px -99px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -99px -99px / 1024px 512px no-repeat;"></div>
<div class="tile" style="background: url(../../../assets/atlases/bnb.png) -132px -99px / 1024px 512px no-repeat;"></div>
</body>
</html>