Re: speed of testtext, directionality



Karl Koehler <koehler@or.uni-bonn.de> writes:

> Hi !
> 
> I spent a little effort trying to find out where pango wasts time.
> 
> #1: Font caching. 
> > One thing that would help is to cache the font lookup on the
> > PangoFont. The recently added Thai shaper should provide a good
> > example of doing this.
> 
> I implemented this for the arabic shaper, but have not cleaned it up yet.
> It does not seem to give much gain.

I wouldn't expect it to be a huge gain - that code was taking
5-10% of the total CPU when I was profiling.

> Maybe it would help more ( memory-wise ) to shape to allow the space
> character to a 'native' arabic character, as it already is a native
> 'left-to-right' character ?
> I can add the space character to the range of the arabic shaper, but that 
> leads to normal text being handeled by the arabic shaper ( altogether, the arabic
> shaper gets faster , being called less often ),
> but altogether this is not such a good idea performance-wise.
> There must be some better way of achieving this. 
> Changing the PangoCoverage * wich  arabic_engine_get_coverage 
> returns does not seem to help this issue.
 
Yes, it would be a good idea not to break the Arabic text into a
run for each word.

We basically need a way to have some characters "neutral" with respect
to the choice of shaper.
 
> #2: Strange behaviour of the arabic shaper when appending text to the end 
> ot the line in left-to-right mode:
> Actually, in this case, no shaping is done, and the characters do not 
> appear ( Or only unshaped, if you have iso10646-1 encoded fonts ).
> In this case, even though several arabic letters may have been typed,
> any shaper's PangoAnalysis reveals that we are in a left-to-right run
> of characters : analysis->level % 2 == 0 ! 
> Amazingly enough, bidi-reordering is done correctly, but nontheless this
> is wrong. Because of this, the arabic shaper in its current state falls 
> back to not shape the letters. 
> A workaround woud be to do reshaping in any case and not check the
> level; but I'd rather like to find out why exactly the directionality
> does not seem correct.

This sounds simply like a bug in fribidi.
 
> #3: One major speed issue:
> When the cursor is moved, all the shapers are being called twice 
> for the stuff on the current line and for which they are responsible.
> This strikes me as strange, because:
> *  If the cursor is really drawn on top of the rest, and is part of
>    the layout, only one reshape ought to be needed.
>    This is still true if I add a character, and the new string
>    fits into the line after reshaping.
> *  If the cursor is XOR'd on top of the string, cursor movement
>    should not need to call for any reshape at all.

XOR'ing the cursor would not reduce the need for reshaping - we
need to know _where_ the cursor goes, so we need to have the
shaped paragraph.

The way the text widget works, we cache the layout information for a
single paragraph, but in all other cases we recompute.  When we are
dealing with a single paragraph, the question then, is why are we
invalidating our cache?

The cause of the two reshapes is:

 1) A reshape because the paragraph is invalidated when we move
    the cursor position. While the PangoLayout structure 
    doesn't actually change, we don't keep detailed information
    about what changed in the paragraph - we just say "something
    changed".

    This could probably be avoided with some more complexity - 
    but a justification for not doing is that reshaping has
    to be fast enough to handle reflowing pages and pages
    of text. If we achieve that goal, we should be able to
    handle a few extra reshapes without it hurting much.

 2) Another reshape when we display because of an optization 
    gone astray. When the code asks for the GtkTextLineDisplay
    structure, it says "only care about the size, ignore colors,
    etc." But when we go back and ask for the paragraph again
    to display, we can't use the cached line-display structure
    because we do need the full information with colors.

    Basically, we really want to pass TRUE for the size-only parameter
    to gtk_text_layout_get_line_display() only when we are
    reflowing multiple paragraphs of text and the current
    paragraph is not the last paragraph we are going to reflow.
    Unfotunately, this condition is rather awkward hard to detect.
    
    A somewhat intermediate step is to use FALSE for this
    value everywhere except for gtk_text_layout_real_wrap().
    If we do this, we'll still occasionally get double reshapes
    (for instance on focus-in and focus-out.) But less often.
    The appended patch does this and seems to help some.

Regards,
                                        Owen


Index: gtktextlayout.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktextlayout.c,v
retrieving revision 1.5
diff -u -r1.5 gtktextlayout.c
--- gtktextlayout.c	2000/06/21 20:41:15	1.5
+++ gtktextlayout.c	2000/07/10 15:20:13
@@ -1459,7 +1459,7 @@
 
   get_line_at_y (layout, y, &line, &line_top);
 
-  display = gtk_text_layout_get_line_display (layout, line, TRUE);
+  display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
   x -= display->x_offset;
   y -= line_top + display->top_margin;
@@ -1521,7 +1521,7 @@
   line = gtk_text_iter_get_line (iter);
   line_top = gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
 
-  display = gtk_text_layout_get_line_display (layout, line, TRUE);
+  display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
   pango_layout_get_cursor_pos (display->layout, gtk_text_iter_get_line_byte (iter),
 			       strong_pos ? &pango_strong_pos : NULL,
@@ -1587,7 +1587,7 @@
   tree = gtk_text_iter_get_btree (iter);
   line = gtk_text_iter_get_line (iter);
 
-  display = gtk_text_layout_get_line_display (layout, line, TRUE);
+  display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
   rect->y = gtk_text_btree_find_line_top (tree, line, layout);
 
@@ -1645,7 +1645,7 @@
 
   while (line && !found_line)
     {
-      GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, TRUE);
+      GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE);
       gint byte_index = 0;
       GSList *tmp_list =  pango_layout_get_lines (display->layout);
 
@@ -1707,7 +1707,7 @@
 
   while (line && !found_line)
     {
-      GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, TRUE);
+      GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE);
       PangoRectangle logical_rect;
       
       gint byte_index = 0;
@@ -1822,7 +1822,7 @@
   line = gtk_text_iter_get_line (iter);
   line_byte = gtk_text_iter_get_line_byte (iter);
   
-  display = gtk_text_layout_get_line_display (layout, line, TRUE);
+  display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
   tmp_list = pango_layout_get_lines (display->layout);
   layout_line = tmp_list->data;
@@ -1836,7 +1836,7 @@
 	  gint byte_offset = 0;
 	  
 	  gtk_text_layout_free_line_display (layout, display);
-	  display = gtk_text_layout_get_line_display (layout, prev_line, TRUE);
+	  display = gtk_text_layout_get_line_display (layout, prev_line, FALSE);
 	  
 	  tmp_list =  pango_layout_get_lines (display->layout);
 
@@ -1913,7 +1913,7 @@
       gint byte_offset = 0;
       GSList *tmp_list;
       
-      display = gtk_text_layout_get_line_display (layout, line, TRUE);
+      display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
       tmp_list = pango_layout_get_lines (display->layout);
       while (tmp_list && !found_after)
@@ -1968,7 +1968,7 @@
   line = gtk_text_iter_get_line (iter);
   line_byte = gtk_text_iter_get_line_byte (iter);
   
-  display = gtk_text_layout_get_line_display (layout, line, TRUE);
+  display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
   tmp_list = pango_layout_get_lines (display->layout);
   while (tmp_list)
@@ -2052,7 +2052,7 @@
     {
       GtkTextLine *line = gtk_text_iter_get_line (iter);
       gint line_byte = gtk_text_iter_get_line_byte (iter);
-      GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, TRUE);
+      GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE);
       int byte_count = gtk_text_line_byte_count (line);
       
       int new_index;




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]