Use a rope type that's entirely (modified) UTF-8 throughout, but with the wrinkle that every character in a node must take the same number of bytes per character. (Use overlong encodings internally where appropriate, namely where you have (for example) 1 one-byte character in the middle of a long run of two-byte characters.)
You can even combine that approach with this.