📄 bitblt.c
字号:
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);
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 + -