richedit: Avoid scanning all text for paragraphs to invalidate.
This commit is contained in:
parent
43c4c4b1c5
commit
1f8cbe1645
|
@ -187,7 +187,7 @@ void ME_DestroyContext(ME_Context *c) DECLSPEC_HIDDEN;
|
|||
|
||||
/* wrap.c */
|
||||
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
||||
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
||||
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor, ME_DisplayItem *start_para, ME_DisplayItem *end_para) DECLSPEC_HIDDEN;
|
||||
void ME_SendRequestResize(ME_TextEditor *editor, BOOL force) DECLSPEC_HIDDEN;
|
||||
|
||||
/* para.c */
|
||||
|
|
|
@ -73,13 +73,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate)
|
|||
|
||||
/* Draw the paragraph if any of the paragraph is in the update region. */
|
||||
if (ys < rcUpdate->bottom && ye > rcUpdate->top)
|
||||
{
|
||||
ME_DrawParagraph(&c, item);
|
||||
/* Clear the repaint flag if the whole paragraph is in the
|
||||
* update region. */
|
||||
if (rcUpdate->top <= ys && rcUpdate->bottom >= ye)
|
||||
item->member.para.nFlags &= ~MEPF_REPAINT;
|
||||
}
|
||||
item = item->member.para.next_para;
|
||||
}
|
||||
if (c.pt.y + editor->nTotalLength < c.rcView.bottom)
|
||||
|
@ -1263,7 +1257,8 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor)
|
|||
void
|
||||
ME_InvalidateSelection(ME_TextEditor *editor)
|
||||
{
|
||||
ME_DisplayItem *para1, *para2;
|
||||
ME_DisplayItem *sel_start, *sel_end;
|
||||
ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL;
|
||||
int nStart, nEnd;
|
||||
int len = ME_GetTextLength(editor);
|
||||
|
||||
|
@ -1273,32 +1268,39 @@ ME_InvalidateSelection(ME_TextEditor *editor)
|
|||
if (nStart == nEnd && editor->nLastSelStart == editor->nLastSelEnd)
|
||||
return;
|
||||
ME_WrapMarkedParagraphs(editor);
|
||||
ME_GetSelectionParas(editor, ¶1, ¶2);
|
||||
assert(para1->type == diParagraph);
|
||||
assert(para2->type == diParagraph);
|
||||
ME_GetSelectionParas(editor, &sel_start, &sel_end);
|
||||
assert(sel_start->type == diParagraph);
|
||||
assert(sel_end->type == diParagraph);
|
||||
/* last selection markers aren't always updated, which means
|
||||
* they can point past the end of the document */
|
||||
if (editor->nLastSelStart > len || editor->nLastSelEnd > len) {
|
||||
ME_MarkForPainting(editor,
|
||||
ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph),
|
||||
editor->pBuffer->pLast);
|
||||
repaint_start = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
|
||||
repaint_end = editor->pBuffer->pLast;
|
||||
ME_MarkForPainting(editor, repaint_start, repaint_end);
|
||||
} else {
|
||||
/* if the start part of selection is being expanded or contracted... */
|
||||
if (nStart < editor->nLastSelStart) {
|
||||
ME_MarkForPainting(editor, para1, editor->pLastSelStartPara->member.para.next_para);
|
||||
repaint_start = sel_start;
|
||||
repaint_end = editor->pLastSelStartPara->member.para.next_para;
|
||||
} else if (nStart > editor->nLastSelStart) {
|
||||
ME_MarkForPainting(editor, editor->pLastSelStartPara, para1->member.para.next_para);
|
||||
repaint_start = editor->pLastSelStartPara;
|
||||
repaint_end = sel_start->member.para.next_para;
|
||||
}
|
||||
ME_MarkForPainting(editor, repaint_start, repaint_end);
|
||||
|
||||
/* if the end part of selection is being contracted or expanded... */
|
||||
if (nEnd < editor->nLastSelEnd) {
|
||||
ME_MarkForPainting(editor, para2, editor->pLastSelEndPara->member.para.next_para);
|
||||
if (!repaint_start) repaint_start = sel_end;
|
||||
repaint_end = editor->pLastSelEndPara->member.para.next_para;
|
||||
ME_MarkForPainting(editor, sel_end, repaint_end);
|
||||
} else if (nEnd > editor->nLastSelEnd) {
|
||||
ME_MarkForPainting(editor, editor->pLastSelEndPara, para2->member.para.next_para);
|
||||
if (!repaint_start) repaint_start = editor->pLastSelEndPara;
|
||||
repaint_end = sel_end->member.para.next_para;
|
||||
ME_MarkForPainting(editor, editor->pLastSelEndPara, repaint_end);
|
||||
}
|
||||
}
|
||||
|
||||
ME_InvalidateMarkedParagraphs(editor);
|
||||
ME_InvalidateMarkedParagraphs(editor, repaint_start, repaint_end);
|
||||
/* remember the last invalidated position */
|
||||
ME_GetSelectionOfs(editor, &editor->nLastSelStart, &editor->nLastSelEnd);
|
||||
ME_GetSelectionParas(editor, &editor->pLastSelStartPara, &editor->pLastSelEndPara);
|
||||
|
|
|
@ -583,12 +583,22 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
|
|||
tp->member.para.nRows = wc.nRow;
|
||||
}
|
||||
|
||||
static void ME_MarkRepaintEnd(ME_DisplayItem *para,
|
||||
ME_DisplayItem **repaint_start,
|
||||
ME_DisplayItem **repaint_end)
|
||||
{
|
||||
if (!*repaint_start)
|
||||
*repaint_start = para;
|
||||
*repaint_end = para->member.para.next_para;
|
||||
para->member.para.nFlags |= MEPF_REPAINT;
|
||||
}
|
||||
|
||||
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
|
||||
{
|
||||
ME_DisplayItem *item;
|
||||
ME_Context c;
|
||||
BOOL bModified = FALSE;
|
||||
int totalWidth = 0;
|
||||
ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL;
|
||||
|
||||
ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost));
|
||||
c.pt.x = 0;
|
||||
|
@ -605,9 +615,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
|
|||
ME_WrapTextParagraph(&c, item);
|
||||
|
||||
if (bRedraw)
|
||||
item->member.para.nFlags |= MEPF_REPAINT;
|
||||
|
||||
bModified = bModified | bRedraw;
|
||||
ME_MarkRepaintEnd(item, &repaint_start, &repaint_end);
|
||||
|
||||
if (item->member.para.nFlags & MEPF_ROWSTART)
|
||||
{
|
||||
|
@ -678,10 +686,10 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
|
|||
{
|
||||
/* The height of the cells has grown, so invalidate the bottom of
|
||||
* the cells. */
|
||||
item->member.para.nFlags |= MEPF_REPAINT;
|
||||
ME_MarkRepaintEnd(item, &repaint_start, &repaint_end);
|
||||
cell = ME_FindItemBack(item, diCell);
|
||||
while (cell) {
|
||||
ME_FindItemBack(cell, diParagraph)->member.para.nFlags |= MEPF_REPAINT;
|
||||
ME_MarkRepaintEnd(ME_FindItemBack(cell, diParagraph), &repaint_start, &repaint_end);
|
||||
cell = cell->member.cell.prev_cell;
|
||||
}
|
||||
}
|
||||
|
@ -729,12 +737,17 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
|
|||
|
||||
ME_DestroyContext(&c);
|
||||
|
||||
if (bModified || editor->nTotalLength < editor->nLastTotalLength)
|
||||
ME_InvalidateMarkedParagraphs(editor);
|
||||
return bModified;
|
||||
if (repaint_start || editor->nTotalLength < editor->nLastTotalLength)
|
||||
{
|
||||
if (!repaint_start) repaint_start = editor->pBuffer->pFirst;
|
||||
ME_InvalidateMarkedParagraphs(editor, repaint_start, repaint_end);
|
||||
}
|
||||
return !!repaint_start;
|
||||
}
|
||||
|
||||
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor)
|
||||
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor,
|
||||
ME_DisplayItem *start_para,
|
||||
ME_DisplayItem *end_para)
|
||||
{
|
||||
ME_Context c;
|
||||
RECT rc;
|
||||
|
@ -745,13 +758,11 @@ void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor)
|
|||
rc = c.rcView;
|
||||
ofs = editor->vert_si.nPos;
|
||||
|
||||
item = editor->pBuffer->pFirst;
|
||||
while(item != editor->pBuffer->pLast) {
|
||||
item = start_para;
|
||||
while(item && item != end_para) {
|
||||
if (item->member.para.nFlags & MEPF_REPAINT) {
|
||||
rc.top = c.rcView.top + item->member.para.pt.y - ofs;
|
||||
rc.bottom = max(c.rcView.top + item->member.para.pt.y
|
||||
+ item->member.para.nHeight - ofs,
|
||||
c.rcView.bottom);
|
||||
rc.bottom = max(rc.top + item->member.para.nHeight, c.rcView.bottom);
|
||||
ITextHost_TxInvalidateRect(editor->texthost, &rc, TRUE);
|
||||
item->member.para.nFlags &= ~MEPF_REPAINT;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue