Commit 6818762a authored by Phil Krylov's avatar Phil Krylov Committed by Alexandre Julliard

riched20: Reduced screen flicker by using proper update region invalidation.

parent 1406010d
......@@ -625,7 +625,6 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
editor->nEventMask = nEventMask;
if (editor->bRedraw)
{
InvalidateRect(editor->hWnd, NULL, TRUE);
ME_UpdateRepaint(editor);
}
if (!(format & SFF_SELECTION)) {
......@@ -800,6 +799,62 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, CHARRANGE *chrg, WCHAR *text, CH
}
static BOOL
ME_KeyDown(ME_TextEditor *editor, WORD nKey)
{
BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
BOOL shift_is_down = GetKeyState(VK_SHIFT) & 0x8000;
switch (nKey)
{
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN:
case VK_HOME:
case VK_END:
case VK_PRIOR:
case VK_NEXT:
ME_ArrowKey(editor, nKey, shift_is_down);
return TRUE;
case VK_BACK:
case VK_DELETE:
/* FIXME backspace and delete aren't the same, they act different wrt paragraph style of the merged paragraph */
if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY)
return FALSE;
if (ME_IsSelection(editor))
ME_DeleteSelection(editor);
else if (nKey == VK_DELETE || ME_ArrowKey(editor, VK_LEFT, FALSE))
ME_DeleteTextAtCursor(editor, 1, 1);
else
return TRUE;
ME_QueueInvalidateFromCursor(editor, 1);
ME_UpdateRepaint(editor);
ME_SendRequestResize(editor, FALSE);
return TRUE;
default:
if (ctrl_is_down)
{
if (nKey == 'W')
{
CHARFORMAT2W chf;
char buf[2048];
ME_GetSelectionCharFormat(editor, &chf);
ME_DumpStyleToBuf(&chf, buf);
MessageBoxA(NULL, buf, "Style dump", MB_OK);
}
if (nKey == 'Q')
{
ME_CheckCharOffsets(editor);
}
}
}
return FALSE;
}
ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ME_TextEditor *ed = ALLOC_OBJ(ME_TextEditor);
HDC hDC;
......@@ -832,6 +887,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ed->nScrollPosY = 0;
ed->nZoomNumerator = ed->nZoomDenominator = 0;
ed->bRedraw = TRUE;
ed->nInvalidOfs = -1;
GetClientRect(hWnd, &ed->rcFormat);
for (i=0; i<HFONT_CACHE_SIZE; i++)
{
......@@ -1820,29 +1876,8 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
TRACE("editor wnd command = %d\n", LOWORD(wParam));
return 0;
case WM_KEYDOWN:
if (ME_ArrowKey(editor, LOWORD(wParam), GetKeyState(VK_CONTROL)<0)) {
ME_CommitUndo(editor);
ME_EnsureVisible(editor, editor->pCursors[0].pRun);
HideCaret(hWnd);
ME_MoveCaret(editor);
ShowCaret(hWnd);
if (ME_KeyDown(editor, LOWORD(wParam)))
return 0;
}
if (GetKeyState(VK_CONTROL)<0)
{
if (LOWORD(wParam)=='W')
{
CHARFORMAT2W chf;
char buf[2048];
ME_GetSelectionCharFormat(editor, &chf);
ME_DumpStyleToBuf(&chf, buf);
MessageBoxA(NULL, buf, "Style dump", MB_OK);
}
if (LOWORD(wParam)=='Q')
{
ME_CheckCharOffsets(editor);
}
}
goto do_default;
case WM_CHAR:
{
......
......@@ -150,12 +150,14 @@ void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars);
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
const WCHAR *str, int len, ME_Style *style);
void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W *pFmt);
BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, int nCtrl);
BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend);
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC);
void ME_DestroyContext(ME_Context *c);
ME_Style *GetInsertStyle(ME_TextEditor *editor, int nCursor);
void ME_MustBeWrapped(ME_Context *c, ME_DisplayItem *para);
void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
int *x, int *y, int *height);
int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor);
void ME_GetSelection(ME_TextEditor *editor, int *from, int *to);
int ME_CountParagraphsBetween(ME_TextEditor *editor, int from, int to);
......@@ -203,6 +205,9 @@ int ME_GetYScrollPos(ME_TextEditor *editor);
void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun);
COLORREF ME_GetBackColor(ME_TextEditor *editor);
void ME_Scroll(ME_TextEditor *editor, int cx, int cy);
void ME_InvalidateFromOfs(ME_TextEditor *editor, int nCharOfs);
void ME_InvalidateSelection(ME_TextEditor *editor);
void ME_QueueInvalidateFromCursor(ME_TextEditor *editor, int nCursor);
BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator);
/* richole.c */
......
......@@ -285,6 +285,7 @@ typedef struct tagME_TextEditor
int nZoomNumerator, nZoomDenominator;
RECT rcFormat;
BOOL bRedraw;
int nInvalidOfs;
} ME_TextEditor;
typedef struct tagME_Context
......
......@@ -143,7 +143,6 @@ void ME_Repaint(ME_TextEditor *editor)
ME_Cursor *pCursor = &editor->pCursors[0];
ME_DisplayItem *pRun = NULL;
int nOffset = -1;
HDC hDC;
int nCharOfs = ME_CharOfsFromRunOfs(editor, pCursor->pRun, pCursor->nOffset);
ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
......@@ -155,11 +154,6 @@ void ME_Repaint(ME_TextEditor *editor)
}
if (editor->bRedraw)
{
hDC = GetDC(editor->hWnd);
ME_HideCaret(editor);
ME_PaintContent(editor, hDC, TRUE, NULL);
ReleaseDC(editor->hWnd, hDC);
ME_ShowCaret(editor);
ME_EnsureVisible(editor, pCursor->pRun);
}
}
......@@ -516,7 +510,64 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
}
}
}
void
ME_InvalidateFromOfs(ME_TextEditor *editor, int nCharOfs)
{
RECT rc;
int x, y, height;
ME_Cursor tmp;
ME_RunOfsFromCharOfs(editor, nCharOfs, &tmp.pRun, &tmp.nOffset);
ME_GetCursorCoordinates(editor, &tmp, &x, &y, &height);
rc.left = 0;
rc.top = y;
rc.bottom = y + height;
rc.right = editor->rcFormat.right;
InvalidateRect(editor->hWnd, &rc, FALSE);
}
void
ME_InvalidateSelection(ME_TextEditor *editor)
{
if (ME_IsSelection(editor) || editor->nLastSelStart != editor->nLastSelEnd)
{
int x, y, height;
int x2, y2, height2;
int last_x, last_y, last_height;
int last_x2, last_y2, last_height2;
RECT rc;
ME_Cursor tmp;
ME_GetCursorCoordinates(editor, &editor->pCursors[1], &x, &y, &height);
ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x2, &y2, &height2);
ME_RunOfsFromCharOfs(editor, editor->nLastSelStart, &tmp.pRun, &tmp.nOffset);
ME_GetCursorCoordinates(editor, &tmp, &last_x, &last_y, &last_height);
ME_RunOfsFromCharOfs(editor, editor->nLastSelEnd, &tmp.pRun, &tmp.nOffset);
ME_GetCursorCoordinates(editor, &tmp, &last_x2, &last_y2, &last_height2);
{
rc.left = 0;
rc.top = min(min(y, last_y), min(y2, last_y2));
rc.right = editor->rcFormat.right;
rc.bottom = max(max(y + height, last_y + last_height),
max(y2 + height2, last_y2 + last_height2));
InvalidateRect(editor->hWnd, &rc, FALSE);
}
}
ME_GetSelection(editor, &editor->nLastSelStart, &editor->nLastSelEnd);
}
void
ME_QueueInvalidateFromCursor(ME_TextEditor *editor, int nCursor)
{
editor->nInvalidOfs = ME_GetCursorOfs(editor, nCursor);
}
BOOL
ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator)
......
......@@ -380,15 +380,17 @@ void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
ME_DisplayItem *p;
ME_DisplayItem *p, *pRow;
/* remove all items that will be reinserted by paragraph wrapper anyway */
tp->member.para.nRows = 0;
for (p = tp->next; p!=tp->member.para.next_para; p = p->next) {
switch(p->type) {
case diStartRow:
pRow = p;
p = p->prev;
ME_Remove(p->next);
ME_Remove(pRow);
ME_DestroyDisplayItem(pRow);
break;
default:
break;
......@@ -422,6 +424,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
ME_DisplayItem *item;
ME_Context c;
BOOL bModified = FALSE;
int yStart = -1, yEnd = -1;
ME_InitContext(&c, editor, hDC);
c.pt.x = 0;
......@@ -439,11 +442,17 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
ME_WrapTextParagraph(&c, item);
if (bRedraw)
{
item->member.para.nFlags |= MEPF_REPAINT;
if (yStart == -1)
yStart = c.pt.y;
}
bModified = bModified | bRedraw;
c.pt.y += item->member.para.nHeight;
if (bRedraw)
yEnd = c.pt.y;
item = item->member.para.next_para;
}
editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
......@@ -453,6 +462,32 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
ME_DestroyContext(&c);
ReleaseDC(hWnd, hDC);
if (editor->bRedraw)
{
RECT rc = c.rcView;
/* Invalidate rewrapped rows */
if (yStart != -1)
{
yStart -= ME_GetYScrollPos(editor);
yEnd -= ME_GetYScrollPos(editor);
if ((yStart >= 0 && yStart < c.rcView.bottom - c.rcView.top)
|| (yEnd >= 0 && yEnd < c.rcView.bottom - c.rcView.top))
{
rc.top = yStart;
rc.bottom = yEnd;
InvalidateRect(editor->hWnd, &rc, TRUE);
}
}
/* Invalidate cursor row */
if (editor->nInvalidOfs != -1)
{
ME_InvalidateFromOfs(editor, editor->nInvalidOfs);
editor->nInvalidOfs = -1;
}
}
return bModified;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment