Dylan Smith : richedit: Borders are drawn for simple tables.

Alexandre Julliard julliard at winehq.org
Mon Aug 18 10:47:08 CDT 2008


Module: wine
Branch: master
Commit: 967c148a68be23f7c75aad2b7d352738005396bf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=967c148a68be23f7c75aad2b7d352738005396bf

Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date:   Tue Aug 12 23:15:32 2008 -0400

richedit: Borders are drawn for simple tables.

---

 dlls/riched20/paint.c |   65 +++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/riched20/wrap.c  |   28 ++++++++++++++++++++-
 2 files changed, 92 insertions(+), 1 deletions(-)

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 = &paragraph->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;




More information about the wine-cvs mailing list