diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/css/cascade.nim | 5 | ||||
-rw-r--r-- | src/css/values.nim | 14 | ||||
-rw-r--r-- | src/display/term.nim | 13 | ||||
-rw-r--r-- | src/local/container.nim | 27 | ||||
-rw-r--r-- | src/render/renderdocument.nim | 33 | ||||
-rw-r--r-- | src/server/buffer.nim | 28 |
6 files changed, 74 insertions, 46 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim index 88f0c211..7741f80a 100644 --- a/src/css/cascade.nim +++ b/src/css/cascade.nim @@ -198,6 +198,8 @@ func calcPresentationalHints(element: Element): CSSComputedValues = of "disc": set_cv "list-style-type", LIST_STYLE_TYPE_DISC of "circle": set_cv "list-style-type", LIST_STYLE_TYPE_CIRCLE of "square": set_cv "list-style-type", LIST_STYLE_TYPE_SQUARE + template set_bgcolor_is_canvas = + set_cv "-cha-bgcolor-is-canvas", true case element.tagType of TAG_DIV: @@ -225,7 +227,10 @@ func calcPresentationalHints(element: Element): CSSComputedValues = of TAG_IMG, TAG_CANVAS: map_width map_height + of TAG_HTML: + set_bgcolor_is_canvas of TAG_BODY: + set_bgcolor_is_canvas map_bgcolor map_text of TAG_TEXTAREA: diff --git a/src/css/values.nim b/src/css/values.nim index 0bf57675..93864212 100644 --- a/src/css/values.nim +++ b/src/css/values.nim @@ -41,7 +41,7 @@ type PROPERTY_MIN_WIDTH, PROPERTY_MIN_HEIGHT, PROPERTY_BACKGROUND_IMAGE, PROPERTY_CHA_COLSPAN, PROPERTY_CHA_ROWSPAN, PROPERTY_FLOAT, PROPERTY_VISIBILITY, PROPERTY_BOX_SIZING, PROPERTY_CLEAR, - PROPERTY_TEXT_TRANSFORM + PROPERTY_TEXT_TRANSFORM, PROPERTY_BGCOLOR_IS_CANVAS CSSValueType* = enum VALUE_NONE, VALUE_LENGTH, VALUE_COLOR, VALUE_CONTENT, VALUE_DISPLAY, @@ -50,7 +50,7 @@ type VALUE_TEXT_ALIGN, VALUE_LIST_STYLE_POSITION, VALUE_POSITION, VALUE_CAPTION_SIDE, VALUE_LENGTH2, VALUE_BORDER_COLLAPSE, VALUE_QUOTES, VALUE_COUNTER_RESET, VALUE_IMAGE, VALUE_FLOAT, VALUE_VISIBILITY, - VALUE_BOX_SIZING, VALUE_CLEAR, VALUE_TEXT_TRANSFORM + VALUE_BOX_SIZING, VALUE_CLEAR, VALUE_TEXT_TRANSFORM, VALUE_BGCOLOR_IS_CANVAS CSSGlobalValueType* = enum VALUE_NOGLOBAL, VALUE_INITIAL, VALUE_INHERIT, VALUE_REVERT, VALUE_UNSET @@ -224,6 +224,8 @@ type clear*: CSSClear of VALUE_TEXT_TRANSFORM: texttransform*: CSSTextTransform + of VALUE_BGCOLOR_IS_CANVAS: + bgcoloriscanvas*: bool of VALUE_NONE: discard CSSComputedValues* = ref array[CSSPropertyType, CSSComputedValue] @@ -300,7 +302,8 @@ const PropertyNames = { "visibility": PROPERTY_VISIBILITY, "box-sizing": PROPERTY_BOX_SIZING, "clear": PROPERTY_CLEAR, - "text-transform": PROPERTY_TEXT_TRANSFORM + "text-transform": PROPERTY_TEXT_TRANSFORM, + "-cha-bgcolor-is-canvas": PROPERTY_BGCOLOR_IS_CANVAS }.toTable() const ValueTypes* = [ @@ -351,7 +354,8 @@ const ValueTypes* = [ PROPERTY_VISIBILITY: VALUE_VISIBILITY, PROPERTY_BOX_SIZING: VALUE_BOX_SIZING, PROPERTY_CLEAR: VALUE_CLEAR, - PROPERTY_TEXT_TRANSFORM: VALUE_TEXT_TRANSFORM + PROPERTY_TEXT_TRANSFORM: VALUE_TEXT_TRANSFORM, + PROPERTY_BGCOLOR_IS_CANVAS: VALUE_BGCOLOR_IS_CANVAS ] const InheritedProperties = { @@ -1196,6 +1200,8 @@ proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, val.clear = ?cssClear(cval) of VALUE_TEXT_TRANSFORM: val.texttransform = ?cssTextTransform(cval) + of VALUE_BGCOLOR_IS_CANVAS: + return err() # internal value of VALUE_NONE: discard return ok() diff --git a/src/display/term.nim b/src/display/term.nim index cd2df219..a4c91e61 100644 --- a/src/display/term.nim +++ b/src/display/term.nim @@ -164,9 +164,7 @@ proc resetFormat(term: Terminal): string = when termcap_found: if term.isatty(): return term.cap me - return SGR() - else: - return SGR() + return SGR() proc startFormat(term: Terminal, flag: FormatFlags): string = when termcap_found: @@ -473,7 +471,8 @@ proc writeGrid*(term: Terminal, grid: FixedGrid, x = 0, y = 0) = for lx in x ..< x + grid.width: let i = ly * term.canvas.width + lx term.canvas[i] = grid[(ly - y) * grid.width + (lx - x)] - if i >= term.canvas.width and FLAG_OVERLINE in term.canvas[i].format.flags and term.emulateOverline: + let isol = FLAG_OVERLINE in term.canvas[i].format.flags + if i >= term.canvas.width and isol and term.emulateOverline: let w = grid[(ly - y) * grid.width + (lx - x)].width() let s = i - term.canvas.width var j = s @@ -483,7 +482,8 @@ proc writeGrid*(term: Terminal, grid: FixedGrid, x = 0, y = 0) = if cell.str == "": cell.str = " " if cell.str == " ": - cell.format.fgcolor = grid[(ly - y) * grid.width + (lx - x)].format.fgcolor + let i = (ly - y) * grid.width + (lx - x) + cell.format.fgcolor = grid[i].format.fgcolor j += cell[].width() proc applyConfig(term: Terminal) = @@ -520,7 +520,8 @@ proc outputGrid*(term: Terminal) = if term.config.display.force_clear: term.applyConfig() term.outfile.write(term.resetFormat()) - let samesize = term.canvas.width == term.pcanvas.width and term.canvas.height == term.pcanvas.height + let samesize = term.canvas.width == term.pcanvas.width and + term.canvas.height == term.pcanvas.height if term.config.display.force_clear or not term.cleared or not samesize: term.outfile.write(term.generateFullOutput(term.canvas)) term.cleared = true diff --git a/src/local/container.nim b/src/local/container.nim index 23c4c2d9..69bad5be 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -128,6 +128,7 @@ type marks: Table[string, PagePos] ishtml*: bool filter*: BufferFilter + bgcolor*: CellColor jsDestructor(Highlight) jsDestructor(Container) @@ -470,11 +471,14 @@ proc requestLines*(container: Container, w = container.lineWindow): EmptyPromise container.lines[y] = res.lines[y] container.lines[y].str.mnormalize() container.updateCursor() + var isBgNew = container.bgcolor != res.bgcolor + if isBgNew: + container.bgcolor = res.bgcolor if res.numLines != container.numLines: container.setNumLines(res.numLines, true) container.triggerEvent(STATUS) let cw = container.fromy ..< container.fromy + container.height - if w.a in cw or w.b in cw or cw.a in w or cw.b in w: + if w.a in cw or w.b in cw or cw.a in w or cw.b in w or isBgNew: container.triggerEvent(UPDATE) ) @@ -1587,6 +1591,12 @@ proc readLines*(container: Container, handle: proc(line: SimpleFlexibleLine)) = proc drawLines*(container: Container, display: var FixedGrid, hlcolor: CellColor) = + let bgcolor = container.bgcolor + template set_fmt(cell, cf: typed) = + if cf.pos != -1: + cell.format = cf.format + if bgcolor != defaultColor and cell.format.bgcolor == defaultColor: + cell.format.bgcolor = bgcolor var r: Rune var by = 0 let endy = min(container.fromy + display.height, container.numLines) @@ -1605,8 +1615,7 @@ proc drawLines*(container: Container, display: var FixedGrid, var k = 0 while k < w - container.fromx: display[dls + k].str &= ' ' - if cf.pos != -1: - display[dls + k].format = cf.format + set_fmt display[dls + k], cf inc k let startw = w # save this for later # Now fill in the visible part of the row. @@ -1625,14 +1634,18 @@ proc drawLines*(container: Container, display: var FixedGrid, let tk = k + rw while k < tk: display[dls + k].str &= ' ' - if cf.pos != -1: - display[dls + k].format = cf.format + set_fmt display[dls + k], cf inc k else: display[dls + k].str &= r - if cf.pos != -1: - display[dls + k].format = cf.format + set_fmt display[dls + k], cf k += rw + if bgcolor != defaultColor: + # Fill the screen if bgcolor is not default. + while k < display.width: + display[dls + k].str &= ' ' + display[dls + k].format.bgcolor = bgcolor + inc k # Finally, override cell formatting for highlighted cells. let hls = container.findHighlights(container.fromy + by) let aw = container.width - (startw - container.fromx) # actual width diff --git a/src/render/renderdocument.nim b/src/render/renderdocument.nim index 2a5ddccd..625984df 100644 --- a/src/render/renderdocument.nim +++ b/src/render/renderdocument.nim @@ -283,6 +283,8 @@ type RenderState = object # Position of the absolute positioning containing block: # https://drafts.csswg.org/css-position/#absolute-positioning-containing-block absolutePos: seq[Offset] + bgcolor: CellColor + root: bool proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState; box: BlockBox; offset: Offset; attrs: WindowAttributes) @@ -378,14 +380,19 @@ proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState; state.absolutePos.add(offset) stack.add((nil, Offset(x: -1, y: -1))) - if box.computed{"visibility"} == VISIBILITY_VISIBLE: + if box.computed{"-cha-bgcolor-is-canvas"} and + state.bgcolor == defaultColor: + #TODO bgimage if box.computed{"background-color"}.a != 0: #TODO color blending - let ix = toInt(offset.x) - let iy = toInt(offset.y) - let iex = toInt(offset.x + box.size.w) - let iey = toInt(offset.y + box.size.h) - let color = box.computed{"background-color"}.cellColor() - grid.paintBackground(color, ix, iy, iex, iey, box.node, attrs) + state.bgcolor = box.computed{"background-color"}.cellColor() + elif box.computed{"visibility"} == VISIBILITY_VISIBLE: + if box.computed{"background-color"}.a != 0: #TODO color blending + let ix = toInt(offset.x) + let iy = toInt(offset.y) + let iex = toInt(offset.x + box.size.w) + let iey = toInt(offset.y + box.size.h) + let color = box.computed{"background-color"}.cellColor() + grid.paintBackground(color, ix, iy, iex, iey, box.node, attrs) if box.computed{"background-image"}.t == CONTENT_IMAGE and box.computed{"background-image"}.s != "": # ugly hack for background-image display... TODO actually display images @@ -418,14 +425,16 @@ proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState; for i in countdown(box.nested.high, 0): stack.add((box.nested[i], offset)) -proc renderDocument*(styledRoot: StyledNode; attrs: WindowAttributes): - FlexibleGrid = - var grid: FlexibleGrid +proc renderDocument*(grid: var FlexibleGrid; bgcolor: var CellColor; + styledRoot: StyledNode; attrs: WindowAttributes) = + grid.setLen(0) var state = RenderState( - absolutePos: @[Offset(x: 0, y: 0)] + absolutePos: @[Offset(x: 0, y: 0)], + root: true, + bgcolor: bgcolor ) let rootBox = renderLayout(styledRoot, attrs) grid.renderBlockBox(state, rootBox, Offset(x: 0, y: 0), attrs) if grid.len == 0: grid.addLine() - return grid + bgcolor = state.bgcolor diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 3c6dfa21..3804d1b9 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -119,6 +119,7 @@ type userstyle: CSSStylesheet htmlParser: HTML5ParserWrapper srenderer: ref StreamRenderer + bgcolor: CellColor InterfaceOpaque = ref object stream: Stream @@ -624,9 +625,11 @@ proc do_reshape(buffer: Buffer) = buffer.uastyle else: buffer.quirkstyle + if buffer.document.cachedSheetsInvalid: + buffer.prevstyled = nil let styledRoot = buffer.document.applyStylesheets(uastyle, buffer.userstyle, buffer.prevstyled) - buffer.lines = renderDocument(styledRoot, buffer.attrs) + buffer.lines.renderDocument(buffer.bgcolor, styledRoot, buffer.attrs) buffer.prevstyled = styledRoot proc processData(buffer: Buffer): bool = @@ -1108,7 +1111,6 @@ proc onload(buffer: Buffer) = # EOF res.atend = true buffer.finishLoad().then(proc() = - buffer.prevstyled = nil # for incremental rendering buffer.do_reshape() res.lines = buffer.lines.len buffer.state = LOADED @@ -1123,20 +1125,10 @@ proc onload(buffer: Buffer) = buffer.resolveTask(LOAD, res) except ErrorAgain: break - if buffer.document != nil: - # incremental rendering: only if we cannot read the entire stream in one - # pass - #TODO this is too simplistic to be really useful - let uastyle = if buffer.document.mode != QUIRKS: - buffer.uastyle - else: - buffer.quirkstyle - if buffer.document.cachedSheetsInvalid: - buffer.prevstyled = nil - let styledRoot = buffer.document.applyStylesheets(uastyle, - buffer.userstyle, buffer.prevstyled) - buffer.lines = renderDocument(styledRoot, buffer.attrs) - buffer.prevstyled = styledRoot + # incremental rendering: only if we cannot read the entire stream in one + # pass + #TODO this could be improved + buffer.do_reshape() proc getTitle*(buffer: Buffer): string {.proxy.} = if buffer.document != nil: @@ -1606,7 +1598,8 @@ proc findAnchor*(buffer: Buffer, anchor: string): bool {.proxy.} = type GetLinesResult* = tuple[ numLines: int, - lines: seq[SimpleFlexibleLine] + lines: seq[SimpleFlexibleLine], + bgcolor: CellColor ] proc getLines*(buffer: Buffer, w: Slice[int]): GetLinesResult {.proxy.} = @@ -1620,6 +1613,7 @@ proc getLines*(buffer: Buffer, w: Slice[int]): GetLinesResult {.proxy.} = line.formats.add(SimpleFormatCell(format: f.format, pos: f.pos)) result.lines.add(line) result.numLines = buffer.lines.len + result.bgcolor = buffer.bgcolor macro bufferDispatcher(funs: static ProxyMap, buffer: Buffer, cmd: BufferCommand, packetid: int) = |