[haiku-commits] r35587 - haiku/trunk/src/apps/terminal

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 23 Feb 2010 16:39:30 +0100 (CET)

Author: bonefish
Date: 2010-02-23 16:39:30 +0100 (Tue, 23 Feb 2010)
New Revision: 35587
Changeset: http://dev.haiku-os.org/changeset/35587/haiku
Ticket: http://dev.haiku-os.org/ticket/2851

Modified:
   haiku/trunk/src/apps/terminal/TermView.cpp
Log:
TermView::Draw():
* Apparently Draw() can be invoked with new view bounds in effect before the
  FrameResized() hook has been invoked (I suppose that's not really kosher).
  Since TermView updates the terminal dimensions in FrameResized() and relied
  on the update rect passed to Draw() to translate to positions within the
  limits, an on-stack buffer could overflow, leading to #2851. Now we clamp
  the translated positions to terminal size.
* Draw the background areas right of the last column and below the last row
  explicitly instead of drawing an additional non-existing partial
  character/row.


Modified: haiku/trunk/src/apps/terminal/TermView.cpp
===================================================================
--- haiku/trunk/src/apps/terminal/TermView.cpp  2010-02-23 14:19:19 UTC (rev 
35586)
+++ haiku/trunk/src/apps/terminal/TermView.cpp  2010-02-23 15:39:30 UTC (rev 
35587)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2009, Haiku, Inc.
+ * Copyright 2001-2010, Haiku, Inc.
  * Copyright 2003-2004 Kian Duffy, myob@xxxxxxxxxxxxxxxxxxxxx
  * Parts Copyright 1998-1999 Kazuho Okui and Takashi Murai.
  * All rights reserved. Distributed under the terms of the MIT license.
@@ -13,7 +13,6 @@
  */
 
 
-
 #include "TermView.h"
 
 #include <ctype.h>
@@ -1090,55 +1089,80 @@
 // }
 // }
 
-       int32 x1 = (int32)(updateRect.left) / fFontWidth;
-       int32 x2 = (int32)(updateRect.right) / fFontWidth;
+       int32 x1 = (int32)updateRect.left / fFontWidth;
+       int32 x2 = std::min((int)updateRect.right / fFontWidth, fColumns - 1);
 
        int32 firstVisible = _LineAt(0);
        int32 y1 = _LineAt(updateRect.top);
-       int32 y2 = _LineAt(updateRect.bottom);
+       int32 y2 = std::min(_LineAt(updateRect.bottom), (int32)fRows - 1);
 
 //debug_printf("TermView::Draw(): (%ld, %ld) - (%ld, %ld), top: %f, 
fontHeight: %d, scrollOffset: %f\n",
 //x1, y1, x2, y2, updateRect.top, fFontHeight, fScrollOffset);
 
-       for (int32 j = y1; j <= y2; j++) {
-               int32 k = x1;
-               char buf[fColumns * 4 + 1];
+       // clear the area to the right of the line ends
+       if (y1 <= y2) {
+               float clearLeft = fColumns * fFontWidth;
+               if (clearLeft < updateRect.right) {
+                       BRect rect(clearLeft, updateRect.top, updateRect.right,
+                               updateRect.bottom);
+                       SetHighColor(fTextBackColor);
+                       FillRect(rect);
+               }
+       }
 
-               if (fVisibleTextBuffer->IsFullWidthChar(j - firstVisible, k))
-                       k--;
+       // clear the area below the last line
+       if (y2 == fRows - 1) {
+               float clearTop = _LineOffset(fRows);
+               if (clearTop < updateRect.bottom) {
+                       BRect rect(updateRect.left, clearTop, updateRect.right,
+                               updateRect.bottom);
+                       SetHighColor(fTextBackColor);
+                       FillRect(rect);
+               }
+       }
 
-               if (k < 0)
-                       k = 0;
+       // draw the affected line parts
+       if (x1 <= x2) {
+               for (int32 j = y1; j <= y2; j++) {
+                       int32 k = x1;
+                       char buf[fColumns * 4 + 1];
 
-               for (int32 i = k; i <= x2;) {
-                       int32 lastColumn = x2;
-                       bool insideSelection = _CheckSelectedRegion(j, i, 
lastColumn);
-                       uint16 attr;
-                       int32 count = fVisibleTextBuffer->GetString(j - 
firstVisible, i,
-                               lastColumn, buf, attr);
+                       if (fVisibleTextBuffer->IsFullWidthChar(j - 
firstVisible, k))
+                               k--;
 
+                       if (k < 0)
+                               k = 0;
+
+                       for (int32 i = k; i <= x2;) {
+                               int32 lastColumn = x2;
+                               bool insideSelection = _CheckSelectedRegion(j, 
i, lastColumn);
+                               uint16 attr;
+                               int32 count = fVisibleTextBuffer->GetString(j - 
firstVisible, i,
+                                       lastColumn, buf, attr);
+
 //debug_printf("  fVisibleTextBuffer->GetString(%ld, %ld, %ld) -> (%ld, 
\"%.*s\"), selected: %d\n",
 //j - firstVisible, i, lastColumn, count, (int)count, buf, insideSelection);
 
-                       if (count == 0) {
-                               BRect rect(fFontWidth * i, _LineOffset(j),
-                                       fFontWidth * (lastColumn + 1) - 1, 0);
-                               rect.bottom = rect.top + fFontHeight - 1;
+                               if (count == 0) {
+                                       BRect rect(fFontWidth * i, 
_LineOffset(j),
+                                               fFontWidth * (lastColumn + 1) - 
1, 0);
+                                       rect.bottom = rect.top + fFontHeight - 
1;
 
-                               SetHighColor(insideSelection ? fSelectBackColor
-                                       : fTextBackColor);
-                               FillRect(rect);
+                                       SetHighColor(insideSelection ? 
fSelectBackColor
+                                               : fTextBackColor);
+                                       FillRect(rect);
 
-                               i = lastColumn + 1;
-                               continue;
-                       }
+                                       i = lastColumn + 1;
+                                       continue;
+                               }
 
-                       if (IS_WIDTH(attr))
-                               count = 2;
+                               if (IS_WIDTH(attr))
+                                       count = 2;
 
-                       _DrawLinePart(fFontWidth * i, (int32)_LineOffset(j),
-                               attr, buf, count, insideSelection, false, this);
-                       i += count;
+                               _DrawLinePart(fFontWidth * i, 
(int32)_LineOffset(j),
+                                       attr, buf, count, insideSelection, 
false, this);
+                               i += count;
+                       }
                }
        }
 


Other related posts: