Bug 1505871. Implement yaml reader/writer for component transfer. r=jrmuizel

This commit is contained in:
Timothy Nikkel 2019-02-25 22:45:16 -06:00
Родитель 5455bb5b62
Коммит 24dc00068c
3 изменённых файлов: 112 добавлений и 0 удалений

Просмотреть файл

@ -1825,6 +1825,7 @@ impl YamlFrameReader {
}
let filters = yaml["filters"].as_vec_filter_op().unwrap_or(vec![]);
let filter_datas = yaml["filter-datas"].as_vec_filter_data().unwrap_or(vec![]);
info.rect = bounds;
info.clip_rect = bounds;
@ -1836,6 +1837,7 @@ impl YamlFrameReader {
transform_style,
mix_blend_mode,
&filters,
&filter_datas,
raster_space,
cache_tiles,
);

Просмотреть файл

@ -217,6 +217,8 @@ fn write_stacking_context(
sc: &StackingContext,
properties: &SceneProperties,
filter_iter: AuxIter<FilterOp>,
filter_data_iter: &[TempFilterData],
display_list: &BuiltDisplayList,
) {
enum_node(parent, "transform-style", sc.transform_style);
@ -266,10 +268,50 @@ fn write_stacking_context(
FilterOp::LinearToSrgb => {
filters.push(Yaml::String("linear-to-srgb".to_string()))
}
FilterOp::ComponentTransfer => {
filters.push(Yaml::String("component-transfer".to_string()))
}
}
}
yaml_node(parent, "filters", Yaml::Array(filters));
// filter datas
let mut filter_datas = vec![];
for filter_data in filter_data_iter {
let func_types = display_list.get(filter_data.func_types).map(|func_type| {
match func_type {
ComponentTransferFuncType::Identity => { Yaml::String("Identity".to_string()) }
ComponentTransferFuncType::Table => { Yaml::String("Table".to_string()) }
ComponentTransferFuncType::Discrete => { Yaml::String("Discrete".to_string()) }
ComponentTransferFuncType::Linear => { Yaml::String("Linear".to_string()) }
ComponentTransferFuncType::Gamma => { Yaml::String("Gamma".to_string()) }
}
}).collect();
let r_values = display_list.get(filter_data.r_values).map(|value| {
Yaml::String(format!("{}", value))
}).collect();
let g_values = display_list.get(filter_data.g_values).map(|value| {
Yaml::String(format!("{}", value))
}).collect();
let b_values = display_list.get(filter_data.b_values).map(|value| {
Yaml::String(format!("{}", value))
}).collect();
let a_values = display_list.get(filter_data.a_values).map(|value| {
Yaml::String(format!("{}", value))
}).collect();
let avec: Vec<Yaml> = [
Yaml::Array(func_types),
Yaml::Array(r_values),
Yaml::Array(g_values),
Yaml::Array(b_values),
Yaml::Array(a_values),
].to_vec();
filter_datas.push(Yaml::Array(avec));
}
yaml_node(parent, "filter-datas", Yaml::Array(filter_datas));
}
#[cfg(target_os = "macos")]
@ -1034,6 +1076,8 @@ impl YamlFrameWriter {
&item.stacking_context,
&scene.properties,
filters,
base.filter_datas(),
display_list,
);
let mut sub_iter = base.sub_iter();
@ -1152,6 +1196,8 @@ impl YamlFrameWriter {
}
Sdi::SetGradientStops => panic!("dummy item yielded?"),
Sdi::SetFilterOps => panic!("dummy item yielded?"),
Sdi::SetFilterData => panic!("dummy item yielded?"),
Sdi::PushShadow(shadow) => {
str_node(&mut v, "type", "shadow");
vector_node(&mut v, "offset", &shadow.offset);

Просмотреть файл

@ -36,6 +36,8 @@ pub trait YamlHelper {
fn as_mix_blend_mode(&self) -> Option<MixBlendMode>;
fn as_filter_op(&self) -> Option<FilterOp>;
fn as_vec_filter_op(&self) -> Option<Vec<FilterOp>>;
fn as_filter_data(&self) -> Option<FilterData>;
fn as_vec_filter_data(&self) -> Option<Vec<FilterData>>;
}
fn string_to_color(color: &str) -> Option<ColorF> {
@ -139,6 +141,17 @@ define_string_enum!(
define_string_enum!(ClipMode, [Clip = "clip", ClipOut = "clip-out"]);
define_string_enum!(
ComponentTransferFuncType,
[
Identity = "Identity",
Table = "Table",
Discrete = "Discrete",
Linear = "Linear",
Gamma = "Gamma"
]
);
// Rotate around `axis` by `degrees` angle
fn make_rotation(
origin: &LayoutPoint,
@ -548,6 +561,9 @@ impl YamlHelper for Yaml {
("identity", _, _) => {
Some(FilterOp::Identity)
}
("component-transfer", _, _) => {
Some(FilterOp::ComponentTransfer)
}
("blur", ref args, _) if args.len() == 1 => {
Some(FilterOp::Blur(args[0].parse().unwrap()))
}
@ -606,4 +622,52 @@ impl YamlHelper for Yaml {
self.as_filter_op().map(|op| vec![op])
}
}
fn as_filter_data(&self) -> Option<FilterData> {
// Parse an array with five entries. First entry is an array of func types (4).
// The remaining entries are arrays of floats.
if let Yaml::Array(ref array) = *self {
if array.len() != 5 {
panic!("Invalid filter data specified, base array doesn't have five entries: {:?}", self);
}
if let Some(func_types_p) = array[0].as_vec_string() {
if func_types_p.len() != 4 {
panic!("Invalid filter data specified, func type array doesn't have five entries: {:?}", self);
}
let func_types: Vec<ComponentTransferFuncType> =
func_types_p.into_iter().map(|x| { match StringEnum::from_str(&x) {
Some(y) => y,
None => panic!("Invalid filter data specified, invalid func type name: {:?}", self),
}}).collect();
if let Some(r_values_p) = array[1].as_vec_f32() {
if let Some(g_values_p) = array[2].as_vec_f32() {
if let Some(b_values_p) = array[3].as_vec_f32() {
if let Some(a_values_p) = array[4].as_vec_f32() {
let filter_data = FilterData {
func_r_type: func_types[0],
r_values: r_values_p,
func_g_type: func_types[1],
g_values: g_values_p,
func_b_type: func_types[2],
b_values: b_values_p,
func_a_type: func_types[3],
a_values: a_values_p,
};
return Some(filter_data)
}
}
}
}
}
}
None
}
fn as_vec_filter_data(&self) -> Option<Vec<FilterData>> {
if let Some(v) = self.as_vec() {
Some(v.iter().map(|x| x.as_filter_data().unwrap()).collect())
} else {
self.as_filter_data().map(|data| vec![data])
}
}
}