Move CSS Writing Modes properties behind a new command-line flag.

This commit is contained in:
Simon Sapin 2014-07-09 21:31:18 +01:00
parent 7f6bd1707e
commit bc2aa8430b
5 changed files with 275 additions and 167 deletions

View file

@ -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();

View file

@ -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>
<%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 {
</%self:raw_longhand>
</%def>
<%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<SpecifiedValue> {
one_component_value(input).and_then(|c| from_component_value(c, base_url))
@ -149,8 +152,8 @@ pub mod longhands {
</%self:longhand>
</%def>
<%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 {
</%self:single_component_value>
</%def>
<%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;
</%self:single_keyword_computed>
@ -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<I: Iterator<Node>>(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
}

View file

@ -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 {

View file

@ -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<T> {
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<T: Show> Show for LogicalSize<T> {
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<T: Zero> LogicalSize<T> {
#[inline]
pub fn zero(mode: WritingMode) -> LogicalSize<T> {
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<T: Copy> LogicalSize<T> {
#[inline]
pub fn new(mode: WritingMode, isize: T, bsize: T) -> LogicalSize<T> {
pub fn new(mode: WritingMode, inline: T, block: T) -> LogicalSize<T> {
LogicalSize {
isize: isize,
bsize: bsize,
inline: inline,
block: block,
debug_writing_mode: DebugWritingMode::new(mode),
}
}
@ -182,9 +183,9 @@ impl<T: Copy> LogicalSize<T> {
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<T: Copy> LogicalSize<T> {
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<T: Copy> LogicalSize<T> {
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<T: Copy> LogicalSize<T> {
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<T: Copy> LogicalSize<T> {
pub fn to_physical(&self, mode: WritingMode) -> Size2D<T> {
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<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
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<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
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<T: Copy + Sub<T, T>> LogicalPoint<T> {
}
}
impl<T: Add<T,T>> LogicalPoint<T> {
/// This doesnt really makes sense,
/// but happens when dealing with mutliple origins.
#[inline]
pub fn add_point(&self, other: &LogicalPoint<T>) -> LogicalPoint<T> {
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<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
#[inline]
fn add(&self, other: &LogicalSize<T>) -> LogicalPoint<T> {
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<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
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<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
/// A positive "margin" can be added to a rectangle to obtain a bigger rectangle.
#[deriving(PartialEq, Eq, Clone)]
pub struct LogicalMargin<T> {
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<T: Show> Show for LogicalMargin<T> {
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<T: Zero> LogicalMargin<T> {
#[inline]
pub fn zero(mode: WritingMode) -> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
#[inline]
pub fn new(mode: WritingMode, bstart: T, iend: T, bend: T, istart: T) -> LogicalMargin<T> {
pub fn new(mode: WritingMode, block_start: T, inline_end: T, block_end: T, inline_start: T)
-> LogicalMargin<T> {
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<T> {
LogicalMargin::new(mode, value, value, value, value)
}
#[inline]
pub fn from_physical(mode: WritingMode, offsets: SideOffsets2D<T>) -> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
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<T: Copy> LogicalMargin<T> {
impl<T: Add<T, T>> LogicalMargin<T> {
#[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<T: Add<T, T>> LogicalMargin<T> {
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<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T>
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<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T>
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<T> {
impl<T: Show> Show for LogicalRect<T> {
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<T: Zero> LogicalRect<T> {
impl<T: Copy> LogicalRect<T> {
#[inline]
pub fn new(mode: WritingMode, istart: T, bstart: T, isize: T, bsize: T) -> LogicalRect<T> {
pub fn new(mode: WritingMode, inline_start: T, block_start: T, inline: T, block: T)
-> LogicalRect<T> {
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<T>, size: LogicalSize<T>)
-> LogicalRect<T> {
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<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> {
#[inline]
pub fn from_physical(mode: WritingMode, rect: Rect<T>, container_size: Size2D<T>)
-> LogicalRect<T> {
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<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> {
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<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> {
mode_to, self.to_physical(mode_from, container_size), container_size)
}
}
pub fn translate(&self, offset: &LogicalPoint<T>) -> LogicalRect<T> {
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<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> {
#[inline]
pub fn union(&self, other: &LogicalRect<T>) -> LogicalRect<T> {
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<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> {
@ -844,13 +918,13 @@ impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> 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<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> 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,

View file

@ -49,6 +49,9 @@ pub struct Opts {
/// and cause it to produce output on that interval (`-m`).
pub memory_profiler_period: Option<f64>,
/// 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<Opts> {
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<Opts> {
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<Opts> {
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
}
}