From e8769538c5be4b68c2158efadd9274e70969d138 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 10 Oct 2026 10:38:34 +0200 Subject: [PATCH] =?UTF-8?q?Unit=C3=A9=20en=20mm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wavy_ribbon_fill.py | 53 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/wavy_ribbon_fill.py b/wavy_ribbon_fill.py index fa492fe..3013cfc 100644 --- a/wavy_ribbon_fill.py +++ b/wavy_ribbon_fill.py @@ -16,6 +16,7 @@ import sys import inkex from inkex import bezier from inkex.localization import localize +from inkex.units import convert_unit # L'extension vit dans son propre sous-dossier des extensions Inkscape, qui # n'est pas forcement dans sys.path : on l'y ajoute pour trouver wavy_ribbon_fill_core. @@ -24,11 +25,59 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from wavy_ribbon_fill_core import ( # noqa: E402 fill_polylines, parse_color, polylines_to_d, rings_bounds) + +def use_system_language(): + """Renseigne LANGUAGE avec la langue du systeme si rien ne la fixe. + + Sous Windows, Inkscape regle sur « langue du systeme » ne transmet aucune + variable de langue au script : gettext retomberait sur l'anglais alors que + la boite de dialogue, traduite par Inkscape lui-meme, est dans la langue + de l'utilisateur. + """ + if any(os.environ.get(name) for name in ("LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG")): + return + try: + import ctypes + import locale + language = locale.windows_locale.get( + ctypes.windll.kernel32.GetUserDefaultUILanguage()) + except Exception: # pylint: disable=broad-except + return # hors Windows : LANG est toujours defini + if language: + os.environ["LANGUAGE"] = language + + # Installe _() dans les builtins : catalogue « wavyribbonfill » de la langue # de l'interface (Inkscape transmet domaine et dossier par l'environnement), # textes anglais d'origine sinon. +use_system_language() localize() + +def uu_per_mm(svg): + """Unites utilisateur par millimetre, comme Inkscape les affiche. + + svg.unittouu() devine l'unite du document par arrondi a l'unite connue la + plus proche : il se trompe des que l'echelle n'est pas standard (page + redimensionnee). On prend le rapport reel page / viewBox ; Inkscape + applique une echelle uniforme (preserveAspectRatio « meet »), soit la + plus petite des deux. + """ + try: + vb_w, vb_h = svg.viewbox_width, svg.viewbox_height + page_w = svg.to_dimensional(svg.viewport_width, "mm") + page_h = svg.to_dimensional(svg.viewport_height, "mm") + except AttributeError: # inkex anterieur a 1.2 + return svg.unittouu("1mm") + if not (vb_w and vb_h and page_w and page_h): + return svg.unittouu("1mm") + return 1 / min(page_w / vb_w, page_h / vb_h) + + +def length_to_uu(svg, value, unit="mm"): + """Longueur reelle (valeur + unite) -> unites utilisateur du document.""" + return convert_unit("{}{}".format(value, unit), "mm") * uu_per_mm(svg) + # Au-dela, le calcul et le SVG produit deviennent trop lourds pour Inkscape. MAX_LINES = 3000 @@ -62,7 +111,7 @@ class WavyRibbonFill(inkex.EffectExtension): inkex.errormsg(_("Select at least one shape.")) return - spacing = self.svg.unittouu("{}{}".format(opt.spacing, opt.unit)) + spacing = length_to_uu(self.svg, opt.spacing, opt.unit) if spacing <= 0: inkex.errormsg(_("The line spacing must be strictly positive.")) return @@ -72,7 +121,7 @@ class WavyRibbonFill(inkex.EffectExtension): "fill": "none", "stroke": color, "stroke-opacity": str(opacity), - "stroke-width": str(self.svg.unittouu("{}{}".format(opt.stroke_width, opt.unit))), + "stroke-width": str(length_to_uu(self.svg, opt.stroke_width, opt.unit)), "stroke-linecap": "round", "stroke-linejoin": "round", })