Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file implicit_grid.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209(* This module is not required for spec compliance, but is used as a performance
optimisation to reduce the number of allocations required when creating a
grid. *)openGeometryopenStyleopenStyle.Grid(* Helper functions for origin zero line *)letimplied_negative_implicit_tracksline=ifline<0thenabslineelse0letimplied_positive_implicit_trackslineexplicit_track_count=ifline>explicit_track_countthenline-explicit_track_countelse0(* Resolves the span for an indefinite placement (a placement that does not
consist of two Lines). Should only be called on indefinite placements *)letindefinite_spanline=letopenOrigin_zero_placementinmatch(line.Line.start,line.Line.end_)with|Line_,Auto->1|Auto,Line_->1|Auto,Auto->1|Line_,Spanspan->span|Spanspan,Line_->span|Spanspan,Auto->span|Auto,Spanspan->span|Spanspan,Span_->span|Line_,Line_->failwith"indefinite_span should only be called on indefinite grid tracks"(* Helper function for compute_grid_size_estimate Produces a conservative
estimate of the greatest and smallest grid lines used by a single grid item
Values are returned in origin-zero coordinates *)letchild_min_line_max_line_spanlineexplicit_track_count=(* 8.3.1. Grid Placement Conflict Handling A. If the placement for a grid item
contains two lines, and the start line is further end-ward than the end
line, swap the two lines. B. If the start line is equal to the end line,
remove the end line. C. If the placement contains two spans, remove the one
contributed by the end grid-placement property. D. If the placement
contains only a span for a named line, replace it with a span of 1. *)(* Convert line into origin-zero coordinates before attempting to analyze We
ignore named lines here as they are accounted for separately *)letoz_line=Grid.Placement.Line.into_origin_zero_ignoring_namedlineexplicit_track_countinletmin=match(oz_line.Line.start,oz_line.Line.end_)with(* Both tracks specified *)|Origin_zero_placement.Linetrack1,Origin_zero_placement.Linetrack2->(* See rules A and B above *)iftrack1=track2thentrack1elsemintrack1track2(* Start track specified *)|Origin_zero_placement.Linetrack,Origin_zero_placement.Auto->track|Origin_zero_placement.Linetrack,Origin_zero_placement.Span_->track(* End track specified *)|Origin_zero_placement.Auto,Origin_zero_placement.Linetrack->track|Origin_zero_placement.Spanspan,Origin_zero_placement.Linetrack->track-span(* Only spans or autos *)(* We ignore spans here by returning 0 which never effect the estimate as these are accounted for separately *)|((Origin_zero_placement.Auto|Origin_zero_placement.Span_),(Origin_zero_placement.Auto|Origin_zero_placement.Span_))->0inletmax=match(oz_line.Line.start,oz_line.Line.end_)with(* Both tracks specified *)|Origin_zero_placement.Linetrack1,Origin_zero_placement.Linetrack2->(* See rules A and B above *)iftrack1=track2thentrack1+1elsemaxtrack1track2(* Start track specified *)|Origin_zero_placement.Linetrack,Origin_zero_placement.Auto->track+1|Origin_zero_placement.Linetrack,Origin_zero_placement.Spanspan->track+span(* End track specified *)|Origin_zero_placement.Auto,Origin_zero_placement.Linetrack->track|Origin_zero_placement.Span_,Origin_zero_placement.Linetrack->track(* Only spans or autos *)(* We ignore spans here by returning 0 which never effect the estimate as these are accounted for separately *)|((Origin_zero_placement.Auto|Origin_zero_placement.Span_),(Origin_zero_placement.Auto|Origin_zero_placement.Span_))->0in(* Calculate span only for indefinitely placed items as we don't need for
other items (whose required space will be taken into account by min and
max) *)letspan=match(oz_line.Line.start,oz_line.Line.end_)with|((Origin_zero_placement.Auto|Origin_zero_placement.Span_),(Origin_zero_placement.Auto|Origin_zero_placement.Span_))->indefinite_spanoz_line|_->1in(min,max,span)(* Iterate over children, producing an estimate of the min and max grid *lines*
along with the span of each item
Min and max grid lines are returned in origin-zero coordinates) The span is
measured in tracks spanned *)letget_known_child_positionschildren_seqexplicit_col_countexplicit_row_count=letcol_min=ref0inletcol_max=ref0inletcol_max_span=ref0inletrow_min=ref0inletrow_max=ref0inletrow_max_span=ref0inSeq.iter(funchild_style->(* Note: children reference the lines in between (and around) the tracks
not tracks themselves, and thus we must subtract 1 to get an accurate
estimate of the number of tracks *)letchild_col_min,child_col_max,child_col_span=child_min_line_max_line_span(Style.grid_columnchild_style)explicit_col_countinletchild_row_min,child_row_max,child_row_span=child_min_line_max_line_span(Style.grid_rowchild_style)explicit_row_countincol_min:=min!col_minchild_col_min;col_max:=max!col_maxchild_col_max;col_max_span:=max!col_max_spanchild_col_span;row_min:=min!row_minchild_row_min;row_max:=max!row_maxchild_row_max;row_max_span:=max!row_max_spanchild_row_span)children_seq;(!col_min,!col_max,!col_max_span,!row_min,!row_max,!row_max_span)(* Estimate the number of rows and columns in the grid This is used as a
performance optimisation to pre-size vectors and reduce allocations. It also
forms a necessary step in the auto-placement - The estimates for the explicit
and negative implicit track counts are exact. - However, the estimates for
the positive explicit track count is a lower bound as auto-placement can
affect this in ways which are impossible to predict until the auto-placement
algorithm is run.
Note that this function internally mixes use of grid track numbers and grid
line numbers *)letcompute_grid_size_estimate~explicit_col_count~explicit_row_count~child_styles_iter=(* Iterate over children, producing an estimate of the min and max grid lines
(in origin-zero coordinates where) along with the span of each item *)letcol_min,col_max,col_max_span,row_min,row_max,row_max_span=get_known_child_positionschild_styles_iterexplicit_col_countexplicit_row_countin(* Compute *track* count estimates for each axis from: - The explicit track
counts - The origin-zero coordinate min and max grid line variables *)letnegative_implicit_inline_tracks=implied_negative_implicit_trackscol_mininletexplicit_inline_tracks=explicit_col_countinletpositive_implicit_inline_tracks=ref(implied_positive_implicit_trackscol_maxexplicit_col_count)inletnegative_implicit_block_tracks=implied_negative_implicit_tracksrow_mininletexplicit_block_tracks=explicit_row_countinletpositive_implicit_block_tracks=ref(implied_positive_implicit_tracksrow_maxexplicit_row_count)in(* In each axis, adjust positive track estimate if any items have a span that
does not fit within the total number of tracks in the estimate *)lettot_inline_tracks=negative_implicit_inline_tracks+explicit_inline_tracks+!positive_implicit_inline_tracksiniftot_inline_tracks<col_max_spanthenpositive_implicit_inline_tracks:=col_max_span-explicit_inline_tracks-negative_implicit_inline_tracks;lettot_block_tracks=negative_implicit_block_tracks+explicit_block_tracks+!positive_implicit_block_tracksiniftot_block_tracks<row_max_spanthenpositive_implicit_block_tracks:=row_max_span-explicit_block_tracks-negative_implicit_block_tracks;letcolumn_counts=Grid_track_counts.make~negative_implicit:negative_implicit_inline_tracks~explicit:explicit_inline_tracks~positive_implicit:!positive_implicit_inline_tracksinletrow_counts=Grid_track_counts.make~negative_implicit:negative_implicit_block_tracks~explicit:explicit_block_tracks~positive_implicit:!positive_implicit_block_tracksin(column_counts,row_counts)