From 5c91d5356ec2f1e3f87ba4d3665c8230dd8ee25c Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Fri, 6 Feb 2009 01:10:06 -0500 Subject: [PATCH] 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. --- dlls/riched20/paint.c | 18 ++++++++---------- dlls/riched20/para.c | 21 +++++++++++---------- dlls/riched20/row.c | 22 ++++++++++++---------- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index 03ece7bd2de..28813d4f4d9 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -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); } } diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index a4a9adb1b29..0836390be2f 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -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) diff --git a/dlls/riched20/row.c b/dlls/riched20/row.c index 3abff5f7a51..d3ef3de6b8f 100644 --- a/dlls/riched20/row.c +++ b/dlls/riched20/row.c @@ -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)