Debugged for a while, I found that, when I click on a brace(if there are some braces already highlighted)
I get to those code:
void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) {
if ((pos0 != braces[0]) || (pos1 != braces[1]) || (matchStyle != bracesMatchStyle)) {
if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) {
CheckForChangeOutsidePaint(Range(braces[0]));
CheckForChangeOutsidePaint(Range(pos0));
braces[0] = pos0;
}
if ((braces[1] != pos1) || (matchStyle != bracesMatchStyle)) {
CheckForChangeOutsidePaint(Range(braces[1]));
CheckForChangeOutsidePaint(Range(pos1));
braces[1] = pos1;
}
bracesMatchStyle = matchStyle;
if (paintState == notPainting) {
Redraw();
}
}
}
This function is called inside the function call "Paint(surfaceWindow, rcPaint);" inside the below function.
void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) {
paintState = painting;
AutoSurface surfaceWindow(dc, this);
if (surfaceWindow) {
rcPaint = PRectangleFromwxRect(rect);
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
ClipChildren(*dc, rcPaint);
Paint(surfaceWindow, rcPaint);
surfaceWindow->Release();
}
if (paintState == paintAbandoned) {
// Painting area was insufficient to cover new styling or brace
// highlight positions. So trigger a new paint event that will
// repaint the whole window.
sci->Refresh(false);
#if defined(__WXOSX__)
// On Mac we also need to finish the current paint to make sure that
// everything is on the screen that needs to be there between now and
// when the next paint event arrives.
FullPaintDC(dc);
#endif
}
paintState = notPainting;
}
Then, we will get into the condition that satisfy this condition "if (!PaintContains(rcRange))", so that "paintAbandonedByStyling = true;" is reached.
void Editor::CheckForChangeOutsidePaint(Range r) {
if (paintState == painting && !paintingAllText) {
//Platform::DebugPrintf("Checking range in paint %d-%d\n", r.start, r.end);
if (!r.Valid())
return;
PRectangle rcRange = RectangleFromRange(r, 0);
PRectangle rcText = GetTextRectangle();
if (rcRange.top < rcText.top) {
rcRange.top = rcText.top;
}
if (rcRange.bottom > rcText.bottom) {
rcRange.bottom = rcText.bottom;
}
if (!PaintContains(rcRange)) {
AbandonPaint();
paintAbandonedByStyling = true;
}
}
}
Back to the function "void ScintillaWX::DoPaint(wxDC* dc, wxRect rect)", you will see the Refresh() call is reached.
if (paintState == paintAbandoned) {
// Painting area was insufficient to cover new styling or brace
// highlight positions. So trigger a new paint event that will
// repaint the whole window.
sci->Refresh(false);
Now, you get a repaint:
void wxScintilla::OnPaint(wxPaintEvent& WXUNUSED(evt))
{
#ifdef __WXGTK__
wxBufferedPaintDC dc(this);
#else
wxPaintDC dc(this);
#endif
m_swx->DoPaint(&dc, GetUpdateRegion().GetBox());
}
But here comes the bug!
I see that "GetUpdateRegion().GetBox()" only gives the area around the current line. This not cover the old brace highlight, so that the old brace highlight is not removed. Also, if you click on the "{", while the associated "}" is on the other line(which means the "}" is not in the area of the "GetUpdateRegion().GetBox()"), so the "}" is not highlighted.
What's wrong with the "GetUpdateRegion().GetBox()", It should at least be a rectangle area which covers the current braces and the old braces.