@@ -774,6 +774,36 @@ Text support has been extended to include complex text layout. This support incl
774774Note, all advanced features require corresponding font support, and may require
775775additional fonts over the builtin DejaVu Sans.
776776
777+ .. admonition :: Remove any pre-shaping workaround
778+ :class: important
779+
780+ Because Matplotlib did not previously reorder text, the usual workaround for
781+ Arabic, Persian, Urdu and Hebrew was to reorder the string before passing it in,
782+ typically with ``arabic_reshaper `` and ``python-bidi ``::
783+
784+ preprocessed = get_display(arabic_reshaper.reshape(text))
785+ ax.set_title(preprocessed)
786+
787+ Matplotlib now reorders the string itself, so a string that arrives already in
788+ visual order is reordered a second time and is drawn backwards. Nothing is
789+ raised, and to a reader who does not read the script the result still looks
790+ like correct text, so this is easy to ship without noticing.
791+
792+ - If you can require Matplotlib 3.11, pass the logical string and delete the
793+ pre-processing.
794+ - If you support older versions as well, branch on the Matplotlib version and
795+ pre-process only on the older one.
796+ - If you cannot change the call at all, because the text is handed to a
797+ third-party library that calls Matplotlib for you, wrap the pre-processed
798+ string in ``LEFT-TO-RIGHT OVERRIDE `` and ``POP DIRECTIONAL FORMATTING ``::
799+
800+ text = ('\N{LEFT-TO-RIGHT OVERRIDE}' + preprocessed +
801+ '\N{POP DIRECTIONAL FORMATTING}')
802+
803+ That reads correctly on every version. It does not always render
804+ identically, because it draws the font's presentation-form glyphs rather
805+ than the font's own shaping, and some fonts space those differently.
806+
777807Specifying font feature tags
778808----------------------------
779809
0 commit comments