diff --git a/kitty/config_data.py b/kitty/config_data.py index 4886ae140..868c2cb82 100644 --- a/kitty/config_data.py +++ b/kitty/config_data.py @@ -223,6 +223,19 @@ def to_font_size(x): o('font_size', 11.0, long_text=_('Font size (in pts)'), option_type=to_font_size) +o('force_ltr', False, long_text=_(""" +Kitty does not yet support BIDI (bidirectional text), however, for RTL scripts, +HarfBuzz will "helpfully" shape text as if we were laying it out RTL. That is +to say, in an RTL script, the words "HELLO WORLD" display in Kitty as "WORLD +HELLO", and if you try to select a substring of an RTL-shaped string, you will +get the character that _would_ be there were the string LTR. For example, +assuming the Hebrew word ירושלים, selecting the character that on the screen +appears to be ם actually writes into the selection buffer the character י. + +Kitty's default behavior is useful in conjunction with a filter to reverse the +word order, however, if you wish to manipulate RTL glyphs, it can be very +challenging to work with, so this option is provided to turn it off.""")) + def adjust_line_height(x): if x.endswith('%'): @@ -315,6 +328,12 @@ Disable the normal ligatures, but keep the :code:`calt` feature which (in this font) breaks up monotony:: font_features TT2020StyleB-Regular -liga +calt + +In conjunction with :opt:`force_ltr`, you may want to disable Arabic shaping +entirely, and only look at their isolated forms if they show up in a document. +You can do this with e.g.:: + + font_features UnifontMedium +isol -medi -fina -init ''')) diff --git a/kitty/fonts.c b/kitty/fonts.c index d8dee7a1c..0c6d1f43f 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -689,6 +689,7 @@ load_hb_buffer(CPUCell *first_cpu_cell, GPUCell *first_gpu_cell, index_type num_ hb_buffer_add_utf32(harfbuzz_buffer, shape_buffer, num, 0, num); } hb_buffer_guess_segment_properties(harfbuzz_buffer); + if (OPT(force_ltr)) hb_buffer_set_direction(harfbuzz_buffer, HB_DIRECTION_LTR); } diff --git a/kitty/state.c b/kitty/state.c index 380f68f92..129d0b8c2 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -527,6 +527,7 @@ PYWRAP1(set_options) { S(macos_thicken_font, PyFloat_AsFloat); S(tab_bar_min_tabs, PyLong_AsUnsignedLong); S(disable_ligatures, PyLong_AsLong); + S(force_ltr, PyObject_IsTrue); S(resize_draw_strategy, PyLong_AsLong); S(resize_in_steps, PyObject_IsTrue); S(pointer_shape_when_grabbed, pointer_shape); diff --git a/kitty/state.h b/kitty/state.h index 0ef2938d5..4b545c5fa 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -42,6 +42,7 @@ typedef struct { Edge tab_bar_edge; unsigned long tab_bar_min_tabs; DisableLigature disable_ligatures; + bool force_ltr; ResizeDrawStrategy resize_draw_strategy; bool resize_in_steps; bool sync_to_monitor;