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, &para, &para_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