riched20: Implement TxDraw().

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2021-03-23 13:04:07 +00:00 committed by Alexandre Julliard
parent 93b6348779
commit 02f083641e
6 changed files with 115 additions and 54 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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 = &rect;
}
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 )
{

View File

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