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:
parent
5a84e193c2
commit
5c91d5356e
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -515,9 +515,12 @@ void
|
|||
ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end)
|
||||
{
|
||||
ME_Cursor *pEndCursor = &editor->pCursors[1];
|
||||
|
||||
|
||||
*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;
|
||||
|
||||
|
@ -525,22 +528,20 @@ ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayIte
|
|||
*para_end = tmp;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt)
|
||||
{
|
||||
ME_DisplayItem *para, *para_end;
|
||||
|
||||
|
||||
ME_GetSelectionParas(editor, ¶, ¶_end);
|
||||
|
||||
|
||||
do {
|
||||
ME_SetParaFormat(editor, para, pFmt);
|
||||
if (para == para_end)
|
||||
|
|
|
@ -89,14 +89,15 @@ 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,18 +107,19 @@ 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;
|
||||
|
||||
|
||||
nOfs -= item->member.para.nCharOfs;
|
||||
item = ME_FindItemFwd(item, diRun);
|
||||
while ((item = ME_FindItemFwd(item, diStartRowOrParagraph)) != NULL)
|
||||
|
|
Loading…
Reference in New Issue