---
name: generate_app_icon
kind: function
lang: py
domain: infra
version: "1.2.0"
purity: impure
signature: "generate_app_icon(phosphor_icon_name: str, accent_hex: str, out_ico_path: str, *, weight: str = 'fill', sizes: list[int] = None, phosphor_root: str = None, style: str = 'fill_white') -> str"
description: "Rasteriza un icono Phosphor SVG sobre un fondo redondeado del color accent y exporta un .ico multi-resolucion (default 16,24,32,48,64,128,256). Soporta tres estilos via param `style`: 'fill_white' (default, glyph blanco solido), 'adaptive_duotone' (glyph duotone con tono claro u oscuro segun luminancia del accent) y 'white_duotone' (glyph duotone phosphor con fill blanco — el path bg al opacity=0.2 deja translucir el accent dando segundo tono suave). Devuelve el path absoluto del .ico escrito."
tags: [cpp-windows, icon, windows, phosphor, ico, pillow, cairosvg]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [cairosvg, PIL]
params:
  - name: phosphor_icon_name
    desc: "Nombre del icono Phosphor sin sufijo de weight (ej. 'chart-bar', 'tree-structure', 'gauge'). Ver https://phosphoricons.com para el catalogo."
  - name: accent_hex
    desc: "Color de fondo en formato hexadecimal '#RRGGBB' (ej. '#0ea5e9', '#7c3aed'). Define la identidad visual de la app."
  - name: out_ico_path
    desc: "Ruta de salida del .ico. Absoluta o relativa al cwd. El directorio padre se crea si no existe. Colocar en <app_dir>/appicon.ico para que add_imgui_app lo detecte automaticamente."
  - name: weight
    desc: "Variante Phosphor: 'fill' (default), 'regular', 'bold', 'light', 'thin', 'duotone'."
  - name: sizes
    desc: "Lista de resoluciones a incluir. Default [16,24,32,48,64,128,256]. Cada tamano se renderiza independientemente para crispness."
  - name: phosphor_root
    desc: "Carpeta raiz de assets phosphor-core (contiene subdirs fill/, regular/, etc.). Default: <registry_root>/sources/phosphor-core/assets."
  - name: style
    desc: "Estilo de render. 'fill_white' (default, glyph blanco solido — backwards-compat). 'adaptive_duotone' (glyph duotone Phosphor con tono claro #f4f4f5 si luminancia(accent)<0.5, tono oscuro #0f0f12 si >=0.5; el path opacity=0.2 da el segundo tono). 'white_duotone' (glyph duotone Phosphor con fill #ffffff; path opacity=0.2 deja translucir el accent dando segundo tono suave; legible en cualquier accent claro u oscuro)."
output: "Ruta absoluta (str) del archivo .ico generado y escrito a disco."
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/infra/generate_app_icon.py"
---

## Ejemplo

```python
from infra import generate_app_icon

# Generar icono para una app C++ del registry
ico_path = generate_app_icon(
    phosphor_icon_name="chart-bar",
    accent_hex="#0ea5e9",
    out_ico_path="apps/chart_demo/appicon.ico",
)
print(ico_path)  # $HOME/fn_registry/apps/chart_demo/appicon.ico
```

```python
# Desde la CLI directa para prueba rapida
import sys
sys.path.insert(0, "python/functions")
from infra import generate_app_icon

generate_app_icon("gauge", "#059669", "/tmp/registry_dashboard.ico")
```

```bash
# Generar iconos para todas las apps del registry con el script batch
python dev/gen_app_icons.py
```

## Cuando usarla

Cuando una app C++ del registry necesita un `.ico` de Windows para distinguirse en el escritorio y taskbar. El macro `add_imgui_app` de `cpp/CMakeLists.txt` detecta `<app_dir>/appicon.ico` y lo enlaza al `.exe` via `windres` automaticamente en builds Windows. Ejecutar esta funcion antes de compilar en Windows o antes de `fn run redeploy_cpp_app_windows <app>`.

## Gotchas

- **Requiere `sources/phosphor-core/`**: el repo debe estar clonado. Si falta: `git clone --depth=1 https://github.com/phosphor-icons/core.git sources/phosphor-core` desde la raiz del registry. La funcion lanza `FileNotFoundError` con el comando exacto si el SVG no existe.
- **`cairosvg` y `Pillow` en el venv**: deben estar instalados en `python/.venv`. Si faltan: `cd python && uv pip install cairosvg pillow`. Ya presentes en el venv por defecto del registry.
- **El `.ico` se sobreescribe sin warning**: si ya existe `appicon.ico` se reemplaza silenciosamente. Hacer backup si se necesita preservar la version anterior.
- **Re-build del `.exe` necesario**: Windows no refleja el icono nuevo hasta que se recompila el ejecutable. Tras generar el `.ico` ejecutar `fn run redeploy_cpp_app_windows <app>` o compilar manualmente con CMake.
- **Solo formato `#RRGGBB`**: `accent_hex` debe tener exactamente 6 digitos hex. Formatos con alpha o notacion corta `#RGB` lanzan `ValueError`.
- **Peso "fill" por defecto**: Phosphor "fill" tiene las formas mas solidas y visibles en tamanos pequeños (16x16). Para iconos lineales usar `weight="regular"` pero verificar legibilidad a 16px.

## Capability growth log

- v1.2.0 (2026-05-18) — añade `style="white_duotone"`. Glyph duotone Phosphor con fill blanco; path bg al opacity=0.2 deja translucir el accent. Mas suave que `fill_white`, mismo punch que `adaptive_duotone` pero sin condicional.
- v1.1.0 (2026-05-17) — añade param `style="adaptive_duotone"`. Glyph duotone con tono claro/oscuro adaptativo segun luminancia del accent (Rec.601). Compatibilidad total con `style="fill_white"` por default.
