When I use StartStyling() or SetStyling() functions, the result is wrong for characters other than basic Latin (a. k. a. ASCII). In the following output, produced by the example code below, the first line is OK (each word has a separate style); in the second line I replaced the second word by a random Cyrillic word, and the styles got messed up:

By the look of it, SetStlying()'s length parameter behaves as if it is the number of bytes, not characters, of a UTF-8 string: for Latin characters those are equal, for others are not. If I use the number of bytes instead of the number of characters, it starts working (see the third line of the output above), but that doesn’t feel like a proper solution. Is there a better way to handle that, by somehow telling the control to treat UTF-8 as UTF-8 everywhere, or something? (StartStyling() is not present in the example but behaves the same.)
import wx
import wx.stc as stc
class MainWindow(wx.Frame):
def __init__(self, parent, id_, title, size):
wx.Frame.__init__(self, parent, id_, title, size=size)
self.content = stc.StyledTextCtrl(self)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.content, 1, wx.EXPAND)
self.SetSizer(self.sizer)
self.content.StyleSetSpec(stc.STC_STYLE_DEFAULT, f"size:14,fore:#0000FF")
self.content.StyleClearAll()
self.content.StyleSetSpec(1, f"size:14,bold,fore:#777777")
self.content.StyleSetSpec(2, f"size:11,italic,fore:#478F0B")
self.content.StyleSetSpec(3, f"size:14,bold,fore:#AA0000")
self.content.StyleSetSpec(4, f"size:14,italic,bold,fore:#0088FF")
self.content.StyleSetSpec(5, f"size:14,italic,bold,fore:#000000")
text1 = "Lorem ipsum dolor sit amet consectetur adipiscing elit"
text2 = "Lorem земля dolor sit amet consectetur adipiscing elit"
# depending on the line used, the text is styled correctly or not
text = text2
self.content.SetText(text)
self.content.StartStyling(0)
for i, word in enumerate(text.split()):
# number of characters + trailing space
length = len(word) + 1
# the workaround:
# number of bytes + trailing space
#length = len(word.encode()) + 1
self.content.SetStyling(length, i % 6)
if __name__ == '__main__':
app = wx.App(0)
frame = MainWindow(None, -1, "Example", size=wx.Size(900, 500))
frame.Show(1)
app.MainLoop()