[PATCH 5/5] riched20: Implement TxDraw().
Huw Davies
huw at codeweavers.com
Tue Mar 23 08:04:07 CDT 2021
Signed-off-by: Huw Davies <huw at 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 )
{
--
2.23.0
More information about the wine-devel
mailing list