diff --git a/docs/marca/README.md b/docs/marca/README.md index 99788c9e..4e78eb0b 100644 --- a/docs/marca/README.md +++ b/docs/marca/README.md @@ -41,17 +41,27 @@ TAWASUYU (el territorio: apps, compositor, filosofía) × TAKANA (la herramienta `scripts/logo-ascii.py` emite el símbolo al estilo de un `*fetch`. **Se deriva del SVG**, no se dibuja a mano: una copia dibujada aparte se desincroniza el día que la marca cambie y nadie se -entera. La grilla es la tocapu 7×7 y cada celda ocupa dos columnas para salir cuadrada (los -caracteres de terminal son ~2:1). +entera. + +| forma | qué hace | tamaño (escala 3) | +|---|---|---| +| `--medio` *(default)* | **Medios bloques** `▀` con color de frente **y de fondo**, así cada renglón lleva DOS filas de píxeles. Trae la placa obsidiana, la celda de espacio libre y las **juntas entre teselas** | 23 × 12 | +| `--bloques` | `██` por celda, sin fondo. Para terminales que renderizan mal los medios bloques | 14 × 7 | +| `--plano` | ASCII de densidad, sin color. Para pipes, `TERM` tonto y consolas que no hablan 24-bit | 14 × 7 | ```sh -scripts/logo-ascii.py # color, ANSI 24-bit -scripts/logo-ascii.py --plano # monocromo, para pipes y TERM sin color -scripts/logo-ascii.py --regenerar # reescribe simbolo.ansi y simbolo.txt +scripts/logo-ascii.py # medios bloques, escala 3 +scripts/logo-ascii.py --escala=5 # más grande; la junta escala con la tesela +scripts/logo-ascii.py --regenerar # reescribe los tres ficheros de docs/marca/ ``` -- `simbolo.ansi` — listo para `cat`. -- `simbolo.txt` — monocromo, densidad decreciente del extremo del gradiente (`#`) a la chispa (`@`). +**Las juntas no son adorno:** en el SVG las teselas son cuadrados de 100 con 8 de aire. La tocapu +son piezas **separadas**, no un bloque macizo, y sin la junta el símbolo se lee como una mancha. +Se apagan solas por debajo de escala 3, donde la junta se comería media tesela. + +**No se interpola ni se suaviza el gradiente.** El símbolo *es* una retícula de cuadrados; +difuminarlo sería «recolorear y deformar», que esta misma hoja prohíbe. Subir la escala repite +píxeles y mantiene el borde duro. ## En el fetch de shuma diff --git a/docs/marca/simbolo-bloques.ansi b/docs/marca/simbolo-bloques.ansi new file mode 100644 index 00000000..5ab05e50 --- /dev/null +++ b/docs/marca/simbolo-bloques.ansi @@ -0,0 +1,7 @@ +██████████████ + ██████████ +██████████████ + ██ + ██ + ██ + ██ diff --git a/docs/marca/simbolo.ansi b/docs/marca/simbolo.ansi index 5ab05e50..52b119bb 100644 --- a/docs/marca/simbolo.ansi +++ b/docs/marca/simbolo.ansi @@ -1,7 +1,12 @@ -██████████████ - ██████████ -██████████████ - ██ - ██ - ██ - ██ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ diff --git a/scripts/logo-ascii.py b/scripts/logo-ascii.py index e67884fd..8ab7b406 100755 --- a/scripts/logo-ascii.py +++ b/scripts/logo-ascii.py @@ -3,23 +3,39 @@ Se DERIVA del SVG de `docs/marca/`, no se dibuja a mano: una copia dibujada aparte se desincroniza del símbolo el día que la marca cambie, y nadie se -entera. La grilla es la tocapu 7x7 y cada celda ocupa dos columnas para que -salga cuadrada en una terminal (los caracteres son ~2:1 de alto). +entera. -Uso: - scripts/logo-ascii.py # color (ANSI 24-bit) - scripts/logo-ascii.py --plano # monocromo, para pipes y TERM tontos - scripts/logo-ascii.py --regenerar # reescribe docs/marca/simbolo.{ansi,txt} +Tres formas, de más a menos fiel: + + --medio (default) MEDIOS BLOQUES: `▀` con color de frente y de fondo, así + cada renglón de terminal lleva DOS filas de píxeles. Es lo que usan + los fetch modernos y lo que permite subir la escala sin que el + dibujo se vuelva un ladrillo. Trae la placa de fondo y la celda de + espacio libre que pide la hoja de marca. + --bloques BLOQUES ENTEROS: `██` por celda. Sin fondo. Para terminales que + renderizan mal los medios bloques. + --plano ASCII de densidad, sin color. Para pipes, `TERM` tonto y consolas + que no hablan 24-bit. + +**No se interpola ni se suaviza el gradiente.** El símbolo ES una retícula +tocapu de cuadrados; difuminarlo sería «recolorear y deformar», que la hoja de +marca prohíbe explícitamente. Subir `--escala` repite píxeles (vecino más +cercano) y mantiene el borde duro. """ import re, sys, pathlib RAIZ = pathlib.Path(__file__).resolve().parent.parent SVG = RAIZ / "docs/marca/simbolo-fondo-oscuro.svg" -# Monocromo: densidad decreciente, del extremo del gradiente a la chispa. +OBSIDIANA = "#17130E" # el fondo de la hoja de marca DENSIDAD = {"#A63A25": "#", "#DF6B2A": "*", "#E3A63D": "+", "#FFF6DE": "@"} +def rgb(h): + return int(h[1:3], 16), int(h[3:5], 16), int(h[5:7], 16) + + def grilla(): + """La retícula {(fila, col): color} leída del SVG.""" s = SVG.read_text() # El SVG trae un manifiesto C2PA enorme en ; los rects van después. cuerpo = s[s.rfind("") + 11:] if "" in s else s @@ -27,14 +43,52 @@ def grilla(): for m in re.finditer( r'= 3 + celdas, filas, cols = grilla() + alto, ancho = filas * escala + 2 * margen, cols * escala + 2 * margen + m = [[None] * ancho for _ in range(alto)] + lleno = escala - 1 if juntas else escala + for (r, c), f in celdas.items(): + for dr in range(lleno): + for dc in range(lleno): + m[margen + r * escala + dr][margen + c * escala + dc] = f + return m + + +def medio(escala=3, margen=1): + """`▀`: color de frente = píxel de arriba, de fondo = el de abajo.""" + m = pixeles(escala, margen) + if len(m) % 2: + m.append([None] * len(m[0])) + out = [] + for y in range(0, len(m), 2): + linea = [] + for x in range(len(m[0])): + ar, ab = m[y][x] or OBSIDIANA, m[y + 1][x] or OBSIDIANA + fr, fg, fb = rgb(ar) + br, bg, bb = rgb(ab) + linea.append(f"\x1b[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m▀") + out.append("".join(linea) + "\x1b[0m") + return "\n".join(out) + + +def bloques(): celdas, filas, cols = grilla() out = [] for r in range(filas): @@ -43,19 +97,32 @@ def render(color=True): f = celdas.get((r, c)) if f is None: linea.append(" ") - elif color: - rr, gg, bb = int(f[1:3], 16), int(f[3:5], 16), int(f[5:7], 16) - linea.append(f"\x1b[38;2;{rr};{gg};{bb}m██\x1b[0m") else: - linea.append(DENSIDAD[f] * 2) + rr, gg, bb = rgb(f) + linea.append(f"\x1b[38;2;{rr};{gg};{bb}m██\x1b[0m") out.append("".join(linea).rstrip()) return "\n".join(out) +def plano(): + celdas, filas, cols = grilla() + return "\n".join( + "".join(DENSIDAD[celdas[(r, c)]] * 2 if (r, c) in celdas else " " for c in range(cols)).rstrip() + for r in range(filas) + ) + + if __name__ == "__main__": - if "--regenerar" in sys.argv: - (RAIZ / "docs/marca/simbolo.ansi").write_text(render(True) + "\n") - (RAIZ / "docs/marca/simbolo.txt").write_text(render(False) + "\n") - print("docs/marca/simbolo.ansi y simbolo.txt regenerados desde el SVG") + a = sys.argv[1:] + esc = int(next((x.split("=")[1] for x in a if x.startswith("--escala=")), 3)) + if "--regenerar" in a: + (RAIZ / "docs/marca/simbolo.ansi").write_text(medio(esc) + "\n") + (RAIZ / "docs/marca/simbolo-bloques.ansi").write_text(bloques() + "\n") + (RAIZ / "docs/marca/simbolo.txt").write_text(plano() + "\n") + print("docs/marca/simbolo{.ansi,-bloques.ansi,.txt} regenerados desde el SVG") + elif "--plano" in a: + print(plano()) + elif "--bloques" in a: + print(bloques()) else: - print(render(color="--plano" not in sys.argv)) + print(medio(esc))