flxzt/rnote · error

creating ImageSurface with dimensions

Error message

creating ImageSurface with dimensions ({width_scaled}, {height_scaled}) failed, Err: {e:?}

What it means

Thrown by Svg::gen_image when cairo::ImageSurface::create(ARgb32, width, height) returns a cairo::Error. Cairo cannot allocate an ARGB32 image surface of the requested pixel dimensions, most often because a dimension is zero, negative, or exceeds cairo's size limits, or memory allocation failed.

Solutions

  1. Check width_scaled/height_scaled are > 0 and <= cairo's limits (32767) before calling create; bail with a clear message otherwise
  2. Clamp or cap image_scale so the scaled dimensions stay in range
  3. Reject empty bounds before gen_image (bounds.assert_valid / extents > 0)
  4. Reduce export size or split the drawing into tiles

Example fix

// before
let surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width_scaled as i32, height_scaled as i32).map_err(|e| anyhow::anyhow!("creating ImageSurface ... failed, Err: {e:?}"))?;
// after
if width_scaled == 0 || height_scaled == 0 || width_scaled > 32767 || height_scaled > 32767 {
    anyhow::bail!("invalid image dimensions: {width_scaled}x{height_scaled}");
}
let surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width_scaled as i32, height_scaled as i32)?;
Defensive patterns

Strategy: validation

Validate before calling

fn valid_image_dims(w: u32, h: u32) -> bool { w > 0 && h > 0 && w <= 32767 && h <= 32767 }

Try / catch

if !valid_image_dims(width_scaled, height_scaled) {
    anyhow::bail!("refusing to create {width_scaled}x{height_scaled} surface");
}
let surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width_scaled as i32, height_scaled as i32)?;

Prevention

When it happens

Trigger: width_scaled/height_scaled (bounds extents * image_scale, rounded to i32) are 0, negative, or larger than cairo's maximum surface size (32767 px per dimension), or allocation fails for huge dimensions.

Common situations: Rendering an empty selection (zero-sized bounds) to an image, exporting at a very large image_scale producing dimensions beyond cairo limits, or out-of-memory on huge exports.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/fefbf7382a967661. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/svg.rs:226

        bounds.ensure_positive();
        bounds.assert_valid()?;

        let svg_data = rnote_compose::utils::wrap_svg_root(
            self.svg_data.as_str(),
            Some(bounds),
            Some(bounds),
            false,
        );
        let width_scaled = ((bounds.extents()[0]) * image_scale).round() as u32;
        let height_scaled = ((bounds.extents()[1]) * image_scale).round() as u32;

        let mut surface = cairo::ImageSurface::create(
                cairo::Format::ARgb32,
                width_scaled as i32,
                height_scaled as i32,
            )
            .map_err(|e| {
                anyhow::anyhow!(
                    "creating ImageSurface with dimensions ({width_scaled}, {height_scaled}) failed, Err: {e:?}"
                )
            })?;

        // Context in new scope, else accessing the surface data fails with a borrow error
        {
            let cx =
                cairo::Context::new(&surface).context("creating new cairo::Context failed.")?;
            cx.scale(image_scale, image_scale);
            cx.translate(-bounds.mins[0], -bounds.mins[1]);

            let stream =
                gio::MemoryInputStream::from_bytes(&glib::Bytes::from(svg_data.as_bytes()));

            let handle = rsvg::Loader::new()
                .with_unlimited_size(true)
                .read_stream::<gio::MemoryInputStream, gio::File, gio::Cancellable>(
                    &stream, None, None,

View on GitHub (pinned to bbc5354502)