diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-12-12 03:25:03 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-12 03:25:03 -0800 |
commit | 1993b6e812de30de06100e7d52c1d90af929f24f (patch) | |
tree | 909da2600ac4dd9282326c6931ed6b83190750ba /components/layout/model.rs | |
parent | 7eb7d7adb2ab10642193f013f59fa93dd042d41a (diff) | |
parent | 7bca3034b2d3d9aa2634d3ca5b7471fed254b770 (diff) | |
download | servo-1993b6e812de30de06100e7d52c1d90af929f24f.tar.gz servo-1993b6e812de30de06100e7d52c1d90af929f24f.zip |
Auto merge of #14490 - stshine:replaced-size, r=emilio
layout: Unify size calculation of replaced elements
<!-- Please describe your changes on the following line: -->
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [ ] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14490)
<!-- Reviewable:end -->
Diffstat (limited to 'components/layout/model.rs')
-rw-r--r-- | components/layout/model.rs | 101 |
1 files changed, 56 insertions, 45 deletions
diff --git a/components/layout/model.rs b/components/layout/model.rs index a0693e0d8f8..89847e0190b 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -436,6 +436,21 @@ impl MaybeAuto { } } +/// Receive an optional container size and return used value for width or height. +/// +/// `style_length`: content size as given in the CSS. +pub fn style_length(style_length: LengthOrPercentageOrAuto, + container_size: Option<Au>) -> MaybeAuto { + match container_size { + Some(length) => MaybeAuto::from_style(style_length, length), + None => if let LengthOrPercentageOrAuto::Length(length) = style_length { + MaybeAuto::Specified(length) + } else { + MaybeAuto::Auto + } + } +} + pub fn specified_or_none(length: LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> { match length { LengthOrPercentageOrNone::None => None, @@ -504,64 +519,60 @@ impl ToGfxMatrix for ComputedMatrix { } } -// https://drafts.csswg.org/css2/visudet.html#min-max-widths -// https://drafts.csswg.org/css2/visudet.html#min-max-heights -/// A min or max constraint -/// -/// A `max` of `None` is equivalent to no limmit for the size in the given -/// dimension. The `min` is >= 0, as negative values are illegal and by -/// default `min` is 0. -#[derive(Debug)] -pub struct MinMaxConstraint { - min: Au, - max: Option<Au> +/// A min-size and max-size constraint. The constructor has a optional `border` +/// parameter, and when it is present the constraint will be subtracted. This is +/// used to adjust the constraint for `box-sizing: border-box`, and when you do so +/// make sure the size you want to clamp is intended to be used for content box. +#[derive(Clone, Copy, Debug)] +pub struct SizeConstraint { + min_size: Au, + max_size: Option<Au>, } -impl MinMaxConstraint { - /// Create a `MinMaxConstraint` for a dimension given the min, max, and content box size for - /// an axis - pub fn new(content_size: Option<Au>, min: LengthOrPercentage, - max: LengthOrPercentageOrNone) -> MinMaxConstraint { - let min = match min { - LengthOrPercentage::Length(length) => length, - LengthOrPercentage::Percentage(percent) => { - match content_size { - Some(size) => size.scale_by(percent), - None => Au(0), - } - }, - LengthOrPercentage::Calc(calc) => { - match content_size { - Some(size) => size.scale_by(calc.percentage()), - None => Au(0), - } +impl SizeConstraint { + /// Create a `SizeConstraint` for an axis. + pub fn new(container_size: Option<Au>, + min_size: LengthOrPercentage, + max_size: LengthOrPercentageOrNone, + border: Option<Au>) -> SizeConstraint { + let mut min_size = match container_size { + Some(container_size) => specified(min_size, container_size), + None => if let LengthOrPercentage::Length(length) = min_size { + length + } else { + Au(0) } }; - let max = match max { - LengthOrPercentageOrNone::Length(length) => Some(length), - LengthOrPercentageOrNone::Percentage(percent) => { - content_size.map(|size| size.scale_by(percent)) - }, - LengthOrPercentageOrNone::Calc(calc) => { - content_size.map(|size| size.scale_by(calc.percentage())) + let mut max_size = match container_size { + Some(container_size) => specified_or_none(max_size, container_size), + None => if let LengthOrPercentageOrNone::Length(length) = max_size { + Some(length) + } else { + None } - LengthOrPercentageOrNone::None => None, }; + // Make sure max size is not smaller than min size. + max_size = max_size.map(|x| max(x, min_size)); + + if let Some(border) = border { + min_size = max((min_size - border), Au(0)); + max_size = max_size.map(|x| max(x - border, Au(0))); + } - MinMaxConstraint { - min: min, - max: max + SizeConstraint { + min_size: min_size, + max_size: max_size } } - /// Clamp the given size by the given `min` and `max` constraints. + /// Clamp the given size by the given min size and max size constraint. pub fn clamp(&self, other: Au) -> Au { - if other < self.min { - self.min + if other < self.min_size { + self.min_size } else { - match self.max { - Some(max) if max < other => max, + match self.max_size { + Some(max_size) if max_size < other => max_size, _ => other } } |