riched20: Simplify some of the drawing code using a few helpers.

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2020-10-22 12:46:50 +01:00 committed by Alexandre Julliard
parent b2c812e3a3
commit 6488613a3a
3 changed files with 52 additions and 32 deletions

View File

@ -280,6 +280,8 @@ ME_Paragraph *editor_first_para( ME_TextEditor *editor ) DECLSPEC_HIDDEN;
/* table.c */ /* table.c */
BOOL ME_IsInTable(ME_DisplayItem *pItem) DECLSPEC_HIDDEN; BOOL ME_IsInTable(ME_DisplayItem *pItem) DECLSPEC_HIDDEN;
ME_Paragraph *cell_end_para( ME_Cell *cell ) DECLSPEC_HIDDEN;
ME_Paragraph *cell_first_para( ME_Cell *cell ) DECLSPEC_HIDDEN;
ME_Cell *cell_next( ME_Cell *cell ) DECLSPEC_HIDDEN; ME_Cell *cell_next( ME_Cell *cell ) DECLSPEC_HIDDEN;
ME_Cell *cell_prev( ME_Cell *cell ) DECLSPEC_HIDDEN; ME_Cell *cell_prev( ME_Cell *cell ) DECLSPEC_HIDDEN;
ME_Paragraph *table_append_row( ME_TextEditor *editor, ME_Paragraph *table_row ) DECLSPEC_HIDDEN; ME_Paragraph *table_append_row( ME_TextEditor *editor, ME_Paragraph *table_row ) DECLSPEC_HIDDEN;
@ -289,6 +291,7 @@ ME_Paragraph *table_insert_row_start( ME_TextEditor *editor, ME_Cursor *cursor )
ME_Paragraph *table_insert_row_start_at_para( ME_TextEditor *editor, ME_Paragraph *para ) DECLSPEC_HIDDEN; ME_Paragraph *table_insert_row_start_at_para( ME_TextEditor *editor, ME_Paragraph *para ) DECLSPEC_HIDDEN;
ME_Paragraph *table_outer_para( ME_Paragraph *para ) DECLSPEC_HIDDEN; ME_Paragraph *table_outer_para( ME_Paragraph *para ) DECLSPEC_HIDDEN;
ME_Paragraph *table_row_end( ME_Paragraph *para ) DECLSPEC_HIDDEN; ME_Paragraph *table_row_end( ME_Paragraph *para ) DECLSPEC_HIDDEN;
ME_Cell *table_row_end_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN;
ME_Cell *table_row_first_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN; ME_Cell *table_row_first_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN;
ME_Paragraph *table_row_start( ME_Paragraph *para ) DECLSPEC_HIDDEN; ME_Paragraph *table_row_start( ME_Paragraph *para ) DECLSPEC_HIDDEN;
void ME_CheckTablesForCorruption(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_CheckTablesForCorruption(ME_TextEditor *editor) DECLSPEC_HIDDEN;

View File

@ -23,12 +23,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(richedit); WINE_DEFAULT_DEBUG_CHANNEL(richedit);
static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph); static void draw_paragraph( ME_Context *c, ME_Paragraph *para );
void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate)
{ {
ME_DisplayItem *item; ME_Paragraph *para;
ME_Context c; ME_Context c;
ME_Cell *cell;
int ys, ye; int ys, ye;
HRGN oldRgn; HRGN oldRgn;
@ -44,36 +45,29 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate)
ME_InitContext(&c, editor, hDC); ME_InitContext(&c, editor, hDC);
SetBkMode(hDC, TRANSPARENT); SetBkMode(hDC, TRANSPARENT);
item = editor->pBuffer->pFirst->next; para = editor_first_para( editor );
/* This context point is an offset for the paragraph positions stored /* This context point is an offset for the paragraph positions stored
* during wrapping. It shouldn't be modified during painting. */ * during wrapping. It shouldn't be modified during painting. */
c.pt.x = c.rcView.left - editor->horz_si.nPos; c.pt.x = c.rcView.left - editor->horz_si.nPos;
c.pt.y = c.rcView.top - editor->vert_si.nPos; c.pt.y = c.rcView.top - editor->vert_si.nPos;
while(item != editor->pBuffer->pLast) while (para_next( para ))
{ {
assert(item->type == diParagraph); ys = c.pt.y + para->pt.y;
cell = para_cell( para );
ys = c.pt.y + item->member.para.pt.y; if (cell && para == cell_end_para( cell ))
if (item->member.para.pCell
!= item->member.para.next_para->member.para.pCell)
{
ME_Cell *cell = NULL;
cell = &ME_FindItemBack(item->member.para.next_para, diCell)->member.cell;
ye = c.pt.y + cell->pt.y + cell->nHeight; ye = c.pt.y + cell->pt.y + cell->nHeight;
} else { else ye = ys + para->nHeight;
ye = ys + item->member.para.nHeight;
} if (cell && !(para->nFlags & MEPF_ROWEND) && para == cell_first_para( cell ))
if (item->member.para.pCell && !(item->member.para.nFlags & MEPF_ROWEND) &&
item->member.para.pCell != item->member.para.prev_para->member.para.pCell)
{ {
/* the border shifts the text down */ /* the border shifts the text down */
ys -= item->member.para.pCell->member.cell.yTextOffset; ys -= para_cell( para )->yTextOffset;
} }
/* Draw the paragraph if any of the paragraph is in the update region. */ /* Draw the paragraph if any of the paragraph is in the update region. */
if (ys < rcUpdate->bottom && ye > rcUpdate->top) if (ys < rcUpdate->bottom && ye > rcUpdate->top)
ME_DrawParagraph(&c, item); draw_paragraph( &c, para );
item = item->member.para.next_para; para = para_next( para );
} }
if (c.pt.y + editor->nTotalLength < c.rcView.bottom) if (c.pt.y + editor->nTotalLength < c.rcView.bottom)
{ {
@ -909,12 +903,12 @@ static void draw_para_number( ME_Context *c, ME_Paragraph *para )
} }
} }
static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) static void draw_paragraph( ME_Context *c, ME_Paragraph *para )
{ {
int align = SetTextAlign(c->hDC, TA_BASELINE); int align = SetTextAlign(c->hDC, TA_BASELINE);
ME_DisplayItem *p; ME_DisplayItem *p;
ME_Cell *cell;
ME_Run *run; ME_Run *run;
ME_Paragraph *para = NULL;
RECT rc, bounds; RECT rc, bounds;
int y; int y;
int height = 0, baseline = 0, no=0; int height = 0, baseline = 0, no=0;
@ -923,32 +917,33 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
rc.left = c->pt.x; rc.left = c->pt.x;
rc.right = c->rcView.right; rc.right = c->rcView.right;
assert(paragraph);
para = &paragraph->member.para;
y = c->pt.y + para->pt.y; y = c->pt.y + para->pt.y;
if (para->pCell) if ((cell = para_cell( para )))
{ {
ME_Cell *cell = &para->pCell->member.cell;
rc.left = c->pt.x + cell->pt.x; rc.left = c->pt.x + cell->pt.x;
rc.right = rc.left + cell->nWidth; rc.right = rc.left + cell->nWidth;
} }
if (para->nFlags & MEPF_ROWSTART) { if (para->nFlags & MEPF_ROWSTART)
ME_Cell *cell = &para->next_para->member.para.pCell->member.cell; {
cell = table_row_first_cell( para );
rc.right = c->pt.x + cell->pt.x; rc.right = c->pt.x + cell->pt.x;
} else if (para->nFlags & MEPF_ROWEND) { }
ME_Cell *cell = &para->prev_para->member.para.pCell->member.cell; else if (para->nFlags & MEPF_ROWEND)
{
cell = table_row_end_cell( para );
rc.left = c->pt.x + cell->pt.x + cell->nWidth; rc.left = c->pt.x + cell->pt.x + cell->nWidth;
} }
ME_DrawParaDecoration(c, para, y, &bounds); ME_DrawParaDecoration(c, para, y, &bounds);
y += bounds.top; y += bounds.top;
if (bounds.left || bounds.right) { if (bounds.left || bounds.right)
{
rc.left = max(rc.left, c->pt.x + bounds.left); rc.left = max(rc.left, c->pt.x + bounds.left);
rc.right = min(rc.right, c->pt.x - bounds.right rc.right = min(rc.right, c->pt.x - bounds.right
+ max(c->editor->sizeWindow.cx, + max(c->editor->sizeWindow.cx,
c->editor->nTotalWidth)); c->editor->nTotalWidth));
} }
for (p = paragraph->next; p != para->next_para; p = p->next) for (p = para_get_di( para )->next; p != para_get_di( para_next( para ) ); p = p->next)
{ {
switch(p->type) { switch(p->type) {
case diParagraph: case diParagraph:

View File

@ -180,6 +180,14 @@ ME_Cell *table_row_first_cell( ME_Paragraph *para )
return para_cell( para ); return para_cell( para );
} }
ME_Cell *table_row_end_cell( ME_Paragraph *para )
{
if (!para_in_table( para )) return NULL;
para = para_prev( table_row_end( para ));
return cell_next( para_cell( para ) );
}
ME_Cell *cell_next( ME_Cell *cell ) ME_Cell *cell_next( ME_Cell *cell )
{ {
if (!cell->next_cell) return NULL; if (!cell->next_cell) return NULL;
@ -192,6 +200,20 @@ ME_Cell *cell_prev( ME_Cell *cell )
return &cell->prev_cell->member.cell; return &cell->prev_cell->member.cell;
} }
ME_Paragraph *cell_first_para( ME_Cell *cell )
{
return &ME_FindItemFwd( cell_get_di( cell ), diParagraph )->member.para;
}
ME_Paragraph *cell_end_para( ME_Cell *cell )
{
ME_Cell *next = cell_next( cell );
if (!next) return cell_first_para( cell ); /* End of row */
return &ME_FindItemBack( cell_get_di( next ), diParagraph )->member.para;
}
/* Make a bunch of assertions to make sure tables haven't been corrupted. /* Make a bunch of assertions to make sure tables haven't been corrupted.
* *
* These invariants may not hold true in the middle of streaming in rich text * These invariants may not hold true in the middle of streaming in rich text