Commit 5c91d535 authored by Dylan Smith's avatar Dylan Smith Committed by Alexandre Julliard

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.
parent 5a84e193
......@@ -1267,26 +1267,24 @@ ME_InvalidateSelection(ME_TextEditor *editor)
assert(para1->type == diParagraph);
assert(para2->type == diParagraph);
/* 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) {
ME_MarkForPainting(editor,
ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph),
ME_FindItemFwd(editor->pBuffer->pFirst, diTextEnd));
editor->pBuffer->pLast);
} else {
/* if the start part of selection is being expanded or contracted... */
if (nStart < editor->nLastSelStart) {
ME_MarkForPainting(editor, para1, ME_FindItemFwd(editor->pLastSelStartPara, diParagraphOrEnd));
} else
if (nStart > editor->nLastSelStart) {
ME_MarkForPainting(editor, editor->pLastSelStartPara, ME_FindItemFwd(para1, diParagraphOrEnd));
ME_MarkForPainting(editor, para1, editor->pLastSelStartPara->member.para.next_para);
} else if (nStart > editor->nLastSelStart) {
ME_MarkForPainting(editor, editor->pLastSelStartPara, para1->member.para.next_para);
}
/* if the end part of selection is being contracted or expanded... */
if (nEnd < editor->nLastSelEnd) {
ME_MarkForPainting(editor, para2, ME_FindItemFwd(editor->pLastSelEndPara, diParagraphOrEnd));
} else
if (nEnd > editor->nLastSelEnd) {
ME_MarkForPainting(editor, editor->pLastSelEndPara, ME_FindItemFwd(para2, diParagraphOrEnd));
ME_MarkForPainting(editor, para2, editor->pLastSelEndPara->member.para.next_para);
} else if (nEnd > editor->nLastSelEnd) {
ME_MarkForPainting(editor, editor->pLastSelEndPara, para2->member.para.next_para);
}
}
......
......@@ -518,6 +518,9 @@ ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayIte
*para = ME_GetParagraph(editor->pCursors[0].pRun);
*para_end = ME_GetParagraph(editor->pCursors[1].pRun);
if (*para == *para_end)
return;
if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) {
ME_DisplayItem *tmp = *para;
......@@ -526,12 +529,10 @@ ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayIte
pEndCursor = &editor->pCursors[0];
}
/* selection consists of chars from nFrom up to nTo-1 */
if ((*para_end)->member.para.nCharOfs > (*para)->member.para.nCharOfs) {
if (!pEndCursor->nOffset) {
*para_end = ME_GetParagraph(ME_FindItemBack(pEndCursor->pRun, diRun));
}
}
/* The paragraph at the end of a non-empty selection isn't included
* if the selection ends at the start of the paragraph. */
if (!pEndCursor->pRun->member.run.nCharOfs && !pEndCursor->nOffset)
*para_end = (*para_end)->member.para.prev_para;
}
......
......@@ -90,13 +90,14 @@ ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
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;
item = ME_FindItemFwd(item, diParagraph);
item = item->member.para.next_para;
}
if (!item)
return item;
if (item->type != diParagraph)
return NULL;
for (item = ME_FindItemFwd(item, diStartRow); item && nCount < nRow; nCount++)
item = ME_FindItemFwd(item, diStartRow);
return item;
......@@ -106,15 +107,16 @@ ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
int
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;
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;
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment