///|
fn SunRasterRenderer::render_command(
  self : SunRasterRenderer,
  command : @render_common.PlanOp,
  canvas_scopes : Array[@render_common.PlanScopeKind],
  opacity_stack : Array[Double],
  blend_mode_stack : Array[@sun_graphics.BlendMode],
  layer_spec_stack : Array[SunLayerScope],
  rounded_clip_transform_stack : Array[@sun_graphics.Transform],
) -> Unit {
  let opacity = sun_current_opacity(opacity_stack)
  match command {
    Clear(color) => self.canvas.clear(sun_color(color))
    FillRect(rect, color) =>
      self.canvas.fill_rect(
        rect.origin.x,
        rect.origin.y,
        rect.size.width,
        rect.size.height,
        sun_paint(color, opacity),
      )
    StrokeRect(rect, color, width) =>
      self.canvas.stroke_rect(
        rect.origin.x,
        rect.origin.y,
        rect.size.width,
        rect.size.height,
        sun_stroke_paint(color, width, opacity),
      )
    FillRoundedRect(rounded, color) =>
      self.fill_rounded_rect(rounded, @core.Brush::solid(color), opacity)
    StrokeRoundedRect(rounded, color, width) =>
      self.stroke_rounded_rect(
        rounded,
        @core.Brush::solid(color),
        width,
        opacity,
      )
    FillRoundedRectBrush(rounded, brush) =>
      self.fill_rounded_rect(rounded, brush, opacity)
    StrokeRoundedRectBrush(rounded, brush, width) =>
      self.stroke_rounded_rect(rounded, brush, width, opacity)
    DrawShadow(shadow) => self.draw_shadow(shadow, opacity)
    DrawText(run) => self.draw_text(run, opacity)
    DrawImage(image) => self.draw_image(image, opacity)
    PushClip(rect) => {
      self.canvas.save()
      canvas_scopes.push(Clip)
      self.canvas.intersect_clip_rect(
        sun_transformed_rect_bounds(self.canvas.get_transform(), rect),
      )
    }
    PopClip => self.pop_canvas_scope(canvas_scopes, opacity_stack, Clip)
    PushRoundedClip(rounded) => {
      self.rounded_clip_stack.push(rounded)
      rounded_clip_transform_stack.push(self.canvas.get_transform())
      self.push_transparent_offscreen_canvas()
      canvas_scopes.push(RoundedClip)
    }
    PopRoundedClip =>
      match canvas_scopes.pop() {
        Some(RoundedClip) => {
          let layer_pixmap = self.canvas.get_pixmap()
          match self.canvas_stack.pop() {
            Some(parent_canvas) =>
              match self.rounded_clip_stack.pop() {
                Some(rounded) => {
                  self.canvas = parent_canvas
                  let transform = match rounded_clip_transform_stack.pop() {
                    Some(value) => value
                    None => {
                      self.record_unsupported_command(
                        "PopRoundedClip", "PopRoundedClip has no matching rounded clip transform stack entry",
                      )
                      @sun_graphics.Transform::identity()
                    }
                  }
                  self.composite_rounded_clip(
                    layer_pixmap, rounded, transform, opacity,
                  )
                }
                None => {
                  self.canvas = parent_canvas
                  match rounded_clip_transform_stack.pop() {
                    Some(_) => ()
                    None => ()
                  }
                  self.record_unsupported_command(
                    "PopRoundedClip", "PopRoundedClip has no matching rounded clip stack entry",
                  )
                }
              }
            None =>
              self.record_unsupported_command(
                "PopRoundedClip", "PopRoundedClip has no matching canvas stack entry",
              )
          }
        }
        Some(other) => {
          canvas_scopes.push(other)
          self.record_unsupported_command(
            "PopRoundedClip",
            "pop did not match active \{@render_common.plan_scope_name(other)} scope",
          )
        }
        None =>
          self.record_unsupported_command(
            "PopRoundedClip", "pop has no matching push scope",
          )
      }
    PushTransform(transform) => {
      self.canvas.save()
      canvas_scopes.push(Transform)
      self.canvas.concat_transform(sun_transform(transform))
    }
    PopTransform =>
      self.pop_canvas_scope(canvas_scopes, opacity_stack, Transform)
    PushOpacity(opacity) => {
      canvas_scopes.push(Opacity)
      opacity_stack.push(sun_clamp_unit(opacity))
    }
    PopOpacity => self.pop_canvas_scope(canvas_scopes, opacity_stack, Opacity)
    PushLayer(spec) => {
      blend_mode_stack.push(sun_blend_mode(spec.blend_mode))
      layer_spec_stack.push({ spec, transform: self.canvas.get_transform(), })
      self.push_transparent_offscreen_canvas()
      canvas_scopes.push(Layer)
    }
    PopLayer =>
      match canvas_scopes.pop() {
        Some(Layer) => {
          let layer_pixmap = self.canvas.get_pixmap()
          let layer_blend = match blend_mode_stack.pop() {
            Some(m) => m
            None => SourceOver
          }
          let layer_scope = match layer_spec_stack.pop() {
            Some(scope) => scope
            None => {
              self.record_unsupported_command(
                "PopLayer", "PopLayer has no matching layer spec stack entry",
              )
              {
                spec: @core.LayerSpec::new(),
                transform: @sun_graphics.Transform::identity(),
              }
            }
          }
          match self.canvas_stack.pop() {
            Some(parent_canvas) => {
              self.canvas = parent_canvas
              self.composite_layer_pixmap(
                layer_pixmap, layer_scope, opacity, layer_blend,
              )
            }
            None =>
              self.record_unsupported_command(
                "PopLayer", "PopLayer has no matching canvas stack entry",
              )
          }
        }
        Some(other) => {
          canvas_scopes.push(other)
          self.record_unsupported_command(
            "PopLayer",
            "pop did not match active \{@render_common.plan_scope_name(other)} scope",
          )
        }
        None =>
          self.record_unsupported_command(
            "PopLayer", "pop has no matching push scope",
          )
      }
    PushFilter(effect) => {
      self.filter_stack.push(sun_filter_effect(effect))
      match effect {
        Blur(radius) => self.blur_radius_stack.push(radius.max(0.0))
        _ => self.blur_radius_stack.push(0.0)
      }
      self.push_transparent_offscreen_canvas()
      canvas_scopes.push(Filter)
    }
    PopFilter => {
      let filter = self.filter_stack.pop()
      let blur_radius_entry = self.blur_radius_stack.pop()
      let blur_radius = blur_radius_entry.unwrap_or(0.0)
      match canvas_scopes.pop() {
        Some(Filter) => {
          let layer_pixmap = self.canvas.get_pixmap()
          let effective_pixmap = if blur_radius > 0.0 {
            sun_box_blur_pixmap(layer_pixmap, blur_radius)
          } else {
            layer_pixmap
          }
          match self.canvas_stack.pop() {
            Some(parent_canvas) => {
              self.canvas = parent_canvas
              // Apply color filter at the pixmap level instead of
              // per-pixel fill_rect calls to avoid w*h Paint allocations
              // and per-pixel clip/transform overhead.
              // Skip the pixmap copy when the filter is identity (common
              // for blur-only PushFilter scopes).
              let composited = match filter {
                Some(paint_filter) =>
                  if paint_filter.is_identity() {
                    effective_pixmap
                  } else {
                    sun_filter_pixmap(effective_pixmap, paint_filter)
                  }
                None => effective_pixmap
              }
              self.canvas.draw_pixmap(
                composited,
                0,
                0,
                @sun_graphics.Paint::new().set_opacity(opacity),
              )
            }
            None =>
              self.record_unsupported_command(
                "PopFilter", "PopFilter has no matching canvas stack entry",
              )
          }
        }
        Some(other) => {
          canvas_scopes.push(other)
          match filter {
            Some(f) => self.filter_stack.push(f)
            None => ()
          }
          match blur_radius_entry {
            Some(radius) => self.blur_radius_stack.push(radius)
            None => ()
          }
          self.record_unsupported_command(
            "PopFilter",
            "pop did not match active \{@render_common.plan_scope_name(other)} scope",
          )
        }
        None => {
          match filter {
            Some(f) => self.filter_stack.push(f)
            None => ()
          }
          match blur_radius_entry {
            Some(radius) => self.blur_radius_stack.push(radius)
            None => ()
          }
          self.record_unsupported_command(
            "PopFilter", "pop has no matching push scope",
          )
        }
      }
    }
    DrawPath(path) => self.draw_path(path, opacity)
    DrawShaderEffect(spec) => self.draw_shader_effect(spec, opacity)
    BeginRetainedLayer(_) =>
      self.record_unsupported_command(
        "BeginRetainedLayer", "cached layer scope not intercepted by render_cached_command_range",
      )
    EndRetainedLayer(_) =>
      self.record_unsupported_command(
        "EndRetainedLayer", "cached layer scope intercepted by render_cached_command_range",
      )
  }
}

///|
fn SunRasterRenderer::fill_rounded_rect(
  self : SunRasterRenderer,
  rounded : @core.RoundedRect,
  brush : @core.Brush,
  opacity : Double,
) -> Unit {
  let rect = rounded.rect
  self.canvas.fill_rounded_rect(
    rect.origin.x,
    rect.origin.y,
    rect.size.width,
    rect.size.height,
    rounded.radius,
    sun_brush_paint(brush, opacity),
  )
}

///|
fn SunRasterRenderer::stroke_rounded_rect(
  self : SunRasterRenderer,
  rounded : @core.RoundedRect,
  brush : @core.Brush,
  width : Double,
  opacity : Double,
) -> Unit {
  let rect = rounded.rect
  self.canvas.stroke_rounded_rect(
    rect.origin.x,
    rect.origin.y,
    rect.size.width,
    rect.size.height,
    rounded.radius,
    sun_brush_stroke_paint(brush, width, opacity),
  )
}

///|
fn SunRasterRenderer::draw_path(
  self : SunRasterRenderer,
  path : @core.PathSpec,
  opacity : Double,
) -> Unit {
  let sun_path = sun_path(path)
  match path.fill {
    Some(brush) =>
      self.canvas.fill_path(sun_path, sun_brush_paint(brush, opacity))
    None => ()
  }
  match path.stroke {
    Some(brush) =>
      self.canvas.stroke_path(
        sun_path,
        sun_brush_stroke_paint(brush, path.stroke_width, opacity),
      )
    None => ()
  }
}

///|
fn SunRasterRenderer::pop_canvas_scope(
  self : SunRasterRenderer,
  canvas_scopes : Array[@render_common.PlanScopeKind],
  opacity_stack : Array[Double],
  expected : @render_common.PlanScopeKind,
) -> Unit {
  match canvas_scopes.pop() {
    Some(actual) =>
      if actual == expected {
        match actual {
          Opacity => ignore(opacity_stack.pop())
          _ => ignore(self.canvas.restore())
        }
      } else {
        canvas_scopes.push(actual)
        self.record_unsupported_command(
          @render_common.plan_scope_pop_command(expected),
          "pop did not match active \{@render_common.plan_scope_name(actual)} scope",
        )
      }
    None =>
      self.record_unsupported_command(
        @render_common.plan_scope_pop_command(expected),
        "pop has no matching push scope",
      )
  }
}

///|
fn SunRasterRenderer::record_unsupported_command(
  self : SunRasterRenderer,
  command : String,
  reason : String,
) -> Unit {
  self.unsupported_command_count = self.unsupported_command_count + 1
  self.unsupported_command_diagnostics.push({ command, reason, })
}

///|
fn sun_dim_to_int(value : Double) -> Int {
  value.ceil().max(1.0).to_int()
}

///|
fn sun_color(color : @core.Color) -> @sun_graphics.Color {
  @sun_graphics.Color::new(
    r=sun_channel(color.r),
    g=sun_channel(color.g),
    b=sun_channel(color.b),
    a=sun_channel(color.a),
  )
}

///|
fn sun_channel(value : Double) -> Byte {
  (sun_clamp_unit(value) * 255.0 + 0.5).to_int().max(0).min(255).to_byte()
}

///|
fn sun_clamp_unit(value : Double) -> Double {
  guard value == value else { return 0.0 }
  if value < 0.0 {
    0.0
  } else if value > 1.0 {
    1.0
  } else {
    value
  }
}

///|
fn sun_current_opacity(opacity_stack : Array[Double]) -> Double {
  let mut opacity = 1.0
  for item in opacity_stack {
    opacity = opacity * item
  }
  opacity
}

///|
fn sun_paint(color : @core.Color, opacity : Double) -> @sun_graphics.Paint {
  @sun_graphics.Paint::new().set_color(sun_color(color)).set_opacity(opacity)
}

///|
fn sun_stroke_paint(
  color : @core.Color,
  width : Double,
  opacity : Double,
) -> @sun_graphics.Paint {
  sun_paint(color, opacity).set_style(Stroke).set_stroke_width(width)
}

///|
fn sun_brush_paint(
  brush : @core.Brush,
  opacity : Double,
) -> @sun_graphics.Paint {
  let paint = @sun_graphics.Paint::new().set_opacity(opacity)
  match brush {
    Solid(color) => paint.set_color(sun_color(color))
    LinearGradient(gradient) =>
      paint
      .set_color(sun_color(gradient.start_color))
      .set_shader(
        @sun_graphics.PaintShader::linear_gradient(
          x0=gradient.start.x,
          y0=gradient.start.y,
          x1=gradient.end.x,
          y1=gradient.end.y,
          start_color=sun_color(gradient.start_color),
          end_color=sun_color(gradient.end_color),
        ),
      )
    RadialGradient(gradient) =>
      paint
      .set_color(sun_color(gradient.center_color))
      .set_shader(
        @sun_graphics.PaintShader::radial_gradient(
          cx=gradient.center.x,
          cy=gradient.center.y,
          radius=gradient.radius,
          start_color=sun_color(gradient.center_color),
          end_color=sun_color(gradient.edge_color),
        ),
      )
  }
}

///|
fn sun_brush_stroke_paint(
  brush : @core.Brush,
  width : Double,
  opacity : Double,
) -> @sun_graphics.Paint {
  sun_brush_paint(brush, opacity)
  .set_style(Stroke)
  .set_stroke_width(width)
  .set_stroke_cap(Round)
  .set_stroke_join(Round)
}

///|
fn sun_transform(transform : @core.Transform2D) -> @sun_graphics.Transform {
  @sun_graphics.Transform::affine(
    a=transform.a,
    b=transform.b,
    c=transform.c,
    d=transform.d,
    tx=transform.tx,
    ty=transform.ty,
  )
}

///|
fn sun_path(path : @core.PathSpec) -> @sun_graphics.Path {
  let out = @sun_graphics.Path::new()
  for verb in path.verbs {
    match verb {
      MoveTo(point) => ignore(out.move_to(point.x, point.y))
      LineTo(point) => ignore(out.line_to(point.x, point.y))
      QuadTo(control, point) =>
        ignore(out.quad_to(control.x, control.y, point.x, point.y))
      CubicTo(control1, control2, point) =>
        ignore(
          out.cubic_to(
            control1.x,
            control1.y,
            control2.x,
            control2.y,
            point.x,
            point.y,
          ),
        )
      Close => ignore(out.close())
    }
  }
  out
}

///|
fn SunRasterRenderer::draw_shadow(
  self : SunRasterRenderer,
  shadow : @core.ShadowSpec,
  opacity : Double,
) -> Unit {
  let rect = shadow.rect.rect
  let corner_radius = shadow.rect.radius.max(0.0)
  let base_color = shadow.color
  let spread = shadow.spread.max(0.0)
  let blur_r = shadow.blur_radius.max(0.0)
  guard opacity > 0.0 else { return }
  guard base_color.a > 0.0 else { return }
  let pad = (blur_r * 2.0).ceil().to_int().max(1)
  let inner_w = rect.size.width + spread * 2.0
  let inner_h = rect.size.height + spread * 2.0
  let shadow_w = inner_w.ceil().to_int().max(1) + pad * 2
  let shadow_h = inner_h.ceil().to_int().max(1) + pad * 2
  let shadow_pixmap = @sun_graphics.Pixmap::new(shadow_w, shadow_h)
  let shadow_color = @sun_graphics.Color::new(
    r=sun_channel(base_color.r),
    g=sun_channel(base_color.g),
    b=sun_channel(base_color.b),
    a=sun_channel(sun_clamp_unit(base_color.a * opacity)),
  )
  let cx = pad.to_double() + inner_w * 0.5
  let cy = pad.to_double() + inner_h * 0.5
  let hx = inner_w * 0.5
  let hy = inner_h * 0.5
  let scaled_radius = corner_radius.min(hx).min(hy)
  for sy in 0.. 0.0 && qy > 0.0 {
        (qx * qx + qy * qy).sqrt()
      } else if qx > 0.0 {
        qx
      } else if qy > 0.0 {
        qy
      } else {
        0.0
      }
      let d = outside_dist - scaled_radius
      if d < 0.5 {
        shadow_pixmap.set_pixel(sx, sy, shadow_color)
      }
    }
  }
  let blurred = if blur_r > 0.5 {
    sun_box_blur_pixmap(shadow_pixmap, blur_r)
  } else {
    shadow_pixmap
  }
  let draw_x = rect.origin.x + shadow.offset.x - spread - pad.to_double()
  let draw_y = rect.origin.y + shadow.offset.y - spread - pad.to_double()
  self.canvas.draw_pixmap(
    blurred,
    draw_x.to_int(),
    draw_y.to_int(),
    @sun_graphics.Paint::new().set_opacity(1.0),
  )
}

///|
fn SunRasterRenderer::draw_shader_effect(
  self : SunRasterRenderer,
  spec : @core.ShaderEffectSpec,
  opacity : Double,
) -> Unit {
  let frame = spec.frame
  match spec.name {
    "solid" => self.fill_shader_effect_frame(frame, spec.fallback, opacity)
    "checker" =>
      self.draw_checker_effect(frame, spec.fallback, spec.uniforms, opacity)
    "linear-gradient-debug" =>
      self.canvas.fill_rect(
        frame.origin.x,
        frame.origin.y,
        frame.size.width,
        frame.size.height,
        sun_linear_gradient_debug_paint(frame, spec.fallback, opacity),
      )
    "vignette" =>
      self.draw_vignette_effect(frame, spec.fallback, spec.uniforms, opacity)
    _ => {
      let fallback_paint = sun_brush_paint(spec.fallback, opacity)
      self.canvas.fill_rect(
        frame.origin.x,
        frame.origin.y,
        frame.size.width,
        frame.size.height,
        fallback_paint,
      )
      self.record_unsupported_command(
        "DrawShaderEffect",
        "unknown shader effect '\{spec.name}' used fallback brush",
      )
    }
  }
}

///|
fn sun_filter_effect(effect : @core.FilterEffect) -> @sun_graphics.PaintFilter {
  match effect {
    Blur(_) => @sun_graphics.PaintFilter::identity()
    Saturate(factor) => @sun_graphics.PaintFilter::saturate(factor)
    Brightness(factor) => @sun_graphics.PaintFilter::brightness(factor)
    Contrast(factor) => @sun_graphics.PaintFilter::contrast(factor)
    ColorMatrix(values) => @sun_graphics.PaintFilter::color_matrix(values)
  }
}

///|
fn sun_box_blur_pixmap(
  src : @sun_graphics.Pixmap,
  radius : Double,
) -> @sun_graphics.Pixmap {
  let r = radius.max(0.0).to_int()
  guard r > 0 else { return src }
  // Three-pass box blur approximates a Gaussian kernel, producing
  // much smoother falloff than a single pass while keeping the same
  // effective blur spread (each pass uses the full integer radius).
  let pass1 = sun_single_box_blur(src, r)
  let pass2 = sun_single_box_blur(pass1, r)
  sun_single_box_blur(pass2, r)
}

///|
fn sun_single_box_blur(
  src : @sun_graphics.Pixmap,
  r : Int,
) -> @sun_graphics.Pixmap {
  let w = src.get_width()
  let h = src.get_height()
  guard w > 0 && h > 0 else { return src }
  let k = 2 * r + 1
  let temp = @sun_graphics.Pixmap::new(w, h)
  // Horizontal pass with sliding window
  for y in 0.. Byte {
  (sum / count.to_double() + 0.5).to_int().max(0).min(255).to_byte()
}

///|
fn sun_filter_pixmap(
  src : @sun_graphics.Pixmap,
  filter : @sun_graphics.PaintFilter,
) -> @sun_graphics.Pixmap {
  let w = src.get_width()
  let h = src.get_height()
  let dst = @sun_graphics.Pixmap::new(w, h)
  let pixels = src.get_pixels()
  for y in 0.. @sun_graphics.BlendMode {
  match mode {
    SourceOver => SourceOver
    Multiply => Multiply
    Screen => Screen
    Overlay => Overlay
    Darken => Darken
    Lighten => Lighten
  }
}