diff options
Diffstat (limited to 'src/css/box.nim')
-rw-r--r-- | src/css/box.nim | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/css/box.nim b/src/css/box.nim new file mode 100644 index 00000000..a40cd4af --- /dev/null +++ b/src/css/box.nim @@ -0,0 +1,159 @@ +import css/cssvalues +import css/lunit +import css/stylednode +import types/bitmap + +type + DimensionType* = enum + dtHorizontal, dtVertical + + Offset* = array[DimensionType, LayoutUnit] + + Size* = array[DimensionType, LayoutUnit] + + Overflow* = array[DimensionType, Span] + + InlineAtomType* = enum + iatWord, iatInlineBlock, iatImage + + InlineAtom* = ref object + offset*: Offset + size*: Size + case t*: InlineAtomType + of iatWord: + str*: string + of iatInlineBlock: + innerbox*: BlockBox + of iatImage: + bmp*: NetworkBitmap + + BoxLayoutState* = object + # offset relative to parent + offset*: Offset + # padding size + size*: Size + # overflow relative to offset + overflow*: Overflow + # minimum content width (usually shortest word) + xminwidth*: LayoutUnit + # baseline of the first line box of all descendants + firstBaseline*: LayoutUnit + # baseline of the last line box of all descendants + baseline*: LayoutUnit + + SplitType* = enum + stSplitStart, stSplitEnd + + Area* = object + offset*: Offset + size*: Size + + InlineFragmentState* = object + startOffset*: Offset # offset of the first word, for position: absolute + areas*: seq[Area] # background that should be painted by fragment + atoms*: seq[InlineAtom] + + InlineFragmentType* = enum + iftParent, iftText, iftNewline, iftBitmap, iftBox + + InlineFragment* = ref object + state*: InlineFragmentState + computed*: CSSComputedValues + node*: StyledNode + splitType*: set[SplitType] + case t*: InlineFragmentType + of iftParent: + children*: seq[InlineFragment] + of iftText: + text*: StyledNode # note: this has no parent. + of iftNewline: + discard + of iftBitmap: + bmp*: NetworkBitmap + of iftBox: + box*: BlockBox + + Span* = object + start*: LayoutUnit + send*: LayoutUnit + + RelativeRect* = array[DimensionType, Span] + + BlockBox* = ref object + state*: BoxLayoutState + computed*: CSSComputedValues + node*: StyledNode + inline*: InlineFragment + children*: seq[BlockBox] + +func offset*(x, y: LayoutUnit): Offset = + return [dtHorizontal: x, dtVertical: y] + +func x*(offset: Offset): LayoutUnit {.inline.} = + return offset[dtHorizontal] + +func x*(offset: var Offset): var LayoutUnit {.inline.} = + return offset[dtHorizontal] + +func `x=`*(offset: var Offset; x: LayoutUnit) {.inline.} = + offset[dtHorizontal] = x + +func y*(offset: Offset): LayoutUnit {.inline.} = + return offset[dtVertical] + +func y*(offset: var Offset): var LayoutUnit {.inline.} = + return offset[dtVertical] + +func `y=`*(offset: var Offset; y: LayoutUnit) {.inline.} = + offset[dtVertical] = y + +func size*(w, h: LayoutUnit): Size = + return [dtHorizontal: w, dtVertical: h] + +func w*(size: Size): LayoutUnit {.inline.} = + return size[dtHorizontal] + +func w*(size: var Size): var LayoutUnit {.inline.} = + return size[dtHorizontal] + +func `w=`*(size: var Size; w: LayoutUnit) {.inline.} = + size[dtHorizontal] = w + +func h*(size: Size): LayoutUnit {.inline.} = + return size[dtVertical] + +func h*(size: var Size): var LayoutUnit {.inline.} = + return size[dtVertical] + +func `h=`*(size: var Size; h: LayoutUnit) {.inline.} = + size[dtVertical] = h + +func `+`*(a, b: Offset): Offset = + return offset(x = a.x + b.x, y = a.y + b.y) + +func `-`*(a, b: Offset): Offset = + return offset(x = a.x - b.x, y = a.y - b.y) + +proc `+=`*(a: var Offset; b: Offset) = + a.x += b.x + a.y += b.y + +proc `-=`*(a: var Offset; b: Offset) = + a.x -= b.x + a.y -= b.y + +func left*(s: RelativeRect): LayoutUnit = + return s[dtHorizontal].start + +func right*(s: RelativeRect): LayoutUnit = + return s[dtHorizontal].send + +func top*(s: RelativeRect): LayoutUnit = + return s[dtVertical].start + +func bottom*(s: RelativeRect): LayoutUnit = + return s[dtVertical].send + +proc `+=`*(span: var Span; u: LayoutUnit) = + span.start += u + span.send += u |