-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
RichTextLabel Refactoring #39248
RichTextLabel Refactoring #39248
Conversation
Might be irrelevant, depending on the amount of changes to the rlt/bbcode text processing you are willing to do, but since we still want to eventually implement BiDi/shaping support, it's probably worth considering some of its specifics during the refactoring, to avoid rewriting it again in the future.
If I recollect correctly, |
@bruvzg here some questions I have in order to get what you want to tell me.
How to define a paragraphs then? When we stumble up on an empty line (like in Markdown)? What is meant with reordering?
Currently this is done in the processing of ItemText. Problem is, that the drawing occurs, when we draw, directly after the processing. If I understood you correctly, the preprocessing should be split apart from the actual drawing. If that is the case, that is one goal I want to achieve, because only then I can get rid of the three function operating modes.
That has to be implemented once the shaping support is implemented, right? I could implement a method get_valid_line_breaks(), which can be later replaced.
What do you mean by reordering? |
Probably start new paragraph at each explicitly set newline ("\n" or bbcode tag that forces newline).
e.g. if you have input string "ĀBČdess" where capital letters represent L-t-R language and small letters R-t-L one. It should be displayed as There will be some function (exact API is not determined) that will take the "ĀBČdess" string + fonts to use with it and return array of graphemes, each containing set of glyphs (images in the font + their relative offset) and a range in string it corresponds to:
Yep. I guess, at this point preprocessing should do something like:
And separate drawing / hit testing that use preprocessed cache.
Nothing of this is implemented yet, but probably it'll be some function taking string, and returning Vector of each position it's safe to break (position of each space for example, but not limited to it). I'm not sure how much of this is possible to take into account without actually having BiDI/shaping implementation. |
@HaSa1002 Yes yes yes, this is absolutely a good first step and I'd be willing to help in any way I can. Breaking that Let's also keep in mind some potential improvements that can be made for Lastly, any way we can streamline the internal text tree? One feature I was attempting to address was the ability dynamically change text within the tree so that you could hotswap specific sections of the rich text with new bbcode text. Also, I have a utility method inside RichTextLabel for custom properties parsing that could streamline the parsing for every bbcode type. Currently, it's only used RichTextEffects. |
AFAIK the FontDrawer is seperate from the RTL. I'd like to stick only to the RTL in this pr.
You mean without reparsing all invalidated lines? I haven't decided yet, what I do with the Items, since I'd like to use the text String as input and parse it then, but my first priority is to finalize the clean cutting of the functions and then see, how to improve it. I didn't really think about what I want to improve in detail, since I still learn, what the detailed use cases and intentions of _process_line is. (The saying, "I read the letters, but don't understand the words" fits very well, here)
Show it, please. Answering your question on the tracker here, (I don't want to pollute it with discussions really):
I would wait with it, until the new structure is finalized, and work on top of it. We might integrate some bugfixes into the refractoring, depending on how the final design will be. The point I see in favor of adding bugfixes in this state is, that sometimes those will lead to a different and perhaps better design. I'd like to get opinions on that one though, especially from Coredevs 😄. |
@HaSa1002 The method is
There are some flaws with the current implementation (specifically, there's no alternative parsing for builds lacking the regex module and it would be nice to support spaces within strings) that need to be addressed. The benefit of doing it this way though is that we can support more, optional parameters and less manual labor needs to happen inside the
One last request, would it be possible to add a signal to the rich text label that emits when the 'visibleCharacters' parameter is set just beyond a bbcode? My thought is that it would be cool to allow for an extension of the RTL that can support some bbcode text like this:
I'm not entirely sure the best way to support this, but my basic idea was that when the visibleCharacter value changes, we can inquire what bbcode text exists between the last visible character and the newly visible character, use the
And simply bind that method to a signal. It could also, alternatively, be a virtual function of some sort for scripts to implement themselves. Just a thought at least...
I don't think I'm considered core, but as someone who has contributed quite a bit to this specific code, I personally think a full refactor should happen first. Most of the existing problems probably stem from the complexity of the If you have any questions on the code, or RichTextEffect related implementations, don't be afraid to @ me though. I wish I could help out more, but the PR workflow doesn't always align itself super well with multiple hands-on-deck. |
I split the three states of _process_line into three functions, but I still have the p_mode ifs in the methods I abstracted away. I am not so sure, how to continue. I'd like to get rid of the ProcessModes completly but I am not sure if that is an intelligent move. Any suggestions? |
319f0eb
to
e8f262f
Compare
This simplyfies the text setting and resolves some bugs
With this commit the engine is compiling, but the class itself doesn't draw. There are changes which need to be made undone, but the priority in this commit was compilability. The inlined defines were refractored into their own functions.
Add _common_initalize_process.
Should compile again. Some bugs are existent and some more refractoring needs to be done.
b7f0784
to
3a23f7f
Compare
If getting rid of them means making the code simpler without losing performance or introducing regressions, it's fine to do it. |
I think that depends on some benchmarking. One thing I don't know is how that affects performance, so I think test that first and let us know the results. |
As I have to do some work unrelated to code, it is very likely that I won't work on this PR until mid July. If somebody wants to continue the refactoring, I might be able to share some knowledge I gained from the already done parts. The current "refactoring" ( The second approach ( Lastly, as there is the is the work package of the right to left and font shaping support, which would require a refactoring ether way, I don't know whether or not it is worth trying to refactor the rtl before that. I tested with some dummy methods which would later be replaced with the shaping engine, but it is hard to guess if your dummy method really fullfills its job and if the shaping engine would work with actually contributing usable data. I have no idea how font shaping works so it is always guessing which hinders progress. That beeing said I really want to emphasize that I still want a refactoring of the rtl and will continue once I found time for it again. Sadly, currently that's not the case. I will leave this as a learning oppurtunity for now, as the first approach actually enhances readability. |
Just wanted to say 1) thanks for working on this, and 2) I think my preferred approach for this class would be for a generic low-level tag tree to be supported in a singular Text node, and then it could optionally have a resource assigned to a property where the resource specifies the configuration and algorithm for parsing the text to generate the tag tree. So, a Text node could have a RichTextParser resource assigned to it or perhaps a MarkdownTextParser resource, etc. And if users wanted to create a script that implements the same interface (perhaps as a TextParser script), then they could do that as well to add their own preferred language support. A Text node that has no parser assigned to it would then behave like the current Label does. Then, all rendering code could function off of the tag tree to implement alignment, text wrapping, tables, alignments within table cells, etc. It sounds to me like your |
superseded by #42595. Might look into extensibility again in the future |
Important: See #39248 (comment) on current status
As we talked about it on IRC I started refractoring the RichTextLabel (RTL). I am nowhere finished, I just wanted to show that I am working on a refractoring, to prevent possible dublication of work.
The current goal of this refractor is to split the process_line method into different methods, as it is responsible for too many things at the same time (it operates in at least three states). I believe a good portion of the RTL bugs have their root in this function and only a few people are willing to deal with this beast.
We could additionally see, if we want to implement godotengine/godot-proposals#826. If we want to go into that direction, we could add support for markdown as well. This is especially interesting for this refractoring as I would change the the input to be the raw text and move all the implementation logic into the bbcode, which is currently stacked into RTL.
Update 2020-06-06
I fixed all compilation issues and removed _process_line from the RTL.cpp. I reimplemented it in the dirtiest possible way (Constructing the BbCodeProcessor inline and calling the correct process function). I removed the ProcessMode from the visible API and hide it inside the BbCodeProcessor. I'd like to get rid of it in the the functions called from within the process methods too, but have no clue if that is the best way, since the current change already added some code duplication. I rebased and reapplied the changes of #39113 into the new _parse_img function.
Update 2020-06-03
Abstracted big chunks in the _process_line function into functions. (parse_image, parse_text, parse_detect_click, and parse_table). Note to self: copy #39113 into new bbcode when rebasing
Original
As for now I managed to transfer the process_line method into a new class and replaced the inlined defines with proper functions. I copied every dependency from RTL into the new Class, to get as fast as possible to a compiling build.
I will merge the commits together, once it is ready.
If merged it supersedes #39148