diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index c2bcfc2..b2a8aed 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -662,6 +662,68 @@ static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT } } +static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) +{ + ME_Paragraph *para = ¶graph->member.para; + if (c->editor->bEmulateVersion10) /* v1.0 - 3.0 */ + { + if (para->pFmt->dwMask & PFM_TABLE && para->pFmt->wEffects & PFE_TABLE) { + HPEN pen = NULL, oldpen = NULL; + int i, firstX, startX, endX, rowY, rowBottom, nHeight; + POINT oldPt; + PARAFORMAT2 *pNextFmt; + + pen = CreatePen(PS_SOLID, 0, RGB(0,0,0)); + oldpen = SelectObject(c->hDC, pen); + + /* Find the start relative to the text */ + firstX = 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->pt.y; + if (para->pFmt->dwMask & PFM_SPACEBEFORE) + rowY += ME_twips2pointsY(c, para->pFmt->dySpaceBefore); + nHeight = ME_FindItemFwd(paragraph, diStartRow)->member.row.nHeight; + rowBottom = rowY + nHeight; + + /* Draw horizontal lines */ + MoveToEx(c->hDC, firstX, rowY, &oldPt); + i = para->pFmt->cTabCount - 1; + endX = startX + ME_twips2pointsX(c, para->pFmt->rgxTabs[i] & 0x00ffffff) + 1; + LineTo(c->hDC, endX, rowY); + pNextFmt = para->next_para->member.para.pFmt; + /* The bottom of the row only needs to be drawn if the next row is + * not a table. */ + if (!(pNextFmt && pNextFmt->dwMask & PFM_TABLE && pNextFmt->wEffects && + para->nRows == 1)) + { + /* Decrement rowBottom to draw the bottom line within the row, and + * to not draw over this line when drawing the vertical lines. */ + rowBottom--; + MoveToEx(c->hDC, firstX, rowBottom, NULL); + LineTo(c->hDC, endX, rowBottom); + } + + /* Draw vertical lines */ + MoveToEx(c->hDC, firstX, rowY, NULL); + LineTo(c->hDC, firstX, rowBottom); + for (i = 0; i < para->pFmt->cTabCount; i++) + { + int rightBoundary = para->pFmt->rgxTabs[i] & 0x00ffffff; + endX = startX + ME_twips2pointsX(c, rightBoundary); + MoveToEx(c->hDC, endX, rowY, NULL); + LineTo(c->hDC, endX, rowBottom); + } + + MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL); + SelectObject(c->hDC, oldpen); + DeleteObject(pen); + } + } +} + void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { int align = SetTextAlign(c->hDC, TA_BASELINE); ME_DisplayItem *p; @@ -773,6 +835,9 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { } no++; } + + ME_DrawTableBorders(c, paragraph); + SetTextAlign(c->hDC, align); } diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 21121a4..70a552d 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -44,7 +44,9 @@ static ME_DisplayItem *ME_MakeRow(int height, int baseline, int width) static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para) { + PARAFORMAT2 *pFmt; assert(para && para->type == diParagraph); + pFmt = para->member.para.pFmt; wc->pRowStart = NULL; wc->bOverflown = FALSE; wc->pLastSplittableRun = NULL; @@ -78,6 +80,10 @@ static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para) wc->nAvailWidth = ~0u >> 1; } wc->pt.x = wc->context->pt.x; + if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ + pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + /* Shift the text down because of the border. */ + wc->pt.y++; } static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) @@ -85,8 +91,10 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) ME_DisplayItem *p, *row, *para; BOOL bSkippingSpaces = TRUE; int ascent = 0, descent = 0, width=0, shift = 0, align = 0; + PARAFORMAT2 *pFmt; /* wrap text */ para = ME_GetParagraph(wc->pRowStart); + pFmt = para->member.para.pFmt; for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev) { @@ -125,6 +133,15 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) } row = ME_MakeRow(ascent+descent, ascent, width); + if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ + pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + { + /* The text was shifted down in ME_BeginRow so move the wrap context + * back to where it should be. */ + wc->pt.y--; + /* The height of the row is increased by the borders. */ + row->member.row.nHeight += 2; + } row->member.row.pt = wc->pt; row->member.row.nLMargin = (!wc->nRow ? wc->nFirstMargin : wc->nLeftMargin); row->member.row.nRMargin = wc->nRightMargin; @@ -142,14 +159,23 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) } ME_InsertBefore(wc->pRowStart, row); wc->nRow++; - wc->pt.y += ascent+descent; + wc->pt.y += row->member.row.nHeight; ME_BeginRow(wc, para); } static void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p) { + ME_DisplayItem *para = p->member.para.prev_para; + PARAFORMAT2 *pFmt = para->member.para.pFmt; if (wc->pRowStart) ME_InsertRowStart(wc, p); + if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ + pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + { + /* ME_BeginRow was called an extra time for the paragraph, and it shifts the + * text down by one pixel for the border, so fix up the wrap context. */ + wc->pt.y--; + } /* p = p->member.para.prev_para->next;