Skip to content

Commit

Permalink
Auto merge of #15331 - Manishearth:stylo-presattr, r=emilio,bz
Browse files Browse the repository at this point in the history
Basic handling framework for presentation attributes in Stylo, with handling for font-size and color

https://bugzilla.mozilla.org/show_bug.cgi?id=1330041

r=emilio,bz

<!-- 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/15331)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Feb 2, 2017
2 parents 8b9dc93 + fdcb1fd commit ab78ac2
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 18 deletions.
11 changes: 1 addition & 10 deletions components/script/dom/htmlfontelement.rs
Expand Up @@ -165,16 +165,7 @@ pub fn parse_legacy_font_size(mut input: &str) -> Option<&'static str> {
}

// Steps 10, 11, 12
Some(match value {
n if n >= 7 => "xxx-large",
6 => "xx-large",
5 => "x-large",
4 => "large",
3 => "medium",
2 => "small",
n if n <= 1 => "x-small",
_ => unreachable!(),
})
Some(specified::Length::from_font_size_int(value))
}

fn parse_length(value: &str) -> Option<specified::Length> {
Expand Down
18 changes: 13 additions & 5 deletions components/style/gecko/wrapper.rs
Expand Up @@ -25,13 +25,15 @@ use gecko::snapshot_helpers;
use gecko_bindings::bindings;
use gecko_bindings::bindings::{Gecko_DropStyleChildrenIterator, Gecko_MaybeCreateStyleChildrenIterator};
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetLastChild, Gecko_GetNextStyleChild};
use gecko_bindings::bindings::{Gecko_GetServoDeclarationBlock, Gecko_IsHTMLElementInHTMLDocument};
use gecko_bindings::bindings::{Gecko_IsLink, Gecko_IsRootElement, Gecko_MatchesElement};
use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink, Gecko_Namespace};
use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
use gecko_bindings::bindings::Gecko_ClassOrClassList;
use gecko_bindings::bindings::Gecko_GetAnimationRule;
use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetStyleAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetStyleContext;
use gecko_bindings::bindings::Gecko_IsHTMLElementInHTMLDocument;
use gecko_bindings::structs;
use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode};
use gecko_bindings::structs::{nsIAtom, nsIContent, nsStyleContext};
Expand All @@ -40,7 +42,7 @@ use gecko_bindings::structs::NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO;
use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
use parking_lot::RwLock;
use parser::ParserContextExtraData;
use properties::{ComputedValues, parse_style_attribute};
use properties::{ComputedValues, Importance, parse_style_attribute};
use properties::PropertyDeclarationBlock;
use selector_parser::{ElementExt, Snapshot};
use selectors::Element;
Expand Down Expand Up @@ -333,7 +335,7 @@ impl<'le> TElement for GeckoElement<'le> {
}

fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>> {
let declarations = unsafe { Gecko_GetServoDeclarationBlock(self.0) };
let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) };
declarations.map(|s| s.as_arc_opt()).unwrap_or(None)
}

Expand Down Expand Up @@ -431,10 +433,16 @@ impl<'le> PartialEq for GeckoElement<'le> {
}

impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> {
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
where V: Push<ApplicableDeclarationBlock>,
{
// FIXME(bholley) - Need to implement this.
let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) };
let declarations = declarations.and_then(|s| s.as_arc_opt());
if let Some(decl) = declarations {
hints.push(
ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), Importance::Normal)
);
}
}
}

Expand Down
13 changes: 12 additions & 1 deletion components/style/gecko_bindings/bindings.rs
Expand Up @@ -503,7 +503,11 @@ extern "C" {
-> u32;
}
extern "C" {
pub fn Gecko_GetServoDeclarationBlock(element: RawGeckoElementBorrowed)
pub fn Gecko_GetStyleAttrDeclarationBlock(element: RawGeckoElementBorrowed)
-> RawServoDeclarationBlockStrongBorrowedOrNull;
}
extern "C" {
pub fn Gecko_GetHTMLPresentationAttrDeclarationBlock(element: RawGeckoElementBorrowed)
-> RawServoDeclarationBlockStrongBorrowedOrNull;
}
extern "C" {
Expand Down Expand Up @@ -1370,6 +1374,13 @@ extern "C" {
property:
nsCSSPropertyID);
}
extern "C" {
pub fn Servo_DeclarationBlock_AddPresValue(declarations:
RawServoDeclarationBlockBorrowed,
property: nsCSSPropertyID,
css_value:
nsCSSValueBorrowedMut);
}
extern "C" {
pub fn Servo_CSSSupports2(name: *const nsACString_internal,
value: *const nsACString_internal) -> bool;
Expand Down
24 changes: 23 additions & 1 deletion components/style/gecko_bindings/sugar/ns_css_value.rs
Expand Up @@ -5,7 +5,7 @@
//! Little helpers for `nsCSSValue`.

use gecko_bindings::bindings::Gecko_CSSValue_Drop;
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit, nsCSSValue_Array};
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit, nsCSSValue_Array, nscolor};
use std::mem;
use std::ops::Index;
use std::slice;
Expand All @@ -26,6 +26,28 @@ impl nsCSSValue {
unsafe { *self.mValue.mInt.as_ref() }
}

/// Checks if it is an integer and returns it if so
pub fn integer(&self) -> Option<i32> {
if self.mUnit == nsCSSUnit::eCSSUnit_Integer ||
self.mUnit == nsCSSUnit::eCSSUnit_Enumerated ||
self.mUnit == nsCSSUnit::eCSSUnit_EnumColor {
Some(unsafe { *self.mValue.mInt.as_ref() })
} else {
None
}
}

/// Checks if it is an RGBA color, returning it if so
/// Only use it with colors set by SetColorValue(),
/// which always sets RGBA colors
pub fn color_value(&self) -> Option<nscolor> {
if self.mUnit == nsCSSUnit::eCSSUnit_RGBAColor {
Some(unsafe { *self.mValue.mColor.as_ref() })
} else {
None
}
}

/// Returns this nsCSSValue value as a floating point value, unchecked in
/// release builds.
pub fn float_unchecked(&self) -> f32 {
Expand Down
12 changes: 12 additions & 0 deletions components/style/values/specified/length.rs
Expand Up @@ -428,6 +428,18 @@ impl Length {
pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Length, ()> {
NoCalcLength::parse_dimension(value, unit).map(Length::NoCalc)
}
/// https://drafts.csswg.org/css-fonts-3/#font-size-prop
pub fn from_font_size_int(i: u8) -> Length {
match i {
0 | 1 => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 4),
2 => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 8 / 9),
3 => Length::Absolute(Au::from_px(FONT_MEDIUM_PX)),
4 => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 6 / 5),
5 => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 2),
6 => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 2),
_ => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3),
}
}

#[inline]
fn parse_internal(input: &mut Parser, context: AllowedNumericType) -> Result<Length, ()> {
Expand Down
57 changes: 56 additions & 1 deletion ports/geckolib/glue.rs
Expand Up @@ -34,7 +34,7 @@ use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSet
use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
use style::gecko_bindings::bindings::{nsACString, nsAString};
use style::gecko_bindings::bindings::{nsACString, nsCSSValueBorrowedMut, nsAString};
use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe;
use style::gecko_bindings::bindings::RawGeckoAnimationValueListBorrowedMut;
use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
Expand Down Expand Up @@ -946,6 +946,61 @@ pub extern "C" fn Servo_DeclarationBlock_RemovePropertyById(declarations: RawSer
remove_property(declarations, get_property_id_from_nscsspropertyid!(property, ()))
}

#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_AddPresValue(declarations: RawServoDeclarationBlockBorrowed,
property: nsCSSPropertyID,
css_value: nsCSSValueBorrowedMut) {
use style::gecko::values::convert_nscolor_to_rgba;
use style::properties::{DeclaredValue, LonghandId, PropertyDeclaration, PropertyId, longhands};
use style::values::specified;

let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
let prop = PropertyId::from_nscsspropertyid(property);

let long = match prop {
Ok(PropertyId::Longhand(long)) => long,
_ => {
error!("stylo: unknown presentation property with id {:?}", property);
return
}
};
let decl = match long {
LonghandId::FontSize => {
if let Some(int) = css_value.integer() {
PropertyDeclaration::FontSize(DeclaredValue::Value(
longhands::font_size::SpecifiedValue(
specified::LengthOrPercentage::Length(
specified::Length::from_font_size_int(int as u8)
)
)
))
} else {
error!("stylo: got unexpected non-integer value for font-size presentation attribute");
return
}
}
LonghandId::Color => {
if let Some(color) = css_value.color_value() {
PropertyDeclaration::Color(DeclaredValue::Value(
specified::CSSRGBA {
parsed: convert_nscolor_to_rgba(color),
authored: None
}
))
} else {
error!("stylo: got unexpected non-integer value for color presentation attribute");
return
}
}
_ => {
error!("stylo: cannot handle longhand {:?} from presentation attribute", long);
return
}
};
declarations.write().declarations.push((decl, Importance::Normal));

}

#[no_mangle]
pub extern "C" fn Servo_CSSSupports2(property: *const nsACString, value: *const nsACString) -> bool {
let property = unsafe { property.as_ref().unwrap().as_str_unchecked() };
Expand Down

0 comments on commit ab78ac2

Please sign in to comment.