diff options
-rw-r--r-- | src/io/buffer.nim | 67 | ||||
-rw-r--r-- | src/io/cell.nim | 15 | ||||
-rw-r--r-- | src/layout/engine.nim | 12 |
3 files changed, 47 insertions, 47 deletions
diff --git a/src/io/buffer.nim b/src/io/buffer.nim index 0dfbf379..7fa926f7 100644 --- a/src/io/buffer.nim +++ b/src/io/buffer.nim @@ -129,10 +129,6 @@ func numLines*(buffer: Buffer): int = buffer.lines.len func lastVisibleLine*(buffer: Buffer): int = min(buffer.fromy + buffer.height, buffer.numLines) -func width(line: seq[FlexibleCell]): int = - for c in line: - result += c.rune.width() - func acursorx(buffer: Buffer): int = return max(0, buffer.cursorx - buffer.fromx) @@ -186,7 +182,7 @@ func canScroll*(buffer: Buffer): bool = return buffer.numLines >= buffer.height proc addLine(buffer: Buffer) = - buffer.lines.add(newSeq[FlexibleCell]()) + buffer.lines.addLine() proc clearText*(buffer: Buffer) = buffer.lines.setLen(0) @@ -454,26 +450,34 @@ proc halfPageDown*(buffer: Buffer) = buffer.restoreCursorX() proc pageUp*(buffer: Buffer) = - buffer.cursory = max(buffer.cursory - buffer.height + 1, 1) - buffer.fromy = max(0, buffer.fromy - buffer.height) - buffer.redraw = true + buffer.cursory = max(buffer.cursory - buffer.height, 0) + let nfy = max(0, buffer.fromy - buffer.height) + if nfy != buffer.fromy: + buffer.fromy = nfy + buffer.redraw = true buffer.restoreCursorX() proc pageDown*(buffer: Buffer) = - buffer.cursory = min(buffer.cursory + buffer.height div 2 - 1, buffer.numLines - 1) - buffer.fromy = min(max(buffer.numLines - buffer.height, 0), buffer.fromy + buffer.height div 2) - buffer.redraw = true + buffer.cursory = min(buffer.cursory + buffer.height, buffer.numLines - 1) + let nfy = min(buffer.fromy + buffer.height, max(buffer.numLines - buffer.height, 0)) + if nfy != buffer.fromy: + buffer.fromy = nfy + buffer.redraw = true buffer.restoreCursorX() proc pageLeft*(buffer: Buffer) = buffer.cursorx = max(buffer.cursorx - buffer.width, 0) - buffer.fromx = max(0, buffer.fromx - buffer.width) - buffer.redraw = true + let nfx = max(0, buffer.fromx - buffer.width) + if nfx != buffer.fromx: + buffer.fromx = nfx + buffer.redraw = true proc pageRight*(buffer: Buffer) = buffer.cursorx = min(buffer.fromx, buffer.currentLineWidth()) - buffer.fromx = min(max(buffer.maxScreenWidth() - buffer.width, 0), buffer.fromx + buffer.width) - buffer.redraw = true + let nfx = min(max(buffer.maxScreenWidth() - buffer.width, 0), buffer.fromx + buffer.width) + if nfx != buffer.fromx: + buffer.fromx = nfx + buffer.redraw = true proc scrollDown*(buffer: Buffer) = if buffer.fromy + buffer.height < buffer.numLines: @@ -532,22 +536,6 @@ proc refreshTermAttrs*(buffer: Buffer): bool = proc setText*(buffer: Buffer, x: int, y: int, text: seq[Rune]) = buffer.lines.setText(x, y, text) -proc setLine*(buffer: Buffer, x: int, y: int, line: FlexibleLine) = - while buffer.lines.len <= y: - buffer.addLine() - - var i = 0 - var cx = 0 - while cx < x and i < buffer.lines[y].len: - cx += buffer.lines[y][i].rune.width() - inc i - - buffer.lines[y].setLen(i) - i = 0 - while i < line.len: - buffer.lines[y].add(line[i]) - inc i - func formatFromLine(line: CSSRowBox): Formatting = result.fgcolor = line.color.cellColor() if line.fontstyle in { FONT_STYLE_ITALIC, FONT_STYLE_OBLIQUE }: @@ -561,11 +549,6 @@ func formatFromLine(line: CSSRowBox): Formatting = if line.textdecoration == TEXT_DECORATION_LINE_THROUGH: result.strike = true -func cellFromLine(line: CSSRowBox, i: int, format: Formatting): FlexibleCell = - result.rune = line.runes[i] - result.formatting = format - result.nodes = line.nodes - proc setRowBox(buffer: Buffer, line: CSSRowBox) = if line.runes.len == 0: return @@ -590,11 +573,11 @@ proc setRowBox(buffer: Buffer, line: CSSRowBox) = #TODO not sure while nx < x: - buffer.lines[y].add(FlexibleCell(rune: Rune(' '))) + buffer.lines.addCell(y, Rune(' ')) inc nx while j < line.runes.len: - buffer.lines[y].add(line.cellFromLine(j, format)) + buffer.lines.addCell(y, line.runes[j], format, line.nodes) nx += line.runes[j].width() inc j @@ -659,17 +642,17 @@ proc renderPlainText*(buffer: Buffer, text: string) = inc i elif text[i] == '\t': for i in 0..8: - buffer.lines[^1].add(FlexibleCell(rune: Rune(' '), formatting: format)) + buffer.lines.addCell(Rune(' '), format) inc i elif text[i] == '\e': i = format.parseAnsiCode(text, i) elif text[i].isControlChar(): - buffer.lines[^1].add(FlexibleCell(rune: Rune('^'), formatting: format)) - buffer.lines[^1].add(FlexibleCell(rune: Rune(text[i].getControlLetter()), formatting: format)) + buffer.lines.addCell(Rune('^'), format) + buffer.lines.addCell(Rune(text[i].getControlLetter()), format) inc i else: fastRuneAt(text, i, r) - buffer.lines[^1].add(FlexibleCell(rune: r, formatting: format)) + buffer.lines.addCell(r, format) buffer.updateCursor() proc renderDocument*(buffer: Buffer) = diff --git a/src/io/cell.nim b/src/io/cell.nim index d757c2de..e1b2aef4 100644 --- a/src/io/cell.nim +++ b/src/io/cell.nim @@ -46,6 +46,21 @@ func width*(cell: FixedCell): int = func newFormatting*(): Formatting = return Formatting(fgcolor: defaultColor, bgcolor: defaultColor) +proc addLine*(grid: var FlexibleGrid) = + grid.add(newSeq[FlexibleCell]()) + +proc addCell*(grid: var FlexibleGrid, y: int, r: Rune) = + grid[y].add(FlexibleCell(rune: r)) + +proc addCell*(grid: var FlexibleGrid, y: int, r: Rune, format: Formatting) = + grid[y].add(FlexibleCell(rune: r, formatting: format)) + +proc addCell*(grid: var FlexibleGrid, y: int, r: Rune, format: Formatting, nodes: seq[Node]) = + grid[y].add(FlexibleCell(rune: r, formatting: format, nodes: nodes)) + +proc addCell*(grid: var FlexibleGrid, r: Rune, format: Formatting) = + grid[^1].add(FlexibleCell(rune: r, formatting: format)) + proc setText*(grid: var FlexibleGrid, x: int, y: int, text: seq[Rune]) = while grid.len <= y: grid.add(newSeq[FlexibleCell]()) diff --git a/src/layout/engine.nim b/src/layout/engine.nim index 7b82cdf9..17cce41c 100644 --- a/src/layout/engine.nim +++ b/src/layout/engine.nim @@ -84,11 +84,9 @@ proc processInlineBox(parent: CSSBox, str: string): CSSBox = rowbox.setup(ibox.cssvalues, ibox.bcontext.nodes) var r: Rune while i < str.len: - fastRuneAt(str, i, r) - if rowbox.width + r.width() > ibox.width: - inlineWrap(ibox, rowi, fromx, rowbox) - if r != Rune(0x00A0) and #NBSP - r.isWhitespace(): + case str[i] + of ' ', '\n', '\t': + inc i let wsr = ibox.cssvalues[PROPERTY_WHITESPACE].whitespace if ibox.context.whitespace: if ibox.context.ws_initial: @@ -114,6 +112,10 @@ proc processInlineBox(parent: CSSBox, str: string): CSSBox = ibox.context.whitespace = false else: ibox.context.whitespace = false + fastRuneAt(str, i, r) + if rowbox.width + r.width() > ibox.width: + inlineWrap(ibox, rowi, fromx, rowbox) + rowbox.width += r.width() rowbox.runes.add(r) if rowbox.runes.len > 0: |