* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* $Id$
*
* 4/6/2004: Created
*/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
-BOOL STDCALL
-EngTransparentBlt(SURFOBJ *Dest,
- SURFOBJ *Source,
+BOOL APIENTRY
+EngTransparentBlt(SURFOBJ *psoDest,
+ SURFOBJ *psoSource,
CLIPOBJ *Clip,
XLATEOBJ *ColorTranslation,
PRECTL DestRect,
INTENG_ENTER_LEAVE EnterLeaveSource, EnterLeaveDest;
SURFOBJ *InputObj, *OutputObj;
RECTL OutputRect, InputRect;
- POINTL Translate, InputPoint;
+ POINTL Translate;
- InputRect.left = 0;
- InputRect.right = DestRect->right - DestRect->left;
- InputRect.top = 0;
- InputRect.bottom = DestRect->bottom - DestRect->top;
+ LONG DstHeight;
+ LONG DstWidth;
+ LONG SrcHeight;
+ LONG SrcWidth;
- if(!IntEngEnter(&EnterLeaveSource, Source, &InputRect, TRUE, &Translate, &InputObj))
+ InputRect = *SourceRect;
+
+ if(!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
{
return FALSE;
}
-
- InputPoint.x = SourceRect->left + Translate.x;
- InputPoint.y = SourceRect->top + Translate.y;
+ InputRect.left += Translate.x;
+ InputRect.right += Translate.x;
+ InputRect.top += Translate.y;
+ InputRect.bottom += Translate.y;
OutputRect = *DestRect;
+ if (OutputRect.right < OutputRect.left)
+ {
+ OutputRect.left = DestRect->right;
+ OutputRect.right = DestRect->left;
+ }
+ if (OutputRect.bottom < OutputRect.top)
+ {
+ OutputRect.top = DestRect->bottom;
+ OutputRect.bottom = DestRect->top;
+ }
+
if(Clip)
{
if(OutputRect.left < Clip->rclBounds.left)
{
InputRect.left += Clip->rclBounds.left - OutputRect.left;
- InputPoint.x += Clip->rclBounds.left - OutputRect.left;
OutputRect.left = Clip->rclBounds.left;
}
if(Clip->rclBounds.right < OutputRect.right)
if(OutputRect.top < Clip->rclBounds.top)
{
InputRect.top += Clip->rclBounds.top - OutputRect.top;
- InputPoint.y += Clip->rclBounds.top - OutputRect.top;
OutputRect.top = Clip->rclBounds.top;
}
if(Clip->rclBounds.bottom < OutputRect.bottom)
return TRUE;
}
- if(!IntEngEnter(&EnterLeaveDest, Dest, &OutputRect, FALSE, &Translate, &OutputObj))
+ if(!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj))
{
IntEngLeave(&EnterLeaveSource);
return FALSE;
ClippingType = (Clip ? Clip->iDComplexity : DC_TRIVIAL);
+ DstHeight = OutputRect.bottom - OutputRect.top;
+ DstWidth = OutputRect.right - OutputRect.left;
+ SrcHeight = InputRect.bottom - InputRect.top;
+ SrcWidth = InputRect.right - InputRect.left;
switch(ClippingType)
{
case DC_TRIVIAL:
{
- Ret = DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_TransparentBlt(
- OutputObj, InputObj, &OutputRect, &InputPoint, ColorTranslation, iTransColor);
+ Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
+ OutputObj, InputObj, &OutputRect, &InputRect, ColorTranslation, iTransColor);
break;
}
case DC_RECT:
{
RECTL ClipRect, CombinedRect;
- POINTL Pt;
+ RECTL InputToCombinedRect;
ClipRect.left = Clip->rclBounds.left + Translate.x;
ClipRect.right = Clip->rclBounds.right + Translate.x;
ClipRect.top = Clip->rclBounds.top + Translate.y;
ClipRect.bottom = Clip->rclBounds.bottom + Translate.y;
- EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
- Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
- Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
- Ret = DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_TransparentBlt(
- OutputObj, InputObj, &CombinedRect, &Pt, ColorTranslation, iTransColor);
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
+ InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
+ InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
+ InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
+ Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
+ OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor);
+ }
break;
}
case DC_COMPLEX:
ULONG Direction, i;
RECT_ENUM RectEnum;
BOOL EnumMore;
- POINTL Pt;
if(OutputObj == InputObj)
{
- if(OutputRect.top < InputPoint.y)
+ if(OutputRect.top < InputRect.top)
{
- Direction = OutputRect.left < (InputPoint.x ? CD_RIGHTDOWN : CD_LEFTDOWN);
+ Direction = OutputRect.left < (InputRect.left ? CD_RIGHTDOWN : CD_LEFTDOWN);
}
else
{
- Direction = OutputRect.left < (InputPoint.x ? CD_RIGHTUP : CD_LEFTUP);
+ Direction = OutputRect.left < (InputRect.left ? CD_RIGHTUP : CD_LEFTUP);
}
}
else
for (i = 0; i < RectEnum.c; i++)
{
RECTL ClipRect, CombinedRect;
+ RECTL InputToCombinedRect;
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;
- EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
- Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
- Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
- Ret = DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_TransparentBlt(
- OutputObj, InputObj, &CombinedRect, &Pt, ColorTranslation, iTransColor);
- if(!Ret)
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
{
- break;
+ InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
+ InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
+ InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
+ InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
+
+ Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
+ OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor);
+ if(!Ret)
+ {
+ break;
+ }
}
}
} while(EnumMore && Ret);
}
BOOL FASTCALL
-IntEngTransparentBlt(SURFOBJ *DestSurf,
- SURFOBJ *SourceSurf,
+IntEngTransparentBlt(SURFOBJ *psoDest,
+ SURFOBJ *psoSource,
CLIPOBJ *Clip,
XLATEOBJ *ColorTranslation,
PRECTL DestRect,
{
BOOL Ret;
RECTL OutputRect, InputClippedRect;
- BITMAPOBJ *DestObj;
- BITMAPOBJ *SourceObj;
+ SURFACE *psurfDest;
+ SURFACE *psurfSource;
+ RECTL InputRect;
+ LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
- ASSERT(DestSurf);
- ASSERT(SourceSurf);
+ ASSERT(psoDest);
+ ASSERT(psoSource);
ASSERT(DestRect);
- DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
- SourceObj = CONTAINING_RECORD(SourceSurf, BITMAPOBJ, SurfObj);
+ psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
+ psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
- ASSERT(DestObj);
- ASSERT(SourceObj);
+ ASSERT(psurfDest);
+ ASSERT(psurfSource);
InputClippedRect = *DestRect;
if(InputClippedRect.right < InputClippedRect.left)
InputClippedRect.bottom = DestRect->top;
}
+ InputRect = *SourceRect;
/* Clip against the bounds of the clipping region so we won't try to write
* outside the surface */
if(Clip)
{
- if(!EngIntersectRect(&OutputRect, &InputClippedRect, &Clip->rclBounds))
+ if(!RECTL_bIntersectRect(&OutputRect, &InputClippedRect, &Clip->rclBounds))
{
return TRUE;
}
- SourceRect->left += OutputRect.left - DestRect->left;
- SourceRect->top += OutputRect.top - DestRect->top;
- SourceRect->right += OutputRect.left - DestRect->left;
- SourceRect->bottom += OutputRect.top - DestRect->top;
+ /* Update source rect */
+ InputClWidth = InputClippedRect.right - InputClippedRect.left;
+ InputClHeight = InputClippedRect.bottom - InputClippedRect.top;
+ InputWidth = InputRect.right - InputRect.left;
+ InputHeight = InputRect.bottom - InputRect.top;
+
+ InputRect.left += (InputWidth * (OutputRect.left - InputClippedRect.left)) / InputClWidth;
+ InputRect.right -= (InputWidth * (InputClippedRect.right - OutputRect.right)) / InputClWidth;
+ InputRect.top += (InputHeight * (OutputRect.top - InputClippedRect.top)) / InputClHeight;
+ InputRect.bottom -= (InputHeight * (InputClippedRect.bottom - OutputRect.bottom)) / InputClHeight;
}
else
{
- OutputRect = *DestRect;
- }
-
- if(SourceSurf != DestSurf)
- {
- BITMAPOBJ_LockBitmapBits(SourceObj);
- MouseSafetyOnDrawStart(SourceSurf, SourceRect->left, SourceRect->top,
- SourceRect->right, SourceRect->bottom);
+ OutputRect = InputClippedRect;
}
- BITMAPOBJ_LockBitmapBits(DestObj);
- MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
- if(DestObj->flHooks & HOOK_TRANSPARENTBLT)
+ if(psurfDest->flags & HOOK_TRANSPARENTBLT)
{
- Ret = GDIDEVFUNCS(DestSurf).TransparentBlt(
- DestSurf, SourceSurf, Clip, ColorTranslation, &OutputRect,
- SourceRect, iTransColor, Reserved);
+ Ret = GDIDEVFUNCS(psoDest).TransparentBlt(
+ psoDest, psoSource, Clip, ColorTranslation, &OutputRect,
+ &InputRect, iTransColor, Reserved);
}
else
Ret = FALSE;
if(!Ret)
{
- Ret = EngTransparentBlt(DestSurf, SourceSurf, Clip, ColorTranslation,
- &OutputRect, SourceRect, iTransColor, Reserved);
- }
-
- MouseSafetyOnDrawEnd(DestSurf);
- BITMAPOBJ_UnlockBitmapBits(DestObj);
- if(SourceSurf != DestSurf)
- {
- MouseSafetyOnDrawEnd(SourceSurf);
- BITMAPOBJ_UnlockBitmapBits(SourceObj);
+ Ret = EngTransparentBlt(psoDest, psoSource, Clip, ColorTranslation,
+ &OutputRect, &InputRect, iTransColor, Reserved);
}
return Ret;