[1/2] richedit: Get the paragraph with ME_RunOfsFromCharOfs.

Dylan Smith dylan.ah.smith at gmail.com
Fri Feb 6 00:09:47 CST 2009


The ME_RunOfsFromCharOfs function finds the paragraph before finding the
run and offset within the run, so the function may as well be able to
return this paragraph to the caller.  Many callers to the function
instead find the paragraph from the run, which ends up unnecessarily
traversing a linked list of runs within the paragraph.
---
 dlls/riched20/editor.c |   55 +++++++++--------------------------------------
 dlls/riched20/editor.h |    4 +-
 dlls/riched20/run.c    |   28 +++++++++++++-----------
 dlls/riched20/writer.c |   14 +++++-------
 4 files changed, 34 insertions(+), 67 deletions(-)
-------------- next part --------------
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index ca1eb97..285ec04 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -1687,33 +1687,18 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
       chrgText->cpMin = chrgText->cpMax = -1;
     return -1;
   }
- 
+
   if (flags & FR_DOWN) /* Forward search */
   {
     /* If possible, find the character before where the search starts */
     if ((flags & FR_WHOLEWORD) && nMin)
     {
-      nStart = nMin - 1;
-      ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart);
-      if (!item)
-      {
-        if (chrgText)
-          chrgText->cpMin = chrgText->cpMax = -1;
-        return -1;
-      }
+      ME_RunOfsFromCharOfs(editor, nMin - 1, NULL, &item, &nStart);
       wLastChar = item->member.run.strText->szData[nStart];
     }
 
-    nStart = nMin;
-    ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart);
-    if (!item)
-    {
-      if (chrgText)
-        chrgText->cpMin = chrgText->cpMax = -1;
-      return -1;
-    }
+    ME_RunOfsFromCharOfs(editor, nMin, &para, &item, &nStart);
 
-    para = ME_GetParagraph(item);
     while (item
            && para->member.para.nCharOfs + item->member.run.nCharOfs + nStart + nLen <= nMax)
     {
@@ -1785,28 +1770,12 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
     /* If possible, find the character after where the search ends */
     if ((flags & FR_WHOLEWORD) && nMax < nTextLen - 1)
     {
-      nEnd = nMax + 1;
-      ME_RunOfsFromCharOfs(editor, nEnd, &item, &nEnd);
-      if (!item)
-      {
-        if (chrgText)
-          chrgText->cpMin = chrgText->cpMax = -1;
-        return -1;
-      }
+      ME_RunOfsFromCharOfs(editor, nMax + 1, NULL, &item, &nEnd);
       wLastChar = item->member.run.strText->szData[nEnd];
     }
 
-    nEnd = nMax;
-    ME_RunOfsFromCharOfs(editor, nEnd, &item, &nEnd);
-    if (!item)
-    {
-      if (chrgText)
-        chrgText->cpMin = chrgText->cpMax = -1;
-      return -1;
-    }
-    
-    para = ME_GetParagraph(item);
-    
+    ME_RunOfsFromCharOfs(editor, nMax, &para, &item, &nEnd);
+
     while (item
            && para->member.para.nCharOfs + item->member.run.nCharOfs + nEnd - nLen >= nMin)
     {
@@ -3841,7 +3810,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     return ME_CharFromPos(editor, ((POINTL *)lParam)->x, ((POINTL *)lParam)->y, NULL);
   case EM_POSFROMCHAR:
   {
-    ME_DisplayItem *pRun;
+    ME_DisplayItem *pPara, *pRun;
     int nCharOfs, nOffset, nLength;
     POINTL pt = {0,0};
 
@@ -3853,11 +3822,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     nCharOfs = min(nCharOfs, nLength);
     nCharOfs = max(nCharOfs, 0);
 
-    ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
+    ME_RunOfsFromCharOfs(editor, nCharOfs, &pPara, &pRun, &nOffset);
     assert(pRun->type == diRun);
     pt.y = pRun->member.run.pt.y;
     pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset);
-    pt.y += ME_GetParagraph(pRun)->member.para.pt.y + editor->rcFormat.top;
+    pt.y += pPara->member.para.pt.y + editor->rcFormat.top;
     pt.x += editor->rcFormat.left;
 
     pt.x -= editor->horz_si.nPos;
@@ -4540,7 +4509,7 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart,
   int nOffset, nWritten = 0;
   WCHAR *pStart = buffer;
 
-  ME_RunOfsFromCharOfs(editor, nStart, &pRun, &nOffset);
+  ME_RunOfsFromCharOfs(editor, nStart, NULL, &pRun, &nOffset);
 
   /* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */
   if (editor->bEmulateVersion10) bCRLF = 0;
@@ -4728,10 +4697,8 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_
   TRACE("sel_min = %d sel_max = %d\n", sel_min, sel_max);
 
   *candidate_min = *candidate_max = -1;
-  ME_RunOfsFromCharOfs(editor, sel_min, &item, &nStart);
-  if (!item) return FALSE;
+  ME_RunOfsFromCharOfs(editor, sel_min, &para, &item, &nStart);
   TRACE("nStart = %d\n", nStart);
-  para = ME_GetParagraph(item);
   if (sel_max == -1) sel_max = ME_GetTextLength(editor);
   while (item && para->member.para.nCharOfs + item->member.run.nCharOfs + nStart < sel_max)
   {
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index a412389..8af4975 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -162,7 +162,7 @@ ME_DisplayItem *ME_SplitFurther(ME_TextEditor *editor, ME_DisplayItem *run);
 void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run);
 SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx);
 void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor);
-void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppRun, int *pOfs);
+void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppPara, ME_DisplayItem **ppRun, int *pOfs);
 int ME_CharOfsFromRunOfs(ME_TextEditor *editor, ME_DisplayItem *pRun, int nOfs);
 void ME_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift);
 void ME_SetCharFormat(ME_TextEditor *editor, int nFrom, int nLen, CHARFORMAT2W *pFmt);
@@ -211,7 +211,7 @@ void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor);
 void ME_SendRequestResize(ME_TextEditor *editor, BOOL force);
 
 /* para.c */
-ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run); 
+ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run);
 void ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end);
 void ME_MakeFirstParagraph(ME_TextEditor *editor);
 ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style, ME_String *eol_str, int paraFlags);
diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c
index 1f8cc18..2092c8e 100644
--- a/dlls/riched20/run.c
+++ b/dlls/riched20/run.c
@@ -164,12 +164,12 @@ int ME_CharOfsFromRunOfs(ME_TextEditor *editor, ME_DisplayItem *pRun, int nOfs)
  * ME_CursorFromCharOfs
  *
  * Converts a character offset (relative to the start of the document) to
- * a cursor structure (which contains a run and a position relative to that 
+ * a cursor structure (which contains a run and a position relative to that
  * run).
  */
 void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor)
 {
-  ME_RunOfsFromCharOfs(editor, nCharOfs, &pCursor->pRun, &pCursor->nOffset);
+  ME_RunOfsFromCharOfs(editor, nCharOfs, NULL, &pCursor->pRun, &pCursor->nOffset);
 }
 
 /******************************************************************************
@@ -179,13 +179,14 @@ void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCurso
  * (absolute offset being an offset relative to the start of the document).
  * Kind of a "global to local" offset conversion.
  */
-void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppRun, int *pOfs)
+void ME_RunOfsFromCharOfs(ME_TextEditor *editor,
+                          int nCharOfs,
+                          ME_DisplayItem **ppPara,
+                          ME_DisplayItem **ppRun,
+                          int *pOfs)
 {
   ME_DisplayItem *item, *next_item;
 
-  assert(ppRun);
-  assert(pOfs);
-
   nCharOfs = max(nCharOfs, 0);
   nCharOfs = min(nCharOfs, ME_GetTextLength(editor));
 
@@ -197,6 +198,7 @@ void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **
   } while (next_item->member.para.nCharOfs <= nCharOfs);
   assert(item->type == diParagraph);
   nCharOfs -= item->member.para.nCharOfs;
+  if (ppPara) *ppPara = item;
 
   /* Find the run at the offset. */
   next_item = ME_FindItemFwd(item, diRun);
@@ -208,8 +210,8 @@ void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **
   assert(item->type == diRun);
   nCharOfs -= item->member.run.nCharOfs;
 
-  *ppRun = item;
-  *pOfs = nCharOfs;
+  if (ppRun) *ppRun = item;
+  if (pOfs) *pOfs = nCharOfs;
 }
 
 /******************************************************************************
@@ -878,17 +880,17 @@ void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
 
 /******************************************************************************
  * ME_GetCharFormat
- * 
+ *
  * Returns the style consisting of those attributes which are consistently set
- * in the whole character range.    
- */     
+ * in the whole character range.
+ */
 void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *pFmt)
 {
   ME_DisplayItem *run, *run_end;
   int nOffset, nOffset2;
   CHARFORMAT2W tmp;
 
-  ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset);
+  ME_RunOfsFromCharOfs(editor, nFrom, NULL, &run, &nOffset);
   if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */
   {
     if (!nOffset)
@@ -905,7 +907,7 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
   
   if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
     nTo--;
-  ME_RunOfsFromCharOfs(editor, nTo, &run_end, &nOffset2);
+  ME_RunOfsFromCharOfs(editor, nTo, NULL, &run_end, &nOffset2);
 
   ME_GetRunCharFormat(editor, run, pFmt);
 
diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c
index 5a5135e..deacaf8 100644
--- a/dlls/riched20/writer.c
+++ b/dlls/riched20/writer.c
@@ -766,13 +766,11 @@ static BOOL
 ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nChars, int dwFormat)
 {
   ME_DisplayItem *p, *pEnd, *pPara;
-  int nOffset, nEndLen; 
-  
-  ME_RunOfsFromCharOfs(editor, nStart, &p, &nOffset);
-  ME_RunOfsFromCharOfs(editor, nStart+nChars, &pEnd, &nEndLen);
-  
-  pPara = ME_GetParagraph(p);
-  
+  int nOffset, nEndLen;
+
+  ME_RunOfsFromCharOfs(editor, nStart, &pPara, &p, &nOffset);
+  ME_RunOfsFromCharOfs(editor, nStart+nChars, NULL, &pEnd, &nEndLen);
+
   if (!ME_StreamOutRTFHeader(pStream, dwFormat))
     return FALSE;
 
@@ -922,7 +920,7 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
   int nBufLen = 0;
   BOOL success = TRUE;
 
-  ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart);
+  ME_RunOfsFromCharOfs(editor, nStart, NULL, &item, &nStart);
 
   if (!item)
     return FALSE;


More information about the wine-patches mailing list