Class: SilkLayout::Layout::BlockLayout

Inherits:
Object
  • Object
show all
Defined in:
lib/silk_layout/layout/block_layout.rb

Class Method Summary collapse

Class Method Details

.layout(box, context, cursor_y = 0, parent_x = 0, containing_width = nil) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/silk_layout/layout/block_layout.rb', line 6

def self.layout(box, context, cursor_y = 0, parent_x = 0, containing_width = nil)
  return FlexLayout.layout(box, context, cursor_y, parent_x, containing_width) if box.is_a?(FlexBox)

  box.x = parent_x + box.margin[:left]
  box.y = cursor_y + box.margin[:top]

  content_x =
    box.x + box.border[:left] + box.padding[:left]

  content_y =
    box.y + box.border[:top] + box.padding[:top]

  available_width = containing_width || context.width
  if box.explicit_width
    content_width = box.width
  else
    content_width =
      available_width -
      box.margin[:left] - box.margin[:right] -
      box.border[:left] - box.border[:right] -
      box.padding[:left] - box.padding[:right]
    content_width = 0 if content_width < 0
  end

  current_y = content_y
  new_children = []
  inline_buffer = []

  box.children.each do |child|
    if child.is_a?(InlineBox)
      inline_buffer << child
      next
    end

    if inline_buffer.any?
      lines = InlineFormatter.layout(inline_buffer, content_width, content_x, current_y)
      lines.each do |line|
        line.x = content_x
        line.y = current_y
        current_y += line.height
        new_children << line
      end
      inline_buffer.clear
    end

    layout(child, context, current_y, content_x, content_width)

    current_y +=
      child.height +
      child.margin[:top] +
      child.margin[:bottom]

    new_children << child
  end

  if inline_buffer.any?
    lines = InlineFormatter.layout(inline_buffer, content_width, content_x, current_y)
    lines.each do |line|
      line.x = content_x
      line.y = current_y
      current_y += line.height
      new_children << line
    end
  end

  box.children = new_children

  content_height = current_y - content_y
  content_height = [content_height, box.height].max if box.explicit_height

  max_child_width =
    box.children.map(&:width).max || 0

  content_width = max_child_width if !box.explicit_width && content_width == 0

  box.width =
    content_width +
    box.padding[:left] + box.padding[:right] +
    box.border[:left] + box.border[:right]

  box.height =
    content_height +
    box.padding[:top] + box.padding[:bottom] +
    box.border[:top] + box.border[:bottom]
end