///|
/// `glyph_bbox` returns the conservative bounding box of a `Glyph` path.
/// It only supports the absolute SVG commands: `M`, `L`, `C`, `Q`, `Z`.
///
/// Note that this function does _NOT_ fully analyze the `Cubic` or `Quadratic`
/// Bézier curves to determine their exact bounding boxes, but instead
/// takes a naive and conservative approach by encapsulating the bounds
/// of all control points in addition to curve anchor points which may result
/// in returning a much larger bounding box than is actually needed to fully
/// contain the glyph.
pub fn glyph_bbox(d : String) -> @geom.BoundingBox raise FontError {
  let cmds = split_path(d)
  let mut xmin = 0.0
  let mut ymin = 0.0
  let mut xmax = 0.0
  let mut ymax = 0.0
  let update_x = fn(x : Double) {
    if x < xmin {
      xmin = x
    }
    if x > xmax {
      xmax = x
    }
  }
  let update_y = fn(y : Double) {
    if y < ymin {
      ymin = y
    }
    if y > ymax {
      ymax = y
    }
  }

  //
  for cmd_idx, cmd in cmds {
    for index, val in cmd.p.0 {
      if cmd.c == "Z" {
        raise FontError(
          "glyph_bbox: cmd_idx=\{cmd_idx}, index=\{index}, unexpected command 'Z' with params: \{Repr(cmd.p.0)}",
        )
      }
      if cmd_idx == 0 && index == 0 {
        if cmd.c != "M" {
          raise FontError(
            "glyph_bbox: cmd_idx=\{cmd_idx}, index=\{index}, unexpected command: '\{cmd.c}'",
          )
        }
        xmin = val
        xmax = val
      } else if cmd_idx == 0 && index == 1 {
        if cmd.c != "M" {
          raise FontError(
            "glyph_bbox: cmd_idx=\{cmd_idx}, index=\{index}, unexpected command: '\{cmd.c}'",
          )
        }
        ymin = val
        ymax = val
      } else if index % 2 == 0 {
        update_x(val)
      } else {
        update_y(val)
      }
    }
  }
  @geom.rect(xmin, ymin, xmax, ymax)
}