aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--components/layout/context.rs61
-rw-r--r--components/layout/display_list/mod.rs12
-rw-r--r--components/layout/replaced.rs6
4 files changed, 53 insertions, 30 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4928ea1be00..e61960b60a7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7409,9 +7409,9 @@ checksum = "e454d048db5527d000bfddb77bd072bbf3a1e2ae785f16d9bd116e07c2ab45eb"
[[package]]
name = "syn"
-version = "2.0.100"
+version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
diff --git a/components/layout/context.rs b/components/layout/context.rs
index 71372ffe224..62f8a8cdae9 100644
--- a/components/layout/context.rs
+++ b/components/layout/context.rs
@@ -61,6 +61,20 @@ impl Drop for LayoutContext<'_> {
}
}
+#[derive(Debug)]
+pub enum ResolveImageError {
+ LoadError,
+ ImagePending,
+ ImageRequested,
+ OnlyMetadata,
+ InvalidUrl,
+ MissingNode,
+ ImageMissingFromImageSet,
+ FailedToResolveImageFromImageSet,
+ NotImplementedYet(&'static str),
+ None,
+}
+
impl LayoutContext<'_> {
#[inline(always)]
pub fn shared_context(&self) -> &SharedStyleContext {
@@ -72,7 +86,7 @@ impl LayoutContext<'_> {
node: OpaqueNode,
url: ServoUrl,
use_placeholder: UsePlaceholder,
- ) -> Option<ImageOrMetadataAvailable> {
+ ) -> Result<ImageOrMetadataAvailable, ResolveImageError> {
// Check for available image or start tracking.
let cache_result = self.image_cache.get_cached_image_status(
url.clone(),
@@ -82,7 +96,7 @@ impl LayoutContext<'_> {
);
match cache_result {
- ImageCacheResult::Available(img_or_meta) => Some(img_or_meta),
+ ImageCacheResult::Available(img_or_meta) => Ok(img_or_meta),
// Image has been requested, is still pending. Return no image for this paint loop.
// When the image loads it will trigger a reflow and/or repaint.
ImageCacheResult::Pending(id) => {
@@ -93,7 +107,7 @@ impl LayoutContext<'_> {
origin: self.origin.clone(),
};
self.pending_images.lock().push(image);
- None
+ Result::Err(ResolveImageError::ImagePending)
},
// Not yet requested - request image or metadata from the cache
ImageCacheResult::ReadyForRequest(id) => {
@@ -104,10 +118,10 @@ impl LayoutContext<'_> {
origin: self.origin.clone(),
};
self.pending_images.lock().push(image);
- None
+ Result::Err(ResolveImageError::ImageRequested)
},
// Image failed to load, so just return nothing
- ImageCacheResult::LoadError => None,
+ ImageCacheResult::LoadError => Result::Err(ResolveImageError::LoadError),
}
}
@@ -136,31 +150,34 @@ impl LayoutContext<'_> {
node: OpaqueNode,
url: ServoUrl,
use_placeholder: UsePlaceholder,
- ) -> Option<WebRenderImageInfo> {
+ ) -> Result<WebRenderImageInfo, ResolveImageError> {
if let Some(existing_webrender_image) = self
.webrender_image_cache
.read()
.get(&(url.clone(), use_placeholder))
{
- return Some(*existing_webrender_image);
+ return Ok(*existing_webrender_image);
}
-
- match self.get_or_request_image_or_meta(node, url.clone(), use_placeholder) {
- Some(ImageOrMetadataAvailable::ImageAvailable { image, .. }) => {
+ let image_or_meta =
+ self.get_or_request_image_or_meta(node, url.clone(), use_placeholder)?;
+ match image_or_meta {
+ ImageOrMetadataAvailable::ImageAvailable { image, .. } => {
self.handle_animated_image(node, image.clone());
let image_info = WebRenderImageInfo {
size: Size2D::new(image.width, image.height),
key: image.id,
};
if image_info.key.is_none() {
- Some(image_info)
+ Ok(image_info)
} else {
let mut webrender_image_cache = self.webrender_image_cache.write();
webrender_image_cache.insert((url, use_placeholder), image_info);
- Some(image_info)
+ Ok(image_info)
}
},
- None | Some(ImageOrMetadataAvailable::MetadataAvailable(..)) => None,
+ ImageOrMetadataAvailable::MetadataAvailable(..) => {
+ Result::Err(ResolveImageError::OnlyMetadata)
+ },
}
}
@@ -168,11 +185,15 @@ impl LayoutContext<'_> {
&self,
node: Option<OpaqueNode>,
image: &'a Image,
- ) -> Option<ResolvedImage<'a>> {
+ ) -> Result<ResolvedImage<'a>, ResolveImageError> {
match image {
// TODO: Add support for PaintWorklet and CrossFade rendering.
- Image::None | Image::CrossFade(_) | Image::PaintWorklet(_) => None,
- Image::Gradient(gradient) => Some(ResolvedImage::Gradient(gradient)),
+ Image::None => Result::Err(ResolveImageError::None),
+ Image::CrossFade(_) => Result::Err(ResolveImageError::NotImplementedYet("CrossFade")),
+ Image::PaintWorklet(_) => {
+ Result::Err(ResolveImageError::NotImplementedYet("PaintWorklet"))
+ },
+ Image::Gradient(gradient) => Ok(ResolvedImage::Gradient(gradient)),
Image::Url(image_url) => {
// FIXME: images won’t always have in intrinsic width or
// height when support for SVG is added, or a WebRender
@@ -180,18 +201,20 @@ impl LayoutContext<'_> {
//
// FIXME: It feels like this should take into account the pseudo
// element and not just the node.
- let image_url = image_url.url()?;
+ let image_url = image_url.url().ok_or(ResolveImageError::InvalidUrl)?;
+ let node = node.ok_or(ResolveImageError::MissingNode)?;
let webrender_info = self.get_webrender_image_for_url(
- node?,
+ node,
image_url.clone().into(),
UsePlaceholder::No,
)?;
- Some(ResolvedImage::Image(webrender_info))
+ Ok(ResolvedImage::Image(webrender_info))
},
Image::ImageSet(image_set) => {
image_set
.items
.get(image_set.selected_index)
+ .ok_or(ResolveImageError::ImageMissingFromImageSet)
.and_then(|image| {
self.resolve_image(node, &image.image)
.map(|info| match info {
diff --git a/components/layout/display_list/mod.rs b/components/layout/display_list/mod.rs
index fa313b306f4..912c69366bd 100644
--- a/components/layout/display_list/mod.rs
+++ b/components/layout/display_list/mod.rs
@@ -838,8 +838,8 @@ impl<'a> BuilderForBoxFragment<'a> {
// Reverse because the property is top layer first, we want to paint bottom layer first.
for (index, image) in b.background_image.0.iter().enumerate().rev() {
match builder.context.resolve_image(node, image) {
- None => {},
- Some(ResolvedImage::Gradient(gradient)) => {
+ Err(_) => {},
+ Ok(ResolvedImage::Gradient(gradient)) => {
let intrinsic = NaturalSizes::empty();
let Some(layer) =
&background::layout_layer(self, painter, builder, index, intrinsic)
@@ -875,7 +875,7 @@ impl<'a> BuilderForBoxFragment<'a> {
},
}
},
- Some(ResolvedImage::Image(image_info)) => {
+ Ok(ResolvedImage::Image(image_info)) => {
// FIXME: https://drafts.csswg.org/css-images-4/#the-image-resolution
let dppx = 1.0;
let intrinsic = NaturalSizes::from_width_and_height(
@@ -1063,8 +1063,8 @@ impl<'a> BuilderForBoxFragment<'a> {
.context
.resolve_image(node, &border.border_image_source)
{
- None => return false,
- Some(ResolvedImage::Image(image_info)) => {
+ Err(_) => return false,
+ Ok(ResolvedImage::Image(image_info)) => {
let Some(key) = image_info.key else {
return false;
};
@@ -1073,7 +1073,7 @@ impl<'a> BuilderForBoxFragment<'a> {
height = image_info.size.height as f32;
NinePatchBorderSource::Image(key, ImageRendering::Auto)
},
- Some(ResolvedImage::Gradient(gradient)) => {
+ Ok(ResolvedImage::Gradient(gradient)) => {
match gradient::build(&self.fragment.style, gradient, border_image_size, builder) {
WebRenderGradient::Linear(gradient) => {
NinePatchBorderSource::Gradient(gradient)
diff --git a/components/layout/replaced.rs b/components/layout/replaced.rs
index 6a6b1979ff9..b82fb947074 100644
--- a/components/layout/replaced.rs
+++ b/components/layout/replaced.rs
@@ -220,13 +220,13 @@ impl ReplacedContents {
image_url.clone().into(),
UsePlaceholder::No,
) {
- Some(ImageOrMetadataAvailable::ImageAvailable { image, .. }) => {
+ Ok(ImageOrMetadataAvailable::ImageAvailable { image, .. }) => {
(Some(image.clone()), image.width as f32, image.height as f32)
},
- Some(ImageOrMetadataAvailable::MetadataAvailable(metadata, _id)) => {
+ Ok(ImageOrMetadataAvailable::MetadataAvailable(metadata, _id)) => {
(None, metadata.width as f32, metadata.height as f32)
},
- None => return None,
+ Err(_) => return None,
};
return Some(Self {