Dylan Smith : richedit: Tabs are now highlighted and underlined.

Alexandre Julliard julliard at winehq.org
Fri Jul 11 08:44:45 CDT 2008


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

Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date:   Thu Jul 10 18:26:56 2008 -0400

richedit: Tabs are now highlighted and underlined.

---

 dlls/riched20/paint.c |   89 ++++++++++++++++++++++++++++++++++--------------
 1 files changed, 63 insertions(+), 26 deletions(-)

diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index a2bc7c5..1aa10b1 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -160,14 +160,23 @@ int ME_twips2pointsY(ME_Context *c, int y)
     return y * c->dpi.cy * c->editor->nZoomNumerator / 1440 / c->editor->nZoomDenominator;
 }
 
-static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, int nChars, 
-  ME_Style *s, int *width, int nSelFrom, int nSelTo, int ymin, int cy) {
+static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText,
+                                 int nChars, ME_Style *s, int width,
+                                 int nSelFrom, int nSelTo, int ymin, int cy)
+{
   HDC hDC = c->hDC;
   HGDIOBJ hOldFont;
   COLORREF rgbOld;
   int yOffset = 0, yTwipsOffset = 0;
   SIZE          sz;
   COLORREF      rgb;
+  int *lpDx = NULL;
+  /* lpDx is only needed for tabs to make sure the underline done automatically
+   * by the font extends to the end of the tab. Tabs are always stored as
+   * a single character run, so we can handle this case separately, since
+   * otherwise lpDx would need to specify the lengths of each character. */
+  if (width && nChars == 1)
+      lpDx = &width; /* Make sure underline for tab extends across tab space */
 
   hOldFont = ME_SelectStyleFont(c, s);
   if ((s->fmt.dwMask & CFM_LINK) && (s->fmt.dwEffects & CFE_LINK))
@@ -186,12 +195,15 @@ static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, in
   }
   if (yTwipsOffset)
     yOffset = ME_twips2pointsY(c, yTwipsOffset);
-  ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL);
+  ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, lpDx);
   GetTextExtentPoint32W(hDC, szText, nChars, &sz);
-  if (width) *width = sz.cx;
+  /* Treat width as an optional parameter.  We can get the width from the
+   * text extent of the string if it isn't specified. */
+  if (!width) width = sz.cx;
+
   if (s->fmt.dwMask & CFM_UNDERLINETYPE)
   {
-    HPEN    hPen;
+    HPEN    hPen = NULL;
     switch (s->fmt.bUnderlineType)
     {
     case CFU_UNDERLINE:
@@ -215,22 +227,36 @@ static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, in
       HPEN hOldPen = SelectObject(hDC, hPen);
       /* FIXME: should use textmetrics info for Descent info */
       MoveToEx(hDC, x, y - yOffset + 1, NULL);
-      LineTo(hDC, x + sz.cx, y - yOffset + 1);
+      LineTo(hDC, x + width, y - yOffset + 1);
       SelectObject(hDC, hOldPen);
       DeleteObject(hPen);
     }
   }
-  if (nSelFrom < nChars && nSelTo >= 0 && nSelFrom<nSelTo)
+  if (nSelFrom < nChars && nSelTo >= 0 && nSelFrom < nSelTo
+      && !c->editor->bHideSelection)
   {
-    if (nSelFrom < 0) nSelFrom = 0;
-    if (nSelTo > nChars) nSelTo = nChars;
-    GetTextExtentPoint32W(hDC, szText, nSelFrom, &sz);
-    x += sz.cx;
-    GetTextExtentPoint32W(hDC, szText+nSelFrom, nSelTo-nSelFrom, &sz);
-    
-    /* Invert selection if not hidden by EM_HIDESELECTION */
-    if (c->editor->bHideSelection == FALSE)
-	PatBlt(hDC, x, ymin, sz.cx, cy, DSTINVERT);
+    int xSelStart, xSelEnd;
+    if (nSelFrom <= 0)
+    {
+      nSelFrom = 0;
+      xSelStart = x;
+    }
+    else
+    {
+      GetTextExtentPoint32W(hDC, szText, nSelFrom, &sz);
+      xSelStart = x + sz.cx;
+    }
+    if (nSelTo >= nChars)
+    {
+      nSelTo = nChars;
+      xSelEnd = x + width;
+    }
+    else
+    {
+      GetTextExtentPoint32W(hDC, szText+nSelFrom, nSelTo-nSelFrom, &sz);
+      xSelEnd = xSelStart + sz.cx;
+    }
+    PatBlt(hDC, xSelStart, ymin, xSelEnd-xSelStart, cy, DSTINVERT);
   }
   SetTextColor(hDC, rgbOld);
   ME_UnselectStyleFont(c, s, hOldFont);
@@ -262,14 +288,25 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
 
   /* Draw selected end-of-paragraph mark */
   if (run->nFlags & MERF_ENDPARA && runofs >= nSelFrom && runofs < nSelTo)
-    ME_DrawTextWithStyle(c, x, y, wszSpace, 1, run->style, NULL, 0, 1,
+    ME_DrawTextWithStyle(c, x, y, wszSpace, 1, run->style, 0, 0, 1,
                          c->pt.y + start->member.row.nYPos,
                          start->member.row.nHeight);
-          
+
   /* you can always comment it out if you need visible paragraph marks */
-  if (run->nFlags & (MERF_ENDPARA | MERF_TAB | MERF_CELL)) 
+  if (run->nFlags & MERF_ENDPARA)
     return;
 
+  if (run->nFlags & (MERF_TAB | MERF_CELL))
+  {
+    /* wszSpace is used instead of the tab character because otherwise
+     * an unwanted symbol can be inserted instead. */
+    ME_DrawTextWithStyle(c, x, y, wszSpace, 1, run->style, run->nWidth,
+                         nSelFrom-runofs,nSelTo-runofs,
+                         c->pt.y + start->member.row.nYPos,
+                         start->member.row.nHeight);
+    return;
+  }
+
   if (run->nFlags & MERF_GRAPHICS)
     ME_DrawOLE(c, x, y, run, para, (runofs >= nSelFrom) && (runofs < nSelTo));
   else
@@ -277,16 +314,16 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
     if (c->editor->cPasswordMask)
     {
       ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,ME_StrVLen(run->strText));
-      ME_DrawTextWithStyle(c, x, y, 
-        szMasked->szData, ME_StrVLen(szMasked), run->style, NULL, 
-	nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.nYPos, start->member.row.nHeight);
+      ME_DrawTextWithStyle(c, x, y,
+        szMasked->szData, ME_StrVLen(szMasked), run->style, run->nWidth,
+        nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.nYPos, start->member.row.nHeight);
       ME_DestroyString(szMasked);
     }
     else
-      ME_DrawTextWithStyle(c, x, y, 
-        run->strText->szData, ME_StrVLen(run->strText), run->style, NULL, 
-	nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.nYPos, start->member.row.nHeight);
-    }
+      ME_DrawTextWithStyle(c, x, y,
+        run->strText->szData, ME_StrVLen(run->strText), run->style, run->nWidth,
+        nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.nYPos, start->member.row.nHeight);
+  }
 }
 
 static const struct {unsigned width_num : 4, width_den : 4, pen_style : 4, dble : 1;} border_details[] = {




More information about the wine-cvs mailing list