RICHEDIT: rewrapping/repainting changes

Krzysztof Foltman kfoltman at portal.onet.pl
Tue Mar 8 15:13:03 CST 2005


ChangeLog:

  * the meaning of the rewrap flag got inverted (MEPF_REWRAP instead of 
MEPF_WRAPPED) for consistency
  * major code cleanups in rewrap/repaint code, leading to "smarter" 
behaviour wrt repainting selections

Krzysztof
-------------- next part --------------
Index: caret.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/caret.c,v
retrieving revision 1.2
diff -u -r1.2 caret.c
--- caret.c	8 Mar 2005 19:03:01 -0000	1.2
+++ caret.c	8 Mar 2005 20:55:36 -0000
@@ -170,7 +170,7 @@
       int i;
       int loc = c.nOffset;
       
-      ME_FindItemBack(c.pRun, diParagraph)->member.para.nFlags &= ~MEPF_WRAPPED;
+      ME_FindItemBack(c.pRun, diParagraph)->member.para.nFlags |= MEPF_REWRAP;
       
       cursor = c;
       ME_StrRelPos(run->strText, loc, &nChars);
@@ -974,3 +974,4 @@
   }
   return FALSE;
 }
+
Index: editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.c,v
retrieving revision 1.6
diff -u -r1.6 editor.c
--- editor.c	8 Mar 2005 19:03:01 -0000	1.6
+++ editor.c	8 Mar 2005 20:55:36 -0000
@@ -216,74 +216,6 @@
 int me_debug = 0;
 HANDLE me_heap = NULL;
 
-void DoWrap(ME_TextEditor *editor) {
-  HDC hDC = GetDC(editor->hWnd);
-  ME_DisplayItem *item;
-  ME_Context c;
-  HWND hWnd = editor->hWnd;
-  int yLength = editor->nTotalLength;
-  int nSelFrom, nSelTo;
-  int nMinSel, nMaxSel;
-  
-  ME_GetSelection(editor, &nSelFrom, &nSelTo);
-  
-  nMinSel = nSelFrom < editor->nOldSelFrom ? nSelFrom : editor->nOldSelFrom;
-  nMaxSel = nSelTo > editor->nOldSelTo ? nSelTo : editor->nOldSelTo;
-  
-  ME_InitContext(&c, editor, hDC);
-  c.pt.x = 0;
-  c.pt.y = 0;
-  item = editor->pBuffer->pFirst->next;
-  while(item != editor->pBuffer->pLast) {
-    int para_from, para_to;
-    BOOL bRedraw = FALSE;
-    
-    para_from = item->member.para.nCharOfs;
-    para_to = item->member.para.next_para->member.para.nCharOfs;
-    
-    if (para_from <= nMaxSel && para_to >= nMinSel && nMinSel != nMaxSel)
-      bRedraw = TRUE;
-    
-    assert(item->type == diParagraph);
-    if (!(item->member.para.nFlags & MEPF_WRAPPED)
-     || (item->member.para.nYPos != c.pt.y))
-      bRedraw = TRUE;
-    item->member.para.nYPos = c.pt.y;
-    
-    ME_WrapTextParagraph(&c, item);
-
-    if (bRedraw) {
-      item->member.para.nFlags |= MEPF_REDRAW;
-    }
-    c.pt.y = item->member.para.nYPos + item->member.para.nHeight;
-    item = item->member.para.next_para;
-  }
-  editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
-  editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;
-  editor->nTotalLength = c.pt.y-c.rcView.top;
-  
-  ME_UpdateScrollBar(editor, -1);
-  ME_EnsureVisible(editor, editor->pCursors[0].pRun);
-  
-  /* FIXME this should be marked for update too somehow, so that painting happens in ME_PaintContent */
-  if (yLength != c.pt.y-c.rcView.top) {
-    RECT rc;
-    rc.left = c.rcView.left;
-    rc.right = c.rcView.right;
-    rc.top = c.pt.y;
-    rc.bottom = c.rcView.bottom;
-    InvalidateRect(editor->hWnd, &rc, FALSE);
-    UpdateWindow(editor->hWnd);
-  }
-  
-  editor->nOldSelFrom = nSelFrom;
-  editor->nOldSelTo = nSelTo;
-  /* PatBlt(hDC, 0, c.pt.y, c.rcView.right, c.rcView.bottom, BLACKNESS);*/
-
-  ME_DestroyContext(&c);
-  ReleaseDC(hWnd, hDC);
-}
-
 ME_TextBuffer *ME_MakeText() {
   
   ME_TextBuffer *buf = ALLOC_OBJ(ME_TextBuffer);
@@ -419,6 +351,7 @@
   ed->pUndoStack = ed->pRedoStack = NULL;
   ed->nUndoMode = umAddToUndo;
   ed->nParagraphs = 1;
+  ed->nLastSelStart = ed->nLastSelEnd = 0;
   for (i=0; i<HFONT_CACHE_SIZE; i++)
   {
     ed->pFontCache[i].nRefs = 0;
@@ -771,7 +704,7 @@
   case WM_CREATE:
     ME_CommitUndo(editor);
 /*    ME_InsertTextFromCursor(editor, 0, (WCHAR *)L"x", 1, editor->pBuffer->pDefaultStyle); */
-    DoWrap(editor);
+    ME_WrapMarkedParagraphs(editor);
     ME_MoveCaret(editor);
     return 0;
   case WM_DESTROY:
@@ -882,17 +815,7 @@
   }
   case WM_SIZE:
   {
-    ME_DisplayItem *tp = editor->pBuffer->pFirst;
-    while(tp)
-    {
-      if (tp->type == diParagraph)
-      {
-        tp->member.para.nFlags &= ~MEPF_WRAPPED;
-        tp = tp->member.para.next_para;
-      }
-      else
-        tp = tp->next;
-    }
+    ME_MarkAllForWrapping(editor);
     ME_Repaint(editor);
     return DefWindowProcW(hWnd, msg, wParam, lParam);
   }
Index: editor.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.h,v
retrieving revision 1.4
diff -u -r1.4 editor.h
--- editor.h	8 Mar 2005 19:03:01 -0000	1.4
+++ editor.h	8 Mar 2005 20:55:36 -0000
@@ -163,6 +163,7 @@
 ME_DisplayItem *ME_MakeRow(int height, int baseline, int width);
 void ME_InsertRowStart(ME_WrapContext *wc, ME_DisplayItem *pEnd);
 void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp);
+void ME_WrapMarkedParagraphs(ME_TextEditor *editor);
 
 /* para.c */
 ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run); 
Index: editstr.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editstr.h,v
retrieving revision 1.2
diff -u -r1.2 editstr.h
--- editstr.h	8 Mar 2005 16:26:23 -0000	1.2
+++ editstr.h	8 Mar 2005 20:55:36 -0000
@@ -108,8 +108,8 @@
 /******************************** para flags *************************/
 
 /* this paragraph was already wrapped and hasn't changed, every change resets that flag */
-#define MEPF_WRAPPED 1
-#define MEPF_REDRAW 2
+#define MEPF_REWRAP 1
+#define MEPF_REPAINT 2
 
 /******************************** structures *************************/
 
@@ -139,6 +139,7 @@
   int nCharOfs;
   int nFlags;
   int nYPos, nHeight;
+  int nLastPaintYPos, nLastPaintHeight;
   struct tagME_DisplayItem *prev_para, *next_para, *document;
 } ME_Paragraph;
 
@@ -221,6 +222,7 @@
   ME_DisplayItem *pUndoStack, *pRedoStack;
   ME_UndoMode nUndoMode;
   int nParagraphs;
+  int nLastSelStart, nLastSelEnd;
   ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE];
 } ME_TextEditor;
 
Index: list.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/list.c,v
retrieving revision 1.1
diff -u -r1.1 list.c
--- list.c	5 Mar 2005 11:19:14 -0000	1.1
+++ list.c	8 Mar 2005 20:55:36 -0000
@@ -132,6 +132,7 @@
     item->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2);
     item->member.para.pFmt->cbSize = sizeof(PARAFORMAT2);
     item->member.para.pFmt->dwMask = 0;
+    item->member.para.nFlags = MEPF_REWRAP;
   }
     
   return item;
Index: paint.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/paint.c,v
retrieving revision 1.3
diff -u -r1.3 paint.c
--- paint.c	8 Mar 2005 16:26:23 -0000	1.3
+++ paint.c	8 Mar 2005 20:55:37 -0000
@@ -34,10 +34,10 @@
   c.pt.y=-GetScrollPos(editor->hWnd, SB_VERT);
   while(item != editor->pBuffer->pLast) {
     assert(item->type == diParagraph);
-    if (!bOnlyNew || (item->member.para.nFlags & MEPF_REDRAW))
+    if (!bOnlyNew || (item->member.para.nFlags & MEPF_REPAINT))
     {
       ME_DrawParagraph(&c, item);
-      item->member.para.nFlags &= ~MEPF_REDRAW;
+      item->member.para.nFlags &= ~MEPF_REPAINT;
     }
     c.pt.y += item->member.para.nHeight;
     item = item->member.para.next_para;
@@ -60,6 +60,51 @@
   ME_DestroyContext(&c);
 }
 
+void ME_MarkParagraphRange(ME_TextEditor *editor, ME_DisplayItem *p1,
+                           ME_DisplayItem *p2, int nFlags)
+{
+  ME_DisplayItem *p3;  
+  if (p1 == p2)
+  {
+    p1->member.para.nFlags |= nFlags;
+    return;
+  }
+  if (p1->member.para.nCharOfs > p2->member.para.nCharOfs)
+    p3 = p1, p1 = p2, p2 = p3;
+    
+  p1->member.para.nFlags |= nFlags;
+  do {
+    p1 = p1->member.para.next_para;
+    p1->member.para.nFlags |= nFlags;
+  } while (p1 != p2);
+}
+
+void ME_MarkOffsetRange(ME_TextEditor *editor, int from, int to, int nFlags)
+{
+  ME_Cursor c1, c2;
+  ME_CursorFromCharOfs(editor, from, &c1);
+  ME_CursorFromCharOfs(editor, to, &c2);
+  
+  ME_MarkParagraphRange(editor, ME_GetParagraph(c1.pRun), ME_GetParagraph(c2.pRun), nFlags);
+}
+
+void ME_MarkSelectionForRepaint(ME_TextEditor *editor)
+{
+  int from, to, from2, to2, end;
+  
+  end = ME_GetTextLength(editor);
+  ME_GetSelection(editor, &from, &to);
+  from2 = editor->nLastSelStart;
+  to2 = editor->nLastSelEnd;
+  if (from<from2) ME_MarkOffsetRange(editor, from, from2, MEPF_REPAINT);
+  if (from>from2) ME_MarkOffsetRange(editor, from2, from, MEPF_REPAINT);
+  if (to<to2) ME_MarkOffsetRange(editor, to, to2, MEPF_REPAINT);
+  if (to>to2) ME_MarkOffsetRange(editor, to2, to, MEPF_REPAINT);
+
+  editor->nLastSelStart = from;
+  editor->nLastSelEnd = to;
+}
+
 void ME_Repaint(ME_TextEditor *editor)
 {
   ME_Cursor *pCursor = &editor->pCursors[0];
@@ -71,7 +116,8 @@
   ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
   assert(pRun == pCursor->pRun);
   assert(nOffset == pCursor->nOffset);
-  DoWrap(editor);
+  ME_MarkSelectionForRepaint(editor);
+  ME_WrapMarkedParagraphs(editor);
   hDC = GetDC(editor->hWnd);
   ME_HideCaret(editor);
   ME_PaintContent(editor, hDC, TRUE);
@@ -81,7 +127,9 @@
 
 void ME_UpdateRepaint(ME_TextEditor *editor)
 {
+/*
   InvalidateRect(editor->hWnd, NULL, TRUE);
+  */
   ME_SendOldNotify(editor, EN_CHANGE);
   ME_Repaint(editor);
   ME_SendOldNotify(editor, EN_UPDATE);
Index: para.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/para.c,v
retrieving revision 1.1
diff -u -r1.1 para.c
--- para.c	5 Mar 2005 11:19:14 -0000	1.1
+++ para.c	8 Mar 2005 20:55:37 -0000
@@ -86,7 +86,7 @@
 {
   while(first != last)
   {
-    first->member.para.nFlags &= ~MEPF_WRAPPED;
+    first->member.para.nFlags |= MEPF_REWRAP;
     first = first->member.para.next_para;
   }
 }
@@ -124,7 +124,7 @@
   new_para->member.para.nCharOfs = ME_GetParagraph(run)->member.para.nCharOfs+ofs;
   new_para->member.para.nCharOfs += 1;
   
-  new_para->member.para.nFlags = 0; /* FIXME copy flags (if applicable) */
+  new_para->member.para.nFlags = MEPF_REWRAP; /* FIXME copy flags (if applicable) */
   /* FIXME initialize format style and call ME_SetParaFormat blah blah */
   CopyMemory(new_para->member.para.pFmt, run_para->member.para.pFmt, sizeof(PARAFORMAT2));
   
@@ -144,8 +144,8 @@
   ME_InsertBefore(new_para, end_run);
 
   /* force rewrap of the */
-  run_para->member.para.prev_para->member.para.nFlags &= ~MEPF_WRAPPED;
-  new_para->member.para.prev_para->member.para.nFlags &= ~MEPF_WRAPPED;
+  run_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP;
+  new_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP;
   
   /* we've added the end run, so we need to modify nCharOfs in the next paragraphs */
   ME_PropagateCharOffset(next_para, 1);
@@ -223,7 +223,7 @@
   ME_CheckCharOffsets(editor);
   
   editor->nParagraphs--;
-  tp->member.para.nFlags &= ~MEPF_WRAPPED;
+  tp->member.para.nFlags |= MEPF_REWRAP;
   return tp;
 }
 
@@ -286,7 +286,7 @@
   /* FIXME to be continued (indents, bulleting and such) */
 
   if (memcmp(&copy, para->member.para.pFmt, sizeof(PARAFORMAT2)))
-    para->member.para.nFlags &= ~MEPF_WRAPPED;
+    para->member.para.nFlags |= MEPF_REWRAP;
 }
 
 void ME_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
Index: run.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/run.c,v
retrieving revision 1.2
diff -u -r1.2 run.c
--- run.c	8 Mar 2005 16:26:23 -0000	1.2
+++ run.c	8 Mar 2005 20:55:39 -0000
@@ -265,7 +265,7 @@
       editor->pCursors[i].nOffset -= nVChar;
     }
   }
-  ME_GetParagraph(item)->member.para.nFlags &= ~MEPF_WRAPPED;
+  ME_GetParagraph(item)->member.para.nFlags |= MEPF_REWRAP;
   return item2;
 }
 
@@ -313,7 +313,7 @@
   ME_InsertBefore(tmp.pRun, pDI);
   TRACE("Shift length:%d\n", pDI->member.run.strText->nLen);
   ME_PropagateCharOffset(tmp.pRun, pDI->member.run.strText->nLen);
-  ME_GetParagraph(tmp.pRun)->member.para.nFlags &= ~MEPF_WRAPPED;
+  ME_GetParagraph(tmp.pRun)->member.para.nFlags |= MEPF_REWRAP;
   
   return pDI;
 }
@@ -526,7 +526,7 @@
     tmp2.pRun = ME_SplitRunSimple(editor, tmp2.pRun, tmp2.nOffset);
 
   para = ME_GetParagraph(tmp.pRun);
-  para->member.para.nFlags &= ~MEPF_WRAPPED;
+  para->member.para.nFlags |= MEPF_REWRAP;
     
   while(tmp.pRun != tmp2.pRun)
   {
@@ -550,7 +550,7 @@
       para = tmp.pRun;
       tmp.pRun = ME_FindItemFwd(tmp.pRun, diRun);
       if (tmp.pRun != tmp2.pRun)
-        para->member.para.nFlags &= ~MEPF_WRAPPED;
+        para->member.para.nFlags |= MEPF_REWRAP;
     }
     assert(tmp.pRun);
   }
Index: wrap.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/wrap.c,v
retrieving revision 1.2
diff -u -r1.2 wrap.c
--- wrap.c	8 Mar 2005 16:26:23 -0000	1.2
+++ wrap.c	8 Mar 2005 20:55:39 -0000
@@ -345,7 +345,7 @@
   ME_WrapContext wc;
 
   assert(tp->type == diParagraph);  
-  if (tp->member.para.nFlags & MEPF_WRAPPED) {
+  if (!(tp->member.para.nFlags & MEPF_REWRAP)) {
     return;
   }
   ME_PrepareParagraphForWrapping(c, tp);
@@ -373,7 +373,7 @@
     p = p->next;
   }
   ME_WrapEndParagraph(&wc, p);
-  tp->member.para.nFlags |= MEPF_WRAPPED;
+  tp->member.para.nFlags &= ~MEPF_REWRAP;
   tp->member.para.nHeight = wc.pt.y;
 }
 
@@ -412,3 +412,39 @@
     }
   }
 }
+
+void ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
+  HWND hWnd = editor->hWnd;
+  HDC hDC = GetDC(hWnd);
+  ME_DisplayItem *item;
+  ME_Context c;
+  
+  ME_InitContext(&c, editor, hDC);
+  c.pt.x = 0;
+  c.pt.y = 0;
+  item = editor->pBuffer->pFirst->next;
+  while(item != editor->pBuffer->pLast) {
+    BOOL bRedraw = FALSE;
+    
+    assert(item->type == diParagraph);
+    if ((item->member.para.nFlags & MEPF_REWRAP)
+     || (item->member.para.nYPos != c.pt.y))
+      bRedraw = TRUE;
+    item->member.para.nYPos = c.pt.y;
+    
+    ME_WrapTextParagraph(&c, item);
+
+    if (bRedraw)
+      item->member.para.nFlags |= MEPF_REPAINT;
+
+    c.pt.y += item->member.para.nHeight;
+    item = item->member.para.next_para;
+  }
+  editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
+  editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;
+  editor->nTotalLength = c.pt.y-c.rcView.top;
+  
+  ME_DestroyContext(&c);
+  ReleaseDC(hWnd, hDC);
+}
+


More information about the wine-patches mailing list