imgui icon indicating copy to clipboard operation
imgui copied to clipboard

Add better support for CJK wrapping.

Open cyx2015s opened this issue 5 months ago • 6 comments

Added better wrapping for mixed language text.

  1. Chinese characters can break at anywhere.
  2. Head prohibited punctuations will overflow and will not appear at the start of the line.
  3. Tail prohibited punctuations will not appear at the end of the line.

Notice how "PR 的同时" in the second paragragh break in the two videos.

Demo text used: The Chinese translation of CONTRIBUTING.md in this repo and 离骚

https://github.com/user-attachments/assets/8fff4326-8ff6-49df-9aeb-3e38ebcd53bb

https://github.com/user-attachments/assets/e4d5e93b-a80f-444b-9044-d1f8b44e7e9a

TODO:

  1. Better way to detect CJK characters. Currently I use 0x3003 <= c && c <= 0xFFFF.
  2. I don't speak Japanese or Korean so I don't know other punctuations. Add more punctuation supports.

Needs feedback in real use cases, currently only tested with a few examples.

cyx2015s avatar Jul 27 '25 02:07 cyx2015s

In the VSCode codebase, this list is more complete.

wordWrapBreakAfterCharacters: register(new EditorStringOption(
EditorOption.wordWrapBreakAfterCharacters, 'wordWrapBreakAfterCharacters',
// allow-any-unicode-next-line
' \t})]?|/&.,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」',
)),
wordWrapBreakBeforeCharacters: register(new EditorStringOption(
EditorOption.wordWrapBreakBeforeCharacters, 'wordWrapBreakBeforeCharacters',
// allow-any-unicode-next-line
'([{‘“〈《「『【〔([{「£¥$£¥++'
)),

heroboy avatar Jul 28 '25 01:07 heroboy

Thank you, that list is longer than that I expected, and some characters are to wide to use the overflow strategy. I need to come up with a more robust method rather than editing on current one. Stay tuned.

cyx2015s avatar Jul 28 '25 14:07 cyx2015s

Demo: Added a text input to word wrapping section to test word wrapping without recompiling the code

Current code lacks optimization and seems to report false real line widths (See Demo -> Text -> Word Wrapping, the boundary takes space into consideration)

and buggy...

cyx2015s avatar Jul 30 '25 12:07 cyx2015s

I found why my behavior is different, my algorithm wraps at the space before words, the old algorithm wraps at the end of words. The rendering result is same.

Wrap candidates before:

This| is| a| sentence.|

Wrap candidates after:

This |is |a |sentence.|

cyx2015s avatar Jul 30 '25 13:07 cyx2015s

Also fixed issue #8503 and #8139, implemented pull #8439

cyx2015s avatar Jul 30 '25 15:07 cyx2015s

Hi,

I tested your PR in my project and it works well — nice job!
I also reviewed the code and have a couple of findings:

  1. Emojis could be included in the ImCharIsLineBreakableW range.
  2. There are a few obvious performance issues. I’ve described them here: https://github.com/ocornut/imgui/issues/9066#issuecomment-3551228467

xuboying avatar Nov 19 '25 07:11 xuboying