feat: primitive styling

This commit is contained in:
IliaDenisov
2026-03-07 17:01:22 +02:00
parent 477e656008
commit e4b956232f
18 changed files with 1264 additions and 175 deletions
+21 -62
View File
@@ -2,6 +2,7 @@ package world
import (
"errors"
"image/color"
"time"
)
@@ -25,6 +26,10 @@ type RenderOptions struct {
// or as a bounded plane without wrap (true).
// Default is false.
DisableWrapScroll bool
// BackgroundColor is used to clear full redraw and dirty regions.
// If nil, default background is opaque black.
BackgroundColor color.Color
}
var (
@@ -166,6 +171,15 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
return err
}
bg := color.RGBA{A: 255} // default black
if params.Options != nil && params.Options.BackgroundColor != nil {
if v, ok := params.Options.BackgroundColor.(color.RGBA); !ok {
panic("Options.BackgroundColor is not color.RGBA type")
} else {
bg = v
}
}
defer func() {
if !params.Debug {
return
@@ -203,17 +217,6 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
policy = *params.Options.Incremental
}
// --- Prepare style / layers (same as before) ---
style := DefaultRenderStyle()
if params.Options != nil && params.Options.Style != nil {
style = *params.Options.Style
}
layers := []RenderLayer{RenderLayerPoints, RenderLayerCircles, RenderLayerLines}
if params.Options != nil && len(params.Options.Layers) > 0 {
layers = params.Options.Layers
}
allowWrap := params.Options == nil || !params.Options.DisableWrapScroll
// --- Try incremental path first when state is initialized and geometry matches ---
@@ -239,30 +242,16 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
if len(toDraw) > 0 {
for _, r := range toDraw {
drawer.ClearRect(r.X, r.Y, r.W, r.H)
drawer.ClearRectTo(r.X, r.Y, r.W, r.H, bg)
}
plan, err := w.buildRenderPlanStageA(params)
if err != nil {
return err
}
catchUpPlan := planRestrictedToDirtyRects(plan, toDraw)
for _, layer := range layers {
switch layer {
case RenderLayerPoints:
applyPointStyle(drawer, style)
drawPointsFromPlanWithRadius(drawer, catchUpPlan, w.W, w.H, style.PointRadiusPx, allowWrap)
case RenderLayerCircles:
applyCircleStyle(drawer, style)
drawCirclesFromPlan(drawer, catchUpPlan, w.W, w.H, allowWrap)
case RenderLayerLines:
applyLineStyle(drawer, style)
drawLinesFromPlan(drawer, catchUpPlan, w.W, w.H, allowWrap)
default:
panic("render: unknown layer")
}
}
catchUpPlan := planRestrictedToDirtyRects(plan, toDraw)
w.drawPlanSinglePass(drawer, catchUpPlan, allowWrap)
}
w.renderState.pendingDirty = remaining
@@ -305,7 +294,7 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
dirtyToDraw := inc.Dirty
for _, r := range dirtyToDraw {
drawer.ClearRect(r.X, r.Y, r.W, r.H)
drawer.ClearRectTo(r.X, r.Y, r.W, r.H, bg)
}
// Additionally redraw a bounded portion of deferred dirty regions.
@@ -320,22 +309,7 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
return err
}
dirtyPlan := planRestrictedToDirtyRects(plan, dirtyToDraw)
for _, layer := range layers {
switch layer {
case RenderLayerPoints:
applyPointStyle(drawer, style)
drawPointsFromPlanWithRadius(drawer, dirtyPlan, w.W, w.H, style.PointRadiusPx, allowWrap)
case RenderLayerCircles:
applyCircleStyle(drawer, style)
drawCirclesFromPlan(drawer, dirtyPlan, w.W, w.H, allowWrap)
case RenderLayerLines:
applyLineStyle(drawer, style)
drawLinesFromPlan(drawer, dirtyPlan, w.W, w.H, allowWrap)
default:
panic("render: unknown layer")
}
}
w.drawPlanSinglePass(drawer, dirtyPlan, allowWrap)
// State already updated by ComputePanShiftPx (lastWorldRect advanced).
return nil
@@ -352,24 +326,9 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
if err != nil {
return err
}
drawer.ClearAll()
for _, layer := range layers {
switch layer {
case RenderLayerPoints:
applyPointStyle(drawer, style)
drawPointsFromPlanWithRadius(drawer, plan, w.W, w.H, style.PointRadiusPx, allowWrap)
case RenderLayerCircles:
applyCircleStyle(drawer, style)
drawCirclesFromPlan(drawer, plan, w.W, w.H, allowWrap)
case RenderLayerLines:
applyLineStyle(drawer, style)
drawLinesFromPlan(drawer, plan, w.W, w.H, allowWrap)
default:
panic("render: unknown layer")
}
}
drawer.ClearAllTo(bg)
w.drawPlanSinglePass(drawer, plan, allowWrap)
return w.CommitFullRedrawState(params)
}