Skip to content

Commit

Permalink
Implement clone_transform.
Browse files Browse the repository at this point in the history
The implementation of clone_transform is an adaptation of set_transform.

MozReview-Commit-ID: ESE1ha0x666
  • Loading branch information
Hiroyuki Ikezoe committed Feb 3, 2017
1 parent 50dca76 commit 10b6c1b
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 16 deletions.
39 changes: 39 additions & 0 deletions components/style/gecko_bindings/sugar/ns_css_value.rs
Expand Up @@ -4,11 +4,19 @@

//! Little helpers for `nsCSSValue`.

use app_units::Au;
use gecko_bindings::bindings::Gecko_CSSValue_Drop;
use gecko_bindings::bindings::Gecko_CSSValue_GetAbsoluteLength;
use gecko_bindings::bindings::Gecko_CSSValue_GetCalc;
use gecko_bindings::bindings::Gecko_CSSValue_GetPercentage;
use gecko_bindings::bindings::Gecko_CSSValue_SetAbsoluteLength;
use gecko_bindings::bindings::Gecko_CSSValue_SetCalc;
use gecko_bindings::bindings::Gecko_CSSValue_SetPercentage;
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit, nsCSSValue_Array};
use std::mem;
use std::ops::Index;
use std::slice;
use values::computed::LengthOrPercentage;

impl nsCSSValue {
/// Create a CSSValue with null unit, useful to be used as a return value.
Expand Down Expand Up @@ -42,6 +50,37 @@ impl nsCSSValue {
debug_assert!(!array.is_null());
&*array
}

/// Sets LengthOrPercentage value to this nsCSSValue.
pub unsafe fn set_lop(&mut self, lop: LengthOrPercentage) {
match lop {
LengthOrPercentage::Length(au) => {
Gecko_CSSValue_SetAbsoluteLength(self, au.0)
}
LengthOrPercentage::Percentage(pc) => {
Gecko_CSSValue_SetPercentage(self, pc)
}
LengthOrPercentage::Calc(calc) => {
Gecko_CSSValue_SetCalc(self, calc.into())
}
}
}

/// Returns LengthOrPercentage value.
pub unsafe fn get_lop(&self) -> LengthOrPercentage {
match self.mUnit {
nsCSSUnit::eCSSUnit_Pixel => {
LengthOrPercentage::Length(Au(Gecko_CSSValue_GetAbsoluteLength(self)))
},
nsCSSUnit::eCSSUnit_Percent => {
LengthOrPercentage::Percentage(Gecko_CSSValue_GetPercentage(self))
},
nsCSSUnit::eCSSUnit_Calc => {
LengthOrPercentage::Calc(Gecko_CSSValue_GetCalc(self).into())
},
x => panic!("The unit should not be {:?}", x),
}
}
}

impl Drop for nsCSSValue {
Expand Down
82 changes: 66 additions & 16 deletions components/style/properties/gecko.mako.rs
Expand Up @@ -1317,7 +1317,7 @@ fn static_assert() {
css_value_setters = {
"length" : "bindings::Gecko_CSSValue_SetAbsoluteLength(%s, %s.0)",
"percentage" : "bindings::Gecko_CSSValue_SetPercentage(%s, %s)",
"lop" : "set_lop(%s, %s)",
"lop" : "%s.set_lop(%s)",
"angle" : "bindings::Gecko_CSSValue_SetAngle(%s, %s.0)",
"number" : "bindings::Gecko_CSSValue_SetNumber(%s, %s)",
}
Expand All @@ -1341,21 +1341,6 @@ fn static_assert() {
use gecko_bindings::sugar::refptr::RefPtr;
use properties::longhands::transform::computed_value::ComputedMatrix;
use properties::longhands::transform::computed_value::ComputedOperation;
use values::computed::LengthOrPercentage;

unsafe fn set_lop(value: &mut structs::nsCSSValue, lop: LengthOrPercentage) {
match lop {
LengthOrPercentage::Length(au) => {
bindings::Gecko_CSSValue_SetAbsoluteLength(value, au.0)
}
LengthOrPercentage::Percentage(pc) => {
bindings::Gecko_CSSValue_SetPercentage(value, pc)
}
LengthOrPercentage::Calc(calc) => {
bindings::Gecko_CSSValue_SetCalc(value, calc.into())
}
}
}

let vec = if let Some(v) = other.0 {
v
Expand Down Expand Up @@ -1396,6 +1381,71 @@ fn static_assert() {
unsafe { self.gecko.mSpecifiedTransform.set(&other.gecko.mSpecifiedTransform); }
}

<%def name="computed_operation_arm(name, keyword, items)">
<%
# %s is substituted with the call to GetArrayItem.
css_value_getters = {
"length" : "Au(bindings::Gecko_CSSValue_GetAbsoluteLength(%s))",
"lop" : "%s.get_lop()",
"angle" : "Angle(bindings::Gecko_CSSValue_GetAngle(%s))",
"number" : "bindings::Gecko_CSSValue_GetNumber(%s)",
}
%>
eCSSKeyword_${keyword} => {
ComputedOperation::${name.title()}(
% if name == "matrix":
ComputedMatrix {
% endif
% for index, item in enumerate(items):
% if name == "matrix":
m${index / 4 + 1}${index % 4 + 1}:
% endif
${css_value_getters[item] % (
"bindings::Gecko_CSSValue_GetArrayItemConst(gecko_value, %d)" % (index + 1)
)},
% endfor
% if name == "matrix":
}
% endif
)
},
</%def>
pub fn clone_transform(&self) -> longhands::transform::computed_value::T {
use app_units::Au;
use gecko_bindings::structs::nsCSSKeyword::*;
use properties::longhands::transform::computed_value;
use properties::longhands::transform::computed_value::ComputedMatrix;
use properties::longhands::transform::computed_value::ComputedOperation;
use values::computed::Angle;

if self.gecko.mSpecifiedTransform.mRawPtr.is_null() {
return computed_value::T(None);
}

let mut result = vec![];
let mut cur = unsafe { (*self.gecko.mSpecifiedTransform.to_safe().get()).mHead };
while !cur.is_null() {
let gecko_value = unsafe { &(*cur).mValue };
let transform_function = unsafe {
bindings::Gecko_CSSValue_GetKeyword(bindings::Gecko_CSSValue_GetArrayItemConst(gecko_value, 0))
};
let servo = unsafe {
match transform_function {
${computed_operation_arm("matrix", "matrix3d", ["number"] * 16)}
${computed_operation_arm("skew", "skew", ["angle"] * 2)}
${computed_operation_arm("translate", "translate3d", ["lop", "lop", "length"])}
${computed_operation_arm("scale", "scale3d", ["number"] * 3)}
${computed_operation_arm("rotate", "rotate3d", ["number"] * 3 + ["angle"])}
${computed_operation_arm("perspective", "perspective", ["length"])}
_ => panic!("We shouldn't set any other transform function types"),
}
};
result.push(servo);
unsafe { cur = (&*cur).mNext };
}
computed_value::T(Some(result))
}

pub fn set_animation_name(&mut self, v: longhands::animation_name::computed_value::T) {
use nsstring::nsCString;
unsafe { self.gecko.mAnimations.ensure_len(v.0.len()) };
Expand Down

0 comments on commit 10b6c1b

Please sign in to comment.