diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/css/cssparser.nim | 7 | ||||
-rw-r--r-- | src/css/values.nim | 45 | ||||
-rw-r--r-- | src/render/renderdocument.nim | 48 |
3 files changed, 68 insertions, 32 deletions
diff --git a/src/css/cssparser.nim b/src/css/cssparser.nim index 864119ea..9c8328de 100644 --- a/src/css/cssparser.nim +++ b/src/css/cssparser.nim @@ -81,8 +81,10 @@ proc `$`*(c: CSSParsedItem): string = if c of CSSToken: let c = CSSToken(c) case c.tokenType: - of CSS_FUNCTION_TOKEN, CSS_AT_KEYWORD_TOKEN, CSS_URL_TOKEN: + of CSS_FUNCTION_TOKEN, CSS_AT_KEYWORD_TOKEN: result &= $c.tokenType & c.value & '\n' + of CSS_URL_TOKEN: + result &= "url(" & c.value & ")" of CSS_HASH_TOKEN: result &= '#' & c.value of CSS_IDENT_TOKEN: @@ -372,7 +374,8 @@ proc consumeIdentLikeToken(state: var CSSTokenizerState): CSSToken = discard state.consume() while state.has(1) and state.peek().isWhitespace() and state.peek(1).isWhitespace(): discard state.consume() - if state.has(1) and state.peek() in {'"', '\''} + AsciiWhitespace and state.peek(1) in {'"', '\''}: + if state.has() and state.peek() in {'"', '\''} or + state.has(1) and state.peek() in {'"', '\''} + AsciiWhitespace and state.peek(1) in {'"', '\''}: return CSSToken(tokenType: CSS_FUNCTION_TOKEN, value: s) else: return state.consumeURL() diff --git a/src/css/values.nim b/src/css/values.nim index 5e5d807c..5916bc89 100644 --- a/src/css/values.nim +++ b/src/css/values.nim @@ -335,6 +335,11 @@ func `$`*(val: CSSComputedValue): string = case val.v of VALUE_COLOR: result &= $val.color + of VALUE_IMAGE: + if val.image.s != "": + result &= "url(" & val.image.s & ")" + else: + result &= "none" else: discard macro `{}`*(vals: CSSComputedValues, s: string): untyped = @@ -868,12 +873,36 @@ func cssMaxMinSize(cval: CSSComponentValue): CSSLength = else: discard raise newException(CSSValueError, "Invalid min/max-size") -#TODO this should be a separate type +#TODO should be URL (parsed with baseurl of document...) +func cssURL(cval: CSSComponentValue): Option[string] = + if isToken(cval): + let tok = getToken(cval) + if tok == CSS_URL_TOKEN: + return some(tok.value) + elif cval of CSSFunction: + let fun = CSSFunction(cval) + if fun.name == "url" or fun.name == "src": + for x in fun.value: + if not isToken(x): + break + let x = getToken(x) + if x == CSS_WHITESPACE_TOKEN: + discard + elif x == CSS_STRING_TOKEN: + return some(x.value) + else: + break + +#TODO this should be bg-image, add gradient, etc etc func cssImage(cval: CSSComponentValue): CSSContent = if isToken(cval): + #TODO bg-image only let tok = getToken(cval) - if tok.tokenType == CSS_URL_TOKEN or tok.tokenType == CSS_BAD_URL_TOKEN: - return CSSContent(t: CONTENT_IMAGE, s: "[img]") + if tok.tokenType == CSS_IDENT_TOKEN and tok.value == "none": + return CSSContent(t: CONTENT_IMAGE, s: "") + let url = cssURL(cval) + if url.isSome: + return CSSContent(t: CONTENT_IMAGE, s: url.get) raise newException(CSSValueError, "Invalid image") func cssInteger(cval: CSSComponentValue, range: Slice[int]): int = @@ -939,7 +968,7 @@ proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueT val.length2.b = cssAbsoluteLength(cval) of VALUE_QUOTES: val.quotes = cssQuotes(d) of VALUE_COUNTER_RESET: val.counterreset = cssCounterReset(d) - of VALUE_IMAGE: val.image = cssImage(d) + of VALUE_IMAGE: val.image = cssImage(cval) of VALUE_NONE: discard func getInitialColor(t: CSSPropertyType): RGBAColor = @@ -1100,12 +1129,16 @@ proc getComputedValues(d: CSSDeclaration): seq[(CSSComputedValue, CSSGlobalValue let bgimageval = CSSComputedValue(t: bgimageptype, v: valueType(bgimageptype)) if global == VALUE_NOGLOBAL: for tok in d.value: + if tok == CSS_WHITESPACE_TOKEN: + continue try: - bgimageval.image = cssImage(tok) + let img = cssImage(tok) + bgimageval.image = img result.add((bgimageval, global)) except CSSValueError: try: - bgcolorval.color = cssColor(tok) + let color = cssColor(tok) + bgcolorval.color = color result.add((bgcolorval, global)) except CSSValueError: discard diff --git a/src/render/renderdocument.nim b/src/render/renderdocument.nim index e2aa1b0e..1d4c28f1 100644 --- a/src/render/renderdocument.nim +++ b/src/render/renderdocument.nim @@ -278,7 +278,7 @@ func calculateErrorY(ctx: InlineContext, window: WindowAttributes): int = error += dy - (dy div window.ppl) * window.ppl return error div (ctx.lines.len - 1) -proc renderBlockContext(grid: var FlexibleGrid, ctx: BlockBox, x, y: int, window: WindowAttributes) +proc renderBlockBox(grid: var FlexibleGrid, box: BlockBox, x, y: int, window: WindowAttributes) proc renderInlineContext(grid: var FlexibleGrid, ctx: InlineContext, x, y: int, window: WindowAttributes) = let x = x + ctx.offset.x @@ -297,7 +297,7 @@ proc renderInlineContext(grid: var FlexibleGrid, ctx: InlineContext, x, y: int, for atom in line.atoms: if atom of InlineBlockBox: let iblock = InlineBlockBox(atom) - grid.renderBlockContext(iblock.innerbox, x + iblock.offset.x, y + iblock.offset.y, window) + grid.renderBlockBox(iblock.innerbox, x + iblock.offset.x, y + iblock.offset.y, window) elif atom of InlineWord: let word = InlineWord(atom) grid.setRowWord(word, x, y, window) @@ -306,42 +306,42 @@ proc renderInlineContext(grid: var FlexibleGrid, ctx: InlineContext, x, y: int, grid.setSpacing(spacing, x, y, window) inc i -proc renderBlockContext(grid: var FlexibleGrid, ctx: BlockBox, x, y: int, window: WindowAttributes) = +proc renderBlockBox(grid: var FlexibleGrid, box: BlockBox, x, y: int, window: WindowAttributes) = var stack = newSeqOfCap[(BlockBox, int, int)](100) - stack.add((ctx, x, y)) + stack.add((box, x, y)) while stack.len > 0: - var (ctx, x, y) = stack.pop() - x += ctx.offset.x - y += ctx.offset.y + var (box, x, y) = stack.pop() + x += box.offset.x + y += box.offset.y - if ctx.computed{"background-color"}.a != 0: #TODO color blending - grid.paintBackground(ctx.computed{"background-color"}, x, y, x + ctx.width, y + ctx.height, ctx.node, window) - if ctx.computed{"background-image"}.t == CONTENT_IMAGE: + if box.computed{"background-color"}.a != 0: #TODO color blending + grid.paintBackground(box.computed{"background-color"}, x, y, x + box.width, y + box.height, box.node, window) + if box.computed{"background-image"}.t == CONTENT_IMAGE and box.computed{"background-image"}.s != "": # ugly hack for background-image display... TODO actually display images - let s = ctx.computed{"background-image"}.s # [img] + let s = "[img]" let w = s.len * window.ppc var x = x - if ctx.width < w: + if box.width < w: # text is larger than image; center it to minimize error x -= w div 2 - x += ctx.width div 2 + x += box.width div 2 x = x div window.ppc y = y div window.ppl if y >= 0 and x + w >= 0: - grid.setText(s, ComputedFormat(node: ctx.node), x, y) + grid.setText(s, ComputedFormat(node: box.node), x, y) - if ctx of ListItemBox: - let ctx = ListItemBox(ctx) - if ctx.marker != nil: - grid.renderInlineContext(ctx.marker, x - ctx.marker.width, y, window) + if box of ListItemBox: + let box = ListItemBox(box) + if box.marker != nil: + grid.renderInlineContext(box.marker, x - box.marker.width, y, window) - if ctx.inline != nil: - assert ctx.nested.len == 0 - grid.renderInlineContext(ctx.inline, x, y, window) + if box.inline != nil: + assert box.nested.len == 0 + grid.renderInlineContext(box.inline, x, y, window) else: - for i in countdown(ctx.nested.high, 0): - stack.add((ctx.nested[i], x, y)) + for i in countdown(box.nested.high, 0): + stack.add((box.nested[i], x, y)) const css = staticRead"res/ua.css" let uastyle = css.parseStylesheet() @@ -356,6 +356,6 @@ proc renderDocument*(document: Document, window: WindowAttributes, userstyle: CS layout.renderLayout(styledNode) result[0].setLen(0) for root in layout.root: - result[0].renderBlockContext(root, 0, 0, window) + result[0].renderBlockBox(root, 0, 0, window) if result[0].len == 0: result[0].addLine() |