mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Add support for object-fit
and object-position
(#33479)
This also makes a couple small improvements: - Rename `IntrinsicSizes` to `NaturalSizes` which reflects more modern spec language. - Move the conversion of Stylo's `ImageRendering` to WebRender's version to a `ToWebRender` trait implementation. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
632d832704
commit
bd632fc814
58 changed files with 169 additions and 563 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -1308,7 +1308,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "derive_common"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
|
@ -1496,7 +1496,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "dom"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
|
@ -4131,7 +4131,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "malloc_size_of"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"accountable-refcell",
|
||||
"app_units",
|
||||
|
@ -5915,7 +5915,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "selectors"
|
||||
version = "0.24.0"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cssparser",
|
||||
|
@ -6203,7 +6203,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "servo_arc"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"stable_deref_trait",
|
||||
|
@ -6212,7 +6212,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "servo_atoms"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"string_cache",
|
||||
"string_cache_codegen",
|
||||
|
@ -6430,7 +6430,7 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
|||
[[package]]
|
||||
name = "size_of_test"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
@ -6571,7 +6571,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|||
[[package]]
|
||||
name = "static_prefs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
|
||||
[[package]]
|
||||
name = "strck"
|
||||
|
@ -6624,7 +6624,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "style"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"app_units",
|
||||
"arrayvec",
|
||||
|
@ -6682,7 +6682,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "style_config"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
@ -6690,7 +6690,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "style_derive"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"derive_common",
|
||||
|
@ -6721,7 +6721,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "style_traits"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"app_units",
|
||||
"bitflags 2.6.0",
|
||||
|
@ -7088,7 +7088,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "to_shmem"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"cssparser",
|
||||
"servo_arc",
|
||||
|
@ -7101,7 +7101,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "to_shmem_derive"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#25daa6b91d77ced8498f0a729d311e4292328313"
|
||||
source = "git+https://github.com/servo/stylo?branch=2024-09-02#1d95da7aec9de466cf0a16d832b6993dad4228fe"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"derive_common",
|
||||
|
|
|
@ -17,7 +17,7 @@ use webrender_api::{self as wr, units};
|
|||
use wr::units::LayoutSize;
|
||||
use wr::ClipChainId;
|
||||
|
||||
use crate::replaced::IntrinsicSizes;
|
||||
use crate::replaced::NaturalSizes;
|
||||
|
||||
pub(super) struct BackgroundLayer {
|
||||
pub common: wr::CommonItemProperties,
|
||||
|
@ -167,7 +167,7 @@ pub(super) fn layout_layer(
|
|||
painter: &BackgroundPainter,
|
||||
builder: &mut super::DisplayListBuilder,
|
||||
layer_index: usize,
|
||||
intrinsic: IntrinsicSizes,
|
||||
natural_sizes: NaturalSizes,
|
||||
) -> Option<BackgroundLayer> {
|
||||
let painting_area = painter.painting_area(fragment_builder, builder, layer_index);
|
||||
let positioning_area = painter.positioning_area(fragment_builder, layer_index);
|
||||
|
@ -180,19 +180,19 @@ pub(super) fn layout_layer(
|
|||
}
|
||||
let size_contain_or_cover = |background_size| {
|
||||
let mut tile_size = positioning_area.size();
|
||||
if let Some(intrinsic_ratio) = intrinsic.ratio {
|
||||
if let Some(natural_ratio) = natural_sizes.ratio {
|
||||
let positioning_ratio = positioning_area.size().width / positioning_area.size().height;
|
||||
// Whether the tile width (as opposed to height)
|
||||
// is scaled to that of the positioning area
|
||||
let fit_width = match background_size {
|
||||
ContainOrCover::Contain => positioning_ratio <= intrinsic_ratio,
|
||||
ContainOrCover::Cover => positioning_ratio > intrinsic_ratio,
|
||||
ContainOrCover::Contain => positioning_ratio <= natural_ratio,
|
||||
ContainOrCover::Cover => positioning_ratio > natural_ratio,
|
||||
};
|
||||
// The other dimension needs to be adjusted
|
||||
if fit_width {
|
||||
tile_size.height = tile_size.width / intrinsic_ratio
|
||||
tile_size.height = tile_size.width / natural_ratio
|
||||
} else {
|
||||
tile_size.width = tile_size.height * intrinsic_ratio
|
||||
tile_size.width = tile_size.height * natural_ratio
|
||||
}
|
||||
}
|
||||
tile_size
|
||||
|
@ -212,18 +212,18 @@ pub(super) fn layout_layer(
|
|||
|
||||
if width.is_none() && height.is_none() {
|
||||
// Both computed values are 'auto':
|
||||
// use intrinsic sizes, treating missing width or height as 'auto'
|
||||
width = intrinsic.width;
|
||||
height = intrinsic.height;
|
||||
// use natural sizes, treating missing width or height as 'auto'
|
||||
width = natural_sizes.width;
|
||||
height = natural_sizes.height;
|
||||
}
|
||||
|
||||
match (width, height) {
|
||||
(Some(w), Some(h)) => units::LayoutSize::new(w.to_f32_px(), h.to_f32_px()),
|
||||
(Some(w), None) => {
|
||||
let h = if let Some(intrinsic_ratio) = intrinsic.ratio {
|
||||
w.scale_by(1.0 / intrinsic_ratio)
|
||||
} else if let Some(intrinsic_height) = intrinsic.height {
|
||||
intrinsic_height
|
||||
let h = if let Some(natural_ratio) = natural_sizes.ratio {
|
||||
w.scale_by(1.0 / natural_ratio)
|
||||
} else if let Some(natural_height) = natural_sizes.height {
|
||||
natural_height
|
||||
} else {
|
||||
// Treated as 100%
|
||||
Au::from_f32_px(positioning_area.size().height)
|
||||
|
@ -231,17 +231,17 @@ pub(super) fn layout_layer(
|
|||
units::LayoutSize::new(w.to_f32_px(), h.to_f32_px())
|
||||
},
|
||||
(None, Some(h)) => {
|
||||
let w = if let Some(intrinsic_ratio) = intrinsic.ratio {
|
||||
h.scale_by(intrinsic_ratio)
|
||||
} else if let Some(intrinsic_width) = intrinsic.width {
|
||||
intrinsic_width
|
||||
let w = if let Some(natural_ratio) = natural_sizes.ratio {
|
||||
h.scale_by(natural_ratio)
|
||||
} else if let Some(natural_width) = natural_sizes.width {
|
||||
natural_width
|
||||
} else {
|
||||
// Treated as 100%
|
||||
Au::from_f32_px(positioning_area.size().width)
|
||||
};
|
||||
units::LayoutSize::new(w.to_f32_px(), h.to_f32_px())
|
||||
},
|
||||
// Both comptued values were 'auto', and neither intrinsic size is present
|
||||
// Both comptued values were 'auto', and neither natural size is present
|
||||
(None, None) => size_contain_or_cover(ContainOrCover::Contain),
|
||||
}
|
||||
},
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
|
||||
use app_units::Au;
|
||||
use style::color::AbsoluteColor;
|
||||
use style::computed_values::image_rendering::T as ComputedImageRendering;
|
||||
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
||||
use style::computed_values::text_decoration_style::T as ComputedTextDecorationStyle;
|
||||
use style::computed_values::transform_style::T as ComputedTransformStyle;
|
||||
use style::values::computed::Filter as ComputedFilter;
|
||||
use style::values::specified::border::BorderImageRepeatKeyword;
|
||||
use webrender_api::{units, FilterOp, LineStyle, MixBlendMode, RepeatMode, Shadow, TransformStyle};
|
||||
use webrender_api::{
|
||||
units, FilterOp, ImageRendering, LineStyle, MixBlendMode, RepeatMode, Shadow, TransformStyle,
|
||||
};
|
||||
|
||||
use crate::geom::{PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize};
|
||||
|
||||
|
@ -142,3 +145,15 @@ impl ToWebRender for BorderImageRepeatKeyword {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWebRender for ComputedImageRendering {
|
||||
type Type = ImageRendering;
|
||||
|
||||
fn to_webrender(&self) -> Self::Type {
|
||||
match self {
|
||||
ComputedImageRendering::Auto => ImageRendering::Auto,
|
||||
ComputedImageRendering::CrispEdges => ImageRendering::CrispEdges,
|
||||
ComputedImageRendering::Pixelated => ImageRendering::Pixelated,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ use crate::fragment_tree::{
|
|||
BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, Tag, TextFragment,
|
||||
};
|
||||
use crate::geom::{PhysicalPoint, PhysicalRect};
|
||||
use crate::replaced::IntrinsicSizes;
|
||||
use crate::replaced::NaturalSizes;
|
||||
use crate::style_ext::ComputedValuesExt;
|
||||
|
||||
mod background;
|
||||
|
@ -272,18 +272,31 @@ impl Fragment {
|
|||
);
|
||||
}
|
||||
},
|
||||
Fragment::Image(i) => match i.style.get_inherited_box().visibility {
|
||||
Fragment::Image(image) => match image.style.get_inherited_box().visibility {
|
||||
Visibility::Visible => {
|
||||
builder.is_contentful = true;
|
||||
let rect = i.rect.translate(containing_block.origin.to_vector());
|
||||
|
||||
let common = builder.common_properties(rect.to_webrender(), &i.style);
|
||||
let image_rendering = image
|
||||
.style
|
||||
.get_inherited_box()
|
||||
.image_rendering
|
||||
.to_webrender();
|
||||
let rect = image
|
||||
.rect
|
||||
.translate(containing_block.origin.to_vector())
|
||||
.to_webrender();
|
||||
let clip = image
|
||||
.clip
|
||||
.translate(containing_block.origin.to_vector())
|
||||
.to_webrender();
|
||||
let common = builder.common_properties(clip, &image.style);
|
||||
|
||||
builder.wr().push_image(
|
||||
&common,
|
||||
rect.to_webrender(),
|
||||
image_rendering(i.style.get_inherited_box().image_rendering),
|
||||
rect,
|
||||
image_rendering,
|
||||
wr::AlphaType::PremultipliedAlpha,
|
||||
i.image_key,
|
||||
image.image_key,
|
||||
wr::ColorF::WHITE,
|
||||
);
|
||||
},
|
||||
|
@ -736,7 +749,7 @@ impl<'a> BuilderForBoxFragment<'a> {
|
|||
match image {
|
||||
Image::None => {},
|
||||
Image::Gradient(ref gradient) => {
|
||||
let intrinsic = IntrinsicSizes::empty();
|
||||
let intrinsic = NaturalSizes::empty();
|
||||
let Some(layer) =
|
||||
&background::layout_layer(self, painter, builder, index, intrinsic)
|
||||
else {
|
||||
|
@ -801,7 +814,7 @@ impl<'a> BuilderForBoxFragment<'a> {
|
|||
|
||||
// FIXME: https://drafts.csswg.org/css-images-4/#the-image-resolution
|
||||
let dppx = 1.0;
|
||||
let intrinsic = IntrinsicSizes::from_width_and_height(
|
||||
let intrinsic = NaturalSizes::from_width_and_height(
|
||||
width as f32 / dppx,
|
||||
height as f32 / dppx,
|
||||
);
|
||||
|
@ -809,14 +822,13 @@ impl<'a> BuilderForBoxFragment<'a> {
|
|||
if let Some(layer) =
|
||||
background::layout_layer(self, painter, builder, index, intrinsic)
|
||||
{
|
||||
let image_rendering = image_rendering(style.clone_image_rendering());
|
||||
if layer.repeat {
|
||||
builder.wr().push_repeating_image(
|
||||
&layer.common,
|
||||
layer.bounds,
|
||||
layer.tile_size,
|
||||
layer.tile_spacing,
|
||||
image_rendering,
|
||||
style.clone_image_rendering().to_webrender(),
|
||||
wr::AlphaType::PremultipliedAlpha,
|
||||
key,
|
||||
wr::ColorF::WHITE,
|
||||
|
@ -825,7 +837,7 @@ impl<'a> BuilderForBoxFragment<'a> {
|
|||
builder.wr().push_image(
|
||||
&layer.common,
|
||||
layer.bounds,
|
||||
image_rendering,
|
||||
style.clone_image_rendering().to_webrender(),
|
||||
wr::AlphaType::PremultipliedAlpha,
|
||||
key,
|
||||
wr::ColorF::WHITE,
|
||||
|
@ -1142,15 +1154,6 @@ fn cursor(kind: CursorKind, auto_cursor: Cursor) -> Cursor {
|
|||
}
|
||||
}
|
||||
|
||||
fn image_rendering(ir: style::computed_values::image_rendering::T) -> wr::ImageRendering {
|
||||
use style::computed_values::image_rendering::T as ImageRendering;
|
||||
match ir {
|
||||
ImageRendering::Auto => wr::ImageRendering::Auto,
|
||||
ImageRendering::CrispEdges => wr::ImageRendering::CrispEdges,
|
||||
ImageRendering::Pixelated => wr::ImageRendering::Pixelated,
|
||||
}
|
||||
}
|
||||
|
||||
/// Radii for the padding edge or content edge
|
||||
fn inner_radii(mut radii: wr::BorderRadius, insets: units::LayoutSideOffsets) -> wr::BorderRadius {
|
||||
assert!(insets.left >= 0.0, "left inset must not be negative");
|
||||
|
|
|
@ -1772,6 +1772,7 @@ impl FlexItem<'_> {
|
|||
let cross_size = flex_axis.vec2_to_flex_relative(size).cross;
|
||||
let fragments = replaced.contents.make_fragments(
|
||||
&replaced.style,
|
||||
containing_block,
|
||||
size.to_physical_size(container_writing_mode),
|
||||
);
|
||||
|
||||
|
|
|
@ -992,6 +992,7 @@ impl FloatBox {
|
|||
);
|
||||
children = replaced.contents.make_fragments(
|
||||
&replaced.style,
|
||||
containing_block,
|
||||
content_size.to_physical_size(containing_block.style.writing_mode),
|
||||
)
|
||||
},
|
||||
|
|
|
@ -1917,7 +1917,11 @@ impl IndependentFormattingContext {
|
|||
.contents
|
||||
.used_size_as_if_inline_element(layout.containing_block, &replaced.style, &pbm)
|
||||
.to_physical_size(container_writing_mode);
|
||||
let fragments = replaced.contents.make_fragments(&replaced.style, size);
|
||||
let fragments = replaced.contents.make_fragments(
|
||||
&replaced.style,
|
||||
layout.containing_block,
|
||||
size,
|
||||
);
|
||||
|
||||
let content_rect = PhysicalRect::new(PhysicalPoint::zero(), size);
|
||||
(fragments, content_rect, None, None)
|
||||
|
|
|
@ -1307,7 +1307,7 @@ fn layout_in_flow_replaced_block_level(
|
|||
|
||||
let containing_block_writing_mode = containing_block.style.writing_mode;
|
||||
let physical_content_size = content_size.to_physical_size(containing_block_writing_mode);
|
||||
let fragments = replaced.make_fragments(style, physical_content_size);
|
||||
let fragments = replaced.make_fragments(style, containing_block, physical_content_size);
|
||||
|
||||
let clearance;
|
||||
if let Some(ref mut sequential_layout_state) = sequential_layout_state {
|
||||
|
|
|
@ -83,6 +83,7 @@ pub(crate) struct ImageFragment {
|
|||
#[serde(skip_serializing)]
|
||||
pub style: ServoArc<ComputedValues>,
|
||||
pub rect: PhysicalRect<Au>,
|
||||
pub clip: PhysicalRect<Au>,
|
||||
#[serde(skip_serializing)]
|
||||
pub image_key: ImageKey,
|
||||
}
|
||||
|
|
|
@ -552,6 +552,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
content_size = computed_size.auto_is(|| unreachable!());
|
||||
fragments = replaced.contents.make_fragments(
|
||||
&style,
|
||||
&containing_block.into(),
|
||||
content_size.to_physical_size(containing_block_writing_mode),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -14,6 +14,7 @@ use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
|
|||
use pixels::Image;
|
||||
use serde::Serialize;
|
||||
use servo_arc::Arc as ServoArc;
|
||||
use style::computed_values::object_fit::T as ObjectFit;
|
||||
use style::logical_geometry::Direction;
|
||||
use style::properties::ComputedValues;
|
||||
use style::servo::url::ComputedUrl;
|
||||
|
@ -35,32 +36,35 @@ use crate::{AuOrAuto, ContainingBlock, IndefiniteContainingBlock};
|
|||
#[derive(Debug, Serialize)]
|
||||
pub(crate) struct ReplacedContent {
|
||||
pub kind: ReplacedContentKind,
|
||||
intrinsic: IntrinsicSizes,
|
||||
natural_size: NaturalSizes,
|
||||
base_fragment_info: BaseFragmentInfo,
|
||||
}
|
||||
|
||||
/// * Raster images always have an intrinsic width and height, with 1 image pixel = 1px.
|
||||
/// The intrinsic ratio should be based on dividing those.
|
||||
/// The natural dimensions of a replaced element, including a height, width, and
|
||||
/// aspect ratio.
|
||||
///
|
||||
/// * Raster images always have an natural width and height, with 1 image pixel = 1px.
|
||||
/// The natural ratio should be based on dividing those.
|
||||
/// See <https://github.com/w3c/csswg-drafts/issues/4572> for the case where either is zero.
|
||||
/// PNG specifically disallows this but I (SimonSapin) am not sure about other formats.
|
||||
///
|
||||
/// * Form controls have both intrinsic width and height **but no intrinsic ratio**.
|
||||
/// * Form controls have both natural width and height **but no natural ratio**.
|
||||
/// See <https://github.com/w3c/csswg-drafts/issues/1044> and
|
||||
/// <https://drafts.csswg.org/css-images/#intrinsic-dimensions> “In general, […]”
|
||||
/// <https://drafts.csswg.org/css-images/#natural-dimensions> “In general, […]”
|
||||
///
|
||||
/// * For SVG, see <https://svgwg.org/svg2-draft/coords.html#SizingSVGInCSS>
|
||||
/// and again <https://github.com/w3c/csswg-drafts/issues/4572>.
|
||||
///
|
||||
/// * IFrames do not have intrinsic width and height or intrinsic ratio according
|
||||
/// * IFrames do not have natural width and height or natural ratio according
|
||||
/// to <https://drafts.csswg.org/css-images/#intrinsic-dimensions>.
|
||||
#[derive(Debug, Serialize)]
|
||||
pub(crate) struct IntrinsicSizes {
|
||||
pub(crate) struct NaturalSizes {
|
||||
pub width: Option<Au>,
|
||||
pub height: Option<Au>,
|
||||
pub ratio: Option<CSSFloat>,
|
||||
}
|
||||
|
||||
impl IntrinsicSizes {
|
||||
impl NaturalSizes {
|
||||
pub(crate) fn from_width_and_height(width: f32, height: f32) -> Self {
|
||||
// https://drafts.csswg.org/css-images/#natural-aspect-ratio:
|
||||
// "If an object has a degenerate natural aspect ratio (at least one part being
|
||||
|
@ -145,16 +149,16 @@ impl ReplacedContent {
|
|||
}
|
||||
}
|
||||
|
||||
let (kind, intrinsic_size_in_dots) = {
|
||||
if let Some((image, intrinsic_size_in_dots)) = element.as_image() {
|
||||
let (kind, natural_size_in_dots) = {
|
||||
if let Some((image, natural_size_in_dots)) = element.as_image() {
|
||||
(
|
||||
ReplacedContentKind::Image(image),
|
||||
Some(intrinsic_size_in_dots),
|
||||
Some(natural_size_in_dots),
|
||||
)
|
||||
} else if let Some((canvas_info, intrinsic_size_in_dots)) = element.as_canvas() {
|
||||
} else if let Some((canvas_info, natural_size_in_dots)) = element.as_canvas() {
|
||||
(
|
||||
ReplacedContentKind::Canvas(canvas_info),
|
||||
Some(intrinsic_size_in_dots),
|
||||
Some(natural_size_in_dots),
|
||||
)
|
||||
} else if let Some((pipeline_id, browsing_context_id)) = element.as_iframe() {
|
||||
(
|
||||
|
@ -164,31 +168,31 @@ impl ReplacedContent {
|
|||
}),
|
||||
None,
|
||||
)
|
||||
} else if let Some((image_key, intrinsic_size_in_dots)) = element.as_video() {
|
||||
} else if let Some((image_key, natural_size_in_dots)) = element.as_video() {
|
||||
(
|
||||
ReplacedContentKind::Video(VideoInfo { image_key }),
|
||||
Some(intrinsic_size_in_dots),
|
||||
Some(natural_size_in_dots),
|
||||
)
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let intrinsic =
|
||||
intrinsic_size_in_dots.map_or_else(IntrinsicSizes::empty, |intrinsic_size_in_dots| {
|
||||
let natural_size =
|
||||
natural_size_in_dots.map_or_else(NaturalSizes::empty, |naturalc_size_in_dots| {
|
||||
// FIXME: should 'image-resolution' (when implemented) be used *instead* of
|
||||
// `script::dom::htmlimageelement::ImageRequest::current_pixel_density`?
|
||||
// https://drafts.csswg.org/css-images-4/#the-image-resolution
|
||||
let dppx = 1.0;
|
||||
let width = (intrinsic_size_in_dots.width as CSSFloat) / dppx;
|
||||
let height = (intrinsic_size_in_dots.height as CSSFloat) / dppx;
|
||||
IntrinsicSizes::from_width_and_height(width, height)
|
||||
let width = (naturalc_size_in_dots.width as CSSFloat) / dppx;
|
||||
let height = (naturalc_size_in_dots.height as CSSFloat) / dppx;
|
||||
NaturalSizes::from_width_and_height(width, height)
|
||||
});
|
||||
|
||||
let base_fragment_info = BaseFragmentInfo::new_for_node(element.opaque());
|
||||
Some(Self {
|
||||
kind,
|
||||
intrinsic,
|
||||
natural_size,
|
||||
base_fragment_info,
|
||||
})
|
||||
}
|
||||
|
@ -215,7 +219,7 @@ impl ReplacedContent {
|
|||
|
||||
return Some(Self {
|
||||
kind: ReplacedContentKind::Image(image),
|
||||
intrinsic: IntrinsicSizes::from_width_and_height(width, height),
|
||||
natural_size: NaturalSizes::from_width_and_height(width, height),
|
||||
base_fragment_info: BaseFragmentInfo::new_for_node(element.opaque()),
|
||||
});
|
||||
}
|
||||
|
@ -234,7 +238,7 @@ impl ReplacedContent {
|
|||
}
|
||||
|
||||
fn flow_relative_intrinsic_size(&self, style: &ComputedValues) -> LogicalVec2<Option<Au>> {
|
||||
let intrinsic_size = PhysicalSize::new(self.intrinsic.width, self.intrinsic.height);
|
||||
let intrinsic_size = PhysicalSize::new(self.natural_size.width, self.natural_size.height);
|
||||
LogicalVec2::from_physical_size(&intrinsic_size, style.writing_mode)
|
||||
}
|
||||
|
||||
|
@ -242,7 +246,7 @@ impl ReplacedContent {
|
|||
&self,
|
||||
style: &ComputedValues,
|
||||
) -> Option<CSSFloat> {
|
||||
self.intrinsic.ratio.map(|width_over_height| {
|
||||
self.natural_size.ratio.map(|width_over_height| {
|
||||
if style.writing_mode.is_vertical() {
|
||||
1. / width_over_height
|
||||
} else {
|
||||
|
@ -276,9 +280,61 @@ impl ReplacedContent {
|
|||
pub fn make_fragments(
|
||||
&self,
|
||||
style: &ServoArc<ComputedValues>,
|
||||
containing_block: &ContainingBlock,
|
||||
size: PhysicalSize<Au>,
|
||||
) -> Vec<Fragment> {
|
||||
let rect = PhysicalRect::new(PhysicalPoint::origin(), size);
|
||||
let aspect_ratio = self.preferred_aspect_ratio(&containing_block.into(), style);
|
||||
let natural_size = PhysicalSize::new(
|
||||
self.natural_size.width.unwrap_or(size.width),
|
||||
self.natural_size.height.unwrap_or(size.height),
|
||||
);
|
||||
|
||||
let object_fit_size = aspect_ratio.map_or(size, |aspect_ratio| {
|
||||
let preserve_aspect_ratio_with_comparison =
|
||||
|size: PhysicalSize<Au>, comparison: fn(&Au, &Au) -> bool| {
|
||||
let (width_axis, height_axis) = if style.writing_mode.is_horizontal() {
|
||||
(Direction::Inline, Direction::Block)
|
||||
} else {
|
||||
(Direction::Block, Direction::Inline)
|
||||
};
|
||||
|
||||
let candidate_width =
|
||||
aspect_ratio.compute_dependent_size(width_axis, size.height);
|
||||
if comparison(&candidate_width, &size.width) {
|
||||
return PhysicalSize::new(candidate_width, size.height);
|
||||
}
|
||||
|
||||
let candidate_height =
|
||||
aspect_ratio.compute_dependent_size(height_axis, size.width);
|
||||
debug_assert!(comparison(&candidate_height, &size.height));
|
||||
PhysicalSize::new(size.width, candidate_height)
|
||||
};
|
||||
|
||||
match style.clone_object_fit() {
|
||||
ObjectFit::Fill => size,
|
||||
ObjectFit::Contain => preserve_aspect_ratio_with_comparison(size, PartialOrd::le),
|
||||
ObjectFit::Cover => preserve_aspect_ratio_with_comparison(size, PartialOrd::ge),
|
||||
ObjectFit::None => natural_size,
|
||||
ObjectFit::ScaleDown => {
|
||||
preserve_aspect_ratio_with_comparison(size.min(natural_size), PartialOrd::le)
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
let object_position = style.clone_object_position();
|
||||
let horizontal_position = object_position
|
||||
.horizontal
|
||||
.to_used_value(size.width - object_fit_size.width);
|
||||
let vertical_position = object_position
|
||||
.vertical
|
||||
.to_used_value(size.height - object_fit_size.height);
|
||||
|
||||
let rect = PhysicalRect::new(
|
||||
PhysicalPoint::new(horizontal_position, vertical_position),
|
||||
object_fit_size,
|
||||
);
|
||||
let clip = PhysicalRect::new(PhysicalPoint::origin(), size);
|
||||
|
||||
match &self.kind {
|
||||
ReplacedContentKind::Image(image) => image
|
||||
.as_ref()
|
||||
|
@ -288,6 +344,7 @@ impl ReplacedContent {
|
|||
base: self.base_fragment_info.into(),
|
||||
style: style.clone(),
|
||||
rect,
|
||||
clip,
|
||||
image_key,
|
||||
})
|
||||
})
|
||||
|
@ -297,6 +354,7 @@ impl ReplacedContent {
|
|||
base: self.base_fragment_info.into(),
|
||||
style: style.clone(),
|
||||
rect,
|
||||
clip,
|
||||
image_key: video.image_key,
|
||||
})],
|
||||
ReplacedContentKind::IFrame(iframe) => {
|
||||
|
@ -309,8 +367,8 @@ impl ReplacedContent {
|
|||
})]
|
||||
},
|
||||
ReplacedContentKind::Canvas(canvas_info) => {
|
||||
if self.intrinsic.width == Some(Au::zero()) ||
|
||||
self.intrinsic.height == Some(Au::zero())
|
||||
if self.natural_size.width == Some(Au::zero()) ||
|
||||
self.natural_size.height == Some(Au::zero())
|
||||
{
|
||||
return vec![];
|
||||
}
|
||||
|
@ -337,6 +395,7 @@ impl ReplacedContent {
|
|||
base: self.base_fragment_info.into(),
|
||||
style: style.clone(),
|
||||
rect,
|
||||
clip,
|
||||
image_key,
|
||||
})]
|
||||
},
|
||||
|
|
|
@ -1,67 +1,4 @@
|
|||
[object-position-interpolation.html]
|
||||
[CSS Transitions: property <object-position> from neutral to [left top\] at (-0.25) should be [62.5% 62.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from neutral to [left top\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from neutral to [left top\] at (0.25) should be [37.5% 37.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from neutral to [left top\] at (0.5) should be [25% 25%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from neutral to [left top\] at (0.75) should be [12.5% 12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from neutral to [left top\] at (1) should be [0% 0%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from neutral to [left top\] at (1.25) should be [-12.5% -12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from neutral to [left top\] at (-0.25) should be [62.5% 62.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from neutral to [left top\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from neutral to [left top\] at (0.25) should be [37.5% 37.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from neutral to [left top\] at (0.5) should be [25% 25%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from neutral to [left top\] at (0.75) should be [12.5% 12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from neutral to [left top\] at (1) should be [0% 0%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from neutral to [left top\] at (1.25) should be [-12.5% -12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from neutral to [left top\] at (-0.25) should be [62.5% 62.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from neutral to [left top\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from neutral to [left top\] at (0.25) should be [37.5% 37.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from neutral to [left top\] at (0.5) should be [25% 25%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from neutral to [left top\] at (0.75) should be [12.5% 12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from neutral to [left top\] at (1) should be [0% 0%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from neutral to [left top\] at (1.25) should be [-12.5% -12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[Web Animations: property <object-position> from neutral to [left top\] at (-0.25) should be [62.5% 62.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -83,69 +20,6 @@
|
|||
[Web Animations: property <object-position> from neutral to [left top\] at (1.25) should be [-12.5% -12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [center top\] at (-0.25) should be [50% 62.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [center top\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [center top\] at (0.25) should be [50% 37.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [center top\] at (0.5) should be [50% 25%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [center top\] at (0.75) should be [50% 12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [center top\] at (1) should be [50% 0%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [center top\] at (1.25) should be [50% -12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [center top\] at (-0.25) should be [50% 62.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [center top\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [center top\] at (0.25) should be [50% 37.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [center top\] at (0.5) should be [50% 25%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [center top\] at (0.75) should be [50% 12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [center top\] at (1) should be [50% 0%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [center top\] at (1.25) should be [50% -12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [center top\] at (-0.25) should be [50% 62.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [center top\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [center top\] at (0.25) should be [50% 37.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [center top\] at (0.5) should be [50% 25%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [center top\] at (0.75) should be [50% 12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [center top\] at (1) should be [50% 0%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [center top\] at (1.25) should be [50% -12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[Web Animations: property <object-position> from [initial\] to [center top\] at (-0.25) should be [50% 62.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -167,69 +41,6 @@
|
|||
[Web Animations: property <object-position> from [initial\] to [center top\] at (1.25) should be [50% -12.5%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [left center\] at (-0.25) should be [62.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [left center\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [left center\] at (0.25) should be [37.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [left center\] at (0.5) should be [25% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [left center\] at (0.75) should be [12.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [left center\] at (1) should be [0% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [initial\] to [left center\] at (1.25) should be [-12.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [left center\] at (-0.25) should be [62.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [left center\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [left center\] at (0.25) should be [37.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [left center\] at (0.5) should be [25% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [left center\] at (0.75) should be [12.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [left center\] at (1) should be [0% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [initial\] to [left center\] at (1.25) should be [-12.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [left center\] at (-0.25) should be [62.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [left center\] at (0) should be [50% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [left center\] at (0.25) should be [37.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [left center\] at (0.5) should be [25% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [left center\] at (0.75) should be [12.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [left center\] at (1) should be [0% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [initial\] to [left center\] at (1.25) should be [-12.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[Web Animations: property <object-position> from [initial\] to [left center\] at (-0.25) should be [62.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -251,69 +62,6 @@
|
|||
[Web Animations: property <object-position> from [initial\] to [left center\] at (1.25) should be [-12.5% 50%\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [20px 20px\] to [100px 100px\] at (-0.25) should be [0px 0px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [20px 20px\] to [100px 100px\] at (0) should be [20px 20px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [20px 20px\] to [100px 100px\] at (0.25) should be [40px 40px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [20px 20px\] to [100px 100px\] at (0.5) should be [60px 60px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [20px 20px\] to [100px 100px\] at (0.75) should be [80px 80px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [20px 20px\] to [100px 100px\] at (1) should be [100px 100px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <object-position> from [20px 20px\] to [100px 100px\] at (1.25) should be [120px 120px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [20px 20px\] to [100px 100px\] at (-0.25) should be [0px 0px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [20px 20px\] to [100px 100px\] at (0) should be [20px 20px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [20px 20px\] to [100px 100px\] at (0.25) should be [40px 40px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [20px 20px\] to [100px 100px\] at (0.5) should be [60px 60px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [20px 20px\] to [100px 100px\] at (0.75) should be [80px 80px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [20px 20px\] to [100px 100px\] at (1) should be [100px 100px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <object-position> from [20px 20px\] to [100px 100px\] at (1.25) should be [120px 120px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [20px 20px\] to [100px 100px\] at (-0.25) should be [0px 0px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [20px 20px\] to [100px 100px\] at (0) should be [20px 20px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [20px 20px\] to [100px 100px\] at (0.25) should be [40px 40px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [20px 20px\] to [100px 100px\] at (0.5) should be [60px 60px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [20px 20px\] to [100px 100px\] at (0.75) should be [80px 80px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [20px 20px\] to [100px 100px\] at (1) should be [100px 100px\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <object-position> from [20px 20px\] to [100px 100px\] at (1.25) should be [120px 120px\]]
|
||||
expected: FAIL
|
||||
|
||||
[Web Animations: property <object-position> from [20px 20px\] to [100px 100px\] at (-0.25) should be [0px 0px\]]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -4,15 +4,3 @@
|
|||
|
||||
[Property image-orientation inherits]
|
||||
expected: FAIL
|
||||
|
||||
[Property object-fit has initial value fill]
|
||||
expected: FAIL
|
||||
|
||||
[Property object-fit does not inherit]
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position has initial value 50% 50%]
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position does not inherit]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-contain-png-001c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-contain-png-001i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-contain-png-001p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-contain-png-002c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-contain-png-002i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-contain-png-002p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-containsize-png-001c.tentative.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-containsize-png-001i.tentative.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-containsize-png-001p.tentative.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-cover-png-001c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-cover-png-001i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-cover-png-001p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-cover-png-002c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-cover-png-002i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-cover-png-002p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-fill-png-001c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-fill-png-001i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-fill-png-001p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-fill-png-002c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-fill-png-002i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-fill-png-002p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-none-png-001c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-none-png-001i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-none-png-001p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-none-png-002c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-none-png-002i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-none-png-002p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-scale-down-png-001c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-scale-down-png-001i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-scale-down-png-001p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-scale-down-png-002c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-scale-down-png-002i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-fit-scale-down-png-002p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-position-png-001c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-position-png-001i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-position-png-001p.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-position-png-002c.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-position-png-002i.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[object-position-png-002p.html]
|
||||
expected: FAIL
|
|
@ -1,18 +1,3 @@
|
|||
[object-fit-computed.html]
|
||||
[Property object-fit value 'contain']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-fit value 'cover']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-fit value 'cover scale-down']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-fit value 'fill']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-fit value 'none']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-fit value 'scale-down']
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,25 +1,10 @@
|
|||
[object-fit-valid.html]
|
||||
[e.style['object-fit'\] = "contain" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-fit'\] = "contain scale-down" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-fit'\] = "cover" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-fit'\] = "cover scale-down" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-fit'\] = "fill" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-fit'\] = "none" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-fit'\] = "scale-down" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-fit'\] = "scale-down contain" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
[object-position-computed.html]
|
||||
[Property object-position value '10% center']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'right 30% top 60px']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value '-20% -30px']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value '30px center']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value '40px top']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'right 20% bottom 10%']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'right bottom']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'center 50px']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'center bottom']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'left center']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'left bottom']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'right 40%']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'center top']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'center']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'center center']
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position value 'right 20px bottom 10px']
|
||||
expected: FAIL
|
|
@ -1,54 +0,0 @@
|
|||
[object-position-valid.html]
|
||||
[e.style['object-position'\] = "10%" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "right 30% top 60px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "-20% -30px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "30px center" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "40px top" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "bottom 10% right 20%" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "bottom right" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "center 50px" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "center bottom" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "center left" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "left" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "left bottom" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "left center" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "right 40%" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "top" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "top center" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "center" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['object-position'\] = "center center" should set the property value]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[canvas-update-with-border-object-fit.html]
|
||||
expected: FAIL
|
|
@ -7,6 +7,3 @@
|
|||
|
||||
[Property mask does not support quirky length]
|
||||
expected: FAIL
|
||||
|
||||
[Property object-position does not support quirky length]
|
||||
expected: FAIL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue