[PATCH] richedit: Add support for encoding number of CR and LF contained within a line break. * Added fields to ME_Run for storing number of CR and LF characters contained * ME_SplitParagraph now contains two additional parameters for specifying the number of CR and LF characters. These values are used to calculate the length of the end run, and also stored in the new end-of-paragraph run. * ME_JoinParagraphs now stores the encoded amount of CR and LF in the end-of-paragraph run about to be removed, so that it can be restored in undo operation. * ME_PlayUndoItem honors CR and LF amounts when re-splitting a paragraph * ME_InsertTextFromCursor uses the additional parameters for ME_SplitParagraph to fill in the standard values according to 1.0 emulation mode. This is a stopgap measure to be removed in a future patch. * Added trace support for debugging end-of-paragraph runs.

Alex Villacís Lasso alex at karlalex.palosanto.com
Sat Apr 26 13:29:53 CDT 2008


---
 dlls/riched20/caret.c   |   10 +++++++++-
 dlls/riched20/editor.h  |    2 +-
 dlls/riched20/editstr.h |    2 ++
 dlls/riched20/list.c    |    2 ++
 dlls/riched20/para.c    |   27 ++++++++++++++++++---------
 dlls/riched20/undo.c    |    6 +++++-
 6 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index 7d50460..2e65426 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -531,7 +531,15 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
       }
       tmp_style = ME_GetInsertStyle(editor, nCursor);
       /* ME_SplitParagraph increases style refcount */
-      tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style);
+
+      /* TODO: move here and fix logic for pos updating according to emulation,
+         so that number of CR and LF encoded are a result of such logic, instead
+         of hardcoded as below. 
+       */
+      if (editor->bEmulateVersion10) 
+        tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, 1, 1);
+      else
+        tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, 1, 0);
       p->pRun = ME_FindItemFwd(tp, diRun);
       end_run = ME_FindItemBack(tp, diRun);
       ME_ReleaseStyle(end_run->member.run.style);
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 0c0d324..992ce7f 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -220,7 +220,7 @@ int  ME_twips2pointsY(ME_Context *c, int y);
 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_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style, int numCR, int numLF);
 ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp);
 void ME_DumpParaStyle(ME_Paragraph *s);
 void ME_DumpParaStyleToBuf(const PARAFORMAT2 *pFmt, char buf[2048]);
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 964f356..aedaefa 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -148,6 +148,7 @@ typedef struct tagME_Run
   POINT pt; /* relative to para's position */
   struct tagME_TableCell *pCell; /* for MERF_CELL: points to respective cell in ME_Paragraph */
   REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */
+  int nCR; int nLF;  /* for MERF_ENDPARA: number of \r and \n characters encoded by run */
 } ME_Run;
 
 typedef struct tagME_Document {
@@ -217,6 +218,7 @@ typedef struct tagME_UndoItem
 {
   ME_DisplayItem di;
   int nStart, nLen;
+  int nCR, nLF;      /* used by diUndoSplitParagraph */
 } ME_UndoItem;
 
 typedef struct tagME_TextBuffer
diff --git a/dlls/riched20/list.c b/dlls/riched20/list.c
index 14f9b17..951e7f3 100644
--- a/dlls/riched20/list.c
+++ b/dlls/riched20/list.c
@@ -200,6 +200,8 @@ void ME_DumpDocument(ME_TextBuffer *buffer)
       case diRun:
         TRACE(" - Run(\"%s\", %d)\n", debugstr_w(pItem->member.run.strText->szData), 
           pItem->member.run.nCharOfs);
+        if (pItem->member.run.nFlags & MERF_ENDPARA)
+          TRACE(" - Paragraph end: %d CR, %d LF\n", pItem->member.run.nCR, pItem->member.run.nLF);
         break;
       case diTextEnd:
         TRACE("End(ofs=%d)\n", pItem->member.para.nCharOfs);
diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c
index b2f8e6c..e25c2e6 100644
--- a/dlls/riched20/para.c
+++ b/dlls/riched20/para.c
@@ -110,7 +110,7 @@ void ME_MarkForPainting(ME_TextEditor *editor, ME_DisplayItem *first, const ME_D
 }
 
 /* split paragraph at the beginning of the run */
-ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME_Style *style)
+ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME_Style *style, int numCR, int numLF)
 {
   ME_DisplayItem *next_para = NULL;
   ME_DisplayItem *run_para = NULL;
@@ -119,10 +119,12 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME
   ME_UndoItem *undo = NULL;
   int ofs;
   ME_DisplayItem *pp;
-  int end_len = (editor->bEmulateVersion10 ? 2 : 1);
+  int end_len = numCR + numLF;
   
   assert(run->type == diRun);  
-
+  
+  end_run->member.run.nCR = numCR;
+  end_run->member.run.nLF = numLF;
   run_para = ME_GetParagraph(run);
   assert(run_para->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
 
@@ -204,7 +206,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
   ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp;
   int i, shift;
   ME_UndoItem *undo = NULL;
-  int end_len = (editor->bEmulateVersion10 ? 2 : 1);
+  int end_len;
 
   assert(tp->type == diParagraph);
   assert(tp->member.para.next_para);
@@ -212,6 +214,15 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
   
   pNext = tp->member.para.next_para;
   
+  /* Need to locate end-of-paragraph run here, in order to know end_len */
+  pRun = ME_FindItemBack(pNext, diRunOrParagraph);
+  
+  assert(pRun);
+  assert(pRun->type == diRun);
+  assert(pRun->member.run.nFlags & MERF_ENDPARA);
+
+  end_len = pRun->member.run.nCR + pRun->member.run.nLF;
+
   {
     /* null char format operation to store the original char format for the ENDPARA run */
     CHARFORMAT2W fmt;
@@ -222,18 +233,16 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
   if (undo)
   {
     undo->nStart = pNext->member.para.nCharOfs - end_len;
+    undo->nCR = pRun->member.run.nCR;
+    undo->nLF = pRun->member.run.nLF;
     assert(pNext->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
     *undo->di.member.para.pFmt = *pNext->member.para.pFmt;
   }
   
   shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len;
   
-  pRun = ME_FindItemBack(pNext, diRunOrParagraph);
   pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph);
-  
-  assert(pRun);
-  assert(pRun->type == diRun);
-  assert(pRun->member.run.nFlags & MERF_ENDPARA);
+
   assert(pFirstRunInNext->type == diRun);
   
   /* if some cursor points at end of paragraph, make it point to the first
diff --git a/dlls/riched20/undo.c b/dlls/riched20/undo.c
index 43f8810..0bb5030 100644
--- a/dlls/riched20/undo.c
+++ b/dlls/riched20/undo.c
@@ -56,6 +56,7 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
   else
   {
     ME_DisplayItem *pItem = (ME_DisplayItem *)ALLOC_OBJ(ME_UndoItem);
+    ((ME_UndoItem *)pItem)->nCR = ((ME_UndoItem *)pItem)->nLF = -1;
     switch(type)
     {
     case diUndoEndTransaction:
@@ -225,7 +226,10 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
     ME_CursorFromCharOfs(editor, pUItem->nStart, &tmp);
     if (tmp.nOffset)
       tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
-    new_para = ME_SplitParagraph(editor, tmp.pRun, tmp.pRun->member.run.style);
+    assert(pUItem->nCR >= 0);
+    assert(pUItem->nLF >= 0);
+    new_para = ME_SplitParagraph(editor, tmp.pRun, tmp.pRun->member.run.style, 
+      pUItem->nCR, pUItem->nLF);
     assert(pItem->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
     *new_para->member.para.pFmt = *pItem->member.para.pFmt;
     break;
-- 
1.5.4.1


--------------080902090505090801090902--



More information about the wine-patches mailing list