Bug 98410

Summary: scrolling slow after showing some japanese characters
Product: [Applications] konsole Reporter: Eduardo Habkost <ehabkost>
Component: generalAssignee: Konsole Developer <konsole-devel>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Conectiva RPMs   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: japanese text example, used to reproduce the bug

Description Eduardo Habkost 2005-02-02 14:37:26 UTC
Version:           1.5 beta (using KDE KDE 3.3.91)
Installed from:    Conectiva RPMs
OS:                Linux

I've enabled unicode on konsole recently, and during my tests, konsole became too slow to draw the screen. If I run some application with lots of output (like 'strace find /'), the screen takes around 0.5 second for each redraw of the screen.

Testing further, I've noticed that it happens only after some wide characters are shown (like japanese chars). Steps to reproduce:

- Start konsole, set encoding to unicode, locale set to pt_BR.UTF-8
- strace find / => drawing ok, fast
- drawing/scrolling is fast for a long time, until a japanese caracter is drawn (e.g. cat some-japanese-text.txt)
- scrolling a single line on the screen become slow. You can see the scren being draw line by line. I have a Celeron 433MHz CPU, but even on a faster machine (1.8GHz) the difference on speed can still be seen
- even after the japanese text is not on the view port anymore, scrolling continues slow
- clearing the history (without any japanese char on the view port), doesn't solve the problem

- Interesting point: The scrolling speed is fast again if I create another shell tab and switch between the tabs (as long as there is not japanese char on the view port of the tab being selected). Speed is restored when switching tabs even if there are japanese chars on the history (but not on the view port), and remains fast until they are drawn on the screen again
Comment 1 Eduardo Habkost 2005-02-02 14:54:53 UTC
Created attachment 9391 [details]
japanese text example, used to reproduce the bug

Adding sample japanese text file. The bugs seems to happen with any japanese
char, but attaching the file just to be sure the bug can be really reproduced.
Comment 2 Waldo Bastian 2005-02-02 15:17:50 UTC
This pretty much corresponds to the "fixed_font" flag being set or not. 
It should probably be set slightly more intelligent (read: not permanent) when faced with double-width characters (such as Japanese)
Comment 3 Waldo Bastian 2005-02-13 16:21:58 UTC
CVS commit by waba: 

Don't set fixed_font flag permanently when double-width characters are
encountered.
BUG: 98410


  M +11 -11    TEWidget.cpp   1.222


--- kdebase/konsole/konsole/TEWidget.cpp  #1.221:1.222
@@ -802,5 +802,4 @@ HCNT("setImage");
   hasBlinker = false;
 
-  bool lineDraw = false;
   int cf  = -1; // undefined
   int cb  = -1; // undefined
@@ -849,5 +848,6 @@ HCNT("setImage");
         int p = 0;
         disstrU[p++] = c; //fontMap(c);
-        lineDraw = isLineChar(c);
+        bool lineDraw = isLineChar(c);
+        bool doubleWidth = (ext[x+1].c == 0);
         cr = ext[x].r;
         cb = ext[x].b;
@@ -858,11 +858,8 @@ HCNT("setImage");
           c = ext[x+len].c;
           if (!c)
-          {
-            fixed_font = false;
             continue; // Skip trailing part of multi-col chars.
-          }
 
           if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
-              !dirtyMask[x+len] || isLineChar(c) != lineDraw)
+              !dirtyMask[x+len] || isLineChar(c) != lineDraw || (ext[x+len+1].c == 0) != doubleWidth)
             break;
 
@@ -892,4 +889,6 @@ HCNT("setImage");
         if (lineDraw)
            fixed_font = false;
+        if (doubleWidth)
+           fixed_font = false;
         drawAttrStr(paint,
                     QRect(bX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
@@ -1056,4 +1055,5 @@ void TEWidget::paintContents(QPainter &p
          disstrU[p++] = c; //fontMap(c);
       bool lineDraw = isLineChar(c);
+      bool doubleWidth = (image[loc(x,y)+1].c == 0);
       int cf = image[loc(x,y)].f;
       int cb = image[loc(x,y)].b;
@@ -1063,17 +1063,15 @@ void TEWidget::paintContents(QPainter &p
              image[loc(x+len,y)].b == cb &&
              image[loc(x+len,y)].r == cr &&
+             (image[loc(x+len,y)+1].c == 0) == doubleWidth &&
              isLineChar( c = image[loc(x+len,y)].c) == lineDraw) // Assignment!
       {
         if (c)
           disstrU[p++] = c; //fontMap(c);
-        else
-          fixed_font = false;
+        if (doubleWidth) // assert((image[loc(x+len,y)+1].c == 0)), see above if condition
+          len++; // Skip trailing part of multi-column char
         len++;
       }
       if ((x+len < columns) && (!image[loc(x+len,y)].c))
-      {
-        fixed_font = false;
         len++; // Adjust for trailing part of multi-column char
-      }
 
       if (!isBlinkEvent || (cr & RE_BLINK))
@@ -1082,4 +1080,6 @@ void TEWidget::paintContents(QPainter &p
          if (lineDraw)
             fixed_font = false;
+         if (doubleWidth)
+            fixed_font = false;
          QString unistr(disstrU,p);
          drawAttrStr(paint,