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
Fl_Text_Editor + pango + word wrap -> hangs on scroll #93
Comments
Thanks for the report. I'll look into it... My guess is that FLTK built with pango is much slower when it comes to calculating all the widths it needs to find the word wrapping positions. This is a well-known issue. However, I also guess that FLTK might calculate too much text (maybe the entire file?) and not only the parts needed for the current display. This is where I'd like to look into further. However, don't expect quick results since |
If you are willing to test further, can you please answer these questions?
|
diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
index ee36e1cf6..ace58845e 100644
--- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
@@ -1352,11 +1352,20 @@ void Fl_Xlib_Graphics_Driver::do_draw(int from_right, const char *str, int n, in
double Fl_Xlib_Graphics_Driver::width_unscaled(const char* str, int n) {
if (!n) return 0;
if (!fl_display || size_ == 0) return -1;
+ //fprintf(stderr, "[%d] %.*s\n", n, n, str);
+ //return 8 * n;
+ static int n1[256] = {0};
+ if (n == 1 && n1[str[0]] != 0) {
+ return (double)n1[str[0]];
+ }
if (!playout_) context();
int width, height;
pango_layout_set_font_description(playout_, pfd_array[font_]);
pango_layout_set_text(playout_, str, n);
pango_layout_get_pixel_size(playout_, &width, &height);
+ if (n == 1) {
+ n1[str[0]] = width;
+ }
return (double)width;
}
With that commented out printf you can see that it's doing a lot of work. I have no idea if I was looking at right place even if I got some results. Maybe solution is not to call that function so many times? |
The Fl_Text_Display widget computes the width of each character in the buffer as drawn Under Xft, these widths are obtained by function XftTextExtents32() which presumably, For a 4500-line C++ text file, I got these durations of the Fl_Text_Display::recalc_display()
Not with small files
Yes
No |
Many thanks to both of you for testing and analysis. @ManoloFLTK, do you have any ideas on how to improve this?
So, whatever OTOH, do you think we could optimize the usage of |
It might be possible to memorize character widths after each has been computed. |
I can try to look into the "calculate less widths" issue, i.e. limit recalculation to the part that is currently displayed. If this works out we'd not need to worry about pango usage and memorizing character widths, which seems not well suited anyway since pango would layout text properly - i.e. the width of a word is not equal to the sum of the individual character widths. Hence memorizing and adding character widths would not be correct. |
I attach a first approach to memorize some character widths when computed under pango. |
@ManoloFLTK Thanks for the patch. I tried it and it works ... somehow. When I looked at the patch I wondered how it could work since it would only cache single character widths and I assumed that the majority of width calculations would be entire words or full lines. Hence I added some more code for statistics output (see attached patch statistics.diff.txt which is an add-on on your patch (apply after yours) and the output in statistics.txt). Some words to the output: both tests were done by starting the editor with the same file, then I scrolled slowly all the way down, then up again, and then a little bit down again until I saw the output given in statistics.txt. Shown Variables:
As we can see in this test all tested characters were strict ASCII (0-127) which is encoded by 1 byte in UTF-8. [Edit: this is only correct for the first test.]
Note that I tried a text file (arbitrary text from a man page). A source file would show a different character pattern in the width[] hit array. My conclusion is that the culprit seems to be in The single character (or whatever) width caching can't work well in general, particularly if we think of international (e.g. Chinese) characters. But anyway many thanks for the patch, it gave some interesting insights. I'm open for other ideas but my gut feeling is that the culprit is really in |
Thanks for these complementary data. |
@albrecht: do you intend to modify Fl_Text_Display to reduce the number of one-char width computations it makes? Here are a few other ways to fix this issue, possibly temporarily, I see :
One of these 3 options could be implemented soon not to delay the release of FLTK 1.4, Opinions? |
@ManoloFLTK Thanks for your suggestions. I'd like to take a look at Fl_Text_Display to reduce the number of one-char width computations but this may take a while. For a temporary solution as suggested by you my thoughts are:
Before we decide (IMHO between 2 and 3) I'd like to take a look at the code to see if I can find a better solution quickly. If that doesn't work out we can still decide to use (1) or (2) as a quick solution. I'll post my findings here ASAP. |
Please, consider in https://github.com/ManoloFLTK/fltk.git, branch fast-pango Furthermore, this code modifies computations of string widths only within the Fl_Text_Display |
I attach a test text file containing, at the end, text from various scripts. |
This issue affects also the test/table demo program which requires a very long time to start |
This should be fixed with commit 368f180 . |
FLTK 1.4 - latest at moment from git
Linux cmake builds: with and without pango
Test case:
Run editor from example programs and open some file (for example editor.cxx). Next select word wrapping from menu and try to scroll view.
Result:
Build without pango works without a hitch.
Build with pango hangs making program unresponsive for a while.
The text was updated successfully, but these errors were encountered: