1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798(* Compute helpers - Helper functions used by layout algorithms *)openGeometryopenStyle(* Compute how much width/height a child contributes to its parent's intrinsic
content size. Respects overflow settings - visible overflow contributes to
content size. *)letcompute_content_size_contribution~location~size~content_size~overflow=letsize_cs=Size.{width=(matchoverflow.Point.xwith|Overflow.Visible->Float.maxsize.widthcontent_size.width|_->size.width);height=(matchoverflow.Point.ywith|Overflow.Visible->Float.maxsize.heightcontent_size.height|_->size.height);}inifsize_cs.width>0.&&size_cs.height>0.thenSize.{width=location.Point.x+.size_cs.width;height=location.Point.y+.size_cs.height;}elseSize.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 *)letapply_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 *)letalignment_mode,is_safe=ifnum_items<=1||free_space<=0.0thenmatchalignment_modewith|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 *)letalignment_mode=iffree_space<=0.0&&is_safethenAlign_content.Startelsealignment_modeinalignment_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. *)letcompute_alignment_offset~free_space~num_items~gap~alignment_mode~layout_is_flex_reversed~is_first=ifis_firstthenmatchalignment_modewith|Align_content.Start->0.0|Align_content.Flex_start->iflayout_is_flex_reversedthenfree_spaceelse0.0|Align_content.End->free_space|Align_content.Flex_end->iflayout_is_flex_reversedthen0.0elsefree_space|Align_content.Center->free_space/.2.0|Align_content.Stretch->0.0|Align_content.Space_between->0.0|Align_content.Space_around->iffree_space>=0.0thenfree_space/.Float.of_intnum_items/.2.0elsefree_space/.2.0|Align_content.Space_evenly->iffree_space>=0.0thenfree_space/.Float.of_int(num_items+1)elsefree_space/.2.0elseletfree_space=Float.maxfree_space0.0ingap+.matchalignment_modewith|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_intnum_items|Align_content.Space_evenly->free_space/.Float.of_int(num_items+1)