From 89017bde2bdab9482f13733ebad705c62ef615a6 Mon Sep 17 00:00:00 2001 From: Kyle Sunden Date: Fri, 4 Sep 2026 13:51:58 -0700 Subject: [PATCH] Backport PR #32263: Doc: tell 3.11 upgraders to remove the pre-shaping workaround --- .../prev_whats_new/whats_new_3.11.0.rst | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/release/prev_whats_new/whats_new_3.11.0.rst b/doc/release/prev_whats_new/whats_new_3.11.0.rst index 95c9f8313873..0ff9fea3b998 100644 --- a/doc/release/prev_whats_new/whats_new_3.11.0.rst +++ b/doc/release/prev_whats_new/whats_new_3.11.0.rst @@ -774,6 +774,36 @@ Text support has been extended to include complex text layout. This support incl Note, all advanced features require corresponding font support, and may require additional fonts over the builtin DejaVu Sans. +.. admonition:: Remove any pre-shaping workaround + :class: important + + Because Matplotlib did not previously reorder text, the usual workaround for + Arabic, Persian, Urdu and Hebrew was to reorder the string before passing it in, + typically with ``arabic_reshaper`` and ``python-bidi``:: + + preprocessed = get_display(arabic_reshaper.reshape(text)) + ax.set_title(preprocessed) + + Matplotlib now reorders the string itself, so a string that arrives already in + visual order is reordered a second time and is drawn backwards. Nothing is + raised, and to a reader who does not read the script the result still looks + like correct text, so this is easy to ship without noticing. + + - If you can require Matplotlib 3.11, pass the logical string and delete the + pre-processing. + - If you support older versions as well, branch on the Matplotlib version and + pre-process only on the older one. + - If you cannot change the call at all, because the text is handed to a + third-party library that calls Matplotlib for you, wrap the pre-processed + string in ``LEFT-TO-RIGHT OVERRIDE`` and ``POP DIRECTIONAL FORMATTING``:: + + text = ('\N{LEFT-TO-RIGHT OVERRIDE}' + preprocessed + + '\N{POP DIRECTIONAL FORMATTING}') + + That reads correctly on every version. It does not always render + identically, because it draws the font's presentation-form glyphs rather + than the font's own shaping, and some fonts space those differently. + Specifying font feature tags ----------------------------