zed-industries/zed · error

Canvas text bounds exceed device coordinates

Error message

Canvas text bounds exceed device coordinates

What it means

Before rasterizing a fallback glyph, the web text system computes device-pixel bounds by combining the measured metrics (left, ascent, right, descent) with the subpixel offset and 1px padding, flooring/ceil-ing to integers. It validates that all four edges fit within i32 device coordinates; otherwise it refuses to rasterize with this error, protecting downstream i32 casts and the GPU atlas from overflow.

Solutions

  1. Validate/clamp font_size before requesting raster bounds — it must be finite and reasonably small (e.g. < 10_000px)
  2. Check where params/offsets come from; a runaway animation or layout loop can inflate the origin — clamp the offset
  3. Verify canvas_text::measure is returning sane metrics for the glyph (compare against expected ascent/descent)
  4. If extreme sizes are legitimate, rasterize in tiles or downscale instead of asking for one giant bitmap

Example fix

// before
let font_size = params.font_size; // possibly huge/NaN from layout
let bounds = text_system.glyph_raster_bounds(params)?;
// after
let font_size = params.font_size;
if !(font_size.is_finite() && font_size > 0.0 && font_size < px(4096.0)) {
    return Ok(Rect::default()); // skip rasterizing degenerate/huge glyphs
}
let bounds = text_system.glyph_raster_bounds(params)?;
Defensive patterns

Strategy: validation

Validate before calling

fn raster_bounds_are_safe(font_size: Pixels, offset: (f64, f64)) -> bool {
    font_size.is_finite()
        && font_size > px(0.0)
        && font_size.0 < 10_000.0
        && offset.0.is_finite()
        && offset.1.is_finite()
        && offset.0.abs() < f64::from(i32::MAX / 4)
        && offset.1.abs() < f64::from(i32::MAX / 4)
}

Type guard

fn finite_f64(value: f64) -> Option<f64> {
    value.is_finite().then_some(value)
}

Try / catch

match text_system.glyph_raster_bounds(&params) {
    Ok(bounds) => bounds,
    Err(err) if err.to_string().contains("exceed device coordinates") => {
        // glyph origin/size is pathological; skip or clamp instead of crashing layout
        Rect::default()
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Calling glyph_raster_bounds (reached via fallback_glyph) with font_size, subpixel offsets, or measured metrics large enough that left/top/right/bottom exceed i32::MIN..i32::MAX after the floor/ceil operations — e.g. an enormous font size, NaN/large metrics from canvas_text::measure, or a bogus negative/left shift producing out-of-range values.

Common situations: Rendering text with an absurd font size (millions of pixels) coming from a bad animation/tween or a units mix-up, a Canvas measurement returning garbage (NaN would fail the ensure too), or layout bugs where the glyph origin drifts far outside the device viewport.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19). Data as JSON: /api/errors/37f1296a868dadfb. Report an issue: GitHub.

Appendix: source

Thrown at crates/gpui_web/src/text_system.rs:359

    fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result<Bounds<DevicePixels>> {
        if self.canvas_font(params.font_id).is_none() {
            return self.native.glyph_raster_bounds(params);
        }
        let metrics = self.measure(
            params.font_id,
            params.glyph_id,
            params.font_size * params.scale_factor,
        )?;
        if metrics.right <= metrics.left || metrics.ascent + metrics.descent <= 0. {
            return Ok(Bounds::default());
        }
        let (offset_x, offset_y) = subpixel_offset(params);
        let left = (f64::from(metrics.left) + f64::from(offset_x)).floor() - 1.;
        let top = (-f64::from(metrics.ascent) + f64::from(offset_y)).floor() - 1.;
        let right = (f64::from(metrics.right) + f64::from(offset_x)).ceil() + 1.;
        let bottom = (f64::from(metrics.descent) + f64::from(offset_y)).ceil() + 1.;
        ensure!(
            [left, top, right, bottom]
                .into_iter()
                .all(|value| value >= f64::from(i32::MIN) && value <= f64::from(i32::MAX)),
            "Canvas text bounds exceed device coordinates"
        );
        let width = (right as i32)
            .checked_sub(left as i32)
            .context("Canvas text width overflow")?;
        let height = (bottom as i32)
            .checked_sub(top as i32)
            .context("Canvas text height overflow")?;
        Ok(Bounds {
            origin: point((left as i32).into(), (top as i32).into()),
            size: size(width.into(), height.into()),
        })
    }

    fn rasterize_glyph(

View on GitHub (pinned to 916fc2b8cb)