richedit: Avoided searching for adjacent paragraphs through runs.

When finding an adjacent paragraph, the next_para and prev_para pointers
should be used because they are direct pointers, a constant time
operation.  Instead I found some places in the code that searched through
the general linked list to get to an adjacent paragraph, which is a linear
time operation, depending on the number of rows and runs in between
paragraphs.
This commit is contained in:
Dylan Smith 2009-02-06 01:10:06 -05:00 committed by Alexandre Julliard
parent 5a84e193c2
commit 5c91d5356e
3 changed files with 31 additions and 30 deletions

View File

@ -1267,26 +1267,24 @@ ME_InvalidateSelection(ME_TextEditor *editor)
assert(para1->type == diParagraph); assert(para1->type == diParagraph);
assert(para2->type == diParagraph); assert(para2->type == diParagraph);
/* last selection markers aren't always updated, which means /* last selection markers aren't always updated, which means
they can point past the end of the document */ * they can point past the end of the document */
if (editor->nLastSelStart > len || editor->nLastSelEnd > len) { if (editor->nLastSelStart > len || editor->nLastSelEnd > len) {
ME_MarkForPainting(editor, ME_MarkForPainting(editor,
ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph), ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph),
ME_FindItemFwd(editor->pBuffer->pFirst, diTextEnd)); editor->pBuffer->pLast);
} else { } else {
/* if the start part of selection is being expanded or contracted... */ /* if the start part of selection is being expanded or contracted... */
if (nStart < editor->nLastSelStart) { if (nStart < editor->nLastSelStart) {
ME_MarkForPainting(editor, para1, ME_FindItemFwd(editor->pLastSelStartPara, diParagraphOrEnd)); ME_MarkForPainting(editor, para1, editor->pLastSelStartPara->member.para.next_para);
} else } else if (nStart > editor->nLastSelStart) {
if (nStart > editor->nLastSelStart) { ME_MarkForPainting(editor, editor->pLastSelStartPara, para1->member.para.next_para);
ME_MarkForPainting(editor, editor->pLastSelStartPara, ME_FindItemFwd(para1, diParagraphOrEnd));
} }
/* if the end part of selection is being contracted or expanded... */ /* if the end part of selection is being contracted or expanded... */
if (nEnd < editor->nLastSelEnd) { if (nEnd < editor->nLastSelEnd) {
ME_MarkForPainting(editor, para2, ME_FindItemFwd(editor->pLastSelEndPara, diParagraphOrEnd)); ME_MarkForPainting(editor, para2, editor->pLastSelEndPara->member.para.next_para);
} else } else if (nEnd > editor->nLastSelEnd) {
if (nEnd > editor->nLastSelEnd) { ME_MarkForPainting(editor, editor->pLastSelEndPara, para2->member.para.next_para);
ME_MarkForPainting(editor, editor->pLastSelEndPara, ME_FindItemFwd(para2, diParagraphOrEnd));
} }
} }

View File

@ -518,6 +518,9 @@ ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayIte
*para = ME_GetParagraph(editor->pCursors[0].pRun); *para = ME_GetParagraph(editor->pCursors[0].pRun);
*para_end = ME_GetParagraph(editor->pCursors[1].pRun); *para_end = ME_GetParagraph(editor->pCursors[1].pRun);
if (*para == *para_end)
return;
if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) { if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) {
ME_DisplayItem *tmp = *para; ME_DisplayItem *tmp = *para;
@ -526,12 +529,10 @@ ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayIte
pEndCursor = &editor->pCursors[0]; pEndCursor = &editor->pCursors[0];
} }
/* selection consists of chars from nFrom up to nTo-1 */ /* The paragraph at the end of a non-empty selection isn't included
if ((*para_end)->member.para.nCharOfs > (*para)->member.para.nCharOfs) { * if the selection ends at the start of the paragraph. */
if (!pEndCursor->nOffset) { if (!pEndCursor->pRun->member.run.nCharOfs && !pEndCursor->nOffset)
*para_end = ME_GetParagraph(ME_FindItemBack(pEndCursor->pRun, diRun)); *para_end = (*para_end)->member.para.prev_para;
}
}
} }

View File

@ -90,13 +90,14 @@ ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph); ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
int nCount = 0; int nCount = 0;
while (item && nCount + item->member.para.nRows <= nRow) while (item->type == diParagraph &&
nCount + item->member.para.nRows <= nRow)
{ {
nCount += item->member.para.nRows; nCount += item->member.para.nRows;
item = ME_FindItemFwd(item, diParagraph); item = item->member.para.next_para;
} }
if (!item) if (item->type != diParagraph)
return item; return NULL;
for (item = ME_FindItemFwd(item, diStartRow); item && nCount < nRow; nCount++) for (item = ME_FindItemFwd(item, diStartRow); item && nCount < nRow; nCount++)
item = ME_FindItemFwd(item, diStartRow); item = ME_FindItemFwd(item, diStartRow);
return item; return item;
@ -106,15 +107,16 @@ ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
int int
ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs) ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs)
{ {
ME_DisplayItem *item = editor->pBuffer->pFirst->next; ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
int nRow = 0; int nRow = 0;
while (item && item->member.para.next_para->member.para.nCharOfs <= nOfs) while (item->type == diParagraph &&
item->member.para.next_para->member.para.nCharOfs <= nOfs)
{ {
nRow += item->member.para.nRows; nRow += item->member.para.nRows;
item = ME_FindItemFwd(item, diParagraph); item = item->member.para.next_para;
} }
if (item) if (item->type == diParagraph)
{ {
ME_DisplayItem *next_para = item->member.para.next_para; ME_DisplayItem *next_para = item->member.para.next_para;