Opened 14 years ago

Last modified 10 years ago

#79 closed defect

Short underflow on in wxWindow::Refresh()

Reported by: kgill Owned by:
Priority: low Milestone:
Component: wxGTK Version:
Keywords: Cc: kgill, robind, roebling
Blocked By: Blocking:
Patch: no

Description

The wxWindow::Refresh() program converts wxRect coordinates to
GdkRectangle. The coordinate system in wxRect uses integers, whereas
the GdkRectangle uses unsigned shorts. I am using a widget in which there
is an error. It calculates a rectangle, where the bottom is in the negative
quadrant.

In the Windows environment, signed coordinates are used, and this code does nothing. However, in wxGTK, the negative quadrant is converted to the positive quadrant, and consquently, the entire document refreshes.

I suggest, that the wxGTK system should clip the wxRect to the positive quadrant before converting to a GdkRectangle.


For background information, this is my mail (wxPython mail list).

Further to my previous posting



Thanks for the pointers Neil & Robin.

The problem appears to be thus...

When I page down the screen using the scrollbar, the current position is
not updated to be on the new page. The current position is unchanged. This is the behaviour regardless of whether the background is a frame or a
notebook. You can see this behaviour in the wxPython demo.

The Scintilla Editor class contains a method to refresh the cursor. Its called 'InvalidateCaret'. This method attempts to invalidate the line on which the cursor is placed.

The line with the cursor has scrolled off the screen. The cursor position is actually in a negative quadrant. The scintilla Editor method RectangleFromRange checks the top of the invalidate area. If it is not in the positive quadrant, is sets it to 0. However, the bottom of the rectangle is left in the negative quadrant.

The Scintilla rectangle is converted to a wxRect by the PlatWX.cpp code. The wxRect is passed to the wxWindow method Refresh(). Refresh() converts the wxRect to a GdkRectangle prior and raises the events which result in the screen refresh. However, the GdkRectangle uses unsigned shorts. The negative numbers convert to positive numbers (65532 + (-500)) = 65032 etc.

I presume that the error does not manifest on Windows, because it can handle negative positions, whereas GDK cannot.


How to resolve the issue



From the wxPython perspective, perhaps there should also be some defensive programming in the passing of wxRects to wxWindows. In general this is not a wxPython error.

From the wxWindows perspective, the wxWindow::Refresh method should clip the rectangle to the positive quadrant when converting to a GdkRectangle.

From the Scintilla perspective, either the caret should not flash when it is off screen, or the scrolldown should reset the current position. I need to raise these issues with the relevent parties. What version of Scintilla is used in wxPython2.2.2 ? I assume that it is 1.32.

Regards


Kevin


===========================================================================
Previous Posting



wxStyledTextCtrl Problem



I am running

Redhat Linux 6.2.
wxGTK 2.2.2
wxPython 2.2.2
Python 2.0


I am experiencing a problem with the wxStyledTextControl. The behaviour is sluggish and it uses up a lot of CPU.

Background



I placed a printf into stc.cpp, in the OnPaint() method. This printf displays the rectangle co-ordinates. I see that the OnPaint method is called each time the cursor blinks.

I notice that the call is made even when the cursor is not blinking, i.e. where the cursor is on another screen (Small problem).

You can see the cursor behavior by placing these lines in OnPrint..

wxRect rect = region.GetBox();
printf("stc.cpp:wxStyledTextCtrl::Painted(%d, %d, %d, %d\n",

rect.x, rect.y, rect.width, rect.height);


If you run the demo program, you can see the paints ...

python2.0 run.py wxStyledTextCtrl_2.py


O.K. So far.

My Issue



I place my wxStyledTextControl on a notebook. There is a wxPanel between the wxStyledTextControl, because I found that this helps. Occasionally, when I scrolldown using the scrollbar, the cursor region height gets totally messed up. It becomes some number > 60000. The resulting refreshes are extremely time consuming.

stc.cpp:(1513)::wxStyledTextCtrl::Painted(40, 0, 579, 65168
stc.cpp:(1513)::wxStyledTextCtrl::Painted(0, 0, 619, 404
stc.cpp:(1513)::wxStyledTextCtrl::Painted(40, 0, 579, 64784
stc.cpp:(1513)::wxStyledTextCtrl::Painted(40, 0, 579, 64784

I am not sufficiently familiar with wxWindows to identify the source of these
events. Perhaps someone else could give me a few pointer as to where to look.

I can defend against the issue by placing the following code in the OnPaint method. (However, I would like to identify the source of the problem.)

wxRect rect = region.GetBox();
if (rect.height > 60000)

rect.height=16;

Change History (2)

comment:1 Changed 14 years ago by robind

A workaround for this issue has been made to the Scintilla code, so it is less critical now,
but I think it is still something that should possible be addressed in wxGTK, so I am
leaving the bug in the Open state.

Robin

FYI, the fix in Scintilla is below:

OK. I've changed Scintilla like this:

void Editor::RedrawRect(PRectangle rc) {

Platform::DebugPrintf("Redraw %d %d - %d %d\n", rc.left, rc.top,

rc.right, rc.bottom);

Clip the redraw rectangle into the client area
PRectangle rcClient = GetClientRectangle();
if (rc.top < rcClient.top)

rc.top = rcClient.top;

if (rc.bottom > rcClient.bottom)

rc.bottom = rcClient.bottom;

if (rc.left < rcClient.left)

rc.left = rcClient.left;

if (rc.right > rcClient.right)

rc.right = rcClient.right;

if ((rc.bottom > rc.top) && (rc.right > rc.left)) {

wDraw.InvalidateRectangle(rc);

}

}

comment:2 Changed 14 years ago by roebling

The problem is that MSW accepts negative heights in Refresh.

Note: See TracTickets for help on using tickets.