diff --git a/src/components/main/servo.rs b/src/components/main/servo.rs index aa61286bd32..7bd2a3e4cfa 100644 --- a/src/components/main/servo.rs +++ b/src/components/main/servo.rs @@ -97,6 +97,7 @@ pub extern "C" fn android_start(argc: int, argv: **u8) -> int { #[cfg(not(test))] pub fn run(opts: opts::Opts) { + ::servo_util::opts::set_experimental_enabled(opts.enable_experimental); RegisterBindings::RegisterProxyHandlers(); let mut pool_config = green::PoolConfig::new(); diff --git a/src/components/style/properties/mod.rs.mako b/src/components/style/properties/mod.rs.mako index 55ec83cc038..384171d08fd 100644 --- a/src/components/style/properties/mod.rs.mako +++ b/src/components/style/properties/mod.rs.mako @@ -35,7 +35,7 @@ def to_rust_ident(name): return name class Longhand(object): - def __init__(self, name, derived_from=None): + def __init__(self, name, derived_from=None, experimental=False): self.name = name self.ident = to_rust_ident(name) self.camel_case, _ = re.subn( @@ -43,6 +43,7 @@ class Longhand(object): lambda m: m.group(1).upper(), self.ident.strip("_").capitalize()) self.style_struct = THIS_STYLE_STRUCT + self.experimental = experimental if derived_from is None: self.derived_from = None else: @@ -94,12 +95,12 @@ pub mod longhands { value } - <%def name="raw_longhand(name, no_super=False, derived_from=None)"> + <%def name="raw_longhand(name, no_super=False, derived_from=None, experimental=False)"> <% if derived_from is not None: derived_from = derived_from.split() - property = Longhand(name, derived_from=derived_from) + property = Longhand(name, derived_from=derived_from, experimental=experimental) THIS_STYLE_STRUCT.longhands.append(property) LONGHANDS.append(property) LONGHANDS_BY_NAME[name] = property @@ -128,8 +129,9 @@ pub mod longhands { } - <%def name="longhand(name, no_super=False, derived_from=None)"> - <%self:raw_longhand name="${name}" derived_from="${derived_from}"> + <%def name="longhand(name, no_super=False, derived_from=None, experimental=False)"> + <%self:raw_longhand name="${name}" derived_from="${derived_from}" + experimental="${experimental}"> ${caller.body()} % if derived_from is None: pub fn parse_specified(_input: &[ComponentValue], _base_url: &Url) @@ -140,8 +142,9 @@ pub mod longhands { - <%def name="single_component_value(name, derived_from=None)"> - <%self:longhand name="${name}" derived_from="${derived_from}"> + <%def name="single_component_value(name, derived_from=None, experimental=False)"> + <%self:longhand name="${name}" derived_from="${derived_from}" + experimental="${experimental}"> ${caller.body()} pub fn parse(input: &[ComponentValue], base_url: &Url) -> Option { one_component_value(input).and_then(|c| from_component_value(c, base_url)) @@ -149,8 +152,8 @@ pub mod longhands { - <%def name="single_keyword_computed(name, values)"> - <%self:single_component_value name="${name}"> + <%def name="single_keyword_computed(name, values, experimental=False)"> + <%self:single_component_value name="${name}" experimental="${experimental}"> ${caller.body()} pub mod computed_value { #[allow(non_camel_case_types)] @@ -179,9 +182,10 @@ pub mod longhands { - <%def name="single_keyword(name, values)"> + <%def name="single_keyword(name, values, experimental=False)"> <%self:single_keyword_computed name="${name}" - values="${values}"> + values="${values}" + experimental="${experimental}"> // The computed value is the same as the specified value. pub use to_computed_value = super::computed_as_specified; @@ -323,7 +327,7 @@ pub mod longhands { ${new_style_struct("InheritedBox", is_inherited=True)} - ${single_keyword("direction", "ltr rtl")} + ${single_keyword("direction", "ltr rtl", experimental=True)} // CSS 2.1, Section 10 - Visual formatting model details @@ -1041,11 +1045,11 @@ pub mod longhands { // http://dev.w3.org/csswg/css-writing-modes/ ${switch_to_style_struct("InheritedBox")} - ${single_keyword("writing-mode", "horizontal-tb vertical-rl vertical-lr")} + ${single_keyword("writing-mode", "horizontal-tb vertical-rl vertical-lr", experimental=True)} // FIXME(SimonSapin): Add 'mixed' and 'upright' (needs vertical text support) // FIXME(SimonSapin): initial (first) value should be 'mixed', when that's implemented - ${single_keyword("text-orientation", "sideways sideways-left sideways-right")} + ${single_keyword("text-orientation", "sideways sideways-left sideways-right", experimental=True)} } @@ -1436,6 +1440,10 @@ pub fn parse_property_declaration_list>(input: I, base_url: &U match PropertyDeclaration::parse(n.as_slice(), v.as_slice(), list, base_url, seen) { UnknownProperty => log_css_error(l, format!( "Unsupported property: {}:{}", n, v.iter().to_css()).as_slice()), + ExperimentalProperty => log_css_error(l, format!( + "Experimental property, use `servo --enable_experimental` \ + or `servo -e` to enable: {}:{}", + n, v.iter().to_css()).as_slice()), InvalidValue => log_css_error(l, format!( "Invalid value: {}:{}", n, v.iter().to_css()).as_slice()), ValidOrIgnoredDeclaration => (), @@ -1486,6 +1494,7 @@ pub enum PropertyDeclaration { pub enum PropertyDeclarationParseResult { UnknownProperty, + ExperimentalProperty, InvalidValue, ValidOrIgnoredDeclaration, } @@ -1502,6 +1511,11 @@ impl PropertyDeclaration { % for property in LONGHANDS: % if property.derived_from is None: "${property.name}" => { + % if property.experimental: + if !::servo_util::opts::experimental_enabled() { + return ExperimentalProperty + } + % endif if seen.get_${property.ident}() { return ValidOrIgnoredDeclaration } diff --git a/src/components/util/geometry.rs b/src/components/util/geometry.rs index e0e980c7659..70882f17178 100644 --- a/src/components/util/geometry.rs +++ b/src/components/util/geometry.rs @@ -67,7 +67,7 @@ pub enum PagePx {} // See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info. // // FIXME: Implement Au using Length and ScaleFactor instead of a custom type. -#[deriving(Clone, PartialEq, PartialOrd, Zero)] +#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Zero)] pub struct Au(pub i32); impl Default for Au { diff --git a/src/components/util/logical_geometry.rs b/src/components/util/logical_geometry.rs index bd0ea74fed4..293c938c77f 100644 --- a/src/components/util/logical_geometry.rs +++ b/src/components/util/logical_geometry.rs @@ -5,6 +5,7 @@ /// Geometry in flow-relative space. use geom::{Size2D, Point2D, SideOffsets2D, Rect}; +use std::cmp::{min, max}; use std::fmt::{Show, Formatter, FormatError}; use std::num::Zero; @@ -130,15 +131,15 @@ impl Show for DebugWritingMode { /// A 2D size in flow-relative dimensions #[deriving(PartialEq, Eq, Clone)] pub struct LogicalSize { - pub isize: T, // inline-size (a.k.a. logical width) - pub bsize: T, // block-size (a.k.a. logical height) + pub inline: T, // inline-size, a.k.a. logical width, a.k.a. measure + pub block: T, // block-size, a.k.a. logical height, a.k.a. extent debug_writing_mode: DebugWritingMode, } impl Show for LogicalSize { fn fmt(&self, formatter: &mut Formatter) -> Result<(), FormatError> { write!(formatter, "LogicalSize[{}, {}, {}]", - self.debug_writing_mode, self.isize, self.bsize) + self.debug_writing_mode, self.inline, self.block) } } @@ -147,24 +148,24 @@ impl LogicalSize { #[inline] pub fn zero(mode: WritingMode) -> LogicalSize { LogicalSize { - isize: Zero::zero(), - bsize: Zero::zero(), + inline: Zero::zero(), + block: Zero::zero(), debug_writing_mode: DebugWritingMode::new(mode), } } #[inline] pub fn is_zero(&self) -> bool { - self.isize.is_zero() && self.bsize.is_zero() + self.inline.is_zero() && self.block.is_zero() } } impl LogicalSize { #[inline] - pub fn new(mode: WritingMode, isize: T, bsize: T) -> LogicalSize { + pub fn new(mode: WritingMode, inline: T, block: T) -> LogicalSize { LogicalSize { - isize: isize, - bsize: bsize, + inline: inline, + block: block, debug_writing_mode: DebugWritingMode::new(mode), } } @@ -182,9 +183,9 @@ impl LogicalSize { pub fn width(&self, mode: WritingMode) -> T { self.debug_writing_mode.check(mode); if mode.is_vertical() { - self.bsize + self.block } else { - self.isize + self.inline } } @@ -192,9 +193,9 @@ impl LogicalSize { pub fn set_width(&mut self, mode: WritingMode, width: T) { self.debug_writing_mode.check(mode); if mode.is_vertical() { - self.bsize = width + self.block = width } else { - self.isize = width + self.inline = width } } @@ -202,9 +203,9 @@ impl LogicalSize { pub fn height(&self, mode: WritingMode) -> T { self.debug_writing_mode.check(mode); if mode.is_vertical() { - self.isize + self.inline } else { - self.bsize + self.block } } @@ -212,9 +213,9 @@ impl LogicalSize { pub fn set_height(&mut self, mode: WritingMode, height: T) { self.debug_writing_mode.check(mode); if mode.is_vertical() { - self.isize = height + self.inline = height } else { - self.bsize = height + self.block = height } } @@ -222,9 +223,9 @@ impl LogicalSize { pub fn to_physical(&self, mode: WritingMode) -> Size2D { self.debug_writing_mode.check(mode); if mode.is_vertical() { - Size2D { width: self.bsize, height: self.isize } + Size2D { width: self.block, height: self.inline } } else { - Size2D { width: self.isize, height: self.bsize } + Size2D { width: self.inline, height: self.block } } } @@ -245,8 +246,8 @@ impl> Add, LogicalSize> for LogicalSize { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalSize { debug_writing_mode: self.debug_writing_mode, - isize: self.isize + other.isize, - bsize: self.bsize + other.bsize, + inline: self.inline + other.inline, + block: self.block + other.block, } } } @@ -257,8 +258,8 @@ impl> Sub, LogicalSize> for LogicalSize { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalSize { debug_writing_mode: self.debug_writing_mode, - isize: self.isize - other.isize, - bsize: self.bsize - other.bsize, + inline: self.inline - other.inline, + block: self.block - other.block, } } } @@ -395,14 +396,28 @@ impl> LogicalPoint { } } +impl> LogicalPoint { + /// This doesn’t really makes sense, + /// but happens when dealing with mutliple origins. + #[inline] + pub fn add_point(&self, other: &LogicalPoint) -> LogicalPoint { + self.debug_writing_mode.check_debug(other.debug_writing_mode); + LogicalPoint { + debug_writing_mode: self.debug_writing_mode, + i: self.i + other.i, + b: self.b + other.b, + } + } +} + impl> Add, LogicalPoint> for LogicalPoint { #[inline] fn add(&self, other: &LogicalSize) -> LogicalPoint { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalPoint { debug_writing_mode: self.debug_writing_mode, - i: self.i + other.isize, - b: self.b + other.bsize, + i: self.i + other.inline, + b: self.b + other.block, } } } @@ -413,8 +428,8 @@ impl> Sub, LogicalPoint> for LogicalPoint { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalPoint { debug_writing_mode: self.debug_writing_mode, - i: self.i - other.isize, - b: self.b - other.bsize, + i: self.i - other.inline, + b: self.b - other.block, } } } @@ -426,17 +441,20 @@ impl> Sub, LogicalPoint> for LogicalPoint { /// A positive "margin" can be added to a rectangle to obtain a bigger rectangle. #[deriving(PartialEq, Eq, Clone)] pub struct LogicalMargin { - pub bstart: T, - pub iend: T, - pub bend: T, - pub istart: T, + pub block_start: T, + pub inline_end: T, + pub block_end: T, + pub inline_start: T, debug_writing_mode: DebugWritingMode, } impl Show for LogicalMargin { fn fmt(&self, formatter: &mut Formatter) -> Result<(), FormatError> { - write!(formatter, "LogicalMargin[{}, bstart: {}, iend: {}, bend: {}, istart: {}]", - self.debug_writing_mode, self.bstart, self.iend, self.bend, self.istart) + write!(formatter, + "LogicalMargin[{}, block_start: {}, inline_end: {}, \ + block_end: {}, inline_start: {}]", + self.debug_writing_mode, self.block_start, + self.inline_end, self.block_end, self.inline_start) } } @@ -444,77 +462,83 @@ impl LogicalMargin { #[inline] pub fn zero(mode: WritingMode) -> LogicalMargin { LogicalMargin { - bstart: Zero::zero(), - iend: Zero::zero(), - bend: Zero::zero(), - istart: Zero::zero(), + block_start: Zero::zero(), + inline_end: Zero::zero(), + block_end: Zero::zero(), + inline_start: Zero::zero(), debug_writing_mode: DebugWritingMode::new(mode), } } #[inline] pub fn is_zero(&self) -> bool { - self.bstart.is_zero() && - self.iend.is_zero() && - self.bend.is_zero() && - self.istart.is_zero() + self.block_start.is_zero() && + self.inline_end.is_zero() && + self.block_end.is_zero() && + self.inline_start.is_zero() } } impl LogicalMargin { #[inline] - pub fn new(mode: WritingMode, bstart: T, iend: T, bend: T, istart: T) -> LogicalMargin { + pub fn new(mode: WritingMode, block_start: T, inline_end: T, block_end: T, inline_start: T) + -> LogicalMargin { LogicalMargin { - bstart: bstart, - iend: iend, - bend: bend, - istart: istart, + block_start: block_start, + inline_end: inline_end, + block_end: block_end, + inline_start: inline_start, debug_writing_mode: DebugWritingMode::new(mode), } } + #[inline] + pub fn new_all_same(mode: WritingMode, value: T) -> LogicalMargin { + LogicalMargin::new(mode, value, value, value, value) + } + #[inline] pub fn from_physical(mode: WritingMode, offsets: SideOffsets2D) -> LogicalMargin { - let bstart; - let iend; - let bend; - let istart; + let block_start; + let inline_end; + let block_end; + let inline_start; if mode.is_vertical() { if mode.is_vertical_lr() { - bstart = offsets.left; - bend = offsets.right; + block_start = offsets.left; + block_end = offsets.right; } else { - bstart = offsets.right; - bend = offsets.left; + block_start = offsets.right; + block_end = offsets.left; } if mode.is_inline_tb() { - istart = offsets.top; - iend = offsets.bottom; + inline_start = offsets.top; + inline_end = offsets.bottom; } else { - istart = offsets.bottom; - iend = offsets.top; + inline_start = offsets.bottom; + inline_end = offsets.top; } } else { - bstart = offsets.top; - bend = offsets.bottom; + block_start = offsets.top; + block_end = offsets.bottom; if mode.is_bidi_ltr() { - istart = offsets.left; - iend = offsets.right; + inline_start = offsets.left; + inline_end = offsets.right; } else { - istart = offsets.right; - iend = offsets.left; + inline_start = offsets.right; + inline_end = offsets.left; } } - LogicalMargin::new(mode, bstart, iend, bend, istart) + LogicalMargin::new(mode, block_start, inline_end, block_end, inline_start) } #[inline] pub fn top(&self, mode: WritingMode) -> T { self.debug_writing_mode.check(mode); if mode.is_vertical() { - if mode.is_inline_tb() { self.istart } else { self.iend } + if mode.is_inline_tb() { self.inline_start } else { self.inline_end } } else { - self.bstart + self.block_start } } @@ -522,9 +546,9 @@ impl LogicalMargin { pub fn set_top(&mut self, mode: WritingMode, top: T) { self.debug_writing_mode.check(mode); if mode.is_vertical() { - if mode.is_inline_tb() { self.istart = top } else { self.iend = top } + if mode.is_inline_tb() { self.inline_start = top } else { self.inline_end = top } } else { - self.bstart = top + self.block_start = top } } @@ -532,9 +556,9 @@ impl LogicalMargin { pub fn right(&self, mode: WritingMode) -> T { self.debug_writing_mode.check(mode); if mode.is_vertical() { - if mode.is_vertical_lr() { self.bend } else { self.bstart } + if mode.is_vertical_lr() { self.block_end } else { self.block_start } } else { - if mode.is_bidi_ltr() { self.iend } else { self.istart } + if mode.is_bidi_ltr() { self.inline_end } else { self.inline_start } } } @@ -542,9 +566,9 @@ impl LogicalMargin { pub fn set_right(&mut self, mode: WritingMode, right: T) { self.debug_writing_mode.check(mode); if mode.is_vertical() { - if mode.is_vertical_lr() { self.bend = right } else { self.bstart = right } + if mode.is_vertical_lr() { self.block_end = right } else { self.block_start = right } } else { - if mode.is_bidi_ltr() { self.iend = right } else { self.istart = right } + if mode.is_bidi_ltr() { self.inline_end = right } else { self.inline_start = right } } } @@ -552,9 +576,9 @@ impl LogicalMargin { pub fn bottom(&self, mode: WritingMode) -> T { self.debug_writing_mode.check(mode); if mode.is_vertical() { - if mode.is_inline_tb() { self.iend } else { self.istart } + if mode.is_inline_tb() { self.inline_end } else { self.inline_start } } else { - self.bend + self.block_end } } @@ -562,9 +586,9 @@ impl LogicalMargin { pub fn set_bottom(&mut self, mode: WritingMode, bottom: T) { self.debug_writing_mode.check(mode); if mode.is_vertical() { - if mode.is_inline_tb() { self.iend = bottom } else { self.istart = bottom } + if mode.is_inline_tb() { self.inline_end = bottom } else { self.inline_start = bottom } } else { - self.bend = bottom + self.block_end = bottom } } @@ -572,9 +596,9 @@ impl LogicalMargin { pub fn left(&self, mode: WritingMode) -> T { self.debug_writing_mode.check(mode); if mode.is_vertical() { - if mode.is_vertical_lr() { self.bstart } else { self.bend } + if mode.is_vertical_lr() { self.block_start } else { self.block_end } } else { - if mode.is_bidi_ltr() { self.istart } else { self.iend } + if mode.is_bidi_ltr() { self.inline_start } else { self.inline_end } } } @@ -582,9 +606,9 @@ impl LogicalMargin { pub fn set_left(&mut self, mode: WritingMode, left: T) { self.debug_writing_mode.check(mode); if mode.is_vertical() { - if mode.is_vertical_lr() { self.bstart = left } else { self.bend = left } + if mode.is_vertical_lr() { self.block_start = left } else { self.block_end = left } } else { - if mode.is_bidi_ltr() { self.istart = left } else { self.iend = left } + if mode.is_bidi_ltr() { self.inline_start = left } else { self.inline_end = left } } } @@ -597,28 +621,28 @@ impl LogicalMargin { let left; if mode.is_vertical() { if mode.is_vertical_lr() { - left = self.bstart; - right = self.bend; + left = self.block_start; + right = self.block_end; } else { - right = self.bstart; - left = self.bend; + right = self.block_start; + left = self.block_end; } if mode.is_inline_tb() { - top = self.istart; - bottom = self.iend; + top = self.inline_start; + bottom = self.inline_end; } else { - bottom = self.istart; - top = self.iend; + bottom = self.inline_start; + top = self.inline_end; } } else { - top = self.bstart; - bottom = self.bend; + top = self.block_start; + bottom = self.block_end; if mode.is_bidi_ltr() { - left = self.istart; - right = self.iend; + left = self.inline_start; + right = self.inline_end; } else { - right = self.istart; - left = self.iend; + right = self.inline_start; + left = self.inline_end; } } SideOffsets2D::new(top, right, bottom, left) @@ -637,22 +661,22 @@ impl LogicalMargin { impl> LogicalMargin { #[inline] - pub fn istart_end(&self) -> T { - self.istart + self.iend + pub fn inline_start_end(&self) -> T { + self.inline_start + self.inline_end } #[inline] - pub fn bstart_end(&self) -> T { - self.bstart + self.bend + pub fn block_start_end(&self) -> T { + self.block_start + self.block_end } #[inline] pub fn top_bottom(&self, mode: WritingMode) -> T { self.debug_writing_mode.check(mode); if mode.is_vertical() { - self.istart_end() + self.inline_start_end() } else { - self.bstart_end() + self.block_start_end() } } @@ -660,9 +684,9 @@ impl> LogicalMargin { pub fn left_right(&self, mode: WritingMode) -> T { self.debug_writing_mode.check(mode); if mode.is_vertical() { - self.bstart_end() + self.block_start_end() } else { - self.istart_end() + self.inline_start_end() } } } @@ -673,10 +697,10 @@ impl> Add, LogicalMargin> for LogicalMargin self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalMargin { debug_writing_mode: self.debug_writing_mode, - bstart: self.bstart + other.bstart, - iend: self.iend + other.iend, - bend: self.bend + other.bend, - istart: self.istart + other.istart, + block_start: self.block_start + other.block_start, + inline_end: self.inline_end + other.inline_end, + block_end: self.block_end + other.block_end, + inline_start: self.inline_start + other.inline_start, } } } @@ -687,10 +711,10 @@ impl> Sub, LogicalMargin> for LogicalMargin self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalMargin { debug_writing_mode: self.debug_writing_mode, - bstart: self.bstart - other.bstart, - iend: self.iend - other.iend, - bend: self.bend - other.bend, - istart: self.istart - other.istart, + block_start: self.block_start - other.block_start, + inline_end: self.inline_end - other.inline_end, + block_end: self.block_end - other.block_end, + inline_start: self.inline_start - other.inline_start, } } } @@ -706,9 +730,11 @@ pub struct LogicalRect { impl Show for LogicalRect { fn fmt(&self, formatter: &mut Formatter) -> Result<(), FormatError> { - write!(formatter, "LogicalRect[{}, istart: {}, bstart: {}, isize: {}, bsize: {}]", + write!(formatter, + "LogicalRect[{}, inline_start: {}, block_start: {}, \ + inline: {}, block: {}]", self.debug_writing_mode, self.start.i, self.start.b, - self.size.isize, self.size.bsize) + self.size.inline, self.size.block) } } @@ -730,10 +756,23 @@ impl LogicalRect { impl LogicalRect { #[inline] - pub fn new(mode: WritingMode, istart: T, bstart: T, isize: T, bsize: T) -> LogicalRect { + pub fn new(mode: WritingMode, inline_start: T, block_start: T, inline: T, block: T) + -> LogicalRect { LogicalRect { - start: LogicalPoint::new(mode, istart, bstart), - size: LogicalSize::new(mode, isize, bsize), + start: LogicalPoint::new(mode, inline_start, block_start), + size: LogicalSize::new(mode, inline, block), + debug_writing_mode: DebugWritingMode::new(mode), + } + } + + #[inline] + pub fn from_point_size(mode: WritingMode, start: LogicalPoint, size: LogicalSize) + -> LogicalRect { + start.debug_writing_mode.check(mode); + size.debug_writing_mode.check(mode); + LogicalRect { + start: start, + size: size, debug_writing_mode: DebugWritingMode::new(mode), } } @@ -743,48 +782,48 @@ impl + Sub> LogicalRect { #[inline] pub fn from_physical(mode: WritingMode, rect: Rect, container_size: Size2D) -> LogicalRect { - let istart; - let bstart; - let isize; - let bsize; + let inline_start; + let block_start; + let inline; + let block; if mode.is_vertical() { - isize = rect.size.height; - bsize = rect.size.width; + inline = rect.size.height; + block = rect.size.width; if mode.is_vertical_lr() { - bstart = rect.origin.x; + block_start = rect.origin.x; } else { - bstart = container_size.width - (rect.origin.x + rect.size.width); + block_start = container_size.width - (rect.origin.x + rect.size.width); } if mode.is_inline_tb() { - istart = rect.origin.y; + inline_start = rect.origin.y; } else { - istart = container_size.height - (rect.origin.y + rect.size.height); + inline_start = container_size.height - (rect.origin.y + rect.size.height); } } else { - isize = rect.size.width; - bsize = rect.size.height; - bstart = rect.origin.y; + inline = rect.size.width; + block = rect.size.height; + block_start = rect.origin.y; if mode.is_bidi_ltr() { - istart = rect.origin.x; + inline_start = rect.origin.x; } else { - istart = container_size.width - (rect.origin.x + rect.size.width); + inline_start = container_size.width - (rect.origin.x + rect.size.width); } } LogicalRect { - start: LogicalPoint::new(mode, istart, bstart), - size: LogicalSize::new(mode, isize, bsize), + start: LogicalPoint::new(mode, inline_start, block_start), + size: LogicalSize::new(mode, inline, block), debug_writing_mode: DebugWritingMode::new(mode), } } #[inline] - pub fn iend(&self) -> T { - self.start.i + self.size.isize + pub fn inline_end(&self) -> T { + self.start.i + self.size.inline } #[inline] - pub fn bend(&self) -> T { - self.start.b + self.size.bsize + pub fn block_end(&self) -> T { + self.start.b + self.size.block } #[inline] @@ -795,26 +834,26 @@ impl + Sub> LogicalRect { let width; let height; if mode.is_vertical() { - width = self.size.bsize; - height = self.size.isize; + width = self.size.block; + height = self.size.inline; if mode.is_vertical_lr() { x = self.start.b; } else { - x = container_size.width - self.bend(); + x = container_size.width - self.block_end(); } if mode.is_inline_tb() { y = self.start.i; } else { - y = container_size.height - self.iend(); + y = container_size.height - self.inline_end(); } } else { - width = self.size.isize; - height = self.size.bsize; + width = self.size.inline; + height = self.size.block; y = self.start.b; if mode.is_bidi_ltr() { x = self.start.i; } else { - x = container_size.width - self.iend(); + x = container_size.width - self.inline_end(); } } Rect { @@ -834,6 +873,41 @@ impl + Sub> LogicalRect { mode_to, self.to_physical(mode_from, container_size), container_size) } } + + pub fn translate(&self, offset: &LogicalPoint) -> LogicalRect { + LogicalRect { + start: self.start + LogicalSize { + inline: offset.i, + block: offset.b, + debug_writing_mode: offset.debug_writing_mode, + }, + size: self.size, + debug_writing_mode: self.debug_writing_mode, + } + } +} + +impl + Sub> LogicalRect { + #[inline] + pub fn union(&self, other: &LogicalRect) -> LogicalRect { + self.debug_writing_mode.check_debug(other.debug_writing_mode); + + let inline_start = min(self.start.i, other.start.i); + let block_start = min(self.start.b, other.start.b); + LogicalRect { + start: LogicalPoint { + i: inline_start, + b: block_start, + debug_writing_mode: self.debug_writing_mode, + }, + size: LogicalSize { + inline: max(self.inline_end(), other.inline_end()) - inline_start, + block: max(self.block_end(), other.block_end()) - block_start, + debug_writing_mode: self.debug_writing_mode, + }, + debug_writing_mode: self.debug_writing_mode, + } + } } impl + Sub> Add, LogicalRect> for LogicalRect { @@ -844,13 +918,13 @@ impl + Sub> Add, LogicalRect> for Logical start: LogicalPoint { // Growing a rectangle on the start side means pushing its // start point on the negative direction. - i: self.start.i - other.istart, - b: self.start.b - other.bstart, + i: self.start.i - other.inline_start, + b: self.start.b - other.block_start, debug_writing_mode: self.debug_writing_mode, }, size: LogicalSize { - isize: self.size.isize + other.istart_end(), - bsize: self.size.bsize + other.bstart_end(), + inline: self.size.inline + other.inline_start_end(), + block: self.size.block + other.block_start_end(), debug_writing_mode: self.debug_writing_mode, }, debug_writing_mode: self.debug_writing_mode, @@ -867,13 +941,13 @@ impl + Sub> Sub, LogicalRect> for Logical start: LogicalPoint { // Shrinking a rectangle on the start side means pushing its // start point on the positive direction. - i: self.start.i + other.istart, - b: self.start.b + other.bstart, + i: self.start.i + other.inline_start, + b: self.start.b + other.block_start, debug_writing_mode: self.debug_writing_mode, }, size: LogicalSize { - isize: self.size.isize - other.istart_end(), - bsize: self.size.bsize - other.bstart_end(), + inline: self.size.inline - other.inline_start_end(), + block: self.size.block - other.block_start_end(), debug_writing_mode: self.debug_writing_mode, }, debug_writing_mode: self.debug_writing_mode, diff --git a/src/components/util/opts.rs b/src/components/util/opts.rs index bdd1d2d4347..c1ce421758d 100644 --- a/src/components/util/opts.rs +++ b/src/components/util/opts.rs @@ -49,6 +49,9 @@ pub struct Opts { /// and cause it to produce output on that interval (`-m`). pub memory_profiler_period: Option, + /// Enable experimental web features (`-e`). + pub enable_experimental: bool, + /// The number of threads to use for layout (`-y`). Defaults to 1, which results in a recursive /// sequential algorithm. pub layout_threads: uint, @@ -87,6 +90,7 @@ pub fn from_cmdline_args(args: &[String]) -> Option { getopts::optopt("r", "rendering", "Rendering backend", "direct2d|core-graphics|core-graphics-accelerated|cairo|skia."), getopts::optopt("s", "size", "Size of tiles", "512"), getopts::optopt("", "device-pixel-ratio", "Device pixels per px", ""), + getopts::optflag("e", "experimental", "Enable experimental web features"), getopts::optopt("t", "threads", "Number of render threads", "1"), getopts::optflagopt("p", "profile", "Profiler flag and output interval", "10"), getopts::optflagopt("m", "memory-profile", "Memory profiler flag and output interval", "10"), @@ -176,6 +180,7 @@ pub fn from_cmdline_args(args: &[String]) -> Option { device_pixels_per_px: device_pixels_per_px, time_profiler_period: time_profiler_period, memory_profiler_period: memory_profiler_period, + enable_experimental: opt_match.opt_present("e"), layout_threads: layout_threads, exit_after_load: opt_match.opt_present("x"), output_file: opt_match.opt_str("o"), @@ -184,3 +189,17 @@ pub fn from_cmdline_args(args: &[String]) -> Option { bubble_widths_separately: opt_match.opt_present("b"), }) } + +static mut EXPERIMENTAL_ENABLED: bool = false; + +pub fn set_experimental_enabled(new_value: bool) { + unsafe { + EXPERIMENTAL_ENABLED = new_value; + } +} + +pub fn experimental_enabled() -> bool { + unsafe { + EXPERIMENTAL_ENABLED + } +}