From 297716e01ca8c58f2ed400da1437b02fb420448a Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Thu, 18 Dec 2008 01:56:49 -0500 Subject: [PATCH] richedit: Made sure text is offset by formatting rectangle. The formatting rectangle is set with EM_SETRECT, and retrieved with EM_GETRECT, so it corresponds to rcFormat in the code. This defines the area that the richedit control should draw the text so that it is offset by the top-left corner of the formatting rectangle, and clipped so that it doesn't draw past the bottom or right hand side. Thus this is important for implementing windowless richedit controls to not interfere with the rest of the window. --- dlls/riched20/caret.c | 17 ++--- dlls/riched20/editor.c | 135 +++++++++++++++++++++++++++++------ dlls/riched20/editstr.h | 4 +- dlls/riched20/paint.c | 107 +++++++++++++++------------ dlls/riched20/run.c | 2 +- dlls/riched20/tests/editor.c | 33 ++++----- dlls/riched20/wrap.c | 24 ++++--- 7 files changed, 213 insertions(+), 109 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 6cb3cbbd781..ab44dac12ff 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -214,8 +214,9 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, } *height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent; - *x = run->member.run.pt.x + sz.cx; - *y = para->member.para.pt.y + row->member.row.nBaseline + run->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor); + *x = c.rcView.left + run->member.run.pt.x + sz.cx; + *y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline + + run->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor); ME_DestroyContext(&c, editor->hWnd); return; } @@ -236,10 +237,7 @@ ME_MoveCaret(ME_TextEditor *editor) ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); if(editor->bHaveFocus && !ME_IsSelection(editor)) { - RECT rect; - - GetClientRect(editor->hWnd, &rect); - x = min(x, rect.right-2); + x = min(x, editor->rcFormat.right-1); CreateCaret(editor->hWnd, NULL, 0, height); SetCaretPos(x, y); } @@ -922,6 +920,9 @@ static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y, int rx = 0; BOOL isExact = TRUE; + x -= editor->rcFormat.left; + y -= editor->rcFormat.top; + if (is_eol) *is_eol = 0; @@ -1109,13 +1110,13 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum) ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd); - if (x >= editor->selofs || is_shift) + if (x >= editor->rcFormat.left || is_shift) { if (clickNum > 1) { editor->pCursors[1] = editor->pCursors[0]; if (is_shift) { - if (x >= editor->selofs) + if (x >= editor->rcFormat.left) ME_SelectByType(editor, stWord); else ME_SelectByType(editor, stParagraph); diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 4d29146fba2..a9994bc9820 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2492,9 +2492,26 @@ static BOOL ME_SetCursor(ME_TextEditor *editor) } ScreenToClient(editor->hWnd, &pt); - if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_SELECTIONBAR) && - (pt.x < editor->selofs || - (editor->nSelectionType == stLine && GetCapture() == editor->hWnd))) + if (editor->nSelectionType == stLine && GetCapture() == editor->hWnd) { + SetCursor(hLeft); + return TRUE; + } + if (!editor->bEmulateVersion10 /* v4.1 */ && + pt.y < editor->rcFormat.top && + pt.x < editor->rcFormat.left) + { + SetCursor(hLeft); + return TRUE; + } + if (pt.y < editor->rcFormat.top || pt.y > editor->rcFormat.bottom) + { + if (editor->bEmulateVersion10) /* v1.0 - 3.0 */ + SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_ARROW)); + else /* v4.1 */ + SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_IBEAM)); + return TRUE; + } + if (pt.x < editor->rcFormat.left) { SetCursor(hLeft); return TRUE; @@ -2530,6 +2547,16 @@ static BOOL ME_SetCursor(ME_TextEditor *editor) return TRUE; } +static void ME_SetDefaultFormatRect(ME_TextEditor *editor) +{ + DWORD exstyle = GetWindowLongW(editor->hWnd, GWL_EXSTYLE); + + GetClientRect(editor->hWnd, &editor->rcFormat); + editor->rcFormat.top += (exstyle & WS_EX_CLIENTEDGE ? 1 : 0); + editor->rcFormat.left += 1 + editor->selofs; + editor->rcFormat.right -= 1; +} + static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y) { CHARRANGE selrange; @@ -2614,6 +2641,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) { ed->selofs = SELECTIONBAR_WIDTH; else ed->selofs = 0; + ed->bDefaultFormatRect = TRUE; ed->nSelectionType = stPosition; if (GetWindowLongW(hWnd, GWL_STYLE) & ES_PASSWORD) @@ -2961,7 +2989,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, { /* these flags are equivalent to the ES_* counterparts */ DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL | - ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN; + ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR; DWORD settings = GetWindowLongW(hWnd, GWL_STYLE) & mask; return settings; @@ -2976,6 +3004,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR; DWORD raw = GetWindowLongW(hWnd, GWL_STYLE); DWORD settings = mask & raw; + DWORD oldSettings = settings; + DWORD changedSettings; switch(wParam) { @@ -2993,13 +3023,21 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, } SetWindowLongW(hWnd, GWL_STYLE, (raw & ~mask) | (settings & mask)); + changedSettings = oldSettings ^ settings; + if (settings & ECO_AUTOWORDSELECTION) FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n"); - if (settings & ECO_SELECTIONBAR) + + if (oldSettings ^ settings) { + if (settings & ECO_SELECTIONBAR) { editor->selofs = SELECTIONBAR_WIDTH; - else + editor->rcFormat.left += SELECTIONBAR_WIDTH; + } else { editor->selofs = 0; - ME_WrapMarkedParagraphs(editor); + editor->rcFormat.left -= SELECTIONBAR_WIDTH; + } + ME_WrapMarkedParagraphs(editor); + } if (settings & ECO_VERTICAL) FIXME("ECO_VERTICAL not implemented yet!\n"); @@ -3716,9 +3754,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, assert(pRun->type == diRun); pt.y = pRun->member.run.pt.y; pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset); - pt.y += ME_GetParagraph(pRun)->member.para.pt.y; - pt.x += editor->selofs; - pt.x++; /* for some reason native offsets x by one */ + pt.y += ME_GetParagraph(pRun)->member.para.pt.y + editor->rcFormat.top; + pt.x += editor->rcFormat.left; pt.y -= editor->vert_si.nPos; si.cbSize = sizeof(si); @@ -3734,7 +3771,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, { SCROLLINFO si; - GetClientRect(hWnd, &editor->rcFormat); + ME_SetDefaultFormatRect(editor); if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL) { /* Squelch the default horizontal scrollbar it would make */ ShowScrollBar(editor->hWnd, SB_HORZ, FALSE); @@ -3816,9 +3853,37 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, case WM_PAINT: { HDC hDC; + RECT rc; PAINTSTRUCT ps; hDC = BeginPaint(hWnd, &ps); + /* Erase area outside of the formatting rectangle */ + if (ps.rcPaint.top < editor->rcFormat.top) + { + rc = ps.rcPaint; + rc.bottom = editor->rcFormat.top; + FillRect(hDC, &rc, editor->hbrBackground); + ps.rcPaint.top = editor->rcFormat.top; + } + if (ps.rcPaint.bottom > editor->rcFormat.bottom) { + rc = ps.rcPaint; + rc.top = editor->rcFormat.bottom; + FillRect(hDC, &rc, editor->hbrBackground); + ps.rcPaint.bottom = editor->rcFormat.bottom; + } + if (ps.rcPaint.left < editor->rcFormat.left) { + rc = ps.rcPaint; + rc.right = editor->rcFormat.left; + FillRect(hDC, &rc, editor->hbrBackground); + ps.rcPaint.left = editor->rcFormat.left; + } + if (ps.rcPaint.right > editor->rcFormat.right) { + rc = ps.rcPaint; + rc.left = editor->rcFormat.right; + FillRect(hDC, &rc, editor->hbrBackground); + ps.rcPaint.right = editor->rcFormat.right; + } + ME_PaintContent(editor, hDC, FALSE, &ps.rcPaint); EndPaint(hWnd, &ps); } @@ -3940,6 +4005,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, case EM_GETRECT: { *((RECT *)lParam) = editor->rcFormat; + if (editor->bDefaultFormatRect) + ((RECT *)lParam)->left -= editor->selofs; return 0; } case EM_SETRECT: @@ -3947,23 +4014,36 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, { if (lParam) { + DWORD exstyle = GetWindowLongW(hWnd, GWL_EXSTYLE); + int border = (exstyle & WS_EX_CLIENTEDGE) ? 1 : 0; + RECT clientRect; RECT *rc = (RECT *)lParam; - - if (wParam) + + GetClientRect(hWnd, &clientRect); + if (wParam == 0) { - editor->rcFormat.left += rc->left; - editor->rcFormat.top += rc->top; - editor->rcFormat.right += rc->right; - editor->rcFormat.bottom += rc->bottom; - } - else - { - editor->rcFormat = *rc; + editor->rcFormat.top = max(0, rc->top - border); + editor->rcFormat.left = max(0, rc->left - border); + editor->rcFormat.bottom = min(clientRect.bottom, rc->bottom); + editor->rcFormat.right = min(clientRect.right, rc->right + border); + } else if (wParam == 1) { + /* MSDN incorrectly says a wParam value of 1 causes the + * lParam rect to be used as a relative offset, + * however, the tests show it just prevents min/max bound + * checking. */ + editor->rcFormat.top = rc->top - border; + editor->rcFormat.left = rc->left - border; + editor->rcFormat.bottom = rc->bottom; + editor->rcFormat.right = rc->right + border; + } else { + return 0; } + editor->bDefaultFormatRect = FALSE; } else { - GetClientRect(hWnd, &editor->rcFormat); + ME_SetDefaultFormatRect(editor); + editor->bDefaultFormatRect = TRUE; } if (msg != EM_SETRECTNP) ME_RewrapRepaint(editor); @@ -3976,7 +4056,16 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, return DefWindowProcW(hWnd, msg, wParam, lParam); case WM_SIZE: { - GetClientRect(hWnd, &editor->rcFormat); + RECT clientRect; + + GetClientRect(hWnd, &clientRect); + if (editor->bDefaultFormatRect) { + ME_SetDefaultFormatRect(editor); + } else { + editor->rcFormat.right += clientRect.right - editor->prevClientRect.right; + editor->rcFormat.bottom += clientRect.bottom - editor->prevClientRect.bottom; + } + editor->prevClientRect = clientRect; ME_RewrapRepaint(editor); return DefWindowProcW(hWnd, msg, wParam, lParam); } diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 248cc02be29..0c8435bdad4 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -90,7 +90,7 @@ typedef enum { diUndoPotentialEndTransaction, /* 20 - allows grouping typed chars for undo */ } ME_DIType; -#define SELECTIONBAR_WIDTH 9 +#define SELECTIONBAR_WIDTH 8 /******************************** run flags *************************/ #define MERF_STYLEFLAGS 0x0FFF @@ -350,7 +350,9 @@ typedef struct tagME_TextEditor ME_DisplayItem *pLastSelStartPara, *pLastSelEndPara; ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE]; int nZoomNumerator, nZoomDenominator; + RECT prevClientRect; RECT rcFormat; + BOOL bDefaultFormatRect; BOOL bWordWrap; int nInvalidOfs; int nTextLimit; diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index 40761db64b0..521f646402f 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -37,7 +37,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT * c.pt.y -= yoffset; while(item != editor->pBuffer->pLast) { int yTextOffset = 0; - int ye; + int ys, ye; assert(item->type == diParagraph); if (item->member.para.pCell != item->member.para.next_para->member.para.pCell) @@ -63,14 +63,20 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT * } if (!bOnlyNew || (item->member.para.nFlags & MEPF_REPAINT)) { + /* Draw the pargraph if any of the paragraph is in the update region. */ BOOL bPaint = (rcUpdate == NULL); + ys = c.pt.y; if (rcUpdate) - bPaint = c.pt.ybottom && ye>rcUpdate->top; + bPaint = ys + c.rcView.top < rcUpdate->bottom && + ye + c.rcView.top > rcUpdate->top; if (bPaint) { c.pt.y += yTextOffset; ME_DrawParagraph(&c, item); - if (!rcUpdate || (rcUpdate->top<=c.pt.y-yTextOffset && rcUpdate->bottom>=ye)) + /* Clear the repaint flag if the whole paragraph is in the + * update region. */ + if (!rcUpdate || (rcUpdate->top <= ys + c.rcView.top && + rcUpdate->bottom >= ye + c.rcView.top)) item->member.para.nFlags &= ~MEPF_REPAINT; } } @@ -103,30 +109,34 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT * } item = item->member.para.next_para; } - if (c.pt.ynTotalLength-yoffset, y2 = editor->nLastTotalLength-yoffset; if (y1left, xe = rcUpdate->right; - if (rcUpdate->top > ys) - ys = rcUpdate->top; - if (rcUpdate->bottom < ye) - ye = rcUpdate->bottom; + ys = ye; /* empty fill area */ } - if (ye>ys) { + if (rcUpdate) + { + /* Clip to update region */ + xs = max(xs, rcUpdate->left); + xe = min(xe, rcUpdate->right); + ys = max(ys, rcUpdate->top); + ye = min(ye, rcUpdate->bottom); + } + + if (xe > xs && ye > ys) + { + RECT rc; rc.left = xs; rc.top = ys; rc.right = xe; @@ -441,7 +451,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa if (runofs >= nSelFrom && runofs < nSelTo) { ME_HighlightSpace(c, x, y, wszSpace, 1, run->style, 0, 0, 1, - c->pt.y + start->member.row.pt.y, + c->rcView.top + c->pt.y + start->member.row.pt.y, start->member.row.nHeight); } return; @@ -452,8 +462,8 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa /* wszSpace is used instead of the tab character because otherwise * an unwanted symbol can be inserted instead. */ ME_DrawTextWithStyle(c, x, y, wszSpace, 1, run->style, run->nWidth, - nSelFrom-runofs,nSelTo-runofs, - c->pt.y + start->member.row.pt.y, + nSelFrom-runofs, nSelTo-runofs, + c->rcView.top + c->pt.y + start->member.row.pt.y, start->member.row.nHeight); return; } @@ -467,13 +477,17 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,ME_StrVLen(run->strText)); ME_DrawTextWithStyle(c, x, y, szMasked->szData, ME_StrVLen(szMasked), run->style, run->nWidth, - nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.pt.y, start->member.row.nHeight); + nSelFrom-runofs,nSelTo-runofs, + c->rcView.top + c->pt.y + start->member.row.pt.y, + start->member.row.nHeight); ME_DestroyString(szMasked); } else ME_DrawTextWithStyle(c, x, y, run->strText->szData, ME_StrVLen(run->strText), run->style, run->nWidth, - nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.pt.y, start->member.row.nHeight); + nSelFrom-runofs,nSelTo-runofs, + c->rcView.top + c->pt.y + start->member.row.pt.y, + start->member.row.nHeight); } } @@ -728,11 +742,11 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) int width; BOOL atTop = (para->pCell != para->prev_para->member.para.pCell); BOOL atBottom = (para->pCell != para->next_para->member.para.pCell); - int top = (atTop ? cell->pt.y : para->pt.y) - ME_GetYScrollPos(c->editor); + int top = c->rcView.top + (atTop ? cell->pt.y : para->pt.y) - ME_GetYScrollPos(c->editor); int bottom = (atBottom ? - cell->pt.y + cell->nHeight - ME_GetYScrollPos(c->editor): + c->rcView.top + cell->pt.y + cell->nHeight - ME_GetYScrollPos(c->editor): top + para->nHeight + (atTop ? cell->yTextOffset : 0)); - rc.left = cell->pt.x; + rc.left = c->rcView.left + cell->pt.x; rc.right = rc.left + cell->nWidth; if (atTop) { /* Erase gap before text if not all borders are the same height. */ @@ -798,10 +812,10 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) ME_DisplayItem *nextEndCell; nextEndCell = ME_FindItemBack(ME_GetTableRowEnd(paraAfterRow), diCell); assert(nextEndCell && !nextEndCell->member.cell.next_cell); - rc.left = nextEndCell->member.cell.pt.x; + rc.left = c->rcView.left + nextEndCell->member.cell.pt.x; /* FIXME: Native draws FROM the bottom of the table rather than * TO the bottom of the table in this case, but just doing so here - * will case the next row to erase the border. */ + * will cause the next row to erase the border. */ /* rc.top = bottom; rc.bottom = rc.top + width; @@ -860,12 +874,12 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) oldpen = SelectObject(c->hDC, pen); /* Find the start relative to the text */ - firstX = ME_FindItemFwd(paragraph, diRun)->member.run.pt.x; + firstX = c->rcView.left + ME_FindItemFwd(paragraph, diRun)->member.run.pt.x; /* Go back by the horizontal gap, which is stored in dxOffset */ firstX -= ME_twips2pointsX(c, para->pFmt->dxOffset); /* The left edge, stored in dxStartIndent affected just the first edge */ startX = firstX - ME_twips2pointsX(c, para->pFmt->dxStartIndent); - rowY = c->pt.y; + rowY = c->rcView.top + c->pt.y; if (para->pFmt->dwMask & PFM_SPACEBEFORE) rowY += ME_twips2pointsY(c, para->pFmt->dySpaceBefore); nHeight = ME_FindItemFwd(paragraph, diStartRow)->member.row.nHeight; @@ -907,13 +921,14 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) } } -void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { +void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) +{ int align = SetTextAlign(c->hDC, TA_BASELINE); ME_DisplayItem *p; ME_Run *run; ME_Paragraph *para = NULL; RECT rc, bounds; - int y = c->pt.y; + int y = c->rcView.top + c->pt.y; int height = 0, baseline = 0, no=0; BOOL visible = FALSE; @@ -928,15 +943,15 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { if (para->pCell) { ME_Cell *cell = ¶->pCell->member.cell; - rc.left = cell->pt.x; + rc.left = c->rcView.left + cell->pt.x; rc.right = rc.left + cell->nWidth; } if (para->nFlags & MEPF_ROWSTART) { ME_Cell *cell = ¶->next_para->member.para.pCell->member.cell; - rc.right = cell->pt.x; + rc.right = c->rcView.left + cell->pt.x; } else if (para->nFlags & MEPF_ROWEND) { ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell; - rc.left = cell->pt.x + cell->nWidth; + rc.left = c->rcView.left + cell->pt.x + cell->nWidth; } ME_DrawParaDecoration(c, para, y, &bounds); y += bounds.top; @@ -953,7 +968,7 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell; rc.bottom = y + cell->nHeight; } else { - rc.bottom = y+p->member.row.nHeight; + rc.bottom = y + p->member.row.nHeight; } visible = RectVisible(c->hDC, &rc); if (visible) { @@ -976,10 +991,10 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { assert(para); run = &p->member.run; if (visible && me_debug) { - rc.left = c->rcView.left+run->pt.x; - rc.right = c->rcView.left+run->pt.x+run->nWidth; - rc.top = c->pt.y+run->pt.y; - rc.bottom = c->pt.y+run->pt.y+height; + rc.left = c->rcView.left + run->pt.x; + rc.right = rc.left + run->nWidth; + rc.top = c->rcView.top + c->pt.y + run->pt.y; + rc.bottom = rc.bottom + height; TRACE("rc = (%d, %d, %d, %d)\n", rc.left, rc.top, rc.right, rc.bottom); if (run->nFlags & MERF_SKIPPED) DrawFocusRect(c->hDC, &rc); @@ -987,7 +1002,9 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { FrameRect(c->hDC, &rc, GetSysColorBrush(COLOR_GRAYTEXT)); } if (visible) - ME_DrawRun(c, run->pt.x, c->pt.y+run->pt.y+baseline, p, ¶graph->member.para); + ME_DrawRun(c, c->rcView.left + run->pt.x, + c->rcView.top + c->pt.y + run->pt.y + baseline, + p, ¶graph->member.para); if (me_debug) { /* I'm using %ls, hope wsprintfW is not going to use wrong (4-byte) WCHAR version */ @@ -995,7 +1012,7 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { WCHAR buf[2560]; POINT pt; pt.x = run->pt.x; - pt.y = c->pt.y + run->pt.y; + pt.y = c->rcView.top + c->pt.y + run->pt.y; wsprintfW(buf, wszRunDebug, no, p->member.run.nFlags, p->member.run.strText->szData); ME_DebugWrite(c->hDC, &pt, buf); } @@ -1007,8 +1024,8 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { break; y += height; rc.top = y; - rc.bottom = p->member.cell.pt.y + p->member.cell.nHeight - - ME_GetYScrollPos(c->editor); + rc.bottom = c->rcView.top + p->member.cell.pt.y + + p->member.cell.nHeight - ME_GetYScrollPos(c->editor); if (RectVisible(c->hDC, &rc)) { FillRect(c->hDC, &rc, c->editor->hbrBackground); diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index e2fde47bcd0..28239057011 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -692,7 +692,7 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run { pos += lDefaultTab - (pos % lDefaultTab); } - ppos = ME_twips2pointsX(c, pos) + c->editor->selofs; + ppos = ME_twips2pointsX(c, pos); if (ppos > startx + run->pt.x) { size.cx = ppos - startx - run->pt.x; break; diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index fbe7d48a412..d6b3ba77766 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -5854,7 +5854,7 @@ static void test_format_rect(void) expected.left += 1; expected.right -= 1; SendMessageW(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - todo_wine ok(rc.top == expected.top && rc.left == expected.left && + ok(rc.top == expected.top && rc.left == expected.left && rc.bottom == expected.bottom && rc.right == expected.right, "rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", rc.top, rc.left, rc.bottom, rc.right, @@ -5875,18 +5875,11 @@ static void test_format_rect(void) expected.bottom = min(clientRect.bottom, rc.bottom); expected.right = min(clientRect.right, rc.right); SendMessageW(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - if (n >= 0) - ok(rc.top == expected.top && rc.left == expected.left && - rc.bottom == expected.bottom && rc.right == expected.right, - "[n=%d] rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", - n, rc.top, rc.left, rc.bottom, rc.right, - expected.top, expected.left, expected.bottom, expected.right); - else - todo_wine ok(rc.top == expected.top && rc.left == expected.left && - rc.bottom == expected.bottom && rc.right == expected.right, - "[n=%d] rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", - n, rc.top, rc.left, rc.bottom, rc.right, - expected.top, expected.left, expected.bottom, expected.right); + ok(rc.top == expected.top && rc.left == expected.left && + rc.bottom == expected.bottom && rc.right == expected.right, + "[n=%d] rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", + n, rc.top, rc.left, rc.bottom, rc.right, + expected.top, expected.left, expected.bottom, expected.right); } rc = clientRect; @@ -5902,10 +5895,10 @@ static void test_format_rect(void) /* Adding the selectionbar adds the selectionbar width to the left side. */ SendMessageW(hwnd, EM_SETOPTIONS, ECOOP_OR, ECO_SELECTIONBAR); options = SendMessageW(hwnd, EM_GETOPTIONS, 0, 0); - todo_wine ok(options & ECO_SELECTIONBAR, "EM_SETOPTIONS failed to add selectionbar.\n"); + ok(options & ECO_SELECTIONBAR, "EM_SETOPTIONS failed to add selectionbar.\n"); expected.left += 8; /* selection bar width */ SendMessageW(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - todo_wine ok(rc.top == expected.top && rc.left == expected.left && + ok(rc.top == expected.top && rc.left == expected.left && rc.bottom == expected.bottom && rc.right == expected.right, "rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", rc.top, rc.left, rc.bottom, rc.right, @@ -5928,7 +5921,7 @@ static void test_format_rect(void) ok(!(options & ECO_SELECTIONBAR), "EM_SETOPTIONS failed to remove selectionbar.\n"); expected.left -= 8; /* selection bar width */ SendMessageW(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - todo_wine ok(rc.top == expected.top && rc.left == expected.left && + ok(rc.top == expected.top && rc.left == expected.left && rc.bottom == expected.bottom && rc.right == expected.right, "rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", rc.top, rc.left, rc.bottom, rc.right, @@ -5955,7 +5948,7 @@ static void test_format_rect(void) expected = rc; SendMessageW(hwnd, EM_SETRECT, 1, (LPARAM)&rc); SendMessageW(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - todo_wine ok(rc.top == expected.top && rc.left == expected.left && + ok(rc.top == expected.top && rc.left == expected.left && rc.bottom == expected.bottom && rc.right == expected.right, "rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", rc.top, rc.left, rc.bottom, rc.right, @@ -5970,7 +5963,7 @@ static void test_format_rect(void) expected = rc; SendMessageW(hwnd, EM_SETRECT, 1, (LPARAM)&rc); SendMessageW(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - todo_wine ok(rc.top == expected.top && rc.left == expected.left && + ok(rc.top == expected.top && rc.left == expected.left && rc.bottom == expected.bottom && rc.right == expected.right, "rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", rc.top, rc.left, rc.bottom, rc.right, @@ -5991,7 +5984,7 @@ static void test_format_rect(void) expected.top += 1; expected.right -= 1; SendMessageW(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - todo_wine ok(rc.top == expected.top && rc.left == expected.left && + ok(rc.top == expected.top && rc.left == expected.left && rc.bottom == expected.bottom && rc.right == expected.right, "rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", rc.top, rc.left, rc.bottom, rc.right, @@ -6008,7 +6001,7 @@ static void test_format_rect(void) expected.right += 1; SendMessageW(hwnd, EM_SETRECT, 0, (LPARAM)&rc); SendMessageW(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - todo_wine ok(rc.top == expected.top && rc.left == expected.left && + ok(rc.top == expected.top && rc.left == expected.left && rc.bottom == expected.bottom && rc.right == expected.right, "rect a(t=%d, l=%d, b=%d, r=%d) != e(t=%d, l=%d, b=%d, r=%d)\n", rc.top, rc.left, rc.bottom, rc.right, diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 3ffe09adea9..d989a2da1cd 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -78,8 +78,7 @@ static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para) wc->bWordWrap = TRUE; } else { wc->nAvailWidth = wc->context->rcView.right - wc->context->rcView.left - - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin - - wc->context->editor->selofs; + - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin; } wc->pt.x = wc->context->pt.x; if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ @@ -458,7 +457,7 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp); -static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD beginofs) { +static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { ME_DisplayItem *p; ME_WrapContext wc; int border = 0; @@ -573,7 +572,8 @@ static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) { } } -BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { +BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) +{ ME_DisplayItem *item; ME_Context c; BOOL bModified = FALSE; @@ -581,7 +581,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { int yLastPos = 0; ME_InitContext(&c, editor, GetDC(editor->hWnd)); - c.pt.x = editor->selofs; + c.pt.x = 0; editor->nHeight = 0; item = editor->pBuffer->pFirst->next; while(item != editor->pBuffer->pLast) { @@ -594,7 +594,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { bRedraw = TRUE; item->member.para.pt = c.pt; - ME_WrapTextParagraph(&c, item, editor->selofs); + ME_WrapTextParagraph(&c, item); if (bRedraw) { @@ -707,7 +707,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { c.pt.x = item->member.para.pCell->member.cell.pt.x; } else { /* Normal paragraph */ - c.pt.x = editor->selofs; + c.pt.x = 0; } c.pt.y += item->member.para.nHeight; } @@ -749,16 +749,18 @@ void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor) item = editor->pBuffer->pFirst; while(item != editor->pBuffer->pLast) { if (item->member.para.nFlags & MEPF_REPAINT) { - rc.top = item->member.para.pt.y - ofs; - rc.bottom = item->member.para.pt.y + item->member.para.nHeight - ofs; + rc.top = c.rcView.top + item->member.para.pt.y - ofs; + rc.bottom = max(c.rcView.top + item->member.para.pt.y + + item->member.para.nHeight - ofs, + c.rcView.bottom); InvalidateRect(editor->hWnd, &rc, TRUE); } item = item->member.para.next_para; } if (editor->nTotalLength < editor->nLastTotalLength) { - rc.top = editor->nTotalLength - ofs; - rc.bottom = editor->nLastTotalLength - ofs; + rc.top = c.rcView.top + editor->nTotalLength - ofs; + rc.bottom = c.rcView.top + editor->nLastTotalLength - ofs; InvalidateRect(editor->hWnd, &rc, TRUE); } ME_DestroyContext(&c, editor->hWnd);