Bug fixes.
authorFilip Navara <filip.navara@gmail.com>
Sun, 21 Dec 2003 18:38:37 +0000 (18:38 +0000)
committerFilip Navara <filip.navara@gmail.com>
Sun, 21 Dec 2003 18:38:37 +0000 (18:38 +0000)
svn path=/trunk/; revision=7161

reactos/include/win32k/coord.h
reactos/lib/user32/controls/edit.c
reactos/lib/user32/windows/nonclient.c
reactos/subsys/win32k/objects/cliprgn.c
reactos/subsys/win32k/objects/coord.c
reactos/subsys/win32k/objects/text.c

index 649bfb3..7bbf868 100644 (file)
@@ -10,6 +10,15 @@ NtGdiCombineTransform (
        CONST LPXFORM   xform1,
        CONST LPXFORM   xform2
        );
+
+VOID
+FASTCALL
+IntDPtoLP ( PDC dc, LPPOINT Points, INT Count );
+
+VOID
+FASTCALL
+CoordDPtoLP ( PDC Dc, LPPOINT Point );
+
 BOOL
 STDCALL
 NtGdiDPtoLP (
index 1673af2..d7ef6df 100644 (file)
@@ -293,7 +293,7 @@ const struct builtin_class_descr EDIT_builtin_class =
 {
 #ifdef __REACTOS__
     L"Edit",               /* name */
-    /*TODO: Fix ExtTextOut so that we can have the CS_PARENTDC style*/
+    /* FIXME: Add CS_PARENTDC when the handling of WM_ERASEBKGND will be fixed! */
     CS_GLOBALCLASS | CS_DBLCLKS, /* style */
     (WNDPROC)EditWndProcW, /* procW */
     (WNDPROC)EditWndProcA, /* procA */
index 61b5423..74d8e2c 100644 (file)
@@ -1095,6 +1095,8 @@ DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags)
     r.top ++;
     r.left += 2;
 
+    r.bottom = r.top + Height;
+
   if ((uFlags & DC_TEXT) && (GetWindowTextW( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) )))
   {
     if (!(uFlags & DC_SMALLCAP) && ((uFlags & DC_ICON) || (uFlags & DC_INBUTTON)))
index 1750bb2..7be727c 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: cliprgn.c,v 1.28 2003/12/15 20:47:57 navaraf Exp $ */
+/* $Id: cliprgn.c,v 1.29 2003/12/21 18:38:37 navaraf Exp $ */
 
 #undef WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -163,14 +163,13 @@ IntGdiGetClipBox(HDC    hDC,
                             LPRECT rc)
 {
   int retval;
-  DC *dc;
+  PDC dc;
 
   if (!(dc = DC_LockDc(hDC)))
        return ERROR;
   retval = UnsafeIntGetRgnBox(dc->w.hGCClipRgn, rc);
-
+  IntDPtoLP(dc, (LPPOINT)rc, 2);
   DC_UnlockDc( hDC );
-  NtGdiDPtoLP(hDC, (LPPOINT)rc, 2);
   return(retval);
 }
 
@@ -206,7 +205,42 @@ int STDCALL NtGdiIntersectClipRect(HDC  hDC,
                            int  RightRect,
                            int  BottomRect)
 {
-  UNIMPLEMENTED;
+   INT Result;
+   RECT Rect;
+   HRGN NewRgn;
+   PDC dc = DC_LockDc(hDC);
+
+   if (!dc)
+      return ERROR;
+
+   Rect.left = LeftRect;
+   Rect.top = TopRect;
+   Rect.right = RightRect;
+   Rect.bottom = BottomRect;
+
+   IntLPtoDP(dc, (LPPOINT)&Rect, 2);
+
+   NewRgn = UnsafeIntCreateRectRgnIndirect(&Rect);
+   if (!NewRgn)
+   {
+      Result = ERROR;
+   }
+   else if (!dc->w.hClipRgn)
+   {
+      dc->w.hClipRgn = NewRgn;
+      Result = SIMPLEREGION;
+   }
+   else
+   {
+      Result = NtGdiCombineRgn(dc->w.hClipRgn, dc->w.hClipRgn, NewRgn, RGN_AND);
+      NtGdiDeleteObject(NewRgn);
+   }
+   if (Result != ERROR)
+      CLIPPING_UpdateGCRegion(dc);
+
+   DC_UnlockDc(hDC);
+
+   return Result;
 }
 
 int STDCALL NtGdiOffsetClipRgn(HDC  hDC,
index e69c62d..4bf071a 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: coord.c,v 1.19 2003/09/09 09:39:21 gvg Exp $
+/* $Id: coord.c,v 1.20 2003/12/21 18:38:37 navaraf Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -69,7 +69,7 @@ BOOL STDCALL NtGdiCombineTransform(LPXFORM  UnsafeXFormResult,
   return  TRUE;
 }
 
-VOID STATIC FASTCALL
+VOID FASTCALL
 CoordDPtoLP(PDC Dc, LPPOINT Point)
 {
 FLOAT x, y;
@@ -81,6 +81,18 @@ FLOAT x, y;
     y * Dc->w.xformVport2World.eM22 + Dc->w.xformVport2World.eDy;
 }
 
+VOID
+FASTCALL
+IntDPtoLP ( PDC dc, LPPOINT Points, INT Count )
+{
+  INT i;
+
+  ASSERT ( Points );
+
+  for ( i = 0; i < Count; i++ )
+    CoordDPtoLP ( dc, &Points[i] );
+}
+
 /*!
  * Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
  * world transfrom, viewport origin settings for the given device context.
@@ -94,38 +106,25 @@ NtGdiDPtoLP(HDC  hDC,
           LPPOINT  UnsafePoints,
           int  Count)
 {
-  PDC dc;
-  INT i;
-  LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT));
-  BOOL ret = FALSE; // default to failure
-
-  ASSERT(Points);
-  if ( !Points )
-    return ret;
+   PDC dc;
+   LPPOINT Points = (LPPOINT)ExAllocatePool(PagedPool, Count * sizeof(POINT));
+   BOOL ret = FALSE; // default to failure
 
-  MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
-
-  dc = DC_LockDc (hDC);
-  if ( dc )
-  {
-    ret = TRUE;
-    if ( dc->w.vport2WorldValid )
-    {
-      for (i = 0; i < Count; i++)
-       {
-         CoordDPtoLP ( dc, &Points[i] );
-       }
-    }
-
-    DC_UnlockDc( hDC );
-
-    MmCopyToCaller(  UnsafePoints, Points, Count*sizeof(POINT) );
-
-  }
-
-  ExFreePool ( Points );
+   if (!Points)
+      return FALSE;
 
-  return(TRUE);
+   dc = DC_LockDc(hDC);
+   if (dc)
+   {
+      ret = TRUE;
+      MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT));
+      IntDPtoLP(dc, Points, Count);
+      MmCopyToCaller(UnsafePoints, Points, Count * sizeof(POINT));
+      DC_UnlockDc(hDC);
+   }
+   ExFreePool(Points);
+
+   return ret;
 }
 
 int
index a5ff2c1..57b10f0 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: text.c,v 1.61 2003/12/13 10:34:13 weiden Exp $ */
+/* $Id: text.c,v 1.62 2003/12/21 18:38:37 navaraf Exp $ */
 
 
 #undef WIN32_LEAN_AND_MEAN
@@ -467,19 +467,276 @@ NtGdiEnumFonts(HDC  hDC,
   UNIMPLEMENTED;
 }
 
-BOOL
-STDCALL
-NtGdiExtTextOut(HDC  hdc,
-                     int  X,
-                     int  Y,
-                     UINT  fuOptions,
-                     CONST RECT  *lprc,
-                     LPCWSTR  lpString,
-                     UINT  cbCount,
-                     CONST INT  *lpDx)
+BOOL STDCALL
+NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
+   CONST RECT *lprc, LPCWSTR String, UINT Count, CONST INT *lpDx)
 {
   /* FIXME: Implement */
-  return NtGdiTextOut(hdc, X, Y, lpString, cbCount);
+//  return NtGdiTextOut(hdc, X, Y, lpString, cbCount);
+  // Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
+
+  DC *dc;
+  SURFOBJ *SurfObj;
+  int error, glyph_index, n, i;
+  FT_Face face;
+  FT_GlyphSlot glyph;
+  ULONG TextLeft, TextTop, pitch, previous, BackgroundLeft;
+  FT_Bool use_kerning;
+  RECTL DestRect, MaskRect;
+  POINTL SourcePoint, BrushOrigin;
+  HBRUSH hBrushFg = NULL;
+  PBRUSHOBJ BrushFg = NULL;
+  HBRUSH hBrushBg = NULL;
+  PBRUSHOBJ BrushBg = NULL;
+  HBITMAP HSourceGlyph;
+  PSURFOBJ SourceGlyphSurf;
+  SIZEL bitSize;
+  FT_CharMap found = 0, charmap;
+  INT yoff;
+  PFONTOBJ FontObj;
+  PFONTGDI FontGDI;
+  PTEXTOBJ TextObj;
+  PPALGDI PalDestGDI;
+  PXLATEOBJ XlateObj;
+  ULONG Mode;
+
+  dc = DC_LockDc(hDC);
+  if( !dc )
+       return FALSE;
+  SurfObj = (SURFOBJ*)AccessUserObject((ULONG) dc->Surface);
+
+  XStart += dc->w.DCOrgX;
+  YStart += dc->w.DCOrgY;
+  TextLeft = XStart;
+  TextTop = YStart;
+  BackgroundLeft = XStart;
+
+  TextObj = TEXTOBJ_LockText(dc->w.hFont);
+
+  if (! NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, &FontObj, &FontGDI)))
+  {
+    goto fail;
+  }
+  face = FontGDI->face;
+
+  if (face->charmap == NULL)
+  {
+    DPRINT("WARNING: No charmap selected!\n");
+    DPRINT("This font face has %d charmaps\n", face->num_charmaps);
+
+    for (n = 0; n < face->num_charmaps; n++)
+    {
+      charmap = face->charmaps[n];
+      DPRINT("found charmap encoding: %u\n", charmap->encoding);
+      if (charmap->encoding != 0)
+      {
+        found = charmap;
+        break;
+      }
+    }
+    if (!found) DPRINT1("WARNING: Could not find desired charmap!\n");
+    error = FT_Set_Charmap(face, found);
+    if (error) DPRINT1("WARNING: Could not set the charmap!\n");
+  }
+
+  error = FT_Set_Pixel_Sizes(face,
+                             /* FIXME should set character height if neg */
+                             (TextObj->logfont.lfHeight < 0 ?
+                              - TextObj->logfont.lfHeight :
+                              TextObj->logfont.lfHeight),
+                             TextObj->logfont.lfWidth);
+  if(error) {
+    DPRINT1("Error in setting pixel sizes: %u\n", error);
+       goto fail;
+  }
+
+  // Create the brushes
+  PalDestGDI = PALETTE_LockPalette(dc->w.hPalette);
+  Mode = PalDestGDI->Mode;
+  PALETTE_UnlockPalette(dc->w.hPalette);
+  XlateObj = (PXLATEOBJ)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
+  hBrushFg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor));
+  BrushFg = BRUSHOBJ_LockBrush(hBrushFg);
+  if (OPAQUE == dc->w.backgroundMode)
+    {
+      hBrushBg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.backgroundColor));
+      if(hBrushBg)
+      {
+        BrushBg = BRUSHOBJ_LockBrush(hBrushBg);
+      }
+      else
+      {
+        EngDeleteXlate(XlateObj);
+        goto fail;
+      }
+    }
+  EngDeleteXlate(XlateObj);
+
+  SourcePoint.x = 0;
+  SourcePoint.y = 0;
+  MaskRect.left = 0;
+  MaskRect.top = 0;
+  BrushOrigin.x = 0;
+  BrushOrigin.y = 0;
+
+  // Determine the yoff from the dc's w.textAlign
+  if (dc->w.textAlign & TA_BASELINE) {
+    yoff = 0;
+  }
+  else
+  if (dc->w.textAlign & TA_BOTTOM) {
+    yoff = -face->size->metrics.descender / 64;
+  }
+  else { // TA_TOP
+    yoff = face->size->metrics.ascender / 64;
+  }
+
+  use_kerning = FT_HAS_KERNING(face);
+  previous = 0;
+
+  for(i=0; i<Count; i++)
+  {
+    glyph_index = FT_Get_Char_Index(face, *String);
+    error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
+    if(error) {
+      DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
+      goto fail;
+    }
+    glyph = face->glyph;
+
+    // retrieve kerning distance and move pen position
+    if (use_kerning && previous && glyph_index)
+    {
+      FT_Vector delta;
+      FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
+      TextLeft += delta.x >> 6;
+    }
+
+    if (glyph->format == ft_glyph_format_outline)
+    {
+      error = FT_Render_Glyph(glyph, ft_render_mode_mono);
+      if(error) {
+        DPRINT1("WARNING: Failed to render glyph!\n");
+               goto fail;
+      }
+      pitch = glyph->bitmap.pitch;
+    } else {
+      pitch = glyph->bitmap.width;
+    }
+
+    if (OPAQUE == dc->w.backgroundMode)
+      {
+       DestRect.left = BackgroundLeft;
+       DestRect.right = TextLeft + (glyph->advance.x + 32) / 64;
+       DestRect.top = TextTop + yoff - (face->size->metrics.ascender + 32) / 64;
+       DestRect.bottom = TextTop + yoff + (- face->size->metrics.descender + 32) / 64;
+       if (fuOptions & ETO_CLIPPED)
+       {
+          if (DestRect.left > lprc->right || DestRect.right < lprc->left ||
+              DestRect.top > lprc->bottom || DestRect.bottom < lprc->top)
+          {
+             DestRect.right = DestRect.left;
+          }
+          else
+          {
+              DestRect.left = max(DestRect.left, lprc->left);
+              DestRect.right = min(DestRect.right, lprc->right);
+              DestRect.top = max(DestRect.top, lprc->top);
+              DestRect.bottom = min(DestRect.bottom, lprc->bottom);
+          }
+       }
+       IntEngBitBlt(SurfObj,
+                    NULL,
+                    NULL,
+                    dc->CombinedClip,
+                    NULL,
+                    &DestRect,
+                    &SourcePoint,
+                    &SourcePoint,
+                    BrushBg,
+                    &BrushOrigin,
+                    PATCOPY);
+       BackgroundLeft = DestRect.right;
+      }
+
+    DestRect.left = TextLeft;
+    DestRect.right = TextLeft + glyph->bitmap.width;
+    DestRect.top = TextTop + yoff - glyph->bitmap_top;
+    DestRect.bottom = DestRect.top + glyph->bitmap.rows;
+       
+    if (fuOptions & ETO_CLIPPED)
+    {
+       if (DestRect.left > lprc->right || DestRect.right < lprc->left ||
+           DestRect.top > lprc->bottom || DestRect.bottom < lprc->top)
+       {
+          break;
+       }
+       else
+       {
+          DestRect.left = max(DestRect.left, lprc->left);
+          DestRect.right = min(DestRect.right, lprc->right);
+          DestRect.top = max(DestRect.top, lprc->top);
+          DestRect.bottom = min(DestRect.bottom, lprc->bottom);
+       }
+    }
+
+    bitSize.cx = glyph->bitmap.width;
+    bitSize.cy = glyph->bitmap.rows;
+    MaskRect.right = glyph->bitmap.width;
+    MaskRect.bottom = glyph->bitmap.rows;
+
+    // We should create the bitmap out of the loop at the biggest possible glyph size
+    // Then use memset with 0 to clear it and sourcerect to limit the work of the transbitblt
+
+    HSourceGlyph = EngCreateBitmap(bitSize, pitch, BMF_1BPP, 0, glyph->bitmap.buffer);
+    SourceGlyphSurf = (PSURFOBJ)AccessUserObject((ULONG) HSourceGlyph);
+
+    // Use the font data as a mask to paint onto the DCs surface using a brush
+    IntEngBitBlt (
+               SurfObj,
+               NULL,
+               SourceGlyphSurf,
+               dc->CombinedClip,
+               NULL,
+               &DestRect,
+               &SourcePoint,
+               (PPOINTL)&MaskRect,
+               BrushFg,
+               &BrushOrigin,
+               0xAACC );
+
+    EngDeleteSurface(HSourceGlyph);
+
+    TextLeft += (glyph->advance.x + 32) / 64;
+    previous = glyph_index;
+
+    String++;
+  }
+  TEXTOBJ_UnlockText(dc->w.hFont);
+  if (NULL != hBrushBg)
+    {
+      BRUSHOBJ_UnlockBrush(hBrushBg);
+      NtGdiDeleteObject(hBrushBg);
+    }
+  BRUSHOBJ_UnlockBrush(hBrushFg);
+  NtGdiDeleteObject(hBrushFg);
+  DC_UnlockDc(hDC);
+  return TRUE;
+
+fail:
+  TEXTOBJ_UnlockText( dc->w.hFont );
+  if (NULL != hBrushBg)
+    {
+      BRUSHOBJ_UnlockBrush(hBrushBg);
+      NtGdiDeleteObject(hBrushBg);
+    }
+  if (NULL != hBrushFg)
+    {
+      BRUSHOBJ_UnlockBrush(hBrushFg);
+      NtGdiDeleteObject(hBrushFg);
+    }
+  DC_UnlockDc( hDC );
+  return FALSE;
 }
 
 BOOL