flxzt/rnote · error
Creating svg surface with dimensions
Error message
Creating svg surface with dimensions ({width}, {height}) failed, Err: {e:?} What it means
svg::gen_with_cairo creates a cairo::SvgSurface writing to an in-memory stream using the extents of the given bounds; if cairo fails to create the surface (invalid dimensions, out-of-memory, or a cairo internal error), the Result is Err and this message wraps it. Bounds are asserted valid first, so failures here are typically dimensional or cairo-level.
Solutions
- Clamp/validate width and height to a sane range (> 0 and within cairo limits) before creating the surface
- Sanity-check bounds for NaN/infinity before calling gen_with_cairo
- Tile the export into multiple smaller SVG surfaces if the extents exceed limits
- Inspect the wrapped {e:?} for cairo's specific status code to confirm the cause
Example fix
// before
let width = bounds.extents()[0];
let height = bounds.extents()[1];
let surface = cairo::SvgSurface::for_stream(width, height, Vec::new())?;
// after
let (width, height) = (bounds.extents()[0], bounds.extents()[1]);
if !(width.is_finite() && height.is_finite() && width > 0.0 && height > 0.0 && width < 32767.0 && height < 32767.0) {
return Err(anyhow!("unsupported svg export size: {width}x{height}"));
}
let surface = cairo::SvgSurface::for_stream(width, height, Vec::new())?; Defensive patterns
Strategy: validation
Validate before calling
let (w, h) = (bounds.extents()[0], bounds.extents()[1]);
if !w.is_finite() || !h.is_finite() || w <= 0.0 || h <= 0.0 || w > 32767.0 || h > 32767.0 {
return Err(anyhow!("svg extents {w}x{h} unsupported"));
} Type guard
fn valid_extents(bounds: &kurbo::Rect) -> bool {
let (w, h) = (bounds.width(), bounds.height());
w.is_finite() && h.is_finite() && w > 0.0 && h > 0.0 && w <= 32767.0 && h <= 32767.0
} Try / catch
match svg::gen_with_cairo(bounds, draw) {
Ok(svg) => svg,
Err(e) if e.to_string().contains("Creating svg surface") => {
eprintln!("export area too large or invalid: {e}");
svg::gen_with_cairo(bounds.shrink_to_limit(), draw)?
}
Err(e) => return Err(e),
} Prevention
- Clamp export extents before creating the surface; tile very large exports
- Reject NaN/infinite bounds early (assert_valid helps but check finiteness explicitly)
- Mind cairo's surface size limit (~32767 px on many backends)
- Log the wrapped cairo status code to distinguish dimension vs resource failures
When it happens
Trigger: Calling gen_with_cairo with bounds whose extents are zero, negative, non-finite, or exceed cairo's surface size limits (roughly >2^15-2^16 px depending on backend/version).
Common situations: Exporting a very large or zoomed canvas producing extents beyond cairo limits; NaN/infinite extents from degenerate geometry slipping past validation; exotic cairo builds on headless systems.
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
- Generating doc svg failed, returned None.
- Finishing Svg surface output stream failed, Err
- Downcasting Svg surface content failed, Err
- The output file " " needs to have a supported extension to…
- Exporting document to format with extension
AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08).
Data as JSON: /api/errors/a587ccfe3cc66dec.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rnote-engine/src/svg.rs:117
self.svg_data = usvg_tree.to_string(&xml_options);
self.bounds = bounds_simplified;
Ok(())
}
/// Generate an Svg through cairo's SvgSurface.
pub fn gen_with_cairo<F>(draw_func: F, mut bounds: Aabb) -> anyhow::Result<Self>
where
F: FnOnce(&cairo::Context) -> anyhow::Result<()>,
{
bounds.ensure_positive();
bounds.assert_valid()?;
let width = bounds.extents()[0];
let height = bounds.extents()[1];
let mut svg_surface =
cairo::SvgSurface::for_stream(width, height, Vec::new()).map_err(|e| {
anyhow::anyhow!(
"Creating svg surface with dimensions ({width}, {height}) failed, Err: {e:?}"
)
})?;
svg_surface.set_document_unit(cairo::SvgUnit::Px);
{
let cairo_cx = cairo::Context::new(&svg_surface)?;
// cairo only draws elements with positive coordinates, so we need to translate the content here
cairo_cx.translate(-bounds.mins[0], -bounds.mins[1]);
// apply the draw function
draw_func(&cairo_cx)?;
}
let content = String::from_utf8(
*svg_surface
.finish_output_stream()
.map_err(|e| {
anyhow::anyhow!("Finishing Svg surface output stream failed, Err: {e:?}")View on GitHub (pinned to bbc5354502)