Repository: typst/typst
File: crates/typst-library/src/visualize/image/mod.rs (Rust)

Code before:
            }
        }

        // Construct the image itself.
        let kind = match format {
            ImageFormat::Raster(format) => ImageKind::Raster(
                RasterImage::new(
                    loaded.data.clone(),
                    format,
                    self.icc.get_ref(styles).as_ref().map(|icc| icc.derived.clone()),
                )
                .at(span)?,
            ),
            ImageFormat::Vector(VectorFormat::Svg) => {
                // Try to identify the parent directory of the SVG file,
                // in case hrefs inside the SVG need to be resolved.
                let svg_file = match self.source.source {
                    DataSource::Path(ref path) => span.resolve_path(path).ok(),
                    DataSource::Bytes(_) => span.id(),
                };
                // The following is a workaround to for the fact that FileID::join
                // takes the parent directory before joining.
                // The result is a FileId object that can be used to resolve hrefs,
                // yet it only contains relevant information about the directory,
                // not the filename, to avoid incorrect cache misses.
                let svg_parent = svg_file.map(|file| file.join("_"));
                ImageKind::Svg(
                    SvgImage::with_fonts(
                        loaded.data.clone(),
                        engine.world,
                        &families(styles).map(|f| f.as_str()).collect::<Vec<_>>(),
                        svg_parent,
                    )
                    .within(loaded)?,
                )
            }
            ImageFormat::Vector(VectorFormat::Pdf) => {
                let document = match PdfDocument::new(loaded.data.clone()) {
                    Ok(doc) => doc,
                    Err(e) => match e {
                        LoadPdfError::Encryption => {
                            bail!(
                                span,
                                "the PDF is encrypted or password-protected";
                                hint: "such PDFs are currently not supported";
                                hint: "preprocess the PDF to remove the encryption"
                            );
                        }
                        LoadPdfError::Invalid => {
                            bail!(
                                span,

Review comment (performance):
I think I had a mistake in my thinking when reviewing this originally. I thought that using an SVG from different files would be a cache miss, but as the `FileId` is already resolved to the SVG's path, that's not the case unless it's a byte SVG. So I think this was actually probably good enough and I'd rather skip this hack (which only has an effect in the bytes case). Sorry for the confusion!

Code after:
            }
        }

        // Construct the image itself.
        let kind = match format {
            ImageFormat::Raster(format) => ImageKind::Raster(
                RasterImage::new(
                    loaded.data.clone(),
                    format,
                    self.icc.get_ref(styles).as_ref().map(|icc| icc.derived.clone()),
                )
                .at(span)?,
            ),
            ImageFormat::Vector(VectorFormat::Svg) => {
                // Identify the SVG file in case contained hrefs need to be resolved.
                let svg_file = match self.source.source {
                    DataSource::Path(ref path) => span.resolve_path(path).ok(),
                    DataSource::Bytes(_) => span.id(),
                };
                ImageKind::Svg(
                    SvgImage::with_fonts_images(
                        loaded.data.clone(),
                        engine.world,
                        &families(styles).map(|f| f.as_str()).collect::<Vec<_>>(),
                        svg_file,
                    )
                    .within(loaded)?,
                )
            }
            ImageFormat::Vector(VectorFormat::Pdf) => {
                let document = match PdfDocument::new(loaded.data.clone()) {
                    Ok(doc) => doc,
                    Err(e) => match e {
                        LoadPdfError::Encryption => {
                            bail!(
                                span,
                                "the PDF is encrypted or password-protected";
                                hint: "such PDFs are currently not supported";
                                hint: "preprocess the PDF to remove the encryption"
                            );
                        }
                        LoadPdfError::Invalid => {
                            bail!(
                                span,
                                "the PDF could not be loaded";
                                hint: "perhaps the PDF file is malformed"
                            );
                        }
                    },
                };