@startuml
title Zivro: последовательность рендера кадра (CPU)

actor User
participant "UI Frame\n(frame.zig)" as UI
participant "Canvas\n(Canvas.zig)" as Canvas
participant "RenderEngine" as RE
participant "CpuRenderEngine" as CPU
participant "drawDocument\n(cpu/draw.zig)" as Draw
participant "Shape modules\nline/ellipse/broken" as Shapes

User -> UI : input/events
UI -> Canvas : processPendingRedraw()
alt redraw pending and throttle passed
  Canvas -> Canvas : computeVisibleImageRect()\ncompute quality scale
  Canvas -> RE : render(document, canvas_size, visible_rect)
  RE -> CPU : renderDocument(...)
  CPU -> Draw : drawDocument(pixels,...)
  loop for each root object
    Draw -> Draw : Transform.compose(parent, local)
    Draw -> Shapes : draw shape by object.kind
    loop for each child
      Draw -> Draw : recursive drawObject(child, world_transform)
    end
  end
  Draw --> CPU : pixels rendered
  CPU --> Canvas : texture
  Canvas -> UI : texture for draw
else no redraw
  Canvas -> UI : keep previous texture
end

@enduml
