[ros-diffs] [jimtabor] 37345: - Add path support for ExtTextOut.

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Thu Nov 13 23:38:16 CET 2008


Author: jimtabor
Date: Thu Nov 13 16:38:16 2008
New Revision: 37345

URL: http://svn.reactos.org/svn/reactos?rev=37345&view=rev
Log:
- Add path support for ExtTextOut.

Modified:
    trunk/reactos/subsystems/win32/win32k/include/path.h
    trunk/reactos/subsystems/win32/win32k/objects/freetype.c
    trunk/reactos/subsystems/win32/win32k/objects/path.c

Modified: trunk/reactos/subsystems/win32/win32k/include/path.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/path.h?rev=37345&r1=37344&r2=37345&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/path.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/path.h [iso-8859-1] Thu Nov 13 16:38:16 2008
@@ -67,6 +67,7 @@
 BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2);
 BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height);
 BOOL FASTCALL PATH_PathToRegion (PPATH pPath, INT nPolyFillMode, HRGN *pHrgn);
+BOOL FASTCALL PATH_ExtTextOut(PDC dc,INT x,INT y,UINT flags,const RECT *lprc,LPCWSTR str,UINT count,const INT *dx);
 
 VOID FASTCALL IntGdiCloseFigure(PPATH pPath);
 BOOL FASTCALL PATH_Delete(HPATH hPath);

Modified: trunk/reactos/subsystems/win32/win32k/objects/freetype.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/freetype.c?rev=37345&r1=37344&r2=37345&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/freetype.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/freetype.c [iso-8859-1] Thu Nov 13 16:38:16 2008
@@ -3162,36 +3162,51 @@
       Status = MmCopyFromCaller(SafeString, UnsafeString, Count * sizeof(WCHAR));
       if (! NT_SUCCESS(Status))
       {
-        goto fail;
+         goto fail;
       }
    }
    String = SafeString;
 
-   if (lprc && (fuOptions & (ETO_OPAQUE | ETO_CLIPPED)))
-   {
-      // At least one of the two flags were specified. Copy lprc. Once.
+   if (NULL != UnsafeDx && Count > 0)
+   {
+      Dx = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_GDITEXT);
+      if (NULL == Dx)
+      {
+         goto fail;
+      }
+      Status = MmCopyFromCaller(Dx, UnsafeDx, Count * sizeof(INT));
+      if (!NT_SUCCESS(Status))
+      {
+         goto fail;
+      }
+   }
+
+   if (lprc)
+   {
       Status = MmCopyFromCaller(&SpecifiedDestRect, lprc, sizeof(RECT));
       if (!NT_SUCCESS(Status))
       {
-         DC_UnlockDc(dc);
          SetLastWin32Error(ERROR_INVALID_PARAMETER);
-         return FALSE;
-      }
+         goto fail;
+      }
+   }
+
+   if (PATH_IsPathOpen(dc->DcLevel))
+   {
+      if (!PATH_ExtTextOut( dc,
+                            XStart,
+                            YStart,
+                            fuOptions,
+             (const RECT *)&SpecifiedDestRect,
+                            SafeString,
+                            Count,
+               (const INT *)Dx)) goto fail;
+      goto good;
+   }
+
+   if (lprc && (fuOptions & (ETO_OPAQUE | ETO_CLIPPED)))
+   {
       IntLPtoDP(dc, (POINT *) &SpecifiedDestRect, 2);
-   }
-
-   if (NULL != UnsafeDx && Count > 0)
-   {
-      Dx = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_GDITEXT);
-      if (NULL == Dx)
-      {
-         goto fail;
-      }
-      Status = MmCopyFromCaller(Dx, UnsafeDx, Count * sizeof(INT));
-      if (! NT_SUCCESS(Status))
-      {
-         goto fail;
-      }
    }
 
    BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
@@ -3636,13 +3651,14 @@
    }
    BRUSHOBJ_UnlockBrush(BrushFg);
    NtGdiDeleteObject(hBrushFg);
+good:
    if (NULL != SafeString)
    {
-      ExFreePool((void*)SafeString);
+      ExFreePoolWithTag((void*)SafeString, TAG_GDITEXT);
    }
    if (NULL != Dx)
    {
-      ExFreePool(Dx);
+      ExFreePoolWithTag(Dx, TAG_GDITEXT);
    }
    DC_UnlockDc( dc );
 
@@ -3669,11 +3685,11 @@
    }
    if (NULL != SafeString)
    {
-      ExFreePool((void*)SafeString);
+      ExFreePoolWithTag((void*)SafeString, TAG_GDITEXT);
    }
    if (NULL != Dx)
    {
-      ExFreePool(Dx);
+      ExFreePoolWithTag(Dx, TAG_GDITEXT);
    }
    DC_UnlockDc(dc);
 

Modified: trunk/reactos/subsystems/win32/win32k/objects/path.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/path.c?rev=37345&r1=37344&r2=37345&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] Thu Nov 13 16:38:16 2008
@@ -1854,6 +1854,239 @@
     return ret;
 }
 
+static inline INT int_from_fixed(FIXED f)
+{
+    return (f.fract >= 0x8000) ? (f.value + 1) : f.value;
+}
+
+/**********************************************************************
+ *      PATH_BezierTo
+ *
+ * internally used by PATH_add_outline
+ */
+static
+VOID
+FASTCALL
+PATH_BezierTo(PPATH pPath, POINT *lppt, INT n)
+{
+    if (n < 2) return;
+
+    if (n == 2)
+    {
+        PATH_AddEntry(pPath, &lppt[1], PT_LINETO);
+    }
+    else if (n == 3)
+    {
+        PATH_AddEntry(pPath, &lppt[0], PT_BEZIERTO);
+        PATH_AddEntry(pPath, &lppt[1], PT_BEZIERTO);
+        PATH_AddEntry(pPath, &lppt[2], PT_BEZIERTO);
+    }
+    else
+    {
+        POINT pt[3];
+        INT i = 0;
+
+        pt[2] = lppt[0];
+        n--;
+
+        while (n > 2)
+        {
+            pt[0] = pt[2];
+            pt[1] = lppt[i+1];
+            pt[2].x = (lppt[i+2].x + lppt[i+1].x) / 2;
+            pt[2].y = (lppt[i+2].y + lppt[i+1].y) / 2;
+            PATH_BezierTo(pPath, pt, 3);
+            n--;
+            i++;
+        }
+
+        pt[0] = pt[2];
+        pt[1] = lppt[i+1];
+        pt[2] = lppt[i+2];
+        PATH_BezierTo(pPath, pt, 3);
+    }
+}
+
+static
+BOOL
+FASTCALL
+PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
+{
+  PPATH pPath;
+  TTPOLYGONHEADER *start;
+  POINT pt;
+
+  start = header;
+
+  pPath = PATH_LockPath(dc->DcLevel.hPath);
+  {
+     return FALSE;
+  }
+
+  while ((char *)header < (char *)start + size)
+  {
+     TTPOLYCURVE *curve;
+
+     if (header->dwType != TT_POLYGON_TYPE)
+     {
+        DPRINT1("Unknown header type %d\n", header->dwType);
+        return FALSE;
+     }
+
+     pt.x = x + int_from_fixed(header->pfxStart.x);
+     pt.y = y - int_from_fixed(header->pfxStart.y);
+     IntLPtoDP(dc, &pt, 1);
+     PATH_AddEntry(pPath, &pt, PT_MOVETO);
+
+     curve = (TTPOLYCURVE *)(header + 1);
+
+     while ((char *)curve < (char *)header + header->cb)
+     {
+        /*DPRINT1("curve->wType %d\n", curve->wType);*/
+
+        switch(curve->wType)
+        {
+           case TT_PRIM_LINE:
+           {
+              WORD i;
+
+              for (i = 0; i < curve->cpfx; i++)
+              {
+                 pt.x = x + int_from_fixed(curve->apfx[i].x);
+                 pt.y = y - int_from_fixed(curve->apfx[i].y);
+                 IntLPtoDP(dc, &pt, 1);
+                 PATH_AddEntry(pPath, &pt, PT_LINETO);
+              }
+              break;
+           }
+
+           case TT_PRIM_QSPLINE:
+           case TT_PRIM_CSPLINE:
+           {
+              WORD i;
+              POINTFX ptfx;
+              POINT *pts = ExAllocatePoolWithTag(PagedPool, (curve->cpfx + 1) * sizeof(POINT), TAG_PATH);
+
+              if (!pts) return FALSE;
+
+              ptfx = *(POINTFX *)((char *)curve - sizeof(POINTFX));
+
+              pts[0].x = x + int_from_fixed(ptfx.x);
+              pts[0].y = y - int_from_fixed(ptfx.y);
+              IntLPtoDP(dc, &pts[0], 1);
+
+              for (i = 0; i < curve->cpfx; i++)
+              {
+                  pts[i + 1].x = x + int_from_fixed(curve->apfx[i].x);
+                  pts[i + 1].y = y - int_from_fixed(curve->apfx[i].y);
+                  IntLPtoDP(dc, &pts[i + 1], 1);
+              }
+
+              PATH_BezierTo(pPath, pts, curve->cpfx + 1);
+
+              ExFreePoolWithTag(pts, TAG_PATH);
+              break;
+           }
+
+           default:
+              DPRINT1("Unknown curve type %04x\n", curve->wType);
+              return FALSE;
+        }
+
+        curve = (TTPOLYCURVE *)&curve->apfx[curve->cpfx];
+     }
+     header = (TTPOLYGONHEADER *)((char *)header + header->cb);
+  }
+
+  IntGdiCloseFigure( pPath );
+  PATH_UnlockPath( pPath );     
+  return TRUE;
+}
+
+/**********************************************************************
+ *      PATH_ExtTextOut
+ */
+BOOL
+FASTCALL 
+PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECT *lprc,
+                     LPCWSTR str, UINT count, const INT *dx)
+{
+    unsigned int idx;
+    double cosEsc, sinEsc;
+    PDC_ATTR Dc_Attr;
+    PTEXTOBJ TextObj;
+    LOGFONTW lf;
+    POINTL org;
+    INT offset = 0, xoff = 0, yoff = 0;
+
+    if (!count) return TRUE;
+
+    Dc_Attr = dc->pDc_Attr;
+    if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+
+    TextObj = RealizeFontInit( Dc_Attr->hlfntNew);
+    if ( !TextObj ) return FALSE;
+
+    FontGetObject( TextObj, sizeof(lf), &lf);
+
+    if (lf.lfEscapement != 0)
+    {
+        cosEsc = cos(lf.lfEscapement * M_PI / 1800);
+        sinEsc = sin(lf.lfEscapement * M_PI / 1800);
+    } else
+    {
+        cosEsc = 1;
+        sinEsc = 0;
+    }
+
+    IntGdiGetDCOrg(dc, &org);
+
+    for (idx = 0; idx < count; idx++)
+    {
+        GLYPHMETRICS gm;
+        DWORD dwSize;
+        void *outline;
+
+        dwSize = ftGdiGetGlyphOutline( dc,
+                                       str[idx],
+                                       GGO_GLYPH_INDEX | GGO_NATIVE,
+                                       &gm,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       TRUE);
+        if (!dwSize) return FALSE;
+
+        outline = ExAllocatePoolWithTag(PagedPool, dwSize, TAG_PATH);
+        if (!outline) return FALSE;
+
+        ftGdiGetGlyphOutline( dc,
+                              str[idx],
+                              GGO_GLYPH_INDEX | GGO_NATIVE,
+                              &gm,
+                              dwSize,
+                              outline,
+                              NULL,
+                              TRUE);
+
+        PATH_add_outline(dc, org.x + x + xoff, org.x + y + yoff, outline, dwSize);
+
+        ExFreePoolWithTag(outline, TAG_PATH);
+
+        if (dx)
+        {
+            offset += dx[idx];
+            xoff = offset * cosEsc;
+            yoff = offset * -sinEsc;
+        }
+        else
+        {
+            xoff += gm.gmCellIncX;
+            yoff += gm.gmCellIncY;
+        }
+    }
+    return TRUE;
+}
 
 
 /***********************************************************************



More information about the Ros-diffs mailing list