From 89075fb429bea37721c44a0b009cf12d19a4b922 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Wed, 9 Mar 2005 11:48:59 +0000 Subject: [PATCH] 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. --- dlls/riched20/caret.c | 2 +- dlls/riched20/editor.c | 83 ++--------------------------------------- dlls/riched20/editor.h | 1 + dlls/riched20/editstr.h | 6 ++- dlls/riched20/list.c | 1 + dlls/riched20/paint.c | 54 +++++++++++++++++++++++++-- dlls/riched20/para.c | 12 +++--- dlls/riched20/run.c | 8 ++-- dlls/riched20/wrap.c | 39 ++++++++++++++++++- 9 files changed, 108 insertions(+), 98 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 91bfcd95a00..c4007f0f8ed 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -170,7 +170,7 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, 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); diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 83c715609cf..a54f527b6d9 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -216,74 +216,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); 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 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) { ed->pUndoStack = ed->pRedoStack = NULL; ed->nUndoMode = umAddToUndo; ed->nParagraphs = 1; + ed->nLastSelStart = ed->nLastSelEnd = 0; for (i=0; ipFontCache[i].nRefs = 0; @@ -771,7 +704,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP 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 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP } 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); } diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index c843e1feae0..bb0ce4a6574 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -163,6 +163,7 @@ void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp); 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); diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index a6e2a01cee5..4f08cb9f01b 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -108,8 +108,8 @@ typedef enum { /******************************** 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 @@ typedef struct tagME_Paragraph int nCharOfs; int nFlags; int nYPos, nHeight; + int nLastPaintYPos, nLastPaintHeight; struct tagME_DisplayItem *prev_para, *next_para, *document; } ME_Paragraph; @@ -221,6 +222,7 @@ typedef struct tagME_TextEditor ME_DisplayItem *pUndoStack, *pRedoStack; ME_UndoMode nUndoMode; int nParagraphs; + int nLastSelStart, nLastSelEnd; ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE]; } ME_TextEditor; diff --git a/dlls/riched20/list.c b/dlls/riched20/list.c index 0480e28adc1..e4e1f403862 100644 --- a/dlls/riched20/list.c +++ b/dlls/riched20/list.c @@ -132,6 +132,7 @@ ME_DisplayItem *ME_MakeDI(ME_DIType type) { 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; diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index 6b1e6d1ac8a..cd2e3652371 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -34,10 +34,10 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew) { 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 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew) { 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 (fromfrom2) ME_MarkOffsetRange(editor, from2, from, MEPF_REPAINT); + if (toto2) 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 @@ void ME_Repaint(ME_TextEditor *editor) 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_Repaint(ME_TextEditor *editor) void ME_UpdateRepaint(ME_TextEditor *editor) { +/* InvalidateRect(editor->hWnd, NULL, TRUE); + */ ME_SendOldNotify(editor, EN_CHANGE); ME_Repaint(editor); ME_SendOldNotify(editor, EN_UPDATE); diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index b43713922b1..ecd8e49e58b 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -86,7 +86,7 @@ void ME_MarkForWrapping(ME_TextEditor *editor, ME_DisplayItem *first, ME_Display { 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 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME 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_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME 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_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp) ME_CheckCharOffsets(editor); editor->nParagraphs--; - tp->member.para.nFlags &= ~MEPF_WRAPPED; + tp->member.para.nFlags |= MEPF_REWRAP; return tp; } @@ -286,7 +286,7 @@ void ME_SetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 * /* FIXME to be continued (indents, bulleting and such) */ if (memcmp(©, 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) diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index cd3c0d077da..fe727eb0d60 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -265,7 +265,7 @@ ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_DisplayItem *item, i 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_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem 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 @@ void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W 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 @@ void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W 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); } diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 493b612500b..bc2420ed486 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -345,7 +345,7 @@ void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { 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 @@ void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { 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,38 @@ void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) { } } } + +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); +}