mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Replace usage of discriminant_value in viewport.rs
This commit is contained in:
parent
f3d6859ab7
commit
3932a82a2c
2 changed files with 74 additions and 33 deletions
|
@ -23,9 +23,6 @@
|
||||||
//! [cssparser]: ../cssparser/index.html
|
//! [cssparser]: ../cssparser/index.html
|
||||||
//! [selectors]: ../selectors/index.html
|
//! [selectors]: ../selectors/index.html
|
||||||
|
|
||||||
// FIXME: replace discriminant_value with per-enum methods that use `match`?
|
|
||||||
#![feature(core_intrinsics)]
|
|
||||||
|
|
||||||
#![cfg_attr(feature = "servo", feature(custom_attribute))]
|
#![cfg_attr(feature = "servo", feature(custom_attribute))]
|
||||||
#![cfg_attr(feature = "servo", feature(custom_derive))]
|
#![cfg_attr(feature = "servo", feature(custom_derive))]
|
||||||
#![cfg_attr(feature = "servo", feature(plugin))]
|
#![cfg_attr(feature = "servo", feature(plugin))]
|
||||||
|
|
|
@ -15,9 +15,7 @@ use euclid::size::{Size2D, TypedSize2D};
|
||||||
use parser::{ParserContext, log_css_error};
|
use parser::{ParserContext, log_css_error};
|
||||||
use properties::{ComputedValues, ServoComputedValues};
|
use properties::{ComputedValues, ServoComputedValues};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::collections::hash_map::{Entry, HashMap};
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::intrinsics;
|
|
||||||
use std::iter::Enumerate;
|
use std::iter::Enumerate;
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom};
|
use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom};
|
||||||
|
@ -26,9 +24,59 @@ use util::geometry::ViewportPx;
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
use values::specified::{Length, LengthOrPercentageOrAuto, ViewportPercentageLength};
|
use values::specified::{Length, LengthOrPercentageOrAuto, ViewportPercentageLength};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
macro_rules! declare_viewport_descriptor {
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
( $( $variant: ident($data: ident), )+ ) => {
|
||||||
pub enum ViewportDescriptor {
|
declare_viewport_descriptor_inner!([] [ $( $variant($data), )+ ] 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! declare_viewport_descriptor_inner {
|
||||||
|
(
|
||||||
|
[ $( $assigned_variant: ident($assigned_data: ident) = $assigned_discriminant: expr, )* ]
|
||||||
|
[
|
||||||
|
$next_variant: ident($next_data: ident),
|
||||||
|
$( $variant: ident($data: ident), )*
|
||||||
|
]
|
||||||
|
$next_discriminant: expr
|
||||||
|
) => {
|
||||||
|
declare_viewport_descriptor_inner! {
|
||||||
|
[
|
||||||
|
$( $assigned_variant($assigned_data) = $assigned_discriminant, )*
|
||||||
|
$next_variant($next_data) = $next_discriminant,
|
||||||
|
]
|
||||||
|
[ $( $variant($data), )* ]
|
||||||
|
$next_discriminant + 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
[ $( $assigned_variant: ident($assigned_data: ident) = $assigned_discriminant: expr, )* ]
|
||||||
|
[ ]
|
||||||
|
$number_of_variants: expr
|
||||||
|
) => {
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub enum ViewportDescriptor {
|
||||||
|
$(
|
||||||
|
$assigned_variant($assigned_data),
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
|
||||||
|
const VIEWPORT_DESCRIPTOR_VARIANTS: usize = $number_of_variants;
|
||||||
|
|
||||||
|
impl ViewportDescriptor {
|
||||||
|
fn discriminant_value(&self) -> usize {
|
||||||
|
match *self {
|
||||||
|
$(
|
||||||
|
ViewportDescriptor::$assigned_variant(..) => $assigned_discriminant,
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_viewport_descriptor! {
|
||||||
MinWidth(ViewportLength),
|
MinWidth(ViewportLength),
|
||||||
MaxWidth(ViewportLength),
|
MaxWidth(ViewportLength),
|
||||||
|
|
||||||
|
@ -40,7 +88,7 @@ pub enum ViewportDescriptor {
|
||||||
MaxZoom(Zoom),
|
MaxZoom(Zoom),
|
||||||
|
|
||||||
UserZoom(UserZoom),
|
UserZoom(UserZoom),
|
||||||
Orientation(Orientation)
|
Orientation(Orientation),
|
||||||
}
|
}
|
||||||
|
|
||||||
trait FromMeta: Sized {
|
trait FromMeta: Sized {
|
||||||
|
@ -287,18 +335,15 @@ impl ViewportRule {
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn from_meta(content: &str) -> Option<ViewportRule> {
|
pub fn from_meta(content: &str) -> Option<ViewportRule> {
|
||||||
let mut declarations = HashMap::new();
|
let mut declarations = vec![None; VIEWPORT_DESCRIPTOR_VARIANTS];
|
||||||
macro_rules! push_descriptor {
|
macro_rules! push_descriptor {
|
||||||
($descriptor:ident($value:expr)) => {{
|
($descriptor:ident($value:expr)) => {{
|
||||||
let descriptor = ViewportDescriptor::$descriptor($value);
|
let descriptor = ViewportDescriptor::$descriptor($value);
|
||||||
declarations.insert(
|
let discriminant = descriptor.discriminant_value();
|
||||||
unsafe {
|
declarations[discriminant] = Some(ViewportDescriptorDeclaration::new(
|
||||||
intrinsics::discriminant_value(&descriptor)
|
Origin::Author,
|
||||||
},
|
descriptor,
|
||||||
ViewportDescriptorDeclaration::new(
|
false));
|
||||||
Origin::Author,
|
|
||||||
descriptor,
|
|
||||||
false))
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -374,7 +419,7 @@ impl ViewportRule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let declarations: Vec<_> = declarations.into_iter().map(|kv| kv.1).collect();
|
let declarations: Vec<_> = declarations.into_iter().filter_map(|entry| entry).collect();
|
||||||
if !declarations.is_empty() {
|
if !declarations.is_empty() {
|
||||||
Some(ViewportRule { declarations: declarations })
|
Some(ViewportRule { declarations: declarations })
|
||||||
} else {
|
} else {
|
||||||
|
@ -471,34 +516,33 @@ impl ViewportDescriptorDeclaration {
|
||||||
fn cascade<'a, I>(iter: I) -> Vec<ViewportDescriptorDeclaration>
|
fn cascade<'a, I>(iter: I) -> Vec<ViewportDescriptorDeclaration>
|
||||||
where I: Iterator<Item=&'a ViewportDescriptorDeclaration>
|
where I: Iterator<Item=&'a ViewportDescriptorDeclaration>
|
||||||
{
|
{
|
||||||
let mut declarations: HashMap<u64, (usize, &'a ViewportDescriptorDeclaration)> = HashMap::new();
|
let mut declarations: Vec<Option<(usize, &'a ViewportDescriptorDeclaration)>> =
|
||||||
|
vec![None; VIEWPORT_DESCRIPTOR_VARIANTS];
|
||||||
|
|
||||||
// index is used to reconstruct order of appearance after all declarations
|
// index is used to reconstruct order of appearance after all declarations
|
||||||
// have been added to the map
|
// have been added to the map
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
for declaration in iter {
|
for declaration in iter {
|
||||||
let descriptor = unsafe {
|
let descriptor = declaration.descriptor.discriminant_value();
|
||||||
intrinsics::discriminant_value(&declaration.descriptor)
|
|
||||||
};
|
|
||||||
|
|
||||||
match declarations.entry(descriptor) {
|
match declarations[descriptor] {
|
||||||
Entry::Occupied(mut entry) => {
|
Some((ref mut entry_index, ref mut entry_declaration)) => {
|
||||||
if declaration.higher_or_equal_precendence(entry.get().1) {
|
if declaration.higher_or_equal_precendence(entry_declaration) {
|
||||||
entry.insert((index, declaration));
|
*entry_declaration = declaration;
|
||||||
|
*entry_index = index;
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Entry::Vacant(entry) => {
|
ref mut entry @ None => {
|
||||||
entry.insert((index, declaration));
|
*entry = Some((index, declaration));
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert to a list and sort the descriptors by order of appearance
|
// sort the descriptors by order of appearance
|
||||||
let mut declarations: Vec<_> = declarations.into_iter().map(|kv| kv.1).collect();
|
declarations.sort_by_key(|entry| entry.map(|(index, _)| index));
|
||||||
declarations.sort_by(|a, b| a.0.cmp(&b.0));
|
declarations.into_iter().filter_map(|entry| entry.map(|(_, decl)| *decl)).collect::<Vec<_>>()
|
||||||
declarations.into_iter().map(|id| *id.1).collect::<Vec<_>>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I> ViewportDescriptorDeclarationCascade for I
|
impl<'a, I> ViewportDescriptorDeclarationCascade for I
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue