diff options
Diffstat (limited to 'src/layout')
-rw-r--r-- | src/layout/box.nim | 5 | ||||
-rw-r--r-- | src/layout/engine.nim | 26 | ||||
-rw-r--r-- | src/layout/renderdocument.nim | 39 |
3 files changed, 52 insertions, 18 deletions
diff --git a/src/layout/box.nim b/src/layout/box.nim index 79f927ef..40628204 100644 --- a/src/layout/box.nim +++ b/src/layout/box.nim @@ -1,5 +1,6 @@ import css/stylednode import css/values +import img/bitmap import layout/layoutunit type @@ -12,7 +13,7 @@ type h*: LayoutUnit InlineAtomType* = enum - iatSpacing, iatWord, iatInlineBlock + iatSpacing, iatWord, iatInlineBlock, iatImage InlineAtom* = ref object offset*: Offset @@ -24,6 +25,8 @@ type str*: string of iatInlineBlock: innerbox*: BlockBox + of iatImage: + bmp*: Bitmap RootInlineFragment* = ref object # offset relative to parent diff --git a/src/layout/engine.nim b/src/layout/engine.nim index 99d205f5..30afb066 100644 --- a/src/layout/engine.nim +++ b/src/layout/engine.nim @@ -5,6 +5,7 @@ import std/unicode import css/stylednode import css/values +import img/bitmap import layout/box import layout/layoutunit import types/winattrs @@ -68,6 +69,7 @@ type text: seq[string] newline: bool splitType: set[SplitType] + bmp: Bitmap BlockBoxBuilder = ref object of BoxBuilder inlinelayout: bool @@ -1500,8 +1502,20 @@ proc layoutInline(ictx: var InlineContext; box: InlineBoxBuilder): if ictx.firstTextFragment == nil: ictx.firstTextFragment = fragment ictx.lastTextFragment = fragment - ictx.layoutText(state, box.text) - ictx.layoutChildren(state, box.children) + if box.bmp != nil: + let iastate = InlineAtomState( + vertalign: state.computed{"vertical-align"}, + baseline: ictx.cellheight + ) + let atom = InlineAtom( + t: iatImage, + bmp: box.bmp, + size: Size(w: int(box.bmp.width), h: int(box.bmp.height)) #TODO overflow + ) + discard ictx.addAtom(state, iastate, atom) + else: + ictx.layoutText(state, box.text) + ictx.layoutChildren(state, box.children) if stSplitEnd in box.splitType: let paddingRight = box.computed{"padding-right"}.px(lctx, ictx.space.w) ictx.currentLine.size.w += paddingRight @@ -2856,10 +2870,10 @@ proc generateFromElem(ctx: var InnerBlockContext; styledNode: StyledNode) = of DisplayNone: discard proc generateAnonymousInlineText(ctx: var InnerBlockContext; text: string; - styledNode: StyledNode) = + styledNode: StyledNode; bmp: Bitmap = nil) = if ctx.iroot == nil: let computed = styledNode.computed.inheritProperties() - ctx.ibox = InlineBoxBuilder(computed: computed, node: styledNode) + ctx.ibox = InlineBoxBuilder(computed: computed, node: styledNode, bmp: bmp) if ctx.inlineStack.len > 0: let iparent = ctx.reconstructInlineParents() iparent.children.add(ctx.ibox) @@ -2900,7 +2914,7 @@ proc generateReplacement(ctx: var InnerBlockContext; ctx.generateAnonymousInlineText(child.content.s, parent) of ContentImage: #TODO idk - ctx.generateAnonymousInlineText("[img]", parent) + ctx.generateAnonymousInlineText("[img]", parent, child.content.bmp) of ContentVideo: ctx.generateAnonymousInlineText("[video]", parent) of ContentAudio: @@ -3116,7 +3130,7 @@ proc generateTableBox(styledNode: StyledNode; lctx: LayoutState; box.generateTableChildWrappers() return box -proc renderLayout*(root: StyledNode; attrsp: ptr WindowAttributes): BlockBox = +proc layout*(root: StyledNode; attrsp: ptr WindowAttributes): BlockBox = let space = AvailableSpace( w: stretch(attrsp[].width_px), h: stretch(attrsp[].height_px) diff --git a/src/layout/renderdocument.nim b/src/layout/renderdocument.nim index fe7b92cb..e57a6d2c 100644 --- a/src/layout/renderdocument.nim +++ b/src/layout/renderdocument.nim @@ -3,12 +3,13 @@ import std/unicode import css/stylednode import css/values +import img/bitmap import layout/box import layout/engine import layout/layoutunit -import types/winattrs import types/cell import types/color +import types/winattrs import utils/strwidth type @@ -208,12 +209,19 @@ proc setText(grid: var FlexibleGrid; linestr: string; x, y: int; format: Format; assert grid[y].formats[fi].pos <= nx # That's it! -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 - attrsp: ptr WindowAttributes +type + PosBitmap* = ref object + x*: int + y*: int + bmp*: Bitmap + + RenderState = object + # Position of the absolute positioning containing block: + # https://drafts.csswg.org/css-position/#absolute-positioning-containing-block + absolutePos: seq[Offset] + bgcolor: CellColor + attrsp: ptr WindowAttributes + images: seq[PosBitmap] template attrs(state: RenderState): WindowAttributes = state.attrsp[] @@ -361,6 +369,15 @@ proc renderInlineFragment(grid: var FlexibleGrid; state: var RenderState; grid.setRowWord(state, atom, offset, format, fragment.node) of iatSpacing: grid.setSpacing(state, atom, offset, format, fragment.node) + of iatImage: + state.images.add(PosBitmap( + x: (offset.x div state.attrs.ppc).toInt, + y: (offset.y div state.attrs.ppl).toInt, + bmp: atom.bmp + )) + else: + for child in fragment.children: + grid.renderInlineFragment(state, child, offset) if fragment.computed{"position"} != PositionStatic: if fragment.splitType != {stSplitStart, stSplitEnd}: if stSplitStart in fragment.splitType: @@ -370,8 +387,6 @@ proc renderInlineFragment(grid: var FlexibleGrid; state: var RenderState; )) if stSplitEnd in fragment.splitType: discard state.absolutePos.pop() - for child in fragment.children: - grid.renderInlineFragment(state, child, offset) proc renderRootInlineFragment(grid: var FlexibleGrid; state: var RenderState; root: RootInlineFragment; offset: Offset) = @@ -440,7 +455,8 @@ proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState; stack.add((box.nested[i], offset)) proc renderDocument*(grid: var FlexibleGrid; bgcolor: var CellColor; - styledRoot: StyledNode; attrsp: ptr WindowAttributes) = + styledRoot: StyledNode; attrsp: ptr WindowAttributes; + images: var seq[PosBitmap]) = grid.setLen(0) if styledRoot == nil: # no HTML element when we run cascade; just clear all lines. @@ -449,8 +465,9 @@ proc renderDocument*(grid: var FlexibleGrid; bgcolor: var CellColor; absolutePos: @[Offset(x: 0, y: 0)], attrsp: attrsp ) - let rootBox = renderLayout(styledRoot, attrsp) + let rootBox = styledRoot.layout(attrsp) grid.renderBlockBox(state, rootBox, Offset(x: 0, y: 0)) if grid.len == 0: grid.addLines(1) bgcolor = state.bgcolor + images = state.images |