Text-Bold/Italic-Toggle: face-Suffix-Stripping + FromQuartet zuerst

User: Bold/Kursiv liessen sich nicht zurueck auf normal stellen.

Diagnose: te.Font.QuartetName kann je nach RhinoCommon-Version den Bold/
Italic-Suffix im Namen mitfuehren (z.B. "Helvetica-Bold"). Dann liest
read_selection_settings face="Helvetica-Bold" → wird in updateTs ans
Backend zurueckgeschickt → _apply_font ruft FindOrCreate("Helvetica-Bold",
False, False) → das matcht intern wieder die Bold-Variante = bleibt fett.

Fix in _apply_font:
- Suffix-Stripping: -Bold, -Italic, -Oblique, -BoldItalic etc. werden vom
  face-String entfernt damit nur die Base-Family ("Helvetica") bleibt
- FromQuartetProperties zuerst (konstruiert Font direkt, unabhaengig vom
  FontTable-Cache). FindOrCreate als Fallback.
- Diagnostic print: "[TEXT] _apply_font face=... bold=... italic=..."
  damit sich nachvollziehen laesst was tatsaechlich angewendet wird

Plus textSettings/textStyles im State-Sig hinzugefuegt damit Idle-Pushes
Aenderungen nicht dedupelt verschlucken.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 00:51:13 +02:00
parent 38041ab6a0
commit 9f257b83e6
2 changed files with 36 additions and 16 deletions
+5 -1
View File
@@ -1264,8 +1264,12 @@ class OberleisteBridge(panel_base.BaseBridge):
_names_tuple, _active_comb, _names_tuple, _active_comb,
info.get("masseActiveId"), info.get("masseActiveId"),
tuple((p.get("id"), p.get("name")) for p in (info.get("massePresets") or [])), tuple((p.get("id"), p.get("name")) for p in (info.get("massePresets") or [])),
# textSelectionSettings: dict → tuple fuer sig-Vergleich # textSettings + textSelectionSettings + textStyleActive im sig
# damit Aenderungen ueber Idle-Pushes nicht dedupelt werden
tuple(sorted((info.get("textSettings") or {}).items())) if info.get("textSettings") else None,
tuple(sorted((info.get("textSelectionSettings") or {}).items())) if info.get("textSelectionSettings") else None, tuple(sorted((info.get("textSelectionSettings") or {}).items())) if info.get("textSelectionSettings") else None,
info.get("textStyleActiveId"),
len(info.get("textStyles") or []),
info.get("lastSetView"), info.get("lastSetView"),
prompt, prompt,
) )
+31 -15
View File
@@ -198,28 +198,44 @@ def _prompt_for_text(default=""):
def _apply_font(te, face, bold, italic): def _apply_font(te, face, bold, italic):
"""Setzt Font auf TextEntity. Mehrere Fallback-Pfade fuer """Setzt Font auf TextEntity. FromQuartetProperties zuerst (sauberer —
verschiedene RhinoCommon-Versionen.""" konstruiert Font-Objekt direkt mit (face, bold, italic), unabhaengig
doc = Rhino.RhinoDoc.ActiveDoc von einem evtl. schon im FontTable existierenden Eintrag mit gleichem
# Pfad 1: FindOrCreate im FontTable + zuweisen Namen aber anderen Flags). Fallback FindOrCreate.
`face` wird normalisiert (Bold/Italic-Suffixe entfernen) damit
QuartetNames wie "Helvetica-Bold" nicht den Quartet-Lookup blockieren."""
face = str(face or "Helvetica").strip()
bold = bool(bold)
italic = bool(italic)
# Suffix-Stripping (haeufige Endungen die manche Fonts in der QuartetName
# haben — wir wollen die Base-Family)
for suffix in ("-BoldItalic", "-BoldOblique", "-Bold", "-Italic",
"-Oblique", " Bold Italic", " Bold Oblique",
" Bold", " Italic", " Oblique"):
if face.endswith(suffix):
face = face[:-len(suffix)].strip()
break
print("[TEXT] _apply_font face={!r} bold={} italic={}".format(face, bold, italic))
# Pfad 1: FromQuartetProperties (direkter, keine FontTable-Cache-Bugs)
try: try:
font_idx = doc.Fonts.FindOrCreate(face, bool(bold), bool(italic)) font = Rhino.DocObjects.Font.FromQuartetProperties(face, bold, italic)
if font is not None:
te.Font = font
return True
except Exception as ex:
print("[TEXT] FromQuartet:", ex)
# Pfad 2: doc.Fonts.FindOrCreate
try:
doc = Rhino.RhinoDoc.ActiveDoc
font_idx = doc.Fonts.FindOrCreate(face, bold, italic)
if font_idx >= 0: if font_idx >= 0:
font = doc.Fonts[font_idx] font = doc.Fonts[font_idx]
if font is not None: if font is not None:
te.Font = font te.Font = font
return True return True
except Exception as ex: except Exception as ex:
print("[TEXT] font path 1:", ex) print("[TEXT] FindOrCreate:", ex)
# Pfad 2: statische FromQuartetProperties
try:
font = Rhino.DocObjects.Font.FromQuartetProperties(
face, bool(bold), bool(italic))
if font is not None:
te.Font = font
return True
except Exception as ex:
print("[TEXT] font path 2:", ex)
return False return False