aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/layout/model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/layout/model.rs')
-rw-r--r--src/components/layout/model.rs337
1 files changed, 0 insertions, 337 deletions
diff --git a/src/components/layout/model.rs b/src/components/layout/model.rs
deleted file mode 100644
index 23647b1b77d..00000000000
--- a/src/components/layout/model.rs
+++ /dev/null
@@ -1,337 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//! Borders, padding, and margins.
-
-#![deny(unsafe_block)]
-
-use fragment::Fragment;
-
-use computed = style::computed_values;
-use geom::SideOffsets2D;
-use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, LP_Length, LP_Percentage};
-use style::ComputedValues;
-use servo_util::geometry::Au;
-use servo_util::geometry;
-use servo_util::logical_geometry::LogicalMargin;
-use std::fmt;
-
-/// A collapsible margin. See CSS 2.1 § 8.3.1.
-pub struct AdjoiningMargins {
- /// The value of the greatest positive margin.
- pub most_positive: Au,
-
- /// The actual value (not the absolute value) of the negative margin with the largest absolute
- /// value. Since this is not the absolute value, this is always zero or negative.
- pub most_negative: Au,
-}
-
-impl AdjoiningMargins {
- pub fn new() -> AdjoiningMargins {
- AdjoiningMargins {
- most_positive: Au(0),
- most_negative: Au(0),
- }
- }
-
- pub fn from_margin(margin_value: Au) -> AdjoiningMargins {
- if margin_value >= Au(0) {
- AdjoiningMargins {
- most_positive: margin_value,
- most_negative: Au(0),
- }
- } else {
- AdjoiningMargins {
- most_positive: Au(0),
- most_negative: margin_value,
- }
- }
- }
-
- pub fn union(&mut self, other: AdjoiningMargins) {
- self.most_positive = geometry::max(self.most_positive, other.most_positive);
- self.most_negative = geometry::min(self.most_negative, other.most_negative)
- }
-
- pub fn collapse(&self) -> Au {
- self.most_positive + self.most_negative
- }
-}
-
-/// Represents the block-start and block-end margins of a flow with collapsible margins. See CSS 2.1 § 8.3.1.
-pub enum CollapsibleMargins {
- /// Margins may not collapse with this flow.
- NoCollapsibleMargins(Au, Au),
-
- /// Both the block-start and block-end margins (specified here in that order) may collapse, but the
- /// margins do not collapse through this flow.
- MarginsCollapse(AdjoiningMargins, AdjoiningMargins),
-
- /// Margins collapse *through* this flow. This means, essentially, that the flow doesn’t
- /// have any border, padding, or out-of-flow (floating or positioned) content
- MarginsCollapseThrough(AdjoiningMargins),
-}
-
-impl CollapsibleMargins {
- pub fn new() -> CollapsibleMargins {
- NoCollapsibleMargins(Au(0), Au(0))
- }
-}
-
-enum FinalMarginState {
- MarginsCollapseThroughFinalMarginState,
- BottomMarginCollapsesFinalMarginState,
-}
-
-pub struct MarginCollapseInfo {
- pub state: MarginCollapseState,
- pub block_start_margin: AdjoiningMargins,
- pub margin_in: AdjoiningMargins,
-}
-
-impl MarginCollapseInfo {
- /// TODO(#2012, pcwalton): Remove this method once `fragment` is not an `Option`.
- pub fn new() -> MarginCollapseInfo {
- MarginCollapseInfo {
- state: AccumulatingCollapsibleTopMargin,
- block_start_margin: AdjoiningMargins::new(),
- margin_in: AdjoiningMargins::new(),
- }
- }
-
- pub fn initialize_block_start_margin(&mut self,
- fragment: &Fragment,
- can_collapse_block_start_margin_with_kids: bool) {
- if !can_collapse_block_start_margin_with_kids {
- self.state = AccumulatingMarginIn
- }
-
- self.block_start_margin = AdjoiningMargins::from_margin(fragment.margin.block_start)
- }
-
- pub fn finish_and_compute_collapsible_margins(mut self,
- fragment: &Fragment,
- can_collapse_block_end_margin_with_kids: bool)
- -> (CollapsibleMargins, Au) {
- let state = match self.state {
- AccumulatingCollapsibleTopMargin => {
- match fragment.style().content_block_size() {
- LPA_Auto | LPA_Length(Au(0)) | LPA_Percentage(0.) => {
- match fragment.style().min_block_size() {
- LP_Length(Au(0)) | LP_Percentage(0.) => {
- MarginsCollapseThroughFinalMarginState
- },
- _ => {
- // If the fragment has non-zero min-block-size, margins may not
- // collapse through it.
- BottomMarginCollapsesFinalMarginState
- }
- }
- },
- _ => {
- // If the fragment has an explicitly specified block-size, margins may not
- // collapse through it.
- BottomMarginCollapsesFinalMarginState
- }
- }
- }
- AccumulatingMarginIn => BottomMarginCollapsesFinalMarginState,
- };
-
- // Different logic is needed here depending on whether this flow can collapse its block-end
- // margin with its children.
- let block_end_margin = fragment.margin.block_end;
- if !can_collapse_block_end_margin_with_kids {
- match state {
- MarginsCollapseThroughFinalMarginState => {
- let advance = self.block_start_margin.collapse();
- self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
- (MarginsCollapse(self.block_start_margin, self.margin_in), advance)
- }
- BottomMarginCollapsesFinalMarginState => {
- let advance = self.margin_in.collapse();
- self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
- (MarginsCollapse(self.block_start_margin, self.margin_in), advance)
- }
- }
- } else {
- match state {
- MarginsCollapseThroughFinalMarginState => {
- self.block_start_margin.union(AdjoiningMargins::from_margin(block_end_margin));
- (MarginsCollapseThrough(self.block_start_margin), Au(0))
- }
- BottomMarginCollapsesFinalMarginState => {
- self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
- (MarginsCollapse(self.block_start_margin, self.margin_in), Au(0))
- }
- }
- }
- }
-
- pub fn current_float_ceiling(&mut self) -> Au {
- match self.state {
- AccumulatingCollapsibleTopMargin => self.block_start_margin.collapse(),
- AccumulatingMarginIn => self.margin_in.collapse(),
- }
- }
-
- /// Adds the child's potentially collapsible block-start margin to the current margin state and
- /// advances the Y offset by the appropriate amount to handle that margin. Returns the amount
- /// that should be added to the Y offset during block layout.
- pub fn advance_block_start_margin(&mut self, child_collapsible_margins: &CollapsibleMargins) -> Au {
- match (self.state, *child_collapsible_margins) {
- (AccumulatingCollapsibleTopMargin, NoCollapsibleMargins(block_start, _)) => {
- self.state = AccumulatingMarginIn;
- block_start
- }
- (AccumulatingCollapsibleTopMargin, MarginsCollapse(block_start, _)) => {
- self.block_start_margin.union(block_start);
- self.state = AccumulatingMarginIn;
- Au(0)
- }
- (AccumulatingMarginIn, NoCollapsibleMargins(block_start, _)) => {
- let previous_margin_value = self.margin_in.collapse();
- self.margin_in = AdjoiningMargins::new();
- previous_margin_value + block_start
- }
- (AccumulatingMarginIn, MarginsCollapse(block_start, _)) => {
- self.margin_in.union(block_start);
- let margin_value = self.margin_in.collapse();
- self.margin_in = AdjoiningMargins::new();
- margin_value
- }
- (_, MarginsCollapseThrough(_)) => {
- // For now, we ignore this; this will be handled by `advance_block-end_margin` below.
- Au(0)
- }
- }
- }
-
- /// Adds the child's potentially collapsible block-end margin to the current margin state and
- /// advances the Y offset by the appropriate amount to handle that margin. Returns the amount
- /// that should be added to the Y offset during block layout.
- pub fn advance_block_end_margin(&mut self, child_collapsible_margins: &CollapsibleMargins) -> Au {
- match (self.state, *child_collapsible_margins) {
- (AccumulatingCollapsibleTopMargin, NoCollapsibleMargins(..)) |
- (AccumulatingCollapsibleTopMargin, MarginsCollapse(..)) => {
- // Can't happen because the state will have been replaced with
- // `AccumulatingMarginIn` above.
- fail!("should not be accumulating collapsible block_start margins anymore!")
- }
- (AccumulatingCollapsibleTopMargin, MarginsCollapseThrough(margin)) => {
- self.block_start_margin.union(margin);
- Au(0)
- }
- (AccumulatingMarginIn, NoCollapsibleMargins(_, block_end)) => {
- assert_eq!(self.margin_in.most_positive, Au(0));
- assert_eq!(self.margin_in.most_negative, Au(0));
- block_end
- }
- (AccumulatingMarginIn, MarginsCollapse(_, block_end)) |
- (AccumulatingMarginIn, MarginsCollapseThrough(block_end)) => {
- self.margin_in.union(block_end);
- Au(0)
- }
- }
- }
-}
-
-pub enum MarginCollapseState {
- AccumulatingCollapsibleTopMargin,
- AccumulatingMarginIn,
-}
-
-/// Intrinsic inline-sizes, which consist of minimum and preferred.
-#[deriving(Encodable)]
-pub struct IntrinsicISizes {
- /// The *minimum inline-size* of the content.
- pub minimum_inline_size: Au,
- /// The *preferred inline-size* of the content.
- pub preferred_inline_size: Au,
- /// The estimated sum of borders, padding, and margins. Some calculations use this information
- /// when computing intrinsic inline-sizes.
- pub surround_inline_size: Au,
-}
-
-impl fmt::Show for IntrinsicISizes {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "min={}, pref={}, surr={}", self.minimum_inline_size, self.preferred_inline_size, self.surround_inline_size)
- }
-}
-
-impl IntrinsicISizes {
- pub fn new() -> IntrinsicISizes {
- IntrinsicISizes {
- minimum_inline_size: Au(0),
- preferred_inline_size: Au(0),
- surround_inline_size: Au(0),
- }
- }
-
- pub fn total_minimum_inline_size(&self) -> Au {
- self.minimum_inline_size + self.surround_inline_size
- }
-
- pub fn total_preferred_inline_size(&self) -> Au {
- self.preferred_inline_size + self.surround_inline_size
- }
-}
-
-/// Useful helper data type when computing values for blocks and positioned elements.
-pub enum MaybeAuto {
- Auto,
- Specified(Au),
-}
-
-impl MaybeAuto {
- #[inline]
- pub fn from_style(length: computed::LengthOrPercentageOrAuto, containing_length: Au)
- -> MaybeAuto {
- match length {
- computed::LPA_Auto => Auto,
- computed::LPA_Percentage(percent) => Specified(containing_length.scale_by(percent)),
- computed::LPA_Length(length) => Specified(length)
- }
- }
-
- #[inline]
- pub fn specified_or_default(&self, default: Au) -> Au {
- match *self {
- Auto => default,
- Specified(value) => value,
- }
- }
-
- #[inline]
- pub fn specified_or_zero(&self) -> Au {
- self.specified_or_default(Au::new(0))
- }
-}
-
-pub fn specified_or_none(length: computed::LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
- match length {
- computed::LPN_None => None,
- computed::LPN_Percentage(percent) => Some(containing_length.scale_by(percent)),
- computed::LPN_Length(length) => Some(length),
- }
-}
-
-pub fn specified(length: computed::LengthOrPercentage, containing_length: Au) -> Au {
- match length {
- computed::LP_Length(length) => length,
- computed::LP_Percentage(p) => containing_length.scale_by(p)
- }
-}
-
-#[inline]
-pub fn padding_from_style(style: &ComputedValues, containing_block_inline_size: Au)
- -> LogicalMargin<Au> {
- let padding_style = style.get_padding();
- LogicalMargin::from_physical(style.writing_mode, SideOffsets2D::new(
- specified(padding_style.padding_top, containing_block_inline_size),
- specified(padding_style.padding_right, containing_block_inline_size),
- specified(padding_style.padding_bottom, containing_block_inline_size),
- specified(padding_style.padding_left, containing_block_inline_size)))
-}
-