about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-07-27 18:18:08 +0200
committerbptato <nincsnevem662@gmail.com>2023-07-27 18:23:28 +0200
commit7e95c6cd3de5408c6090cef346fbe32d429ead21 (patch)
treee28af6b04ea3da0ee711bfb553a6a278a812a192 /src
parent4c0d69b01d20e30439c3e46c19a9af2e633c5681 (diff)
downloadchawan-7e95c6cd3de5408c6090cef346fbe32d429ead21.tar.gz
layout: distinguish padding from spacing
Re-consideration of 1e0506adb: we do need to explicitly specify padding
after all, so the rendering engine knows of it too.
Diffstat (limited to 'src')
-rw-r--r--src/layout/box.nim3
-rw-r--r--src/layout/engine.nim25
2 files changed, 23 insertions, 5 deletions
diff --git a/src/layout/box.nim b/src/layout/box.nim
index 2bee81ad..190313b9 100644
--- a/src/layout/box.nim
+++ b/src/layout/box.nim
@@ -91,6 +91,9 @@ type
   InlineSpacing* = ref object of InlineAtom
     format*: ComputedFormat
 
+  # Treated exactly the same as InlineSpacing, except it signifies padding.
+  InlinePadding* = ref object of InlineSpacing
+
   InlineWord* = ref object of InlineAtom
     str*: string
     format*: ComputedFormat
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index 4fa61dff..b8b787b7 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -76,12 +76,15 @@ func cellheight(viewport: Viewport): LayoutUnit =
 func cellheight(ictx: InlineContext): LayoutUnit =
   ictx.viewport.cellheight
 
+func hasLastSpacing(ictx: InlineContext): bool =
+  return ictx.currentLine.atoms[^1] of InlineSpacing and
+    not (ictx.currentLine.atoms[^1] of InlinePadding)
+
 # Whitespace between words
 func computeShift(ictx: InlineContext, computed: CSSComputedValues):
     LayoutUnit =
   if ictx.whitespacenum > 0:
-    if ictx.currentLine.atoms.len > 0 and
-        not (ictx.currentLine.atoms[^1] of InlineSpacing) or
+    if ictx.currentLine.atoms.len > 0 and not ictx.hasLastSpacing() or
         computed.whitespacepre:
       let spacing = computed{"word-spacing"}
       if spacing.auto:
@@ -245,6 +248,13 @@ proc verticalAlignLine(ictx: InlineContext) =
   line.height += margin_top
   line.height += margin_bottom
 
+proc addPadding(line: LineBox, width, height: LayoutUnit,
+    format: ComputedFormat) =
+  let padding = InlinePadding(width: width, height: height, baseline: height, format: format)
+  padding.offset.x = line.width
+  line.width += width
+  line.atoms.add(padding)
+
 proc addSpacing(line: LineBox, width, height: LayoutUnit,
     format: ComputedFormat, hang = false) =
   let spacing = InlineSpacing(width: width, height: height, baseline: height, format: format)
@@ -892,9 +902,11 @@ proc buildInline(ictx: InlineContext, box: InlineBoxBuilder) =
 
     let padding_left = box.computed{"padding-left"}.px(ictx.viewport,
       ictx.availableWidth)
-    # Padding should not be treated as whitespace, so we just increase line
-    # width instead of adding fake spacing.
-    ictx.currentLine.width += padding_left
+    if padding_left > 0:
+      # We must add spacing to the line to make sure that it is formatted
+      # appropriately.
+      # We need this so long as we have no proper inline boxes.
+      ictx.currentLine.addPadding(padding_left, ictx.cellheight, paddingformat)
 
   assert not (box.children.len > 0 and box.text.len > 0)
   for text in box.text:
@@ -921,6 +933,9 @@ proc buildInline(ictx: InlineContext, box: InlineBoxBuilder) =
     # Padding should not be treated as whitespace, so we just increase line
     # width instead of adding fake spacing.
     ictx.currentLine.width += padding_right
+    if padding_right > 0:
+      ictx.currentLine.addPadding(padding_right,
+        max(ictx.currentLine.height, 1), paddingformat)
     let margin_right = box.computed{"margin-right"}.px(ictx.viewport,
       ictx.availableWidth)
     ictx.currentLine.width += margin_right