⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fillshap.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
	    }
	}
      else
 	{
	  for (i = 0; i < deltax; i++)
	    {
	      SETPOINT(x, y, Type);
	      x = x + xchange;
	      error = error + deltay;
	      if (deltax <= error)
		{
		  y = y + ychange;
		  error = error - deltax;
		}
	    }
	}
    }
}

STATIC int
CDECL
CompareShapePoints(const void *pv1, const void *pv2)
{
  if (((const PSHAPEPOINT) pv1)->Y < ((const PSHAPEPOINT) pv2)->Y)
    {
      return -1;
    }
  else if (((const PSHAPEPOINT) pv2)->Y < ((const PSHAPEPOINT) pv1)->Y)
    {
      return +1;
    }
  else if (((const PSHAPEPOINT) pv1)->X < ((const PSHAPEPOINT) pv2)->X)
    {
      return -1;
    }
  else if (((const PSHAPEPOINT) pv2)->X < ((const PSHAPEPOINT) pv1)->X)
    {
      return +1;
    }
  else
    {
      return 0;
    }
}
#endif


BOOL
STDCALL
NtGdiPie(HDC  hDC,
              int  Left,
              int  Top,
              int  Right,
              int  Bottom,
              int  XRadialStart,
              int  YRadialStart,
              int  XRadialEnd,
              int  YRadialEnd)
{
#ifdef TODO
  PDC dc;
  RECTL RectBounds;
  SURFOBJ *SurfObj;
  BRUSHOBJ PenBrushObj;
  PBRUSHOBJ FillBrushObj;
  PSHAPEPOINT ShapePoints;
  UINT Point, PointCount;
  BOOL ret = TRUE;
  int Y, CircleStart, CircleEnd, LineStart, LineEnd;
  BOOL FullFill;

  if (Right <= Left || Bottom <= Top)
    {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return FALSE;
    }

  if (Right - Left != Bottom - Top)
    {
      UNIMPLEMENTED;
    }

  dc = DC_LockDc ( hDC );
  if (NULL == dc)
    {
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return FALSE;
    }
  if (dc->IsIC)
    {
      DC_UnlockDc(dc);
      /* Yes, Windows really returns TRUE in this case */
      return TRUE;
    }

  FillBrushObj = BRUSHOBJ_LockBrush(dc->Dc_Attr.hbrush);
  if (NULL == FillBrushObj)
    {
      DC_UnlockDc(dc);
      SetLastWin32Error(ERROR_INTERNAL_ERROR);
      return FALSE;
    }

  Left += dc->w.DCOrgX;
  Right += dc->w.DCOrgX;
  Top += dc->w.DCOrgY;
  Bottom += dc->w.DCOrgY;
  XRadialStart += dc->w.DCOrgX;
  YRadialStart += dc->w.DCOrgY;
  XRadialEnd += dc->w.DCOrgX;
  YRadialEnd += dc->w.DCOrgY;

  RectBounds.left = Left;
  RectBounds.right = Right;
  RectBounds.top = Top;
  RectBounds.bottom = Bottom;

  SurfObj = (SURFOBJ*) AccessUserObject((ULONG)dc->Surface);
  HPenToBrushObj(&PenBrushObj, dc->Dc_Attr.hpen);

  /* Number of points for the circle is 4 * sqrt(2) * Radius, start
     and end line have at most Radius points, so allocate at least
     that much */
  ShapePoints = ExAllocatePoolWithTag(PagedPool, 8 * (Right - Left + 1) / 2 * sizeof(SHAPEPOINT), TAG_SHAPE);
  if (NULL == ShapePoints)
    {
      BRUSHOBJ_UnlockBrush(FillBrushObj);
      DC_UnlockDc(dc);

      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
      return FALSE;
    }

  if (Left == Right)
    {
      PUTPIXEL(Left, Top, &PenBrushObj);
      BRUSHOBJ_UnlockBrush(FillBrushObj);
      DC_UnlockDc(dc);

      return ret;
    }

  PointCount = 0;
  CirclePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom);
  LinePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom,
             XRadialStart, YRadialStart, TRUE);
  LinePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom,
             XRadialEnd, YRadialEnd, FALSE);
  ASSERT(PointCount <= 8 * (Right - Left + 1) / 2);
  EngSort((PBYTE) ShapePoints, sizeof(SHAPEPOINT), PointCount, CompareShapePoints);

  FullFill = TRUE;
  Point = 0;
  while (Point < PointCount)
    {
      Y = ShapePoints[Point].Y;

      /* Skip any line pixels before circle */
      while (Point < PointCount && ShapePoints[Point].Y == Y
             && SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type)
	{
	  Point++;
	}

      /* Handle left side of circle */
      if (Point < PointCount && ShapePoints[Point].Y == Y)
	{
	  CircleStart = ShapePoints[Point].X;
	  Point++;
	  while (Point < PointCount && ShapePoints[Point].Y == Y
	         && ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
	         && SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
	    {
	      Point++;
	    }
	  CircleEnd = ShapePoints[Point - 1].X;

	  PUTLINE(CircleStart, Y, CircleEnd + 1, Y, &PenBrushObj);
	}

      /* Handle line(s) (max 2) inside the circle */
      while (Point < PointCount && ShapePoints[Point].Y == Y
             && SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type)
	{
	  LineStart = ShapePoints[Point].X;
	  Point++;
	  while (Point < PointCount && ShapePoints[Point].Y == Y
	         && ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
	         && ShapePoints[Point].Type == ShapePoints[Point - 1].Type)
	    {
	      Point++;
	    }
	  LineEnd = ShapePoints[Point - 1].X;

	  PUTLINE(LineStart, Y, LineEnd + 1, Y, &PenBrushObj);
	}

      /* Handle right side of circle */
      while (Point < PointCount && ShapePoints[Point].Y == Y
             && SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
	{
	  CircleStart = ShapePoints[Point].X;
	  Point++;
	  while (Point < PointCount && ShapePoints[Point].Y == Y
	         && ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
	         && SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
	    {
	      Point++;
	    }
	  CircleEnd = ShapePoints[Point - 1].X;

	  PUTLINE(CircleStart, Y, CircleEnd + 1, Y, &PenBrushObj);
	}

      /* Skip any line pixels after circle */
      while (Point < PointCount && ShapePoints[Point].Y == Y)
	{
	  Point++;
	}
    }

  ExFreePool(ShapePoints);
  BRUSHOBJ_UnlockBrush(FillBrushObj);
  DC_UnlockDc(dc);

  return ret;
#else
return TRUE;
#endif
}

#if 0

//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
//even-numbered polygon sides on each scan line. That is, GDI fills the area between the
//first and second side, between the third and fourth side, and so on.

//WINDING Selects winding mode (fills any region with a nonzero winding value).
//When the fill mode is WINDING, GDI fills any region that has a nonzero winding value.
//This value is defined as the number of times a pen used to draw the polygon would go around the region.
//The direction of each edge of the polygon is important.

extern BOOL FillPolygon(PDC dc,
				  SURFOBJ *SurfObj,
				  PBRUSHOBJ BrushObj,
				  MIX RopMode,
				  CONST PPOINT Points,
				  int Count,
				  RECTL BoundRect);

#endif

BOOL
STDCALL
NtGdiPolygon(HDC          hDC,
             CONST PPOINT UnsafePoints,
             int          Count)
{
  DC *dc;
  LPPOINT Safept;
  NTSTATUS Status = STATUS_SUCCESS;
  BOOL Ret = FALSE;

  if ( Count < 2 )
  {
    SetLastWin32Error(ERROR_INVALID_PARAMETER);
    return FALSE;
  }
  
  _SEH_TRY
  {
    ProbeForRead(UnsafePoints,
                 Count * sizeof(POINT),
                 1);
  }
  _SEH_HANDLE
  {
    Status = _SEH_GetExceptionCode();
  }
  _SEH_END;
  
  if (!NT_SUCCESS(Status))
  {
    SetLastNtError(Status);
    return FALSE;
  }

  dc = DC_LockDc(hDC);
  if(!dc)
    SetLastWin32Error(ERROR_INVALID_HANDLE);
  else
  {
    if (dc->IsIC)
    {
      DC_UnlockDc(dc);
      /* Yes, Windows really returns TRUE in this case */
      return TRUE;
    }
    Safept = ExAllocatePoolWithTag(PagedPool, sizeof(POINT) * Count, TAG_SHAPE);
    if(!Safept)
      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
    else
    {
      _SEH_TRY
      {
        /* pointer was already probed! */
        RtlCopyMemory(Safept,
                      UnsafePoints,
                      Count * sizeof(POINT));
      }
      _SEH_HANDLE
      {
        Status = _SEH_GetExceptionCode();
      }
      _SEH_END;

      if(!NT_SUCCESS(Status))
        SetLastNtError(Status);
      else
        Ret = IntGdiPolygon(dc, Safept, Count);

      ExFreePool(Safept);
    }
    DC_UnlockDc(dc);
  }

  return Ret;
}


BOOL
STDCALL
NtGdiPolyPolygon(HDC           hDC,
                 CONST LPPOINT Points,
                 CONST LPINT   PolyCounts,
                 int           Count)
{
  DC *dc;
  LPPOINT Safept;
  LPINT SafePolyPoints;
  NTSTATUS Status = STATUS_SUCCESS;
  BOOL Ret;

  dc = DC_LockDc(hDC);
  if(!dc)
  {
    SetLastWin32Error(ERROR_INVALID_HANDLE);
    return FALSE;
  }
  if (dc->IsIC)
  {
    DC_UnlockDc(dc);
    /* Yes, Windows really returns TRUE in this case */
    return TRUE;
  }

  if(Count > 0)
  {
    _SEH_TRY
    {
      ProbeForRead(Points,
                   Count * sizeof(POINT),
                   1);
      ProbeForRead(PolyCounts,
                   Count * sizeof(INT),
                   1);
    }
    _SEH_HANDLE
    {
      Status = _SEH_GetExceptionCode();
    }
    _SEH_END;

    if (!NT_SUCCESS(Status))
    {
      DC_UnlockDc(dc);
      SetLastNtError(Status);
      return FALSE;
    }
  
    Safept = ExAllocatePoolWithTag(PagedPool, (sizeof(POINT) + sizeof(INT)) * Count, TAG_SHAPE);
    if(!Safept)
    {
      DC_UnlockDc(dc);
      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
      return FALSE;
    }

    SafePolyPoints = (LPINT)&Safept[Count];
    
    _SEH_TRY
    {
      /* pointers already probed! */
      RtlCopyMemory(Safept,
                    Points,
                    Count * sizeof(POINT));
      RtlCopyMemory(SafePolyPoints,
                    PolyCounts,
                    Count * sizeof(INT));
    }
    _SEH_HANDLE
    {
      Status = _SEH_GetExceptionCode();
    }
    _SEH_END;

    if(!NT_SUCCESS(Status))
    {
      DC_UnlockDc(dc);
      ExFreePool(Safept);
      SetLastNtError(Status);
      return FALSE;
    }
  }
  else
  {
    DC_UnlockDc(dc);
    SetLastWin32Error(ERROR_INVALID_PARAMETER);
    return FALSE;
  }

  Ret = IntGdiPolyPolygon(dc, Safept, SafePolyPoints, Count);

  ExFreePool(Safept);
  DC_UnlockDc(dc);

  return Ret;
}


ULONG_PTR
STDCALL
NtGdiPolyPolyDraw( IN HDC hdc,
                   IN PPOINT ppt,
                   IN PULONG pcpt,
                   IN ULONG ccpt,
                   IN INT iFunc )
{
  return (ULONG_PTR) 0;
}


BOOL
FASTCALL
IntRectangle(PDC dc,
	     int LeftRect,
	     int TopRect,
	     int RightRect,
	     int BottomRect)
{
  BITMAPOBJ *BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
  PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
  GDIBRUSHINST PenBrushInst, FillBrushInst;
  BOOL       ret = FALSE; // default to failure
  RECTL      DestRect;
  MIX        Mix;

  ASSERT ( dc ); // caller's responsibility to set this up
  /* FIXME - BitmapObj can be NULL!!! Don't assert but handle this case gracefully! */
  ASSERT ( BitmapObj );

  if ( PATH_IsPathOpen(dc->w.path) )
  {
    ret = PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
  }
  else
  {
    LeftRect   += dc->w.DCOrgX;
    RightRect  += dc->w.DCOrgX - 1;
    TopRect    += dc->w.DCOrgY;
    BottomRect += dc->w.DCOrgY - 1;

    DestRect.left = LeftRect;
    DestRect.right = RightRect;
    DestRect.top = TopRect;
    DestRect.bottom = BottomRect;

    FillBrushObj = BRUSHOBJ_LockBrush(dc->Dc_Attr.hbrush);

    if ( FillBrushObj )
    {
      if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
      {
        IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
        ret = IntEngBitBlt(&BitmapObj->SurfObj,
                           NULL,
                           NULL,
                           dc->CombinedClip,
                           NULL,
                           &DestRect,
                           NULL,
                           NULL,
                           &FillBrushInst.BrushObject,
                           NULL,
                           ROP3_TO_ROP4(PATCOPY));
      }
    }

    BRUSHOBJ_UnlockBrush(FillBrushObj);

    /* get BRUSHOBJ from current pen. */
    PenBrushObj = PENOBJ_LockPen(dc->Dc_Attr.hpen);
    if (PenBrushObj == NULL)
    {
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      BITMAPOBJ_UnlockBitmap(BitmapObj);
      return FALSE;
    }

    IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);

    // Draw the rectangle with the current pen

    ret = TRUE; // change default to success

    if (!(PenBrushObj->flAttrs & GDIBRUSH_IS_NULL))
    {
      Mix = ROP2_TO_MIX(dc->Dc_Attr.jROP2);
      ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
			 dc->CombinedClip,
			 &PenBrushInst.BrushObject,
			 LeftRect, TopRect, RightRect, TopRect,
			 &DestRect, // Bounding rectangle
			 Mix);

      ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
			 dc->CombinedClip,
			 &PenBrushInst.BrushObject,
			 RightRect, TopRect, RightRect, BottomRect,
			 &DestRect, // Bounding rectangle
			 Mix);

      ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
			 dc->CombinedClip,
			 &PenBrushInst.BrushObject,
			 RightRect, BottomRect, LeftRect, BottomRect,
			 &DestRect, // Bounding rectangle
			 Mix);

      ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
			 dc->CombinedClip,
			 &PenBrushInst.BrushObject,
			 LeftRect, BottomRect, LeftRect, TopRect,
			 &DestRect, // Bounding rectangle
			 Mix);
    }

    PENOBJ_UnlockPen(PenBrushObj);
  }

  BITMAPOBJ_UnlockBitmap(BitmapObj);

  /* Move current position in DC?
     MSDN: The current position is neither used nor updated by Rectangle. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -