╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │784 first = false; │ │785 } │ │786 │ │787 - try appendEscapedHtml(allocator, output, if (covered_by_scroll) " " else (cell.rune orelse " ")); │ │787 + if (covered_by_scroll) { │ │788 + try appendEscapedHtml(allocator, output, " "); │ │789 + } else if (cell.continuation) { │ │790 + // the wide rune to the left was emitted 2ch wide, covering this column │ │791 + } else if (cell.rune) |rune| { │ │792 + // a double-width rune is pinned inside a 2ch span so the │ │793 + // fallback glyph's advance width can't shift the rest of the row │ │794 + const wide = x + 1 < grid.size.width and grid.cells.items[try grid.cells.at(.{ y, x + 1 })].continuation;│ │795 + if (wide) { │ │796 + try output.appendSlice(allocator, "<span class=\"w2\">"); │ │797 + try appendEscapedHtml(allocator, output, rune); │ │798 + try output.appendSlice(allocator, "</span>"); │ │799 + } else { │ │800 + try appendEscapedHtml(allocator, output, rune); │ │801 + } │ │802 + } else { │ │803 + try appendEscapedHtml(allocator, output, " "); │ │804 + } │ │805 } │ │806 if (open_tag) |t| try output.appendSlice(allocator, t.closeTag()); │ │807 try output.append(allocator, '\n'); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯