diff --git a/rhino/elemente.py b/rhino/elemente.py index 63c2918..c57cb7d 100644 --- a/rhino/elemente.py +++ b/rhino/elemente.py @@ -440,37 +440,50 @@ def _list_hatch_patterns(doc): return out +_RAUM_FONTS_CACHE = None # einmal pro Session, danach gecacht (System-Fonts aendern sich nicht) + + def _list_system_fonts(): """Sammelt installierte Font-Quartet-Namen via Rhino.DocObjects.Font. - Liefert sortierte Liste mit den haeufig benutzten DOSSIER-Fonts oben.""" - out = [] + Probiert mehrere API-Varianten (Rhino-Versionen unterscheiden sich) + und fuegt die DOSSIER-Default-Fonts oben an. Gecacht.""" + global _RAUM_FONTS_CACHE + if _RAUM_FONTS_CACHE is not None: + return _RAUM_FONTS_CACHE preferred = ["DM Mono", "Krungthep", "Archivo Black", "Playfair Display", "Helvetica", "Helvetica Neue", "Arial", "SF Pro Display", "Times New Roman", "Courier New"] + raw = [] try: from Rhino.DocObjects import Font as _Font - installed = _Font.InstalledFontsAsString() - # InstalledFontsAsString liefert ; oder \n separated — beide handeln - raw = [] - if installed: - for sep in (";", "\n", "\r"): - if sep in installed: - raw = [s.strip() for s in installed.split(sep) if s.strip()] - break - if not raw: raw = [installed.strip()] - seen = set() - # Erst Preferred wenn installiert - for f in preferred: - if f in raw and f not in seen: - out.append(f); seen.add(f) - # Dann der Rest alphabetisch - for f in sorted(raw): - if f and f not in seen: - out.append(f); seen.add(f) - except Exception as ex: - print("[ELEMENTE] list_system_fonts:", ex) - # Fallback: nur die DOSSIER-Defaults - out = preferred[:] + # Variante A: InstalledFonts() liefert IEnumerable[Font] + try: + for f in _Font.InstalledFonts(): + try: + n = f.QuartetName + if n: raw.append(n) + except Exception: pass + except Exception: pass + # Variante B: AvailableFontFaces (Rhino 7+) + if not raw: + try: + for f in _Font.AvailableFontFaces: + try: + n = getattr(f, "QuartetName", None) or getattr(f, "FamilyPlusFaceName", None) + if n: raw.append(str(n)) + except Exception: pass + except Exception: pass + except Exception: pass + # Dedupe + sortieren, Preferred zuerst + out = [] + seen = set() + for f in preferred: + if f and f not in seen: + out.append(f); seen.add(f) + for f in sorted(set(raw)): + if f and f not in seen: + out.append(f); seen.add(f) + _RAUM_FONTS_CACHE = out return out _TREPPE_SOLL_DEFAULT = { @@ -10077,6 +10090,27 @@ class ElementeBridge(panel_base.BaseBridge): if not isinstance(r_layout, list): r_layout = [] r_modus = p.get("txtModus", old_meta.get("raum_txt_modus", "fix")) if r_modus not in ("fix", "masstab"): r_modus = "fix" + # Modus-Wechsel: txt_h automatisch in die neue Einheit + # umrechnen, damit die Stempelgroesse visuell stabil bleibt. + # User hat 0.20m in fix → toggelt auf masstab → ohne Umrechnung + # wuerde das als 0.20mm@1:100 interpretiert = 0.02m Text. Mit + # Umrechnung: 0.20m @ 1:100 = 2mm Paper. + old_modus = old_meta.get("raum_txt_modus", "fix") + if r_modus != old_modus and "txtH" not in p: + try: + import massstab as _ms + scale = (_ms.get_applied_scale_ratio() + or _ms.get_current_scale_ratio() or 100.0) + except Exception: scale = 100.0 + if r_modus == "masstab" and old_modus == "fix": + # m → paper-mm: paper_mm = m * 1000 / scale + r_th = float(r_th) * 1000.0 / float(scale) + elif r_modus == "fix" and old_modus == "masstab": + # paper-mm → m: m = paper_mm * scale / 1000 + r_th = float(r_th) * float(scale) / 1000.0 + print("[ELEMENTE] Raum-Modus {} → {} @ 1:{:.0f}: " + "txt_h umgerechnet auf {:.4f}".format( + old_modus, r_modus, scale, r_th)) gstart = p.get("geschoss", old_meta["geschoss"]) attrs = axis_obj.Attributes if gstart != old_meta["geschoss"]: