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/in…
==============================================================================
--- 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/ob…
==============================================================================
--- 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/ob…
==============================================================================
--- 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;
+}
/***********************************************************************