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

📄 bitblt.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
    if (UsesSource)
      {
      IntEngLeave(&EnterLeaveSource);
      }
    return TRUE;
    }

  if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate,
                    &OutputObj))
    {
    if (UsesSource)
      {
      IntEngLeave(&EnterLeaveSource);
      }
    return FALSE;
    }

  OutputRect.left += Translate.x;
  OutputRect.right += Translate.x;
  OutputRect.top += Translate.y;
  OutputRect.bottom += Translate.y;

  if(BrushOrigin)
    {
    AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
    AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
    }
  else
    {
    AdjustedBrushOrigin = Translate;
    }

  /* Determine clipping type */
  if (ClipRegion == (CLIPOBJ *) NULL)
    {
    clippingType = DC_TRIVIAL;
    }
  else
    {
    clippingType = ClipRegion->iDComplexity;
    }

  if (R4_MASK == Rop4)
    {
      BltRectFunc = BltMask;
    }
  else if (ROP3_TO_ROP4(PATCOPY) == Rop4)
    {
      if (Brush->iSolidColor == 0xFFFFFFFF)
        BltRectFunc = CallDibBitBlt;
      else
        BltRectFunc = BltPatCopy;
    }
  else
    {
      BltRectFunc = CallDibBitBlt;
    }


  switch(clippingType)
  {
    case DC_TRIVIAL:
      Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
                           &OutputRect, &InputPoint, MaskOrigin, Brush,
                           &AdjustedBrushOrigin, Rop4);
      break;
    case DC_RECT:
      /* Clip the blt to the clip rectangle */
      ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
      ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
      ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
      ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
      if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
        {
          Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
          Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
          Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
                               &CombinedRect, &Pt, MaskOrigin, Brush,
                               &AdjustedBrushOrigin, Rop4);
        }
      break;
    case DC_COMPLEX:
      Ret = TRUE;
      if (OutputObj == InputObj)
	{
	  if (OutputRect.top < InputPoint.y)
	    {
	      Direction = OutputRect.left < InputPoint.x ?
                          CD_RIGHTDOWN : CD_LEFTDOWN;
	    }
	  else
	    {
	      Direction = OutputRect.left < InputPoint.x ?
                          CD_RIGHTUP : CD_LEFTUP;
	    }
	}
      else
	{
	  Direction = CD_ANY;
	}
      CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0);
      do
	{
	  EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
                                   (PVOID) &RectEnum);

	  for (i = 0; i < RectEnum.c; i++)
	    {
	      ClipRect.left = RectEnum.arcl[i].left + Translate.x;
	      ClipRect.right = RectEnum.arcl[i].right + Translate.x;
	      ClipRect.top = RectEnum.arcl[i].top + Translate.y;
	      ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
	      if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
                {
                  Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
                  Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
                  Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
                                       ColorTranslation, &CombinedRect, &Pt,
                                       MaskOrigin, Brush, &AdjustedBrushOrigin,
                                       Rop4) && Ret;
                }
	    }
	}
      while(EnumMore);
      break;
  }


  IntEngLeave(&EnterLeaveDest);
  if (UsesSource)
    {
    IntEngLeave(&EnterLeaveSource);
    }

  return Ret;
}

BOOL STDCALL
IntEngBitBltEx(SURFOBJ *DestSurf,
               SURFOBJ *SourceSurf,
               SURFOBJ *MaskSurf,
               CLIPOBJ *ClipRegion,
               XLATEOBJ *ColorTranslation,
               RECTL *DestRect,
               POINTL *SourcePoint,
               POINTL *MaskOrigin,
               BRUSHOBJ *Brush,
               POINTL *BrushOrigin,
               ROP4 Rop4,
               BOOL RemoveMouse)
{
  BOOLEAN ret;
  RECTL InputClippedRect;
  RECTL OutputRect;
  POINTL InputPoint;
  BOOLEAN UsesSource;
  BITMAPOBJ *DestObj;
  BITMAPOBJ *SourceObj = NULL;

  if (DestSurf == NULL)
    return FALSE;

  ASSERT(DestSurf);
  DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
  ASSERT(DestObj);

  InputClippedRect = *DestRect;
  if (InputClippedRect.right < InputClippedRect.left)
    {
      InputClippedRect.left = DestRect->right;
      InputClippedRect.right = DestRect->left;
    }
  if (InputClippedRect.bottom < InputClippedRect.top)
    {
      InputClippedRect.top = DestRect->bottom;
      InputClippedRect.bottom = DestRect->top;
    }
  UsesSource = ROP4_USES_SOURCE(Rop4);
  if (UsesSource)
    {
      if (NULL == SourcePoint || NULL == SourceSurf)
        {
          return FALSE;
        }
      InputPoint = *SourcePoint;

      /* Make sure we don't try to copy anything outside the valid source
         region */
      if (InputPoint.x < 0)
        {
          InputClippedRect.left -= InputPoint.x;
          InputPoint.x = 0;
        }
      if (InputPoint.y < 0)
        {
          InputClippedRect.top -= InputPoint.y;
          InputPoint.y = 0;
        }
      if (SourceSurf->sizlBitmap.cx < InputPoint.x +
                                      InputClippedRect.right -
                                      InputClippedRect.left)
        {
          InputClippedRect.right = InputClippedRect.left +
                                   SourceSurf->sizlBitmap.cx - InputPoint.x;
        }
      if (SourceSurf->sizlBitmap.cy < InputPoint.y +
                                      InputClippedRect.bottom -
                                      InputClippedRect.top)
        {
          InputClippedRect.bottom = InputClippedRect.top +
                                    SourceSurf->sizlBitmap.cy - InputPoint.y;
        }

      if (InputClippedRect.right < InputClippedRect.left ||
          InputClippedRect.bottom < InputClippedRect.top)
        {
          /* Everything clipped away, nothing to do */
          return TRUE;
        }
    }

  /* Clip against the bounds of the clipping region so we won't try to write
   * outside the surface */
  if (NULL != ClipRegion)
    {
      if (! EngIntersectRect(&OutputRect, &InputClippedRect,
                             &ClipRegion->rclBounds))
	{
	  return TRUE;
	}
      InputPoint.x += OutputRect.left - InputClippedRect.left;
      InputPoint.y += OutputRect.top - InputClippedRect.top;
    }
  else
    {
      OutputRect = InputClippedRect;
    }

  if (RemoveMouse)
    {
    BITMAPOBJ_LockBitmapBits(DestObj);

    if (UsesSource)
      {
      if (SourceSurf != DestSurf)
        {
        SourceObj = CONTAINING_RECORD(SourceSurf, BITMAPOBJ, SurfObj);
        BITMAPOBJ_LockBitmapBits(SourceObj);
        }
      MouseSafetyOnDrawStart(SourceSurf, InputPoint.x, InputPoint.y,
                             (InputPoint.x + abs(DestRect->right - DestRect->left)),
  			   (InputPoint.y + abs(DestRect->bottom - DestRect->top)));
      }
    MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
                           OutputRect.right, OutputRect.bottom);
    }

  /* No success yet */
  ret = FALSE;

  /* Call the driver's DrvBitBlt if available */
  if (DestObj->flHooks & HOOK_BITBLT)
    {
      ret = GDIDEVFUNCS(DestSurf).BitBlt(
                            DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
                            &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
                            Rop4);
    }

  if (! ret)
    {
      ret = EngBitBlt(DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
                      &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
                      Rop4);
    }

  if (RemoveMouse)
    {
    MouseSafetyOnDrawEnd(DestSurf);
    if (UsesSource)
      {
      MouseSafetyOnDrawEnd(SourceSurf);
      if (SourceSurf != DestSurf)
        {
        BITMAPOBJ_UnlockBitmapBits(SourceObj);
        }
      }

    BITMAPOBJ_UnlockBitmapBits(DestObj);
    }

  return ret;
}

static BOOLEAN STDCALL
CallDibStretchBlt(SURFOBJ* OutputObj,
                  SURFOBJ* InputObj,
                  SURFOBJ* Mask,
	          CLIPOBJ* ClipRegion,
                  XLATEOBJ* ColorTranslation,
                  RECTL* OutputRect,
                  RECTL* InputRect,
                  POINTL* MaskOrigin,
                  POINTL* BrushOrigin,
                  ULONG Mode)
{
  POINTL RealBrushOrigin;
  if (BrushOrigin == NULL)
    {
      RealBrushOrigin.x = RealBrushOrigin.y = 0;
    }
  else
    {
      RealBrushOrigin = *BrushOrigin;
    }
  return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_StretchBlt(
    OutputObj, InputObj, OutputRect, InputRect, MaskOrigin, RealBrushOrigin, ClipRegion, ColorTranslation, Mode);
}


BOOL
STDCALL
EngStretchBlt(
	IN SURFOBJ  *DestObj,
	IN SURFOBJ  *SourceObj,
	IN SURFOBJ  *Mask,
	IN CLIPOBJ  *ClipRegion,
	IN XLATEOBJ  *ColorTranslation,
	IN COLORADJUSTMENT  *pca,
	IN POINTL  *BrushOrigin,
	IN RECTL  *prclDest,
	IN RECTL  *prclSrc,
	IN POINTL  *MaskOrigin,
	IN ULONG  Mode
	)
{
  // www.osr.com/ddk/graphics/gdifncs_0bs7.htm

  POINTL             InputPoint;
  RECTL              InputRect;
  RECTL              OutputRect;
  POINTL             Translate;
  INTENG_ENTER_LEAVE EnterLeaveSource;
  INTENG_ENTER_LEAVE EnterLeaveDest;
  SURFOBJ*           InputObj;
  SURFOBJ*           OutputObj;
  PSTRETCHRECTFUNC   BltRectFunc;
  BOOLEAN            Ret;
  POINTL             AdjustedBrushOrigin;

  InputRect.left = prclSrc->left;
  InputRect.right = prclSrc->right;
  InputRect.top = prclSrc->top;
  InputRect.bottom = prclSrc->bottom;

  if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
    {
      return FALSE;
    }

  InputPoint.x = InputRect.left + Translate.x;
  InputPoint.y = InputRect.top + Translate.y;

  OutputRect = *prclDest;

  /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
     nothing to do */
  if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
    {
      IntEngLeave(&EnterLeaveSource);
      return TRUE;
    }

  if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
    {
      IntEngLeave(&EnterLeaveSource);
      return FALSE;
    }

  OutputRect.left = prclDest->left + Translate.x;
  OutputRect.right = prclDest->right + Translate.x;
  OutputRect.top = prclDest->top + Translate.y;
  OutputRect.bottom = prclDest->bottom + Translate.y;

  if (NULL != BrushOrigin)
    {
      AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
      AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
    }
  else
    {
      AdjustedBrushOrigin = Translate;

⌨️ 快捷键说明

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