about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-11-24 14:04:51 +0100
committerbptato <nincsnevem662@gmail.com>2024-11-24 14:07:59 +0100
commitb445b3a54a471b98e59545b6416eee9484f6d945 (patch)
tree464b970a3979d4ec4e275674c5612e2021f4d9a8 /src
parentdf2e58dd2ccf4140a368acf21a83e6efb2f8d9ac (diff)
downloadchawan-b445b3a54a471b98e59545b6416eee9484f6d945.tar.gz
layout: fix intrinsic min width for words with wrapping opportunities
This broke CJK combined with table layouts.

(Inline layout's state dependencies between procs are getting a bit
scary...)
Diffstat (limited to 'src')
-rw-r--r--src/css/layout.nim29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/css/layout.nim b/src/css/layout.nim
index 5ad9cce6..b48bee57 100644
--- a/src/css/layout.nim
+++ b/src/css/layout.nim
@@ -619,14 +619,6 @@ proc finishLine(ictx: var InlineContext; state: var InlineState; wrap: bool;
     ictx.lbstate = LineBoxState(offsety: y + ictx.lbstate.size.h)
     ictx.initLine()
 
-func xminwidth(atom: InlineAtom): LayoutUnit =
-  if atom.t == iatInlineBlock:
-    return atom.innerbox.state.xminwidth
-  elif atom.t == iatImage:
-    # We calculate this in addInlineImage instead.
-    return 0
-  return atom.size.w
-
 func shouldWrap(ictx: InlineContext; w: LayoutUnit;
     pcomputed: CSSComputedValues): bool =
   if pcomputed != nil and pcomputed.nowrap:
@@ -679,8 +671,18 @@ proc addAtom(ictx: var InlineContext; state: var InlineState;
   if atom.size.w > 0 and atom.size.h > 0 or atom.t == iatInlineBlock:
     if shift > 0:
       ictx.addSpacing(shift, state)
-    ictx.state.xminwidth = max(ictx.state.xminwidth, atom.xminwidth)
-    if atom.t == iatWord:
+    case atom.t
+    of iatWord:
+      if ictx.wrappos != -1:
+        # set xminwidth to the first wrapping opportunity
+        ictx.state.xminwidth = max(ictx.state.xminwidth, ictx.wrappos)
+      elif state.prevrw == 2:
+        # last char was double width; we can wrap anywhere.
+        # (I think this isn't quite right when double width + half width
+        # are mixed, but whatever...)
+        ictx.state.xminwidth = max(ictx.state.xminwidth, 2)
+      else:
+        ictx.state.xminwidth = max(ictx.state.xminwidth, atom.size.w)
       if ictx.lbstate.atoms.len > 0 and state.fragment.state.atoms.len > 0:
         let oatom = ictx.lbstate.atoms[^1]
         if oatom.t == iatWord and oatom == state.fragment.state.atoms[^1]:
@@ -688,7 +690,12 @@ proc addAtom(ictx: var InlineContext; state: var InlineState;
           oatom.size.w += atom.size.w
           ictx.lbstate.size.w += atom.size.w
           return
-    else:
+    of iatInlineBlock:
+      ictx.state.xminwidth = max(ictx.state.xminwidth,
+        atom.innerbox.state.xminwidth)
+      ictx.lbstate.charwidth = 0
+    of iatImage:
+      # We calculate xminwidth in addInlineImage instead.
       ictx.lbstate.charwidth = 0
     ictx.lbstate.putAtom(atom, iastate, state.fragment)
     atom.offset.x += ictx.lbstate.size.w