package toffee

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file compute_helpers.ml

1
2
3
4
5
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
91
92
93
94
95
96
97
98
(* Compute helpers - Helper functions used by layout algorithms *)

open Geometry
open Style

(* Compute how much width/height a child contributes to its parent's intrinsic
   content size. Respects overflow settings - visible overflow contributes to
   content size. *)
let compute_content_size_contribution ~location ~size ~content_size ~overflow =
  let size_cs =
    Size.
      {
        width =
          (match overflow.Point.x with
          | Overflow.Visible -> Float.max size.width content_size.width
          | _ -> size.width);
        height =
          (match overflow.Point.y with
          | Overflow.Visible -> Float.max size.height content_size.height
          | _ -> size.height);
      }
  in
  if size_cs.width > 0. && size_cs.height > 0. then
    Size.
      {
        width = location.Point.x +. size_cs.width;
        height = location.Point.y +. size_cs.height;
      }
  else Size.zero

(* Implement fallback alignment.

   In addition to the spec at https://www.w3.org/TR/css-align-3/ this
   implementation follows the resolution of
   https://github.com/w3c/csswg-drafts/issues/10154 *)
let apply_alignment_fallback ~free_space ~num_items ~alignment_mode ~is_safe =
  (* Fallback occurs in two cases: *)

  (* 1. If there is only a single item being aligned and alignment is a
     distributed alignment keyword
     https://www.w3.org/TR/css-align-3/#distribution-values *)
  let alignment_mode, is_safe =
    if num_items <= 1 || free_space <= 0.0 then
      match alignment_mode with
      | Align_content.Stretch -> (Align_content.Flex_start, true)
      | Align_content.Space_between -> (Align_content.Flex_start, true)
      | Align_content.Space_around -> (Align_content.Center, true)
      | Align_content.Space_evenly -> (Align_content.Center, true)
      | _ -> (alignment_mode, is_safe)
    else (alignment_mode, is_safe)
  in

  (* 2. If free space is negative the "safe" alignment variants all fallback to
     Start alignment *)
  let alignment_mode =
    if free_space <= 0.0 && is_safe then Align_content.Start else alignment_mode
  in

  alignment_mode

(* Generic alignment function that is used: - For both align-content and
   justify-content alignment - For both the Flexbox and CSS Grid algorithms

   CSS Grid does not apply gaps as part of alignment, so the gap parameter
   should always be set to zero for CSS Grid. *)
let compute_alignment_offset ~free_space ~num_items ~gap ~alignment_mode
    ~layout_is_flex_reversed ~is_first =
  if is_first then
    match alignment_mode with
    | Align_content.Start -> 0.0
    | Align_content.Flex_start ->
        if layout_is_flex_reversed then free_space else 0.0
    | Align_content.End -> free_space
    | Align_content.Flex_end ->
        if layout_is_flex_reversed then 0.0 else free_space
    | Align_content.Center -> free_space /. 2.0
    | Align_content.Stretch -> 0.0
    | Align_content.Space_between -> 0.0
    | Align_content.Space_around ->
        if free_space >= 0.0 then free_space /. Float.of_int num_items /. 2.0
        else free_space /. 2.0
    | Align_content.Space_evenly ->
        if free_space >= 0.0 then free_space /. Float.of_int (num_items + 1)
        else free_space /. 2.0
  else
    let free_space = Float.max free_space 0.0 in
    gap
    +.
    match alignment_mode with
    | Align_content.Start -> 0.0
    | Align_content.Flex_start -> 0.0
    | Align_content.End -> 0.0
    | Align_content.Flex_end -> 0.0
    | Align_content.Center -> 0.0
    | Align_content.Stretch -> 0.0
    | Align_content.Space_between -> free_space /. Float.of_int (num_items - 1)
    | Align_content.Space_around -> free_space /. Float.of_int num_items
    | Align_content.Space_evenly -> free_space /. Float.of_int (num_items + 1)