about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-02-04 22:25:45 +0100
committerbptato <nincsnevem662@gmail.com>2025-02-04 22:25:45 +0100
commitb0afdb827276f7d8516bf37659172bf8b28cda19 (patch)
tree8eb1a52e0cacf354d76e9a126963cab3956d8d22
parent8af354f43a79953b9207e63e81ff8eb2713b34db (diff)
downloadchawan-b0afdb827276f7d8516bf37659172bf8b28cda19.tar.gz
layout: round out small list-item margins and padding
They can be especially distracting when the rounding error fluctuates
between items.
-rw-r--r--doc/css.md7
-rw-r--r--src/css/layout.nim24
2 files changed, 20 insertions, 11 deletions
diff --git a/doc/css.md b/doc/css.md
index cc82de63..7bb4c20b 100644
--- a/doc/css.md
+++ b/doc/css.md
@@ -153,9 +153,10 @@ as an in-cell offset.
 The lengths `1em` and `1ch` compute to the cell height and cell width
 respectively.
 
-In outer inline boxes (`inline-block`, `inline-flex`), margins and
-padding that are smaller than one cell (on the respective axis) are
-ignored.  This does not apply to blockified inline boxes.
+In outer inline boxes (`inline-block`, `inline-flex`) and `list-item`
+boxes, margins and padding that are smaller than one cell (on the
+respective axis) are ignored.  This does not apply to blockified inline
+boxes.
 
 When calculating clip boxes (`overflow: hidden` or `clip`), the clip
 box's offset is floored, and its size is ceiled to the nearest cell's
diff --git a/src/css/layout.nim b/src/css/layout.nim
index c1c264e6..a578d442 100644
--- a/src/css/layout.nim
+++ b/src/css/layout.nim
@@ -1053,6 +1053,17 @@ proc resolvePadding(lctx: LayoutContext; availableWidth: SizeConstraint;
     )
   ]
 
+proc roundSmallMarginsAndPadding(lctx: LayoutContext;
+    sizes: var ResolvedSizes) =
+  for i, it in sizes.padding.mpairs:
+    let cs = lctx.cellSize[i]
+    it.start = (it.start div cs).toInt.toLUnit * cs
+    it.send = (it.send div cs).toInt.toLUnit * cs
+  for i, it in sizes.margin.mpairs:
+    let cs = lctx.cellSize[i]
+    it.start = (it.start div cs).toInt.toLUnit * cs
+    it.send = (it.send div cs).toInt.toLUnit * cs
+
 func resolvePositioned(lctx: LayoutContext; size: Size;
     computed: CSSValues): RelativeRect =
   # As per standard, vertical percentages refer to the *height*, not the width
@@ -1308,6 +1319,10 @@ proc resolveBlockSizes(lctx: LayoutContext; space: AvailableSpace;
   #TODO parent height should be lctx height in quirks mode for percentage
   # resolution.
   sizes.resolveBlockHeight(space.h, paddingSum[dtVertical], computed, lctx)
+  if computed{"display"} == DisplayListItem:
+    # Eliminate distracting margins and padding here, because
+    # resolveBlockWidth may change them beforehand.
+    lctx.roundSmallMarginsAndPadding(sizes)
   return sizes
 
 proc append(a: var Strut; b: LUnit) =
@@ -1704,14 +1719,7 @@ proc addInlineBlock(fstate: var FlowState; istate: var InlineState;
     box: BlockBox) =
   let lctx = fstate.lctx
   var sizes = lctx.resolveFloatSizes(fstate.space, box.computed)
-  for i, it in sizes.padding.mpairs:
-    let cs = lctx.cellSize[i]
-    it.start = (it.start div cs).toInt.toLUnit * cs
-    it.send = (it.send div cs).toInt.toLUnit * cs
-  for i, it in sizes.margin.mpairs:
-    let cs = lctx.cellSize[i]
-    it.start = (it.start div cs).toInt.toLUnit * cs
-    it.send = (it.send div cs).toInt.toLUnit * cs
+  lctx.roundSmallMarginsAndPadding(sizes)
   lctx.layoutRootBlock(box, sizes.margin.topLeft, sizes)
   # Apply the block box's properties to the atom itself.
   let iastate = InlineAtomState(