Dylan Smith : richedit: Avoided searching for adjacent paragraphs through runs.
Alexandre Julliard
julliard at winehq.org
Fri Feb 6 09:56:06 CST 2009
Module: wine
Branch: master
Commit: 5c91d5356ec2f1e3f87ba4d3665c8230dd8ee25c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5c91d5356ec2f1e3f87ba4d3665c8230dd8ee25c
Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date: Fri Feb 6 01:10:06 2009 -0500
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 03ece7b..28813d4 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 a4a9adb..0836390 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 3abff5f..d3ef3de 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)
More information about the wine-cvs
mailing list