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

📄 bitblt.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
    }

  if (Mask != NULL)
    {
      //BltRectFunc = BltMask;
      DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
      IntEngLeave(&EnterLeaveDest);
      IntEngLeave(&EnterLeaveSource);

      return FALSE;
    }
  else
    {
      BltRectFunc = CallDibStretchBlt;
    }


  Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ClipRegion,
                       ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
                       &AdjustedBrushOrigin, Mode);

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

  return Ret;
}

BOOL STDCALL
IntEngStretchBlt(SURFOBJ *DestSurf,
                 SURFOBJ *SourceSurf,
                 SURFOBJ *MaskSurf,
                 CLIPOBJ *ClipRegion,
                 XLATEOBJ *ColorTranslation,
                 RECTL *DestRect,
                 RECTL *SourceRect,
                 POINTL *pMaskOrigin,
                 BRUSHOBJ *Brush,
                 POINTL *BrushOrigin,
                 ULONG Mode)
{
  BOOLEAN ret;
  COLORADJUSTMENT ca;
  POINT MaskOrigin;
  BITMAPOBJ *DestObj;
  BITMAPOBJ *SourceObj = NULL;

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

  if (pMaskOrigin != NULL)
    {
      MaskOrigin.x = pMaskOrigin->x; MaskOrigin.y = pMaskOrigin->y;
    }

  /* No success yet */
  ret = FALSE;
  ASSERT(DestRect);
  BITMAPOBJ_LockBitmapBits(DestObj);
  MouseSafetyOnDrawStart(DestSurf, DestRect->left, DestRect->top,
                         DestRect->right, DestRect->bottom);

  if (NULL != SourceSurf)
    {
    SourceObj = CONTAINING_RECORD(SourceSurf, BITMAPOBJ, SurfObj);
    ASSERT(SourceRect);
    if (SourceSurf != DestSurf)
      {
      BITMAPOBJ_LockBitmapBits(SourceObj);
      }
    MouseSafetyOnDrawStart(SourceSurf, SourceRect->left, SourceRect->top,
                           SourceRect->right, SourceRect->bottom);
    }

  /* Prepare color adjustment */

  /* Call the driver's DrvStretchBlt if available */
  if (DestObj->flHooks & HOOK_STRETCHBLT)
    {
      /* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm )
      SURFOBJ *psoMask // optional, if it exists, then rop4=0xCCAA, otherwise rop4=0xCCCC */
      // FIXME: MaskOrigin is always NULL !
      ret = GDIDEVFUNCS(DestSurf).StretchBlt(
                            DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
                            &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
    }

  if (! ret)
    {
      // FIXME: see previous fixme
      ret = EngStretchBlt(DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
                          &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
    }

  if (NULL != SourceSurf)
    {
    MouseSafetyOnDrawEnd(SourceSurf);
    if (SourceSurf != DestSurf)
      {
      BITMAPOBJ_UnlockBitmapBits(SourceObj);
      }
    }
  MouseSafetyOnDrawEnd(DestSurf);
  BITMAPOBJ_UnlockBitmapBits(DestObj);

  return ret;
}

BOOL
STDCALL
EngAlphaBlend(IN SURFOBJ *Dest,
              IN SURFOBJ *Source,
              IN CLIPOBJ *ClipRegion,
              IN XLATEOBJ *ColorTranslation,
              IN PRECTL DestRect,
              IN PRECTL SourceRect,
              IN BLENDOBJ *BlendObj)
{
  RECTL              SourceStretchedRect;
  SIZEL              SourceStretchedSize;
  HBITMAP            SourceStretchedBitmap = 0;
  SURFOBJ*           SourceStretchedObj = NULL;
  RECTL              InputRect;
  RECTL              OutputRect;
  RECTL              ClipRect;
  RECTL              CombinedRect;
  RECTL              Rect;
  POINTL             Translate;
  INTENG_ENTER_LEAVE EnterLeaveSource;
  INTENG_ENTER_LEAVE EnterLeaveDest;
  SURFOBJ*           InputObj;
  SURFOBJ*           OutputObj;
  LONG               Width;
  LONG               ClippingType;
  RECT_ENUM          RectEnum;
  BOOL               EnumMore;
  INT                i;
  BOOLEAN            Ret;

  DPRINT("EngAlphaBlend(Dest:0x%p, Source:0x%p, ClipRegion:0x%p, ColorTranslation:0x%p,\n", Dest, Source, ClipRegion, ColorTranslation);
  DPRINT("              DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x, 0x%x, 0x%x},\n",
         DestRect->left, DestRect->top, DestRect->right, DestRect->bottom,
         SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
  DPRINT("              BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n", BlendObj->BlendFunction.BlendOp,
         BlendObj->BlendFunction.BlendFlags, BlendObj->BlendFunction.SourceConstantAlpha,
         BlendObj->BlendFunction.AlphaFormat);

  /* Validate input */
  if (DestRect->left >= DestRect->right || DestRect->top >= DestRect->bottom)
    {
      DPRINT1("Empty destination rectangle!\n");
      return FALSE;
    }
  if (SourceRect->left >= SourceRect->right || SourceRect->top >= SourceRect->bottom)
    {
      DPRINT1("Empty source rectangle!\n");
      return FALSE;
    }
  if (Dest == Source &&
      !(DestRect->left >= SourceRect->right || SourceRect->left >= DestRect->right ||
        DestRect->top >= SourceRect->bottom || SourceRect->top >= DestRect->bottom))
    {
      DPRINT1("Source and destination rectangles overlap!\n");
      return FALSE;
    }

  if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER)
    {
      DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n", BlendObj->BlendFunction.BlendOp);
      return FALSE;
    }
  if (BlendObj->BlendFunction.BlendFlags != 0)
    {
      DPRINT1("BlendFlags != 0 (0x%x)\n", BlendObj->BlendFunction.BlendFlags);
      return FALSE;
    }
  if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0)
    {
      DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendObj->BlendFunction.AlphaFormat);
      return FALSE;
    }

  /* Check if there is anything to draw */
  if (ClipRegion != NULL &&
      (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
       ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
    {
      /* Nothing to do */
      return TRUE;
    }

  /* Stretch source if needed */
  if (DestRect->right - DestRect->left != SourceRect->right - SourceRect->left ||
      DestRect->bottom - DestRect->top != SourceRect->bottom - SourceRect->top)
    {
      SourceStretchedSize.cx = DestRect->right - DestRect->left;
      SourceStretchedSize.cy = DestRect->bottom - DestRect->top;
      Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx, BitsPerFormat(Source->iBitmapFormat));
      /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and IntEngStretchBlt
                if possible to get a HW accelerated stretch. */
      SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width, Source->iBitmapFormat,
                                              BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
      if (SourceStretchedBitmap == 0)
        {
          DPRINT1("EngCreateBitmap failed!\n");
          return FALSE;
        }
      SourceStretchedObj = EngLockSurface((HSURF)SourceStretchedBitmap);
      if (SourceStretchedObj == NULL)
        {
          DPRINT1("EngLockSurface failed!\n");
          EngDeleteSurface((HSURF)SourceStretchedBitmap);
          return FALSE;
        }

      SourceStretchedRect.left = 0;
      SourceStretchedRect.right = SourceStretchedSize.cx;
      SourceStretchedRect.top = 0;
      SourceStretchedRect.bottom = SourceStretchedSize.cy;
      /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
                try to acquire an already acquired mutex (lock the already locked source surface) */
      /*if (!IntEngStretchBlt(SourceStretchedObj, Source, NULL, NULL,
                            NULL, &SourceStretchedRect, SourceRect, NULL,
                            NULL, NULL, COLORONCOLOR))*/
      if (!EngStretchBlt(SourceStretchedObj, Source, NULL, NULL, NULL,
                         NULL, NULL, &SourceStretchedRect, SourceRect,
                         NULL, COLORONCOLOR))
        {
          DPRINT1("EngStretchBlt failed!\n");
          EngFreeMem(SourceStretchedObj->pvBits);
          EngUnlockSurface(SourceStretchedObj);
          EngDeleteSurface((HSURF)SourceStretchedBitmap);
          return FALSE;
        }
      SourceRect = &SourceStretchedRect;
      Source = SourceStretchedObj;
    }

  /* Now call the DIB function */
  InputRect.left = SourceRect->left;
  InputRect.right = SourceRect->right;
  InputRect.top = SourceRect->top;
  InputRect.bottom = SourceRect->bottom;
  if (!IntEngEnter(&EnterLeaveSource, Source, &InputRect, TRUE, &Translate, &InputObj))
    {
      if (SourceStretchedObj != NULL)
        {
          EngFreeMem(SourceStretchedObj->pvBits);
          EngUnlockSurface(SourceStretchedObj);
        }
      if (SourceStretchedBitmap != 0)
        {
          EngDeleteSurface((HSURF)SourceStretchedBitmap);
        }
      return FALSE;
    }
  InputRect.left = SourceRect->left + Translate.x;
  InputRect.right = SourceRect->right + Translate.x;
  InputRect.top = SourceRect->top + Translate.y;
  InputRect.bottom = SourceRect->bottom + Translate.y;

  OutputRect.left = DestRect->left;
  OutputRect.right = DestRect->right;
  OutputRect.top = DestRect->top;
  OutputRect.bottom = DestRect->bottom;
  if (!IntEngEnter(&EnterLeaveDest, Dest, &OutputRect, FALSE, &Translate, &OutputObj))
    {
      IntEngLeave(&EnterLeaveSource);
      if (SourceStretchedObj != NULL)
        {
          EngFreeMem(SourceStretchedObj->pvBits);
          EngUnlockSurface(SourceStretchedObj);
        }
      if (SourceStretchedBitmap != 0)
        {
          EngDeleteSurface((HSURF)SourceStretchedBitmap);
        }
      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;

  Ret = FALSE;
  ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity;
  switch(ClippingType)
    {
    case DC_TRIVIAL:
      Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion, ColorTranslation, BlendObj);
      break;

    case DC_RECT:
      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))
        {
          Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
          Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
          Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
          Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
          Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                    OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj);
        }
      break;

    case DC_COMPLEX:
      Ret = TRUE;
      CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 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))
                {
                  Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
                  Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
                  Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
                  Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
                  Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                            OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj) && Ret;
                }
            }
        }
      while(EnumMore);
      break;

    default:
      UNIMPLEMENTED;
      ASSERT(FALSE);
      break;
    }

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

  if (SourceStretchedObj != NULL)
    {
      EngFreeMem(SourceStretchedObj->pvBits);
      EngUnlockSurface(SourceStretchedObj);
    }
  if (SourceStretchedBitmap != 0)
    {
      EngDeleteSurface((HSURF)SourceStretchedBitmap);
    }

  return Ret;
}

BOOL STDCALL
IntEngAlphaBlend(IN SURFOBJ *Dest,
                 IN SURFOBJ *Source,
                 IN CLIPOBJ *ClipRegion,
                 IN XLATEOBJ *ColorTranslation,
                 IN PRECTL DestRect,
                 IN PRECTL SourceRect,
                 IN BLENDOBJ *BlendObj)
{
  BOOL ret = FALSE;
  BITMAPOBJ *DestObj;
  BITMAPOBJ *SourceObj;

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

  ASSERT(Source);
  SourceObj = CONTAINING_RECORD(Source, BITMAPOBJ, SurfObj);
  ASSERT(SourceObj);

  ASSERT(DestRect);
  ASSERT(SourceRect);

  /* Check if there is anything to draw */
  if (ClipRegion != NULL &&
      (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
       ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
    {
      /* Nothing to do */
      return TRUE;
    }

  BITMAPOBJ_LockBitmapBits(DestObj);

⌨️ 快捷键说明

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