Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/riched20/editor.h | 3 +- dlls/riched20/paint.c | 19 +++++---- dlls/riched20/tests/txtsrv.c | 55 ++++++++++++++++++------- dlls/riched20/txthost.c | 2 +- dlls/riched20/txtsrv.c | 79 ++++++++++++++++++++++++------------ dlls/riched20/wrap.c | 13 ++++-- 6 files changed, 116 insertions(+), 55 deletions(-)
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index bad48ba54da..075fe534783 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -202,6 +202,7 @@ void ME_DestroyContext(ME_Context *c) DECLSPEC_HIDDEN; BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) DECLSPEC_HIDDEN; void para_range_invalidate( ME_TextEditor *editor, ME_Paragraph *start_para, ME_Paragraph *last_para ) DECLSPEC_HIDDEN; void ME_SendRequestResize(ME_TextEditor *editor, BOOL force) DECLSPEC_HIDDEN; +BOOL wrap_marked_paras_dc( ME_TextEditor *editor, HDC hdc ) DECLSPEC_HIDDEN;
/* para.c */ void editor_get_selection_paras(ME_TextEditor *editor, ME_Paragraph **para, ME_Paragraph **para_end ) DECLSPEC_HIDDEN; @@ -237,7 +238,7 @@ static inline ME_DisplayItem *para_get_di(ME_Paragraph *para) }
/* paint.c */ -void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN; +void editor_draw( ME_TextEditor *editor, HDC hDC, const RECT *update ) DECLSPEC_HIDDEN; void ME_Repaint(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_RewrapRepaint(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index e6eef7a0acd..4be76e441d0 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -25,17 +25,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
static void draw_paragraph( ME_Context *c, ME_Paragraph *para );
-void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) +void editor_draw( ME_TextEditor *editor, HDC hDC, const RECT *update ) { ME_Paragraph *para; ME_Context c; ME_Cell *cell; int ys, ye; HRGN oldRgn; - RECT rc; + RECT rc, client; HBRUSH brush = CreateSolidBrush( ITextHost_TxGetSysColor( editor->texthost, COLOR_WINDOW ) );
ME_InitContext( &c, editor, hDC ); + if (!update) + { + client = c.rcView; + client.left -= editor->selofs; + update = &client; + }
oldRgn = CreateRectRgn(0, 0, 0, 0); if (!GetClipRgn(hDC, oldRgn)) @@ -43,8 +49,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DeleteObject(oldRgn); oldRgn = NULL; } - IntersectClipRect(hDC, rcUpdate->left, rcUpdate->top, - rcUpdate->right, rcUpdate->bottom); + IntersectClipRect( hDC, update->left, update->top, update->right, update->bottom );
brush = SelectObject( hDC, brush ); SetBkMode(hDC, TRANSPARENT); @@ -69,7 +74,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) }
/* Draw the paragraph if any of the paragraph is in the update region. */ - if (ys < rcUpdate->bottom && ye > rcUpdate->top) + if (ys < update->bottom && ye > update->top) draw_paragraph( &c, para ); para = para_next( para ); } @@ -79,7 +84,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) rc.left = c.rcView.left; rc.bottom = c.rcView.bottom; rc.right = c.rcView.right; - if (IntersectRect( &rc, &rc, rcUpdate )) + if (IntersectRect( &rc, &rc, update )) PatBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); } if (editor->selofs) @@ -88,7 +93,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) rc.top = c.rcView.top; rc.right = c.rcView.left; rc.bottom = c.rcView.bottom; - if (IntersectRect( &rc, &rc, rcUpdate )) + if (IntersectRect( &rc, &rc, update )) PatBlt( hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY ); } if (editor->nTotalLength != editor->nLastTotalLength || editor->nTotalWidth != editor->nLastTotalWidth) diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c index 20eb318d464..7ca6074587d 100644 --- a/dlls/riched20/tests/txtsrv.c +++ b/dlls/riched20/tests/txtsrv.c @@ -764,26 +764,51 @@ static void test_TxDraw(void) { ITextServices *txtserv; ITextHost *host; - HDC tmphdc = GetDC(NULL); - DWORD dwAspect = DVASPECT_CONTENT; - HDC hicTargetDev = NULL; /* Means "default" device */ - DVTARGETDEVICE *ptd = NULL; - void *pvAspect = NULL; - HRESULT result; - RECTL client = {0,0,100,100}; - + HRESULT hr; + RECT client = {0, 0, 100, 100}; + ITextHostTestImpl *host_impl; + HDC hdc;
if (!init_texthost(&txtserv, &host)) return;
- todo_wine { - result = ITextServices_TxDraw(txtserv, dwAspect, 0, pvAspect, ptd, - tmphdc, hicTargetDev, &client, NULL, - NULL, NULL, 0, 0); - ok(result == S_OK, "TxDraw failed (result = %x)\n", result); - } - + host_impl = impl_from_ITextHost( host ); + host_impl->window = CreateWindowExA( 0, "static", NULL, WS_POPUP | WS_VISIBLE, + 0, 0, 400, 400, 0, 0, 0, NULL ); + host_impl->client_rect = client; + host_impl->props = TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP; + ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_CLIENTRECTCHANGE | TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP, + host_impl->props ); + hdc = GetDC( host_impl->window ); + + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, NULL, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, (RECTL *)&client, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == E_FAIL, "got %08x\n", hr ); + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, (RECTL *)&client, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, (RECTL *)&client, NULL, + NULL, NULL, 0, TXTVIEW_ACTIVE ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = ITextServices_OnTxInPlaceActivate( txtserv, &client ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = ITextServices_OnTxInPlaceDeactivate( txtserv ); + + ReleaseDC( host_impl->window, hdc ); ITextServices_Release(txtserv); + DestroyWindow( host_impl->window ); ITextHost_Release(host); }
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c index cda9b35b199..ab13879c664 100644 --- a/dlls/riched20/txthost.c +++ b/dlls/riched20/txthost.c @@ -1222,7 +1222,7 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam, ps.rcPaint.right = editor->rcFormat.right; }
- ME_PaintContent( editor, hdc, &ps.rcPaint ); + editor_draw( editor, hdc, &ps.rcPaint ); DeleteObject( SelectObject( hdc, brush ) ); EndPaint( editor->hWnd, &ps ); return 0; diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c index bab52269db6..6ef7b7ef029 100644 --- a/dlls/riched20/txtsrv.c +++ b/dlls/riched20/txtsrv.c @@ -142,17 +142,62 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxSendMessage( ITextServices *iface return hr; }
+static HRESULT update_client_rect( struct text_services *services, const RECT *client ) +{ + RECT rect; + HRESULT hr; + + if (!client) + { + if (!services->editor->in_place_active) return E_INVALIDARG; + hr = ITextHost_TxGetClientRect( services->host, &rect ); + if (FAILED( hr )) return hr; + } + else rect = *client; + + rect.left += services->editor->selofs; + + if (EqualRect( &rect, &services->editor->rcFormat )) return S_FALSE; + services->editor->rcFormat = rect; + return S_OK; +} + DEFINE_THISCALL_WRAPPER(fnTextSrv_TxDraw,52) -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxDraw(ITextServices *iface, DWORD dwDrawAspect, LONG lindex, - void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcDraw, HDC hdcTargetDev, - LPCRECTL lprcBounds, LPCRECTL lprcWBounds, LPRECT lprcUpdate, - BOOL (CALLBACK * pfnContinue)(DWORD), DWORD dwContinue, - LONG lViewId) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxDraw( ITextServices *iface, DWORD aspect, LONG index, void *aspect_info, + DVTARGETDEVICE *td, HDC draw, HDC target, + const RECTL *bounds, const RECTL *mf_bounds, RECT *update, + BOOL (CALLBACK *continue_fn)(DWORD), DWORD continue_param, + LONG view_id ) { struct text_services *services = impl_from_ITextServices( iface ); + HRESULT hr; + HDC dc = draw; + BOOL rewrap = FALSE;
- FIXME( "%p: STUB\n", services ); - return E_NOTIMPL; + TRACE( "%p: aspect %d, %d, %p, %p, draw %p, target %p, bounds %s, mf_bounds %s, update %s, %p, %d, view %d\n", + services, aspect, index, aspect_info, td, draw, target, wine_dbgstr_rect( (RECT *)bounds ), + wine_dbgstr_rect( (RECT *)mf_bounds ), wine_dbgstr_rect( update ), continue_fn, continue_param, view_id ); + + if (aspect != DVASPECT_CONTENT || aspect_info || td || target || mf_bounds || continue_fn ) + FIXME( "Many arguments are ignored\n" ); + + hr = update_client_rect( services, (RECT *)bounds ); + if (FAILED( hr )) return hr; + if (hr == S_OK) rewrap = TRUE; + + if (!dc && services->editor->in_place_active) + dc = ITextHost_TxGetDC( services->host ); + if (!dc) return E_FAIL; + + if (rewrap) + { + editor_mark_rewrap_all( services->editor ); + wrap_marked_paras_dc( services->editor, dc ); + } + editor_draw( services->editor, dc, update ); + + if (!draw) ITextHost_TxReleaseDC( services->host, dc ); + return S_OK; }
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetHScroll,24) @@ -213,26 +258,6 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxQueryHitPoint(ITextServices *ifac return E_NOTIMPL; }
-static HRESULT update_client_rect( struct text_services *services, const RECT *client ) -{ - RECT rect; - HRESULT hr = S_OK; - - if (!client) - { - if (!services->editor->in_place_active) return E_INVALIDARG; - hr = ITextHost_TxGetClientRect( services->host, &rect ); - client = ▭ - } - - if (SUCCEEDED( hr )) - { - services->editor->rcFormat = *client; - services->editor->rcFormat.left += services->editor->selofs; - } - return hr; -} - DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInPlaceActivate,8) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxInPlaceActivate( ITextServices *iface, const RECT *client ) { diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 3d7e030fe50..468b267ceae 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -1020,18 +1020,16 @@ static void adjust_para_y( ME_Paragraph *para, ME_Context *c, struct repaint_ran } }
-BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) +BOOL wrap_marked_paras_dc( ME_TextEditor *editor, HDC hdc ) { ME_Paragraph *para, *next; struct wine_rb_entry *entry, *next_entry = NULL; ME_Context c; int totalWidth = editor->nTotalWidth, prev_width; struct repaint_range repaint = { NULL, NULL }; - HDC hdc;
if (!editor->marked_paras.root) return FALSE;
- hdc = ITextHost_TxGetDC( editor->texthost ); ME_InitContext( &c, editor, hdc );
entry = wine_rb_head( editor->marked_paras.root ); @@ -1087,13 +1085,20 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) editor->nTotalWidth = totalWidth;
ME_DestroyContext(&c); - ITextHost_TxReleaseDC( editor->texthost, hdc );
if (repaint.start || editor->nTotalLength < editor->nLastTotalLength) para_range_invalidate( editor, repaint.start, repaint.end); return !!repaint.start; }
+BOOL ME_WrapMarkedParagraphs( ME_TextEditor *editor ) +{ + HDC hdc = ITextHost_TxGetDC( editor->texthost ); + BOOL ret = wrap_marked_paras_dc( editor, hdc ); + ITextHost_TxReleaseDC( editor->texthost, hdc ); + return ret; +} + void para_range_invalidate( ME_TextEditor *editor, ME_Paragraph *start_para, ME_Paragraph *last_para ) {