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.
This commit is contained in:
Krzysztof Foltman 2005-03-09 11:48:59 +00:00 committed by Alexandre Julliard
parent aa5676bd27
commit 89075fb429
9 changed files with 108 additions and 98 deletions

View File

@ -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);

View File

@ -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; i<HFONT_CACHE_SIZE; i++)
{
ed->pFontCache[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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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 (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 @@ 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);

View File

@ -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(&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)

View File

@ -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);
}

View File

@ -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);
}