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

📄 bitblt.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
  MouseSafetyOnDrawStart(Dest, DestRect->left, DestRect->top,
                         DestRect->right, DestRect->bottom);

  if (Source != Dest)
    BITMAPOBJ_LockBitmapBits(SourceObj);
  MouseSafetyOnDrawStart(Source, SourceRect->left, SourceRect->top,
                         SourceRect->right, SourceRect->bottom);

  /* Call the driver's DrvAlphaBlend if available */
  if (DestObj->flHooks & HOOK_ALPHABLEND)
    {
      ret = GDIDEVFUNCS(Dest).AlphaBlend(
                        Dest, Source, ClipRegion, ColorTranslation,
                        DestRect, SourceRect, BlendObj);
    }

  if (! ret)
    {
      ret = EngAlphaBlend(Dest, Source, ClipRegion, ColorTranslation,
                          DestRect, SourceRect, BlendObj);
    }

  MouseSafetyOnDrawEnd(Source);
  if (Source != Dest)
    BITMAPOBJ_UnlockBitmapBits(SourceObj);
  MouseSafetyOnDrawEnd(Dest);
  BITMAPOBJ_UnlockBitmapBits(DestObj);

  return ret;
}

/**** REACTOS FONT RENDERING CODE *********************************************/

/* renders the alpha mask bitmap */
static BOOLEAN STDCALL
AlphaBltMask(SURFOBJ* Dest,
	SURFOBJ* Source,
	SURFOBJ* Mask,
	XLATEOBJ* ColorTranslation,
	XLATEOBJ* SrcColorTranslation,
	RECTL* DestRect,
	POINTL* SourcePoint,
	POINTL* MaskPoint,
	BRUSHOBJ* Brush,
	POINTL* BrushPoint)
{
  LONG i, j, dx, dy;
  int r, g, b;
  ULONG Background, BrushColor, NewColor;
  BYTE *tMask, *lMask;

  dx = DestRect->right  - DestRect->left;
  dy = DestRect->bottom - DestRect->top;

  if (Mask != NULL)
    {
      BrushColor = XLATEOBJ_iXlate(SrcColorTranslation, Brush->iSolidColor);
      r = (int)GetRValue(BrushColor);
      g = (int)GetGValue(BrushColor);
      b = (int)GetBValue(BrushColor);

      tMask = (PBYTE)Mask->pvScan0 + (SourcePoint->y * Mask->lDelta) + SourcePoint->x;
      for (j = 0; j < dy; j++)
        {
          lMask = tMask;
          for (i = 0; i < dx; i++)
            {
              if (*lMask > 0)
                {
                  if (*lMask == 0xff)
                    {
                      DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
                          Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
                    }
                  else
                    {
                      Background = DIB_GetSource(Dest, DestRect->left + i, DestRect->top + j,
                                                 SrcColorTranslation);

                      NewColor =
                          RGB((*lMask * (r - GetRValue(Background)) >> 8) + GetRValue(Background),
                              (*lMask * (g - GetGValue(Background)) >> 8) + GetGValue(Background),
                              (*lMask * (b - GetBValue(Background)) >> 8) + GetBValue(Background));

                      Background = XLATEOBJ_iXlate(ColorTranslation, NewColor);
                      DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
                        Dest, DestRect->left + i, DestRect->top + j, Background);
                    }
                }
              lMask++;
            }
          tMask += Mask->lDelta;
        }
      return TRUE;
    }
  else
    {
      return FALSE;
    }
}

BOOL STDCALL
EngMaskBitBlt(SURFOBJ *DestObj,
	  SURFOBJ *Mask,
	  CLIPOBJ *ClipRegion,
	  XLATEOBJ *DestColorTranslation,
	  XLATEOBJ *SourceColorTranslation,
	  RECTL *DestRect,
	  POINTL *SourcePoint,
	  POINTL *MaskOrigin,
	  BRUSHOBJ *Brush,
	  POINTL *BrushOrigin)
{
  BYTE               clippingType;
  RECTL              CombinedRect;
  RECT_ENUM          RectEnum;
  BOOL               EnumMore;
  POINTL             InputPoint;
  RECTL              InputRect;
  RECTL              OutputRect;
  POINTL             Translate;
  INTENG_ENTER_LEAVE EnterLeaveSource;
  INTENG_ENTER_LEAVE EnterLeaveDest;
  SURFOBJ*           InputObj;
  SURFOBJ*           OutputObj;
  BOOLEAN            Ret = TRUE;
  RECTL              ClipRect;
  unsigned           i;
  POINTL             Pt;
  ULONG              Direction;
  POINTL             AdjustedBrushOrigin;

  ASSERT ( Mask );

  if (NULL != SourcePoint)
    {
    InputRect.left = SourcePoint->x;
    InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left);
    InputRect.top = SourcePoint->y;
    InputRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top);
    }
  else
    {
    InputRect.left = 0;
    InputRect.right = DestRect->right - DestRect->left;
    InputRect.top = 0;
    InputRect.bottom = DestRect->bottom - DestRect->top;
    }

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

  if (NULL != SourcePoint)
    {
    InputPoint.x = SourcePoint->x + Translate.x;
    InputPoint.y = SourcePoint->y + Translate.y;
    }
  else
    {
    InputPoint.x = 0;
    InputPoint.y = 0;
    }

  OutputRect = *DestRect;
  if (NULL != ClipRegion)
    {
      if (OutputRect.left < ClipRegion->rclBounds.left)
	{
	  InputRect.left += ClipRegion->rclBounds.left - OutputRect.left;
	  InputPoint.x += ClipRegion->rclBounds.left - OutputRect.left;
	  OutputRect.left = ClipRegion->rclBounds.left;
	}
      if (ClipRegion->rclBounds.right < OutputRect.right)
	{
	  InputRect.right -=  OutputRect.right - ClipRegion->rclBounds.right;
	  OutputRect.right = ClipRegion->rclBounds.right;
	}
      if (OutputRect.top < ClipRegion->rclBounds.top)
	{
	  InputRect.top += ClipRegion->rclBounds.top - OutputRect.top;
	  InputPoint.y += ClipRegion->rclBounds.top - OutputRect.top;
	  OutputRect.top = ClipRegion->rclBounds.top;
	}
      if (ClipRegion->rclBounds.bottom < OutputRect.bottom)
	{
	  InputRect.bottom -=  OutputRect.bottom - ClipRegion->rclBounds.bottom;
	  OutputRect.bottom = ClipRegion->rclBounds.bottom;
	}
    }

  /* 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 = DestRect->left + Translate.x;
  OutputRect.right = DestRect->right + Translate.x;
  OutputRect.top = DestRect->top + Translate.y;
  OutputRect.bottom = DestRect->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;
  }

  switch(clippingType)
  {
    case DC_TRIVIAL:
      if(Mask->iBitmapFormat == BMF_8BPP)
        Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
                           &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin);
      else
        Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
                           &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin,
                           R4_MASK);
      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;
          if(Mask->iBitmapFormat == BMF_8BPP)
            {
              Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
                                 &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin);
            }
          else
            {
              Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
                            &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, R4_MASK);
            }
        }
      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;
                  if(Mask->iBitmapFormat == BMF_8BPP)
                    {
                      Ret = AlphaBltMask(OutputObj, InputObj, Mask,
                                         DestColorTranslation,
                                         SourceColorTranslation,
                                         &CombinedRect, &Pt, MaskOrigin, Brush,
                                         &AdjustedBrushOrigin) && Ret;
                    }
                  else
                    {
                      Ret = BltMask(OutputObj, InputObj, Mask,
                                    DestColorTranslation, &CombinedRect, &Pt,
                                    MaskOrigin, Brush, &AdjustedBrushOrigin,
                                    R4_MASK) && Ret;
                    }
                }
	    }
	}
      while(EnumMore);
      break;
  }


  IntEngLeave(&EnterLeaveDest);
  IntEngLeave(&EnterLeaveSource);

  return Ret;
}

BOOL STDCALL
IntEngMaskBlt(SURFOBJ *DestSurf,
              SURFOBJ *Mask,
              CLIPOBJ *ClipRegion,
              XLATEOBJ *DestColorTranslation,
              XLATEOBJ *SourceColorTranslation,
              RECTL *DestRect,
              POINTL *SourcePoint,
              POINTL *MaskOrigin,
              BRUSHOBJ *Brush,
              POINTL *BrushOrigin)
{
  BOOLEAN ret;
  RECTL OutputRect;
  POINTL InputPoint;
  BITMAPOBJ *DestObj;

  ASSERT(Mask);

  if (NULL != SourcePoint)
    {
      InputPoint = *SourcePoint;
    }

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

  /* No success yet */
  ret = FALSE;
  ASSERT(DestSurf);
  DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);

  BITMAPOBJ_LockBitmapBits(DestObj);
  MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
                         OutputRect.right, OutputRect.bottom);

  /* Dummy BitBlt to let driver know that it should flush its changes.
     This should really be done using a call to DrvSynchronizeSurface,
     but the VMware driver doesn't hook that call. */
  IntEngBitBltEx(DestSurf, NULL, Mask, ClipRegion, DestColorTranslation,
                 DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin,
                 R4_NOOP, FALSE);

  ret = EngMaskBitBlt(DestSurf, Mask, ClipRegion, DestColorTranslation, SourceColorTranslation,
                      &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin);

  /* Dummy BitBlt to let driver know that something has changed. */
  IntEngBitBltEx(DestSurf, NULL, Mask, ClipRegion, DestColorTranslation,
                 DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin,
                 R4_NOOP, FALSE);

  MouseSafetyOnDrawEnd(DestSurf);
  BITMAPOBJ_UnlockBitmapBits(DestObj);

  return ret;
}
/* EOF */

⌨️ 快捷键说明

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