diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index 521f646..50d46a5 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -23,10 +23,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); -void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *rcUpdate) { +void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *rcUpdate) +{ ME_DisplayItem *item; ME_Context c; int yoffset; + int ys, ye; editor->nSequence++; yoffset = ME_GetYScrollPos(editor); @@ -34,115 +36,70 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT * SetBkMode(hDC, TRANSPARENT); ME_MoveCaret(editor); /* Calls ME_WrapMarkedParagraphs */ item = editor->pBuffer->pFirst->next; - c.pt.y -= yoffset; - while(item != editor->pBuffer->pLast) { - int yTextOffset = 0; - int ys, ye; + /* This context point is an offset for the paragraph positions stored + * during wrapping. It shouldn't be modified during painting. */ + c.pt.x = c.rcView.left; + c.pt.y = c.rcView.top - yoffset; + while(item != editor->pBuffer->pLast) + { assert(item->type == diParagraph); + + ys = c.pt.y + item->member.para.pt.y; 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 = cell->pt.y + cell->nHeight - yoffset; + ye = c.pt.y + cell->pt.y + cell->nHeight; } else { - ye = c.pt.y + item->member.para.nHeight; + ye = ys + item->member.para.nHeight; } - if (!(item->member.para.nFlags & MEPF_ROWEND) && + if (item->member.para.pCell && !(item->member.para.nFlags & MEPF_ROWEND) && item->member.para.pCell != item->member.para.prev_para->member.para.pCell) { - ME_DisplayItem *cell; - if (item->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART) - cell = item->member.para.pCell; - else - cell = item->member.para.prev_para->member.para.pCell; - assert(cell); /* the border shifts the text down */ - yTextOffset = cell->member.cell.yTextOffset; - ye += yTextOffset; + ys -= item->member.para.pCell->member.cell.yTextOffset; } + 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 = ys + c.rcView.top < rcUpdate->bottom && - ye + c.rcView.top > rcUpdate->top; + bPaint = ys < rcUpdate->bottom && ye > rcUpdate->top; if (bPaint) { - c.pt.y += yTextOffset; ME_DrawParagraph(&c, item); /* 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)) + if (!rcUpdate || (rcUpdate->top <= ys && rcUpdate->bottom >= ye)) item->member.para.nFlags &= ~MEPF_REPAINT; } } - if (item->member.para.pCell) - { - ME_Cell *cell = &item->member.para.pCell->member.cell; - ME_DisplayItem *next_para = item->member.para.next_para; - c.pt.x = cell->pt.x + cell->nWidth; - if (item->member.para.pCell == next_para->member.para.pCell && - !(next_para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND))) - { - c.pt.y = ye; - } else { - if (next_para->member.para.nFlags & MEPF_ROWSTART) - { - cell = &ME_FindItemFwd(next_para, diCell)->member.cell; - } - else if (next_para->member.para.nFlags & MEPF_ROWEND) - { - cell = &cell->next_cell->member.cell; - } - else - { - cell = &next_para->member.para.pCell->member.cell; - } - c.pt.y = cell->pt.y - yoffset; - } - } else if (!(item->member.para.nFlags & MEPF_ROWSTART)) { - c.pt.y = ye; - } item = item->member.para.next_para; } - if (c.pt.y < c.rcView.bottom - c.rcView.top) + if (c.pt.y + editor->nTotalLength < c.rcView.bottom) { /* Fill space after the end of the text. */ - int xs = c.rcView.left, xe = c.rcView.right; - int ys = c.rcView.top + c.pt.y, ye = c.rcView.bottom; + RECT rc; + rc.top = c.pt.y + editor->nTotalLength; + rc.left = c.rcView.left; + rc.bottom = c.rcView.bottom; + rc.right = c.rcView.right; if (bOnlyNew) { /* Only erase region drawn from previous call to ME_PaintContent */ - int y1 = editor->nTotalLength-yoffset, y2 = editor->nLastTotalLength-yoffset; - if (y1nTotalLength < editor->nLastTotalLength) + rc.bottom = c.pt.y + editor->nLastTotalLength; else - ys = ye; /* empty fill area */ + SetRectEmpty(&rc); } - 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); - } + IntersectRect(&rc, &rc, rcUpdate); - if (xe > xs && ye > ys) - { - RECT rc; - rc.left = xs; - rc.top = ys; - rc.right = xe; - rc.bottom = ye; + if (!IsRectEmpty(&rc)) FillRect(hDC, &rc, c.editor->hbrBackground); - } } if (editor->nTotalLength != editor->nLastTotalLength) ME_SendRequestResize(editor, FALSE); @@ -451,7 +408,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->rcView.top + c->pt.y + start->member.row.pt.y, + c->pt.y + para->pt.y + start->member.row.pt.y, start->member.row.nHeight); } return; @@ -463,7 +420,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa * an unwanted symbol can be inserted instead. */ ME_DrawTextWithStyle(c, x, y, wszSpace, 1, run->style, run->nWidth, nSelFrom-runofs, nSelTo-runofs, - c->rcView.top + c->pt.y + start->member.row.pt.y, + c->pt.y + para->pt.y + start->member.row.pt.y, start->member.row.nHeight); return; } @@ -478,7 +435,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa ME_DrawTextWithStyle(c, x, y, szMasked->szData, ME_StrVLen(szMasked), run->style, run->nWidth, nSelFrom-runofs,nSelTo-runofs, - c->rcView.top + c->pt.y + start->member.row.pt.y, + c->pt.y + para->pt.y + start->member.row.pt.y, start->member.row.nHeight); ME_DestroyString(szMasked); } @@ -486,7 +443,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa ME_DrawTextWithStyle(c, x, y, run->strText->szData, ME_StrVLen(run->strText), run->style, run->nWidth, nSelFrom-runofs,nSelTo-runofs, - c->rcView.top + c->pt.y + start->member.row.pt.y, + c->pt.y + para->pt.y + start->member.row.pt.y, start->member.row.nHeight); } } @@ -742,11 +699,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 = c->rcView.top + (atTop ? cell->pt.y : para->pt.y) - ME_GetYScrollPos(c->editor); + int top = c->pt.y + (atTop ? cell->pt.y : para->pt.y); int bottom = (atBottom ? - c->rcView.top + cell->pt.y + cell->nHeight - ME_GetYScrollPos(c->editor): + c->pt.y + cell->pt.y + cell->nHeight : top + para->nHeight + (atTop ? cell->yTextOffset : 0)); - rc.left = c->rcView.left + cell->pt.x; + rc.left = c->pt.x + cell->pt.x; rc.right = rc.left + cell->nWidth; if (atTop) { /* Erase gap before text if not all borders are the same height. */ @@ -759,7 +716,7 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) } } /* Draw cell borders. - * The borders borders are draw in is left, top, bottom, right in order + * The order borders are draw in is left, top, bottom, right in order * to be consistent with native richedit. This is noticeable from the * overlap of borders of different colours. */ if (!(para->nFlags & MEPF_ROWEND)) { @@ -812,7 +769,7 @@ 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 = c->rcView.left + nextEndCell->member.cell.pt.x; + rc.left = c->pt.x + 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 cause the next row to erase the border. */ @@ -874,12 +831,12 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) oldpen = SelectObject(c->hDC, pen); /* Find the start relative to the text */ - firstX = c->rcView.left + ME_FindItemFwd(paragraph, diRun)->member.run.pt.x; + firstX = c->pt.x + 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->rcView.top + c->pt.y; + rowY = c->pt.y + para->pt.y; if (para->pFmt->dwMask & PFM_SPACEBEFORE) rowY += ME_twips2pointsY(c, para->pFmt->dySpaceBefore); nHeight = ME_FindItemFwd(paragraph, diStartRow)->member.row.nHeight; @@ -928,45 +885,45 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) ME_Run *run; ME_Paragraph *para = NULL; RECT rc, bounds; - int y = c->rcView.top + c->pt.y; + int y; int height = 0, baseline = 0, no=0; BOOL visible = FALSE; - c->pt.x = c->rcView.left; - rc.left = c->rcView.left; + rc.left = c->pt.x; rc.right = c->rcView.right; - for (p = paragraph; p!=paragraph->member.para.next_para; p = p->next) { + + assert(paragraph); + para = ¶graph->member.para; + y = c->pt.y + para->pt.y; + if (para->pCell) + { + ME_Cell *cell = ¶->pCell->member.cell; + rc.left = c->pt.x + 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 = c->pt.x + cell->pt.x; + } else if (para->nFlags & MEPF_ROWEND) { + ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell; + rc.left = c->pt.x + cell->pt.x + cell->nWidth; + } + ME_DrawParaDecoration(c, para, y, &bounds); + y += bounds.top; + rc.left += bounds.left; + rc.right -= bounds.right; + + for (p = paragraph->next; p != para->next_para; p = p->next) + { switch(p->type) { case diParagraph: - para = &p->member.para; - assert(para); - if (para->pCell) - { - ME_Cell *cell = ¶->pCell->member.cell; - 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 = c->rcView.left + cell->pt.x; - } else if (para->nFlags & MEPF_ROWEND) { - ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell; - rc.left = c->rcView.left + cell->pt.x + cell->nWidth; - } - ME_DrawParaDecoration(c, para, y, &bounds); - y += bounds.top; + assert(FALSE); break; case diStartRow: - /* we should have seen a diParagraph before */ - assert(para); y += height; rc.top = y; - if (para->nFlags & MEPF_ROWSTART) { - ME_Cell *cell = ¶->next_para->member.para.pCell->member.cell; - rc.bottom = y + cell->nHeight; - } else if (para->nFlags & MEPF_ROWEND) { - ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell; - rc.bottom = y + cell->nHeight; + if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) { + rc.bottom = y + para->nHeight; } else { rc.bottom = y + p->member.row.nHeight; } @@ -991,9 +948,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; + RECT rc; + rc.left = c->pt.x + run->pt.x; rc.right = rc.left + run->nWidth; - rc.top = c->rcView.top + c->pt.y + run->pt.y; + rc.top = c->pt.y + para->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) @@ -1002,30 +960,27 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) FrameRect(c->hDC, &rc, GetSysColorBrush(COLOR_GRAYTEXT)); } if (visible) - ME_DrawRun(c, c->rcView.left + run->pt.x, - c->rcView.top + c->pt.y + run->pt.y + baseline, - p, ¶graph->member.para); + ME_DrawRun(c, c->pt.x + run->pt.x, + c->pt.y + para->pt.y + run->pt.y + baseline, p, para); if (me_debug) { /* I'm using %ls, hope wsprintfW is not going to use wrong (4-byte) WCHAR version */ const WCHAR wszRunDebug[] = {'[','%','d',':','%','x',']',' ','%','l','s',0}; WCHAR buf[2560]; POINT pt; - pt.x = run->pt.x; - pt.y = c->rcView.top + c->pt.y + run->pt.y; + pt.x = c->pt.x + run->pt.x; + pt.y = c->pt.y + para->pt.y + run->pt.y; wsprintfW(buf, wszRunDebug, no, p->member.run.nFlags, p->member.run.strText->szData); ME_DebugWrite(c->hDC, &pt, buf); } - /* c->pt.x += p->member.run.nWidth; */ break; case diCell: /* Clear any space at the bottom of the cell after the text. */ - if (para->nFlags & MEPF_ROWSTART) + if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) break; y += height; - rc.top = y; - rc.bottom = c->rcView.top + p->member.cell.pt.y - + p->member.cell.nHeight - ME_GetYScrollPos(c->editor); + rc.top = c->pt.y + para->pt.y + para->nHeight; + rc.bottom = c->pt.y + p->member.cell.pt.y + p->member.cell.nHeight; if (RectVisible(c->hDC, &rc)) { FillRect(c->hDC, &rc, c->editor->hbrBackground); diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index d989a2d..0247e66 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -698,7 +698,8 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) c.pt.x = cell->pt.x + cell->nWidth; c.pt.y = cell->pt.y; cell->next_cell->member.cell.pt = c.pt; - c.pt.y += cell->yTextOffset; + if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWEND)) + c.pt.y += cell->yTextOffset; } else {