Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Inline text instructions #666

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

PROP65
Copy link
Contributor

@PROP65 PROP65 commented Aug 14, 2024

An alternative method to achieve something similar to #560

The idea is to use the UTF-8 Private Use Area ( U+E000 -> U+F8FF ) to pass instructions to the text renderer in a manner similar to ANSI escape codes.

I've implemented hex RGB (\uE000), hex RGBA (\uE001) and color reset (\uE002) instructions.

Each instruction has a hardcoded value(payload) length.
RGB expects 6 ASCII bytes containing a color in hex format
while color reset expects no payload

Backends using nk_convert will only require minimal, if any, modification to take advantage of this feature while any other backends will need to implement the instructions for them to function. A function is provided to filter out the inlined instructions along with their payloads (nk_utf_filter_instructions) for use in copy/cut/paste operations. Selecting text in nk_edit_string (including NK_EDIT_BOX) has been adjusted and copying text works as intended. Cut and paste have not been tested on text containing these instructions.

nk_label(ctx,
	NK_INSTRUCT_SET_RGB  "FF0000"   "N"
	NK_INSTRUCT_SET_RGB  "00FF00"   "u"
	NK_INSTRUCT_SET_RGB  "0000FF"   "k"
	NK_INSTRUCT_SET_RGB  "00FFFF"   "l"
	NK_INSTRUCT_SET_RGB  "FF00FF"   "e"
	NK_INSTRUCT_SET_RGB  "FFFF00"   "a"
	NK_INSTRUCT_SET_RGBA "FFFFFF88" "r"
	NK_INSTRUCT_RESET_COLOR, NK_TEXT_LEFT);

looks like

glfw_opengl3

The following backends have been tested and work

  • glfw_opengl2
  • glfw_opengl3
  • glfw_vulkan
  • sdl_opengl2
  • sdl_opengl3
  • sdl_renderer
  • x11
  • x11_opengl2
  • x11_opengl3
  • x11_xft

@RobLoach
Copy link
Contributor

This is really cool, thanks for putting it together. Would you provide a small example in the overview demo for this? It would be great way to showcase it.

@PROP65
Copy link
Contributor Author

PROP65 commented Aug 17, 2024

glfw_vulkan

src/nuklear_utf8.c Outdated Show resolved Hide resolved
src/nuklear_utf8.c Outdated Show resolved Hide resolved
@awschult002
Copy link
Contributor

I decided to take a look at the last two X11 tasks for this PR and I am not sure how to go about solving it. I am learning UTF8 for the first time, and I don't have much experience with X11, but I still tried to give it my best shot.

At the moment, X11 is not rendering the UTF8 encoded string at all. Or, at least, it renders up until the first character with a special color encoding; then it chokes.

I have discovered that both of the final X11 demos do not render UTF8 at all, so I wouldn't really expect this to work even without the special color codes, yet I have not tested this. There is an Xutf8DrawText() function, but that one also chokes on our new UTF strings.

But aside from that, setting the color for X seems to be "global" kind of thing; or at least, its expecting the entire string to be one color. So the only solution that I see is to process the UTF colors glyph by glyph; then set the FG color, then call XDraw, then move our X, Y, by the glyph width amount of the particular font, then get/set the color of the next glyph.

not super efficient, but it would get us the color. In my attempts at getting that to work, I realized that I would need to turn on VERTEX_BUFFER_OUTPUT in order to get glyph width information and font->querying. But the comments say that is really for hardware rendering like OpenGL (makes sense to me); so i chose to abandon that attempt and just get something working to pass this PR.

So can we just print the string without color and anyone using the X11 basic render is just out of luck? Well, sort of. Using the new nk_filter_instructions function, I was able to get the XDraw function to print out the entire string. This was a great success. The only issue is that XDraw doesn't have the rectangle bounds of the window; so it doesn't line wrap the text at the boundary. I have no idea how to figure that out without knowing the glyph width and calculating what is needed to get to the window rect; then adding newlines or a second draw call.

hopefully someone less ignorant that myself can come to swift solution with the above information.

@RobLoach
Copy link
Contributor

Tried this out on a few other renderers too, and it wasn't quite working correctly. Will have to investigate further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants