Shadow Baking: - ShadowCache prerenderiza sombras blur (key: w,h,blur,radius,spread) - initWithCache() habilita cache, deinit() lo libera - 4.2x más rápido en Debug, 2.5x en ReleaseSafe Glyph Blitting: - Early exit si glifo fuera de clip - Pre-cálculo región visible - Acceso directo fb.pixels[] - Aritmética u32 (sin structs Color) - Fast path alpha=255 Correcciones: - Integer overflow: saturating arithmetic (+|, -|, *|) - u16→u32 en blitShadowCache 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9.7 KiB
zcatgui - Historial de Versiones
Extraído de CLAUDE.md para mantener archivo principal conciso. Ver CLAUDE.md para documentación del proyecto.
Historial Completo
| Fecha | Versión | Cambios |
|---|---|---|
| 2025-12-09 | v0.1.0 | Proyecto creado, estructura base, documentación |
| 2025-12-09 | v0.2.0 | Widgets Fase 2 completados (Label, Button, TextInput, Checkbox, Select, List, Focus) |
| 2025-12-09 | v0.3.0 | Widgets Fase 3 completados (Table editable, Split panels, Panel container) |
| 2025-12-09 | v0.3.5 | Keyboard integration: InputState ahora trackea teclas, Table responde a flechas/Enter/Escape/Tab/F2 |
| 2025-12-09 | v0.4.0 | Modal widget: diálogos modales (alert, confirm, input), plan extendido documentado |
| 2025-12-09 | v0.5.0 | AutoComplete widget, comparativa DVUI/Gio/zcatui en WIDGET_COMPARISON.md |
| 2025-12-09 | v0.6.0 | FASE 1 Optimización: FrameArena, ObjectPool, dirty rectangles, Benchmark suite |
| 2025-12-09 | v0.7.0 | FASE 2: Progress, Tooltip, Toast, Spinner |
| 2025-12-09 | v0.8.0 | FASE 2: TextArea, Tree, Badge/TagGroup |
| 2025-12-09 | v0.9.0 | FASE 3: Image, ReorderableList, ColorPicker, DatePicker |
| 2025-12-09 | v0.10.0 | FASE 4: NumberEntry, RichText, Breadcrumb |
| 2025-12-09 | v0.11.0 | FASE 5: Canvas, Charts (line/bar/pie), Icon system (60+ icons) |
| 2025-12-09 | v0.12.0 | FASE 6: Clipboard, DragDrop, Shortcuts, FocusGroups |
| 2025-12-09 | v0.13.0 | FASE 7: Animation/Easing, Effects (shadow/gradient/blur), VirtualScroll, AA rendering |
| 2025-12-09 | v0.14.0 | FASE 8: Accessibility system, Testing framework, 274 tests |
| 2025-12-09 | v0.14.1 | FASE 9: Gio parity - 12 widgets + gesture system |
| 2025-12-09 | v0.15.0 | FASE 10: Mobile/Web - WASM, Android, iOS backends |
| 2025-12-09 | v0.15.0 | Documentación: REFERENCE.md completo (1370 líneas) |
| 2025-12-11 | v0.15.1 | FocusSystem rediseñado: registration_group/active_group, focus implícito |
| 2025-12-11 | v0.15.2 | Widgets adaptados a FocusSystem: numberentry, textarea, select, radio, slider, tabs |
| 2025-12-16 | v0.16.0 | TTF rasterization con antialiasing (supersampling 2x) |
| 2025-12-16 | v0.16.1 | Fuente embebida: TtfFont.initEmbedded() |
| 2025-12-16 | v0.16.2 | Fix TTF: DroidSans (187KB) reemplaza AdwaitaSans (variable). Y-flip rasterización. |
| 2025-12-17 | v0.17.0 | ⭐ Integración zcatttf v1.0 - TTF FUNCIONA PERFECTAMENTE |
| 2025-12-17 | v0.18.0 | Paridad Visual DVUI Fase 1: RenderMode dual, esquinas redondeadas, sombras |
| 2025-12-17 | v0.19.0 | Paridad Visual DVUI Fase 2: HoverTransition, Focus Ring AA en 9 widgets |
| 2025-12-17 | v0.20.0 | AdvancedTable: 8 fases completas (~2,700 LOC) - Schema, CRUD, Sorting, Lookup |
| 2025-12-17 | v0.21.0 | AdvancedTable: +990 LOC (multi-select, search, validation) |
| 2025-12-17 | v0.21.1 | Fix: AdvancedTable teclado - result.selected_row/col en handleKeyboard |
| 2025-12-19 | v0.21.2 | AdvancedTable: selected_row_unfocus, color selección según focus |
| 2025-12-19 | v0.22.0 | ⭐ AutoComplete: focus system integration, getTextInput(), first_frame guard |
| 2025-12-19 | v0.22.1 | ⭐ Text Metrics: ctx.measureText/measureTextToCursor para fuentes TTF de ancho variable |
| 2025-12-19 | v0.22.2 | Cursor blink rate: 500ms→300ms (más responsive durante edición) |
| 2025-12-30 | v0.23.0 | ⭐ FilledTriangle primitive: scanline rasterizer for 3D graphics |
| 2025-12-30 | v0.24.0 | ⭐ FilledCircle primitive: Midpoint Circle Algorithm (Bresenham) |
| 2025-12-30 | v0.25.0 | ⭐ IdleCompanion widget: mascota animada que aparece tras inactividad |
| 2025-12-31 | v0.26.0 | ⭐ Z-Design V5 Pixel Perfect: títulos legibles (contrastTextColor), botones centrados (+2px TTF), semáforo reubicado (texto + cuadrado derecha) |
| 2025-12-31 | v0.26.1 | Fix: drawBeveledRect bisel ahora +1px inset (no solapa borde exterior) |
| 2026-01-02 | v0.27.0 | ⭐ PERF: Shadow Baking - Cache de sombras prerenderizadas en SoftwareRenderer |
| 2026-01-02 | v0.27.1 | ⭐ PERF: Glyph Blitting Optimizado - drawGlyphBitmap con acceso directo a píxeles |
Hitos Importantes
v0.17.0 - TTF Funcional (2025-12-17)
Integración de zcatttf v1.0. El texto TTF ahora se renderiza perfectamente.
→ Detalle: docs/research/ y teamdocs hitos
v0.18.0-v0.19.0 - Paridad Visual DVUI (2025-12-17)
Sistema de rendering dual (simple/fancy), esquinas redondeadas, sombras, transiciones hover, focus ring AA.
→ Detalle: docs/research/DVUI_AUDIT_2025-12-17.md
v0.20.0-v0.21.1 - AdvancedTable (2025-12-17)
Widget de tabla avanzada con schema, CRUD, sorting, lookup, multi-select, search, validation.
→ Detalle: docs/ADVANCED_TABLE_MERGE_PLAN.md
v0.22.0-v0.22.2 - AutoComplete + Text Metrics (2025-12-19)
- AutoComplete: Integración completa con sistema de focus (registerFocusable, requestFocus, hasFocus)
- Text Metrics: Nuevo sistema ctx.measureText() para posicionamiento correcto del cursor con fuentes TTF
- Cursor: Velocidad de parpadeo aumentada (500ms→300ms) para mejor feedback durante edición
→ Archivos:
context.zig,text_input.zig,autocomplete.zig
v0.23.0-v0.24.0 - Primitivas Gráficas 2D (2025-12-30)
Nuevas primitivas para gráficos 2D y mascotas animadas:
-
FilledTriangle (v0.23.0):
- Rasterización por scanlines con interpolación de bordes
- Soporte para backface culling y Z-sorting (3D)
- Clipping integrado con sistema de clip rects
- Uso: logos 3D, iconos, formas geométricas
-
FilledCircle (v0.24.0):
- Algoritmo Midpoint Circle (Bresenham)
- Solo aritmética entera (eficiente, sin sqrt/trig)
- Relleno por scanlines horizontales simétricos
- Uso: mascotas, avatares, UI orgánica, gráficos
Aplicación: Mascota "Zcat" en zsimifactu (aparece tras 15s de inactividad)
→ Archivos: core/command.zig, render/software.zig
→ Doc: zsimifactu/docs/PLAN_CIRCULOS_Y_ZCAT_2025-12-30.md
v0.25.0 - IdleCompanion Widget (2025-12-30)
Sistema de mascota animada reutilizable para cualquier aplicación:
-
Características:
- Aparece tras periodo configurable de inactividad (default: 15s)
- Se asoma por bordes de paneles/rectángulos aleatorios
- Animación suave con clipping correcto (respeta bordes)
- Ojos que miran a los lados (izq/centro/der)
- "Salto de pánico" al detectar actividad del usuario
- Diseño de gato con orejas puntiagudas, pupilas verticales, mejillas y bigotes
-
Estados de animación:
hidden: Esperando idlepeeking: Asomándose lentamente (4s)watching: Completamente visible, mirando alrededor (3s)hiding: Bajando normal (1s) o salto de pánico (0.2s)
-
Uso:
const IdleCompanion = zcatgui.widgets.idle_companion; var state: IdleCompanion.State = .{}; const panels = [_]IdleCompanion.Rect{ ... }; IdleCompanion.draw(ctx, &panels, &state, last_activity, color);
→ Archivo: widgets/idle_companion.zig
v0.27.0-v0.27.1 - Optimizaciones de Rendimiento (2026-01-02)
Optimizaciones profundas del motor de renderizado software para alcanzar 60fps.
Shadow Baking (v0.27.0)
Sistema de cache de sombras prerenderizadas que elimina el recálculo costoso de sombras blur cada frame.
Problema original:
- Las sombras con blur dibujaban N capas de rectángulos redondeados por frame
- Cada capa ejecutaba
fillRoundedRectque hace@sqrt()por cada píxel - Una sombra blur=8 sobre 200x100px = 8 × 20,000 × sqrt = 160,000 operaciones sqrt/frame
Solución:
- Nuevo
ShadowCachestruct con HashMap para sombras prerenderizadas - Key: (w, h, blur, radius, spread) - forma de la sombra
- Value: Buffer de alpha (u8[]) con la sombra ya calculada
- Primer frame: renderiza sombra a buffer, cachea
- Frames siguientes: blit rápido del buffer con color aplicado
Resultados medidos:
| Modo | Sin Cache | Con Cache | Mejora |
|---|---|---|---|
| Debug | ~180ms | ~43ms | 4.2x |
| ReleaseSafe | ~11ms | ~4.4ms | 2.5x |
API:
// Antes (sin cache)
var renderer = SoftwareRenderer.init(&fb);
// Ahora (con cache - recomendado)
var renderer = SoftwareRenderer.initWithCache(&fb, allocator);
defer renderer.deinit();
Archivos modificados:
src/render/software.zig: +200 LOC (ShadowCache, ShadowCacheKey, ShadowCacheEntry, fillAlphaRect, fillAlphaRectAdditive, blitShadowCache)
Glyph Blitting Optimizado (v0.27.1)
Optimización de drawGlyphBitmap en TTF rendering.
Problema original:
- 6 checks de bounds por cada píxel del glifo
- Llamadas a
getPixel()/setPixel()(con más bounds checks) - Creación de struct
Colorpor cada píxel semi-transparente - Sin early exit para glifos fuera del clip
Optimizaciones aplicadas:
- Early exit: Si glifo entero está fuera de clip/framebuffer, return inmediato
- Pre-cálculo de región visible: Intersección glifo ∩ clip ∩ framebuffer calculada una vez
- Acceso directo a
fb.pixels[]: Sin getPixel/setPixel - Aritmética u32: Sin crear structs Color por cada píxel
- Fast path opaco: Si alpha=255, escritura directa sin blending
Archivos modificados:
src/render/ttf.zig: drawGlyphBitmap() reescrito (~80 LOC)
Correcciones de Estabilidad
Durante la implementación se detectaron y corrigieron varios integer overflows:
- fillAlphaRect/fillAlphaRectAdditive: Aritmética saturante (
+|,-|,*|) y bounds checks - blitShadowCache: Color math con u32 en lugar de u16 para evitar overflow en multiplicación
- renderShadow: Límite de tamaño máximo (2048x2048) para evitar allocaciones enormes
→ Archivos: src/render/software.zig, src/render/ttf.zig
→ Telemetría: Añadida en zsimifactu/src/main.zig para medir Exec time