mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Rename the MinMaxConstraint to SizeConstraint and enhancement
Renamed to `SizeConstraint`, add an optional `border` parameter to deal with `box-sizing: border-box`, and fix its bug when involving with `calc`.
This commit is contained in:
parent
b9a8ccd775
commit
39780e894b
3 changed files with 66 additions and 49 deletions
|
@ -19,7 +19,7 @@ use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
|
||||||
use gfx::display_list::StackingContext;
|
use gfx::display_list::StackingContext;
|
||||||
use gfx_traits::ScrollRootId;
|
use gfx_traits::ScrollRootId;
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::{IntrinsicISizes, MaybeAuto, MinMaxConstraint};
|
use model::{IntrinsicISizes, MaybeAuto, SizeConstraint};
|
||||||
use model::{specified, specified_or_none};
|
use model::{specified, specified_or_none};
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
@ -38,7 +38,7 @@ use style::values::computed::{LengthOrPercentageOrAutoOrContent, LengthOrPercent
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum AxisSize {
|
enum AxisSize {
|
||||||
Definite(Au),
|
Definite(Au),
|
||||||
MinMax(MinMaxConstraint),
|
MinMax(SizeConstraint),
|
||||||
Infinite,
|
Infinite,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ impl AxisSize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LengthOrPercentageOrAuto::Auto => {
|
LengthOrPercentageOrAuto::Auto => {
|
||||||
AxisSize::MinMax(MinMaxConstraint::new(content_size, min, max))
|
AxisSize::MinMax(SizeConstraint::new(content_size, min, max, None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT, LineMetrics};
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto};
|
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, SizeConstraint};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use net_traits::image::base::{Image, ImageMetadata};
|
use net_traits::image::base::{Image, ImageMetadata};
|
||||||
use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder};
|
use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder};
|
||||||
|
@ -1202,6 +1202,27 @@ impl Fragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Return a size constraint that can be used the clamp size in given direction.
|
||||||
|
/// To take `box-sizing: border-box` into account, the `border_padding` field
|
||||||
|
/// must be initialized first.
|
||||||
|
///
|
||||||
|
/// TODO(stshine): Maybe there is a more convenient way.
|
||||||
|
pub fn size_constraint(&self, containing_size: Option<Au>, direction: Direction) -> SizeConstraint {
|
||||||
|
let (style_min_size, style_max_size) = match direction {
|
||||||
|
Direction::Inline => (self.style.min_inline_size(), self.style.max_inline_size()),
|
||||||
|
Direction::Block => (self.style.min_block_size(), self.style.max_block_size())
|
||||||
|
};
|
||||||
|
|
||||||
|
let border = if self.style().get_position().box_sizing == box_sizing::T::border_box {
|
||||||
|
Some(self.border_padding.start_end(direction))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
SizeConstraint::new(containing_size, style_min_size, style_max_size, border)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a guess as to the distances from the margin edge of this fragment to its content
|
/// Returns a guess as to the distances from the margin edge of this fragment to its content
|
||||||
/// in the inline direction. This will generally be correct unless percentages are involved.
|
/// in the inline direction. This will generally be correct unless percentages are involved.
|
||||||
///
|
///
|
||||||
|
|
|
@ -504,64 +504,60 @@ impl ToGfxMatrix for ComputedMatrix {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
/// A min-size and max-size constraint. The constructor has a optional `border`
|
||||||
// https://drafts.csswg.org/css2/visudet.html#min-max-heights
|
/// parameter, and when it is present the constraint will be subtracted. This is
|
||||||
/// A min or max constraint
|
/// 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.
|
||||||
/// A `max` of `None` is equivalent to no limmit for the size in the given
|
#[derive(Clone, Copy, Debug)]
|
||||||
/// dimension. The `min` is >= 0, as negative values are illegal and by
|
pub struct SizeConstraint {
|
||||||
/// default `min` is 0.
|
min_size: Au,
|
||||||
#[derive(Debug)]
|
max_size: Option<Au>,
|
||||||
pub struct MinMaxConstraint {
|
|
||||||
min: Au,
|
|
||||||
max: Option<Au>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MinMaxConstraint {
|
impl SizeConstraint {
|
||||||
/// Create a `MinMaxConstraint` for a dimension given the min, max, and content box size for
|
/// Create a `SizeConstraint` for an axis.
|
||||||
/// an axis
|
pub fn new(container_size: Option<Au>,
|
||||||
pub fn new(content_size: Option<Au>, min: LengthOrPercentage,
|
min_size: LengthOrPercentage,
|
||||||
max: LengthOrPercentageOrNone) -> MinMaxConstraint {
|
max_size: LengthOrPercentageOrNone,
|
||||||
let min = match min {
|
border: Option<Au>) -> SizeConstraint {
|
||||||
LengthOrPercentage::Length(length) => length,
|
let mut min_size = match container_size {
|
||||||
LengthOrPercentage::Percentage(percent) => {
|
Some(container_size) => specified(min_size, container_size),
|
||||||
match content_size {
|
None => if let LengthOrPercentage::Length(length) = min_size {
|
||||||
Some(size) => size.scale_by(percent),
|
length
|
||||||
None => Au(0),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
LengthOrPercentage::Calc(calc) => {
|
|
||||||
match content_size {
|
|
||||||
Some(size) => size.scale_by(calc.percentage()),
|
|
||||||
None => 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()))
|
|
||||||
}
|
|
||||||
LengthOrPercentageOrNone::None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
MinMaxConstraint {
|
|
||||||
min: min,
|
|
||||||
max: max
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clamp the given size by the given `min` and `max` constraints.
|
|
||||||
pub fn clamp(&self, other: Au) -> Au {
|
|
||||||
if other < self.min {
|
|
||||||
self.min
|
|
||||||
} else {
|
} else {
|
||||||
match self.max {
|
Au(0)
|
||||||
Some(max) if max < other => max,
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeConstraint {
|
||||||
|
min_size: min_size,
|
||||||
|
max_size: max_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clamp the given size by the given min size and max size constraint.
|
||||||
|
pub fn clamp(&self, other: Au) -> Au {
|
||||||
|
if other < self.min_size {
|
||||||
|
self.min_size
|
||||||
|
} else {
|
||||||
|
match self.max_size {
|
||||||
|
Some(max_size) if max_size < other => max_size,
|
||||||
_ => other
|
_ => other
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue