mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Make layout use available image data before querying the image cache.
This commit is contained in:
parent
5f463d3c97
commit
49d2ea4f74
8 changed files with 102 additions and 5 deletions
|
@ -401,6 +401,11 @@ pub struct ImageFragmentInfo {
|
||||||
pub metadata: Option<ImageMetadata>,
|
pub metadata: Option<ImageMetadata>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ImageOrMetadata {
|
||||||
|
Image(Arc<Image>),
|
||||||
|
Metadata(ImageMetadata),
|
||||||
|
}
|
||||||
|
|
||||||
impl ImageFragmentInfo {
|
impl ImageFragmentInfo {
|
||||||
/// Creates a new image fragment from the given URL and local image cache.
|
/// Creates a new image fragment from the given URL and local image cache.
|
||||||
///
|
///
|
||||||
|
@ -412,14 +417,29 @@ impl ImageFragmentInfo {
|
||||||
node: &N,
|
node: &N,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
) -> ImageFragmentInfo {
|
) -> ImageFragmentInfo {
|
||||||
let image_or_metadata = url.and_then(|url| {
|
// First use any image data present in the element...
|
||||||
layout_context.get_or_request_image_or_meta(node.opaque(), url, UsePlaceholder::Yes)
|
let image_or_metadata = node.image_data().and_then(|(image, metadata)| {
|
||||||
});
|
match (image, metadata) {
|
||||||
|
(Some(image), _) => Some(ImageOrMetadata::Image(image)),
|
||||||
|
(None, Some(metadata)) => Some(ImageOrMetadata::Metadata(metadata)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}).or_else(|| url.and_then(|url| {
|
||||||
|
// Otherwise query the image cache for anything known about the associated source URL.
|
||||||
|
layout_context.get_or_request_image_or_meta(
|
||||||
|
node.opaque(),
|
||||||
|
url,
|
||||||
|
UsePlaceholder::Yes
|
||||||
|
).map(|result| match result {
|
||||||
|
ImageOrMetadataAvailable::ImageAvailable(i, _) => ImageOrMetadata::Image(i),
|
||||||
|
ImageOrMetadataAvailable::MetadataAvailable(m) => ImageOrMetadata::Metadata(m),
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
let current_pixel_density = density.unwrap_or(1f64);
|
let current_pixel_density = density.unwrap_or(1f64);
|
||||||
|
|
||||||
let (image, metadata) = match image_or_metadata {
|
let (image, metadata) = match image_or_metadata {
|
||||||
Some(ImageOrMetadataAvailable::ImageAvailable(i, _)) => {
|
Some(ImageOrMetadata::Image(i)) => {
|
||||||
let height = (i.height as f64 / current_pixel_density) as u32;
|
let height = (i.height as f64 / current_pixel_density) as u32;
|
||||||
let width = (i.width as f64 / current_pixel_density) as u32;
|
let width = (i.width as f64 / current_pixel_density) as u32;
|
||||||
(
|
(
|
||||||
|
@ -434,7 +454,7 @@ impl ImageFragmentInfo {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
Some(ImageOrMetadataAvailable::MetadataAvailable(m)) => {
|
Some(ImageOrMetadata::Metadata(m)) => {
|
||||||
(
|
(
|
||||||
None,
|
None,
|
||||||
Some(ImageMetadata {
|
Some(ImageMetadata {
|
||||||
|
|
|
@ -36,6 +36,7 @@ use html5ever::{LocalName, Namespace};
|
||||||
use layout::data::StyleAndLayoutData;
|
use layout::data::StyleAndLayoutData;
|
||||||
use layout::wrapper::GetRawData;
|
use layout::wrapper::GetRawData;
|
||||||
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
||||||
|
use net_traits::image::base::{Image, ImageMetadata};
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use script::layout_exports::{CharacterDataTypeId, ElementTypeId, HTMLElementTypeId, NodeTypeId};
|
use script::layout_exports::{CharacterDataTypeId, ElementTypeId, HTMLElementTypeId, NodeTypeId};
|
||||||
use script::layout_exports::{Document, Element, Node, Text};
|
use script::layout_exports::{Document, Element, Node, Text};
|
||||||
|
@ -59,6 +60,7 @@ use std::fmt::Debug;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
use std::sync::Arc as StdArc;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use style::CaseSensitivityExt;
|
use style::CaseSensitivityExt;
|
||||||
use style::applicable_declarations::ApplicableDeclarationBlock;
|
use style::applicable_declarations::ApplicableDeclarationBlock;
|
||||||
|
@ -1048,6 +1050,11 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
|
||||||
this.image_density()
|
this.image_density()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn image_data(&self) -> Option<(Option<StdArc<Image>>, Option<ImageMetadata>)> {
|
||||||
|
let this = unsafe { self.get_jsmanaged() };
|
||||||
|
this.image_data()
|
||||||
|
}
|
||||||
|
|
||||||
fn canvas_data(&self) -> Option<HTMLCanvasData> {
|
fn canvas_data(&self) -> Option<HTMLCanvasData> {
|
||||||
let this = unsafe { self.get_jsmanaged() };
|
let this = unsafe { self.get_jsmanaged() };
|
||||||
this.canvas_data()
|
this.canvas_data()
|
||||||
|
|
|
@ -1328,6 +1328,9 @@ pub trait LayoutHTMLImageElementHelpers {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn image_density(&self) -> Option<f64>;
|
unsafe fn image_density(&self) -> Option<f64>;
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
unsafe fn image_data(&self) -> (Option<Arc<Image>>, Option<ImageMetadata>);
|
||||||
|
|
||||||
fn get_width(&self) -> LengthOrPercentageOrAuto;
|
fn get_width(&self) -> LengthOrPercentageOrAuto;
|
||||||
fn get_height(&self) -> LengthOrPercentageOrAuto;
|
fn get_height(&self) -> LengthOrPercentageOrAuto;
|
||||||
}
|
}
|
||||||
|
@ -1351,6 +1354,14 @@ impl LayoutHTMLImageElementHelpers for LayoutDom<HTMLImageElement> {
|
||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
unsafe fn image_data(&self) -> (Option<Arc<Image>>, Option<ImageMetadata>) {
|
||||||
|
let current_request = (*self.unsafe_get())
|
||||||
|
.current_request
|
||||||
|
.borrow_for_layout();
|
||||||
|
(current_request.image.clone(), current_request.metadata.clone())
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn image_density(&self) -> Option<f64> {
|
unsafe fn image_density(&self) -> Option<f64> {
|
||||||
(*self.unsafe_get())
|
(*self.unsafe_get())
|
||||||
|
|
|
@ -62,6 +62,7 @@ use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||||
use libc::{self, c_void, uintptr_t};
|
use libc::{self, c_void, uintptr_t};
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
||||||
|
use net_traits::image::base::{Image, ImageMetadata};
|
||||||
use ref_slice::ref_slice;
|
use ref_slice::ref_slice;
|
||||||
use script_layout_interface::{HTMLCanvasData, HTMLMediaData, LayoutElementType, LayoutNodeType};
|
use script_layout_interface::{HTMLCanvasData, HTMLMediaData, LayoutElementType, LayoutNodeType};
|
||||||
use script_layout_interface::{OpaqueStyleAndLayoutData, SVGSVGData, TrustedNodeAddress};
|
use script_layout_interface::{OpaqueStyleAndLayoutData, SVGSVGData, TrustedNodeAddress};
|
||||||
|
@ -81,6 +82,7 @@ use std::default::Default;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use std::sync::Arc as StdArc;
|
||||||
use style::context::QuirksMode;
|
use style::context::QuirksMode;
|
||||||
use style::dom::OpaqueNode;
|
use style::dom::OpaqueNode;
|
||||||
use style::selector_parser::{SelectorImpl, SelectorParser};
|
use style::selector_parser::{SelectorImpl, SelectorParser};
|
||||||
|
@ -1086,6 +1088,7 @@ pub trait LayoutNodeHelpers {
|
||||||
fn selection(&self) -> Option<Range<usize>>;
|
fn selection(&self) -> Option<Range<usize>>;
|
||||||
fn image_url(&self) -> Option<ServoUrl>;
|
fn image_url(&self) -> Option<ServoUrl>;
|
||||||
fn image_density(&self) -> Option<f64>;
|
fn image_density(&self) -> Option<f64>;
|
||||||
|
fn image_data(&self) -> Option<(Option<StdArc<Image>>, Option<ImageMetadata>)>;
|
||||||
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
||||||
fn media_data(&self) -> Option<HTMLMediaData>;
|
fn media_data(&self) -> Option<HTMLMediaData>;
|
||||||
fn svg_data(&self) -> Option<SVGSVGData>;
|
fn svg_data(&self) -> Option<SVGSVGData>;
|
||||||
|
@ -1233,6 +1236,13 @@ impl LayoutNodeHelpers for LayoutDom<Node> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn image_data(&self) -> Option<(Option<StdArc<Image>>, Option<ImageMetadata>)> {
|
||||||
|
unsafe {
|
||||||
|
self.downcast::<HTMLImageElement>().map(|e| e.image_data())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn image_density(&self) -> Option<f64> {
|
fn image_density(&self) -> Option<f64> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -13,10 +13,12 @@ use atomic_refcell::AtomicRef;
|
||||||
use gfx_traits::{ByteIndex, FragmentType, combine_id_with_fragment_type};
|
use gfx_traits::{ByteIndex, FragmentType, combine_id_with_fragment_type};
|
||||||
use html5ever::{Namespace, LocalName};
|
use html5ever::{Namespace, LocalName};
|
||||||
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
use msg::constellation_msg::{BrowsingContextId, PipelineId};
|
||||||
|
use net_traits::image::base::{Image, ImageMetadata};
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::sync::Arc as StdArc;
|
||||||
use style::attr::AttrValue;
|
use style::attr::AttrValue;
|
||||||
use style::context::SharedStyleContext;
|
use style::context::SharedStyleContext;
|
||||||
use style::data::ElementData;
|
use style::data::ElementData;
|
||||||
|
@ -276,6 +278,9 @@ pub trait ThreadSafeLayoutNode:
|
||||||
/// If this is an image element, returns its current-pixel-density. If this is not an image element, fails.
|
/// If this is an image element, returns its current-pixel-density. If this is not an image element, fails.
|
||||||
fn image_density(&self) -> Option<f64>;
|
fn image_density(&self) -> Option<f64>;
|
||||||
|
|
||||||
|
/// If this is an image element, returns its image data. Otherwise, returns `None`.
|
||||||
|
fn image_data(&self) -> Option<(Option<StdArc<Image>>, Option<ImageMetadata>)>;
|
||||||
|
|
||||||
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
||||||
|
|
||||||
fn svg_data(&self) -> Option<SVGSVGData>;
|
fn svg_data(&self) -> Option<SVGSVGData>;
|
||||||
|
|
|
@ -188281,6 +188281,18 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"html/semantics/embedded-content/the-img-element/available-images.html": [
|
||||||
|
[
|
||||||
|
"/html/semantics/embedded-content/the-img-element/available-images.html",
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/html/semantics/embedded-content/the-img-element/available-images-ref.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"html/semantics/embedded-content/the-img-element/document-adopt-base-url.html": [
|
"html/semantics/embedded-content/the-img-element/document-adopt-base-url.html": [
|
||||||
[
|
[
|
||||||
"/html/semantics/embedded-content/the-img-element/document-adopt-base-url.html",
|
"/html/semantics/embedded-content/the-img-element/document-adopt-base-url.html",
|
||||||
|
@ -292039,6 +292051,11 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"html/semantics/embedded-content/the-img-element/available-images-ref.html": [
|
||||||
|
[
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"html/semantics/embedded-content/the-img-element/brokenimg.jpg": [
|
"html/semantics/embedded-content/the-img-element/brokenimg.jpg": [
|
||||||
[
|
[
|
||||||
{}
|
{}
|
||||||
|
@ -614936,6 +614953,14 @@
|
||||||
"15e02bcf51535d45a702b0977f919eff8ce5ba9c",
|
"15e02bcf51535d45a702b0977f919eff8ce5ba9c",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
|
"html/semantics/embedded-content/the-img-element/available-images-ref.html": [
|
||||||
|
"8061abae50899a2befe286723d8bd5c285b356ab",
|
||||||
|
"support"
|
||||||
|
],
|
||||||
|
"html/semantics/embedded-content/the-img-element/available-images.html": [
|
||||||
|
"779ff978689e4f5565b8d45d383efa75ac78b8b2",
|
||||||
|
"reftest"
|
||||||
|
],
|
||||||
"html/semantics/embedded-content/the-img-element/brokenimg.jpg": [
|
"html/semantics/embedded-content/the-img-element/brokenimg.jpg": [
|
||||||
"ccff177ae9b5066a7085f7e967ab869e665975cc",
|
"ccff177ae9b5066a7085f7e967ab869e665975cc",
|
||||||
"support"
|
"support"
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
<!doctype html>
|
||||||
|
<img src="3.jpg">
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<title>Ensure images from available images list are rendered</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="match" href="available-images-ref.html">
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-img-element">
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
var i = new Image();
|
||||||
|
i.onload = function() {
|
||||||
|
var i2 = new Image();
|
||||||
|
i2.src = "3.jpg";
|
||||||
|
document.body.appendChild(i2);
|
||||||
|
document.documentElement.classList.remove("reftest-wait");
|
||||||
|
};
|
||||||
|
i.src = "3.jpg";
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue