diff --git a/README.md b/README.md index 86ae5f1..46b6f34 100644 --- a/README.md +++ b/README.md @@ -461,7 +461,7 @@ secure-messenger/ app/windows/ CMake, runner, and bitdm.iss for the installer app/linux/ runner; the release tar.gz comes from .github/workflows/linux.yml app/web/ shell for bitdm.net/app, built as in deploy/webapp/README.md - app/tool/symbol/ 3 Python scripts that render and distribute the app icon + app/tool/symbol/ the BitDM mark (f1.py) and the script that writes every icon app/tool/*.py checks for the main.dart split: pure move, name collisions server/ Python relay + blob store, 5,106 lines; tests 5,568 lines, 206 tests (18.10.2026) diff --git a/secure-messenger/DESIGN.md b/secure-messenger/DESIGN.md index a454459..3d65f7f 100644 --- a/secure-messenger/DESIGN.md +++ b/secure-messenger/DESIGN.md @@ -59,6 +59,14 @@ Plattenbeschriftungen, 0.12em für Modulbezeichnungen, 0.08em für Zustände. - Tiefe entsteht durch **Versatz und weiche Streuung**, nie durch farbige Höfe ohne Versatz. +## Zeichen + +Seit 24.10.2026: ein **Anzeigefenster** mit Punktmatrix, darin leuchtet **DM** +im Akzent, die übrigen Punkte sind aus. Es ist dieselbe Welt wie die App: eine +Gerätefront, die nur dort leuchtet, wo sie etwas anzeigt. Bis 32 Pixel gibt es +eine Kleinfassung ohne Fenster und Raster. Vorlage, Maße und alle Ausgaben: +`app/tool/symbol/` (`py tool/symbol/verteilen.py`). + ## Grammatik der Frontplatte Neue Flächen erben diese Sprache: diff --git a/secure-messenger/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/secure-messenger/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 6deb4dd..f6aed61 100644 Binary files a/secure-messenger/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/secure-messenger/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/secure-messenger/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/secure-messenger/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 612e90b..81874cc 100644 Binary files a/secure-messenger/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/secure-messenger/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/secure-messenger/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/secure-messenger/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index a7acfd0..63a7e50 100644 Binary files a/secure-messenger/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/secure-messenger/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/secure-messenger/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/secure-messenger/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index b173a8b..d4213f9 100644 Binary files a/secure-messenger/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/secure-messenger/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/secure-messenger/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/secure-messenger/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index f03a040..7acaf81 100644 Binary files a/secure-messenger/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/secure-messenger/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/secure-messenger/app/fastlane/metadata/android/en-US/images/icon.png b/secure-messenger/app/fastlane/metadata/android/en-US/images/icon.png index df242e9..b9b3e90 100644 Binary files a/secure-messenger/app/fastlane/metadata/android/en-US/images/icon.png and b/secure-messenger/app/fastlane/metadata/android/en-US/images/icon.png differ diff --git a/secure-messenger/app/icon_bitdm_1024.png b/secure-messenger/app/icon_bitdm_1024.png deleted file mode 100644 index 4726e60..0000000 Binary files a/secure-messenger/app/icon_bitdm_1024.png and /dev/null differ diff --git a/secure-messenger/app/icon_bitdm_klein.png b/secure-messenger/app/icon_bitdm_klein.png deleted file mode 100644 index 0136d27..0000000 Binary files a/secure-messenger/app/icon_bitdm_klein.png and /dev/null differ diff --git a/secure-messenger/app/icon_master_1024.png b/secure-messenger/app/icon_master_1024.png deleted file mode 100644 index 700d539..0000000 Binary files a/secure-messenger/app/icon_master_1024.png and /dev/null differ diff --git a/secure-messenger/app/tool/symbol/01_gross.py b/secure-messenger/app/tool/symbol/01_gross.py deleted file mode 100644 index 84cf707..0000000 --- a/secure-messenger/app/tool/symbol/01_gross.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -"""BitDM-Symbol: Sprechblase als Umriss, B in Doto. - -DIE KERBE WAR EIN AUFBAUFEHLER, kein Zeichenfehler. Zuerst hatte ich Blase und -Zipfel als zwei getrennte Formen mit `outline` gezeichnet und danach versucht, -die Kante zwischen ihnen mit einem schwarzen Strich wegzuradieren. Genau dort -klaffte die Kerbe: zwei Umrisse, die sich beruehren, haben an der Naht immer -eine. - -RICHTIG IST EINE SILHOUETTE. Blase und Zipfel werden zu EINER gefuellten Form -vereinigt, dieselbe Form ein zweites Mal nach innen versetzt gezeichnet, und die -Differenz IST der Umriss. Damit kann an der Naht nichts klaffen — es gibt keine -Naht mehr. - -Der innere Rand: das Rechteck exakt um die Strichbreite eingezogen und der -Eckradius um denselben Betrag verkleinert (so gehoert es sich bei abgerundeten -Rechtecken). Der Zipfel wird um den Blasenmittelpunkt skaliert — bei einer -kompakten Form ergibt das einen optisch gleichmaessigen Strich, und die -Ueberlappung mit dem inneren Rechteck haelt die Form geschlossen. -""" -import pathlib -from PIL import Image, ImageChops, ImageDraw, ImageFont - -APP = pathlib.Path(r'C:\KI-Workstation\BitDM\secure-messenger\app') -S, U = 1024, 4 -N = S * U -SCHWARZ = (11, 12, 18, 255) -WEISS = (243, 243, 246, 255) - -BX0, BY0, BX1, BY1, RAD = 176, 206, 848, 700, 126 -STRICH = 48 -ZIPFEL = [(302, 636), (474, 636), (302, 852)] -CX, CY = (BX0 + BX1) / 2, (BY0 + BY1) / 2 - - -def k(v): - return round(v * U) - - -def silhouette(einzug): - """Blase + Zipfel als eine gefuellte Maske, um [einzug] nach innen.""" - m = Image.new('L', (N, N), 0) - d = ImageDraw.Draw(m) - d.rounded_rectangle( - (k(BX0 + einzug), k(BY0 + einzug), k(BX1 - einzug), k(BY1 - einzug)), - radius=k(max(RAD - einzug, 2)), fill=255) - if einzug: - sx = (BX1 - BX0 - 2 * einzug) / (BX1 - BX0) - sy = (BY1 - BY0 - 2 * einzug) / (BY1 - BY0) - z = [(CX + (x - CX) * sx, CY + (y - CY) * sy) for x, y in ZIPFEL] - else: - z = ZIPFEL - d.polygon([(k(x), k(y)) for x, y in z], fill=255) - return m - - -umriss = ImageChops.subtract(silhouette(0), silhouette(STRICH)) - -bild = Image.new('RGBA', (N, N), (0, 0, 0, 0)) -d = ImageDraw.Draw(bild) -d.rounded_rectangle((0, 0, N - 1, N - 1), radius=k(278), fill=SCHWARZ) -bild.paste(Image.new('RGBA', (N, N), WEISS), (0, 0), umriss) - -# Das B in Doto — NACH DER TINTE GESETZT, nicht nach den Schriftmassen. -# -# Erst hatte ich mit `textbbox` zentriert. Gemessen kam das B dann 19 Pixel zu -# weit links und 14 zu hoch heraus und fuellte nur 32 % der Innenbreite: Doto -# ist eine Punktmatrix-Schrift und meldet ihre Glyphenmasse ungenau, wie bei -# dieser Art Schrift ueblich. -# -# Darum: Buchstabe auf eine eigene Ebene, mit `getbbox()` auf die tatsaechliche -# Tinte beschneiden, und dieses Stueck mittig einsetzen. Unabhaengig davon, was -# die Schrift ueber sich behauptet. -ebene = Image.new('RGBA', (N, N), (0, 0, 0, 0)) -ImageDraw.Draw(ebene).text( - (k(200), k(200)), 'B', - font=ImageFont.truetype(str(APP / 'assets/fonts/Doto.ttf'), k(470)), - fill=WEISS) -tinte = ebene.crop(ebene.getbbox()) -zx = round(CX * U - tinte.width / 2) -zy = round(CY * U - tinte.height / 2) -bild.paste(tinte, (zx, zy), tinte) -print(f' B-Tinte {tinte.width // U}x{tinte.height // U} px, ' - f'Fuellung {100 * tinte.height / U / 398:.0f} % der Innenhoehe') - -bild = bild.resize((S, S), Image.LANCZOS) -bild.save(APP / 'icon_bitdm_1024.png') -print('gezeichnet, Strichbreite', STRICH) -print(' Ecke ', bild.getpixel((3, 3))) -print(' Blasenkante ', bild.getpixel((S // 2, round(BY0 * S / 1024) + 6))) -print(' Blaseninnen ', bild.getpixel((S // 2, round((BY0 + 90) * S / 1024)))) diff --git a/secure-messenger/app/tool/symbol/02_klein.py b/secure-messenger/app/tool/symbol/02_klein.py deleted file mode 100644 index e8e97b6..0000000 --- a/secure-messenger/app/tool/symbol/02_klein.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -"""Kleinfassung fuer 16 bis 32 Pixel. - -BEI 24 PIXELN VERSCHMELZEN DIE PUNKTE. Gemessen an der Groessenprobe: ab 48 ist -das Doto-B lesbar, darunter wird es ein Fleck, und der 48er Umriss wird bei -16 Pixeln 0,75 Pixel dick — also grau statt weiss. - -Darum fuer die kleinen Groessen: dieselbe Silhouette (Blase mit Zipfel als -Umriss, damit das Symbol nicht die Form wechselt), aber kraeftiger Strich und -ein VOLLES B aus Chivo Mono statt der Punktmatrix. So bleibt bei 16 Pixeln ein -erkennbarer Buchstabe stehen. - -Die .ico traegt beides: klein diese Fassung, gross die mit den Punkten. -""" -import pathlib -from PIL import Image, ImageChops, ImageDraw, ImageFont - -APP = pathlib.Path(r'C:\KI-Workstation\BitDM\secure-messenger\app') -S, U = 256, 8 -N = S * U -SCHWARZ = (11, 12, 18, 255) -WEISS = (243, 243, 246, 255) - -# Entwurf im 256er Raster, damit die Zahlen zur Zielgroesse passen. -BX0, BY0, BX1, BY1, RAD = 30, 40, 226, 172, 30 -STRICH = 20 # deutlich dicker als 48/1024 -ZIPFEL = [(64, 150), (110, 150), (64, 214)] -CX, CY = (BX0 + BX1) / 2, (BY0 + BY1) / 2 - - -def k(v): - return round(v * U) - - -def sil(ein): - m = Image.new('L', (N, N), 0) - d = ImageDraw.Draw(m) - d.rounded_rectangle((k(BX0 + ein), k(BY0 + ein), k(BX1 - ein), k(BY1 - ein)), - radius=k(max(RAD - ein, 2)), fill=255) - if ein: - sx = (BX1 - BX0 - 2 * ein) / (BX1 - BX0) - sy = (BY1 - BY0 - 2 * ein) / (BY1 - BY0) - z = [(CX + (x - CX) * sx, CY + (y - CY) * sy) for x, y in ZIPFEL] - else: - z = ZIPFEL - d.polygon([(k(x), k(y)) for x, y in z], fill=255) - return m - - -b = Image.new('RGBA', (N, N), (0, 0, 0, 0)) -ImageDraw.Draw(b).rounded_rectangle((0, 0, N - 1, N - 1), - radius=k(69.5), fill=SCHWARZ) -b.paste(Image.new('RGBA', (N, N), WEISS), (0, 0), - ImageChops.subtract(sil(0), sil(STRICH))) - -# Volles B, wieder nach der Tinte gesetzt statt nach den Schriftmassen. -e = Image.new('RGBA', (N, N), (0, 0, 0, 0)) -ImageDraw.Draw(e).text((k(60), k(50)), 'B', - font=ImageFont.truetype( - str(APP / 'assets/fonts/ChivoMono.ttf'), k(96)), - fill=WEISS) -t = e.crop(e.getbbox()) -b.paste(t, (round(CX * U - t.width / 2), round(CY * U - t.height / 2)), t) - -b = b.resize((S, S), Image.LANCZOS) -b.save(APP / 'icon_bitdm_klein.png') -print(f'Kleinfassung {b.size}, B-Tinte {t.width // U}x{t.height // U} px im ' - f'256er Raster') diff --git a/secure-messenger/app/tool/symbol/03_verteilen.py b/secure-messenger/app/tool/symbol/03_verteilen.py deleted file mode 100644 index 23083bd..0000000 --- a/secure-messenger/app/tool/symbol/03_verteilen.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -"""Aus icon_bitdm_1024.png alle Ziele schreiben.""" -import pathlib -from PIL import Image - -APP = pathlib.Path(r'C:\KI-Workstation\BitDM\secure-messenger\app') -q = Image.open(APP / 'icon_bitdm_1024.png').convert('RGBA') - - -def s(n): - return q.resize((n, n), Image.LANCZOS) - - -res = APP / 'android/app/src/main/res' -for ordner, n in [('mdpi', 48), ('hdpi', 72), ('xhdpi', 96), - ('xxhdpi', 144), ('xxxhdpi', 192)]: - s(n).save(res / f'mipmap-{ordner}' / 'ic_launcher.png') -print('android : 48 72 96 144 192') - -ico = APP / 'windows/runner/resources/app_icon.ico' -s(256).save(ico, sizes=[(16, 16), (24, 24), (32, 32), (48, 48), - (64, 64), (128, 128), (256, 256)]) -print('windows : .ico mit 7 Groessen') - -web = APP / 'web' -s(32).save(web / 'favicon.png') -s(192).save(web / 'icons/Icon-192.png') -s(512).save(web / 'icons/Icon-512.png') - -# Maskierbar: Chrome legt eine eigene Form darueber und schneidet bis zu 20 % -# weg. Vollflaechig dunkel hinterlegt und das Motiv eingeruecht, sonst faellt -# die Rundung dem fremden Zuschnitt zum Opfer. -for n in (192, 512): - g = Image.new('RGBA', (n, n), (11, 12, 18, 255)) - innen = int(n * 0.74) - k = s(innen) - g.paste(k, ((n - innen) // 2, (n - innen) // 2), k) - g.save(web / f'icons/Icon-maskable-{n}.png') -print('web : favicon 32, 192, 512, maskierbar 192+512') - -# Fuer die Webseite, damit der Reiter im Browser nicht leer bleibt. -s(180).save(APP.parent / 'website/bilder/icon-180.png') -print('website : bilder/icon-180.png') diff --git a/secure-messenger/app/tool/symbol/README.md b/secure-messenger/app/tool/symbol/README.md index 2a797e1..f83497f 100644 --- a/secure-messenger/app/tool/symbol/README.md +++ b/secure-messenger/app/tool/symbol/README.md @@ -1,31 +1,37 @@ -# Das App-Symbol neu bauen +# Das BitDM-Zeichen bauen -Reihenfolge, sonst fehlt die Vorlage: +Seit 24.10.2026 gilt Entwurf **F1, „Anzeigefenster“**: ein Displayfenster auf +der Gerätefront, darin eine Punktmatrix, und DM leuchtet in Violett. Henrik hat +es aus sechs Entwürfen und sechs Varianten gewählt. Es löst die Sprechblase mit +dem B ab (`65fd2dc`), die schwarz-weiß war und neben dem Favicon ein zweites +Zeichen bildete. ```bash -py tool/symbol/01_gross.py # icon_bitdm_1024.png — Blase + Doto-B -py tool/symbol/02_klein.py # icon_bitdm_klein.png — kraeftiger, volles B -py tool/symbol/03_verteilen.py # Android, Web, Webseite +py tool/symbol/verteilen.py ``` -Danach die `.ico` gemischt schreiben — klein bis 32, Punktmatrix ab 48: +schreibt alles neu, aus einer einzigen Vorlage in `f1.py`: -```python -gr = Image.open('icon_bitdm_1024.png'); kl = Image.open('icon_bitdm_klein.png') -t = [kl.resize((n, n)) for n in (16, 24, 32)] + \ - [gr.resize((n, n)) for n in (48, 64, 128, 256)] -t[-1].save('windows/runner/resources/app_icon.ico', - sizes=[x.size for x in t], append_images=t[:-1]) -``` +| Ziel | Fassung | +|---|---| +| Android `mipmap-*/ic_launcher.png` (48–192) | groß | +| Windows `app_icon.ico` | 16–32 klein, 48–256 groß | +| Web-App `web/favicon.png` (32) | klein | +| Web-App `web/icons/Icon-*.png`, maskierbar | groß | +| F-Droid `fastlane/.../images/icon.png` (512) | groß | +| Website `bilder/icon-180.png`, `bilder/bitdm-zeichen.svg` | groß | +| Website `favicon.ico` | 16/32 klein, 48 groß | +| Website `favicon.svg` | klein | -**Warum zwei Fassungen.** Gemessen an einer Groessenprobe: das Doto-B ist ab -48 Pixeln lesbar, darunter verschmelzen die Punkte, und der Umriss wird bei 16 -Pixeln 0,75 Pixel dick — also grau statt weiss. Eine `.ico` darf pro Groesse -ein eigenes Bild tragen, also traegt sie klein die kraeftige Fassung. +**Warum zwei Fassungen.** Unter 48 Pixeln werden Fensterrahmen und +unbeleuchtete Punkte zu grauem Brei, bei 16 Pixeln wäre ein Punkt 0,7 Pixel +breit. Die Kleinfassung zeigt dasselbe DM ohne Fenster und Raster, mit Punkten, +die fast aneinanderstoßen. So bleibt es bei 16 Pixeln eine lesbare Pixelschrift. +Dieselbe Grenze galt schon für das alte Zeichen; damals gemessen an einer +Größenprobe, jetzt erneut nachgesehen. -**Was NICHT nochmal probiert werden muss** (alles am 30.07.2026 gebaut und -verworfen): den gefalteten Rhombus der ersten Vorlage nachzuzeichnen — die -Facetten werden bei 48 Pixeln Brei; Kreise mit Rechteck-Schnitt fuer die Drei — -das beisst ein quadratisches Loch in die Form; `textbbox` zum Zentrieren von -Doto — die Schrift meldet ihre Glyphenmasse ungenau, das B sass 19 Pixel zu -weit links. Zentriert wird nach `getbbox()` der gezeichneten Tinte. +**Maße.** Alles steht im 108er Raster eines Android-Symbols: Kachelradius 24, +Fenster 10/22 bis 98/86 mit Radius 10, Raster 13 × 9 Punkte im Abstand 6,4. DM +sitzt eine Zelle eingerückt auf demselben Raster, die leuchtenden Punkte liegen +also genau über unbeleuchteten. Farben aus `DESIGN.md`: Grund `#0b0c12`, Linie +`#3f424d`, Akzent `#b5abfc`, aus `#1f1d31`. diff --git a/secure-messenger/app/tool/symbol/f1.py b/secure-messenger/app/tool/symbol/f1.py new file mode 100644 index 0000000..8e8de90 --- /dev/null +++ b/secure-messenger/app/tool/symbol/f1.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +"""Das BitDM-Zeichen seit 24.10.2026: Entwurf F1, "Anzeigefenster". + +Ein Displayfenster auf der Geraetefront, darin eine Punktmatrix. Die meisten +Punkte sind aus, DM leuchtet. Henrik hat es aus sechs Entwuerfen gewaehlt; es +loest die Sprechblase mit dem B ab (65fd2dc), die schwarz-weiss war, das +Violett der App nicht kannte und neben dem Favicon (fuenf Punkte) ein zweites +Zeichen war. + +ALLES STEHT IM 108er RASTER, dem Mass eines Android-Symbols. Daraus rechnen +Pixelbilder und SVG dieselbe Form, damit es nur EINE Vorlage gibt. + +ZWEI FASSUNGEN, wie schon beim alten Zeichen gemessen: unter 48 Pixeln werden +Fensterrahmen (1,5 Einheiten) und die unbeleuchteten Punkte zu grauem Brei, bei +16 Pixeln waere ein Punkt 0,7 Pixel breit. Darum bis 32 Pixel `klein`: dasselbe +DM, ohne Fenster und Raster, die Punkte so gross, dass sie fast aneinander +stossen. Das bleibt bei 16 Pixeln ein lesbares DM in Pixelschrift. +""" +from PIL import Image, ImageDraw + +GRUND = (11, 12, 18, 255) # #0b0c12, Seitenhintergrund (DESIGN.md) +LINIE = (63, 66, 77, 255) # #3f424d, Hairline/Bezelkante +AUS = (31, 29, 49, 255) # #1f1d31, unbeleuchteter Punkt +AN = (181, 171, 252, 255) # #b5abfc, Akzent: die Anzeige leuchtet + +D = ['xxxx.', 'x...x', 'x...x', 'x...x', 'x...x', 'x...x', 'xxxx.'] +M = ['x...x', 'xx.xx', 'x.x.x', 'x.x.x', 'x...x', 'x...x', 'x...x'] +DM = [d + '.' + m for d, m in zip(D, M)] # 11 Spalten, 7 Zeilen + +KACHEL_RADIUS = 24 +# gross: Fenster, 13 x 9 Raster, DM eine Zelle eingerueckt +FENSTER = (10, 22, 98, 86) +FENSTER_RADIUS, FENSTER_STRICH = 10, 1.5 +RASTER = dict(abstand=6.4, x0=15.6, y0=28.4, spalten=13, zeilen=9, r_aus=2.2, r_an=2.4) +# klein: nur DM, gross gesetzt +KLEIN = dict(abstand=8.2, x0=13.0, y0=29.4, r=3.6) + + +def _hex(farbe): + return '#%02x%02x%02x' % farbe[:3] + + +def _punkte(zeilen, abstand, x0, y0): + """Mittelpunkte der leuchtenden Punkte in Rastereinheiten.""" + for y, zeile in enumerate(zeilen): + for x, c in enumerate(zeile): + if c == 'x': + yield x0 + x * abstand, y0 + y * abstand + + +def zeichne(n, klein=False, ueberabtastung=4): + """Das Zeichen als RGBA-Bild n x n, mit durchsichtigen Ecken.""" + s = n * ueberabtastung + k = s / 108 + bild = Image.new('RGBA', (s, s), (0, 0, 0, 0)) + d = ImageDraw.Draw(bild) + d.rounded_rectangle((0, 0, s - 1, s - 1), radius=round(KACHEL_RADIUS * k), fill=GRUND) + + def kreis(cx, cy, r, farbe): + d.ellipse(((cx - r) * k, (cy - r) * k, (cx + r) * k, (cy + r) * k), fill=farbe) + + if klein: + for cx, cy in _punkte(DM, KLEIN['abstand'], KLEIN['x0'], KLEIN['y0']): + kreis(cx, cy, KLEIN['r'], AN) + else: + x0, y0, x1, y1 = FENSTER + d.rounded_rectangle((x0 * k, y0 * k, x1 * k, y1 * k), radius=round(FENSTER_RADIUS * k), + outline=LINIE, width=max(1, round(FENSTER_STRICH * k))) + a = RASTER['abstand'] + for y in range(RASTER['zeilen']): + for x in range(RASTER['spalten']): + kreis(RASTER['x0'] + x * a, RASTER['y0'] + y * a, RASTER['r_aus'], AUS) + # DM sitzt eine Zelle eingerueckt auf demselben Raster: die leuchtenden + # Punkte liegen genau ueber unbeleuchteten. + for cx, cy in _punkte(DM, a, RASTER['x0'] + a, RASTER['y0'] + a): + kreis(cx, cy, RASTER['r_an'], AN) + return bild.resize((n, n), Image.LANCZOS) + + +def svg(klein=False): + """Dasselbe Zeichen als SVG im 108er Raster.""" + teile = [f''] + if klein: + teile += [f'' + for cx, cy in _punkte(DM, KLEIN['abstand'], KLEIN['x0'], KLEIN['y0'])] + punkte = f'' + ''.join(teile[1:]) + '' + teile = teile[:1] + [punkte] + else: + x0, y0, x1, y1 = FENSTER + teile.append(f'') + a = RASTER['abstand'] + aus = ''.join(f'' + for y in range(RASTER['zeilen']) for x in range(RASTER['spalten'])) + an = ''.join(f'' + for cx, cy in _punkte(DM, a, RASTER['x0'] + a, RASTER['y0'] + a)) + teile += [f'{aus}', f'{an}'] + return ('' + + ''.join(teile) + '\n') diff --git a/secure-messenger/app/tool/symbol/verteilen.py b/secure-messenger/app/tool/symbol/verteilen.py new file mode 100644 index 0000000..6486d9e --- /dev/null +++ b/secure-messenger/app/tool/symbol/verteilen.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +"""Das Zeichen F1 an alle Stellen schreiben, an denen App und Seite es zeigen. + +Bis 32 Pixel die Kleinfassung, ab 48 das volle Anzeigefenster (siehe f1.py). +Die .ico-Dateien tragen beides: pro Groesse ein eigenes Bild. +""" +import pathlib +import sys + +from PIL import Image + +HIER = pathlib.Path(__file__).resolve().parent +sys.path.insert(0, str(HIER)) +import f1 # noqa: E402 + +APP = HIER.parent.parent +SEITE = APP.parent / 'website' + + +def gross(n): + return f1.zeichne(n) + + +def klein(n): + return f1.zeichne(n, klein=True) + + +def ico(ziel, groessen): + """Eine .ico, jede Groesse mit ihrer eigenen Fassung.""" + bilder = [klein(n) if n <= 32 else gross(n) for n in groessen] + bilder[-1].save(ziel, sizes=[(n, n) for n in groessen], append_images=bilder[:-1]) + + +res = APP / 'android/app/src/main/res' +for ordner, n in [('mdpi', 48), ('hdpi', 72), ('xhdpi', 96), + ('xxhdpi', 144), ('xxxhdpi', 192)]: + gross(n).save(res / f'mipmap-{ordner}' / 'ic_launcher.png') +print('android : 48 72 96 144 192') + +ico(APP / 'windows/runner/resources/app_icon.ico', [16, 24, 32, 48, 64, 128, 256]) +print('windows : .ico, 16-32 klein, 48-256 gross') + +web = APP / 'web' +klein(32).save(web / 'favicon.png') +gross(192).save(web / 'icons/Icon-192.png') +gross(512).save(web / 'icons/Icon-512.png') +# Maskierbar: Chrome legt eine eigene Form darueber und schneidet bis zu 20 % +# weg. Vollflaechig dunkel hinterlegt und das Motiv eingerueckt, sonst faellt +# das Fenster dem fremden Zuschnitt zum Opfer. +for n in (192, 512): + g = Image.new('RGBA', (n, n), f1.GRUND) + innen = int(n * 0.74) + z = gross(innen) + g.paste(z, ((n - innen) // 2, (n - innen) // 2), z) + g.save(web / f'icons/Icon-maskable-{n}.png') +print('web : favicon 32 klein, 192, 512, maskierbar 192+512') + +gross(512).save(APP / 'fastlane/metadata/android/en-US/images/icon.png') +print('fastlane: icon.png 512 (F-Droid-Eintrag)') + +gross(180).save(SEITE / 'bilder/icon-180.png') +ico(SEITE / 'favicon.ico', [16, 32, 48]) +# newline='\n': sonst schreibt Windows CRLF, und git meldet die Dateien bei +# jedem Lauf als geaendert. +(SEITE / 'favicon.svg').write_text(f1.svg(klein=True), encoding='utf-8', newline='\n') +(SEITE / 'bilder/bitdm-zeichen.svg').write_text(f1.svg(), encoding='utf-8', newline='\n') +print('website : bilder/icon-180.png, favicon.ico (16/32 klein, 48 gross), ' + 'favicon.svg (klein), bilder/bitdm-zeichen.svg (gross)') diff --git a/secure-messenger/app/web/favicon.png b/secure-messenger/app/web/favicon.png index a7f1d09..df65569 100644 Binary files a/secure-messenger/app/web/favicon.png and b/secure-messenger/app/web/favicon.png differ diff --git a/secure-messenger/app/web/icons/Icon-192.png b/secure-messenger/app/web/icons/Icon-192.png index f03a040..7acaf81 100644 Binary files a/secure-messenger/app/web/icons/Icon-192.png and b/secure-messenger/app/web/icons/Icon-192.png differ diff --git a/secure-messenger/app/web/icons/Icon-512.png b/secure-messenger/app/web/icons/Icon-512.png index 390a6a8..b9b3e90 100644 Binary files a/secure-messenger/app/web/icons/Icon-512.png and b/secure-messenger/app/web/icons/Icon-512.png differ diff --git a/secure-messenger/app/web/icons/Icon-maskable-192.png b/secure-messenger/app/web/icons/Icon-maskable-192.png index f25d29f..4f416e9 100644 Binary files a/secure-messenger/app/web/icons/Icon-maskable-192.png and b/secure-messenger/app/web/icons/Icon-maskable-192.png differ diff --git a/secure-messenger/app/web/icons/Icon-maskable-512.png b/secure-messenger/app/web/icons/Icon-maskable-512.png index 4048dad..7531f03 100644 Binary files a/secure-messenger/app/web/icons/Icon-maskable-512.png and b/secure-messenger/app/web/icons/Icon-maskable-512.png differ diff --git a/secure-messenger/app/windows/runner/resources/app_icon.ico b/secure-messenger/app/windows/runner/resources/app_icon.ico index 81a9be3..eb08bf8 100644 Binary files a/secure-messenger/app/windows/runner/resources/app_icon.ico and b/secure-messenger/app/windows/runner/resources/app_icon.ico differ diff --git a/secure-messenger/website/README.md b/secure-messenger/website/README.md index f1b569b..502f23e 100644 --- a/secure-messenger/website/README.md +++ b/secure-messenger/website/README.md @@ -17,6 +17,7 @@ website/ ├─ sitemap.xml alle Seiten oben + llms.txt, je mit .html ├─ 1e0f…5274.txt IndexNow-Schlüssel (öffentlich mit Absicht, siehe unten) ├─ favicon.ico Seitenzeichen 16/32/48 px, favicon.svg dasselbe als Vektor +├─ bilder/bitdm-zeichen.svg das volle Zeichen als Vektor (app/tool/symbol) ├─ bilder/ App-Icon ├─ fonts/ Doto + Chivo Mono (SIL OFL, lokal eingebettet) └─ README.md diff --git a/secure-messenger/website/bilder/bitdm-zeichen.svg b/secure-messenger/website/bilder/bitdm-zeichen.svg new file mode 100644 index 0000000..87ed93a --- /dev/null +++ b/secure-messenger/website/bilder/bitdm-zeichen.svg @@ -0,0 +1 @@ + diff --git a/secure-messenger/website/bilder/icon-180.png b/secure-messenger/website/bilder/icon-180.png index 3781979..569ed3a 100644 Binary files a/secure-messenger/website/bilder/icon-180.png and b/secure-messenger/website/bilder/icon-180.png differ diff --git a/secure-messenger/website/favicon.ico b/secure-messenger/website/favicon.ico index 12e9d09..f2c0a0f 100644 Binary files a/secure-messenger/website/favicon.ico and b/secure-messenger/website/favicon.ico differ diff --git a/secure-messenger/website/favicon.svg b/secure-messenger/website/favicon.svg index 73a09ac..66ffdc5 100644 --- a/secure-messenger/website/favicon.svg +++ b/secure-messenger/website/favicon.svg @@ -1 +1 @@ - +