2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: GDI stretch blt functions
5 * FILE: win32ss/gdi/eng/stretchblt.c
6 * PROGRAMERS: Jason Filby
15 /***************************************************************************************************************************
16 We want to receive and send the flip state along to existing functions without changing their parameter lists.
17 So a way that we can do this is to use the DestRect to carry this information along with it.
18 Since there are four values, we can use their relative positions (coordinates) to indicate the four flip conditions.
19 if delta-x == 0 then there can be no Left-to-Right flip. If delta-y == 0 there can be no Top-to-Bottom flip.
20 So we can set the four flip conditions based on BOOLEAN flags as follows:
22 We will use internal bits bTopToBottom and bLeftToRight as follows:
24 !bTopToBottom && !bLeftToRight means no flips therefore left < right and top < bottom (normal well-formed rectangle)
25 bTopToBottom means there is a Top-To-Bottom flip therefore left < right and top > bottom
26 bLeftToRight means there is a Left-To-Right flip therefore left > right and top < bottom
27 bLeftToRight && bTopToBottom means both flips therefore left > right and top > bottom
28 ****************************************************************************************************************************/
30 typedef BOOLEAN (APIENTRY
*PSTRETCHRECTFUNC
)(SURFOBJ
* OutputObj
,
33 XLATEOBJ
* ColorTranslation
,
41 static BOOLEAN APIENTRY
42 CallDibStretchBlt(SURFOBJ
* psoDest
,
45 XLATEOBJ
* ColorTranslation
,
53 POINTL RealBrushOrigin
;
57 DPRINT("Entering CallDibStretchBlt: psoSource cx/cy (%d/%d), psoDest cx/cy (%d/%d) OutputRect: (%d,%d)-(%d,%d)\n",
58 psoSource
->sizlBitmap
.cx
, psoSource
->sizlBitmap
.cy
,
59 psoDest
->sizlBitmap
.cx
, psoDest
->sizlBitmap
.cy
,
60 OutputRect
->left
, OutputRect
->top
, OutputRect
->right
, OutputRect
->bottom
);
62 if (BrushOrigin
== NULL
)
64 RealBrushOrigin
.x
= RealBrushOrigin
.y
= 0;
68 RealBrushOrigin
= *BrushOrigin
;
72 if (ROP4_USES_PATTERN(Rop4
) && pbo
&& pbo
->iSolidColor
== 0xFFFFFFFF)
74 psoPattern
= BRUSHOBJ_psoPattern(pbo
);
76 if (!psoPattern
) return FALSE
;
83 bResult
= DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_StretchBlt(
84 psoDest
, psoSource
, Mask
, psoPattern
,
85 OutputRect
, InputRect
, MaskOrigin
, pbo
, &RealBrushOrigin
,
86 ColorTranslation
, Rop4
);
100 IN SURFOBJ
*psoSource
,
102 IN CLIPOBJ
*ClipRegion
,
103 IN XLATEOBJ
*ColorTranslation
,
104 IN COLORADJUSTMENT
*pca
,
105 IN POINTL
*BrushOrigin
,
108 IN POINTL
*MaskOrigin
,
116 INTENG_ENTER_LEAVE EnterLeaveSource
;
117 INTENG_ENTER_LEAVE EnterLeaveDest
;
120 PSTRETCHRECTFUNC BltRectFunc
;
122 POINTL AdjustedBrushOrigin
;
123 BOOL UsesSource
= ROP4_USES_SOURCE(Rop4
);
131 RECTL InputToCombinedRect
;
139 LONG cxSrc
, cySrc
, cxDest
, cyDest
;
140 BOOLEAN bLeftToRight
, bTopToBottom
;
143 DPRINT("Entering EngStretchBltROP: prclSrc: (%d/%d)-(%d/%d) prclDest: (%d,%d)-(%d,%d)\n",
144 prclSrc
->left
, prclSrc
->top
, prclSrc
->right
, prclSrc
->bottom
,
145 prclDest
->left
, prclDest
->top
, prclDest
->right
, prclDest
->bottom
);
147 cxSrc
= prclSrc
->right
- prclSrc
->left
;
148 cySrc
= prclSrc
->bottom
- prclSrc
->top
;
149 cxDest
= prclDest
->right
- prclDest
->left
;
150 cyDest
= prclDest
->bottom
- prclDest
->top
;
152 /* Here we do the tests and set our conditions */
153 if (((cxSrc
< 0) && (cxDest
< 0)) || ((cxSrc
>= 0) && (cxDest
>= 0)))
154 bLeftToRight
= FALSE
;
158 if (((cySrc
< 0) && (cyDest
< 0)) || ((cySrc
>= 0) && (cyDest
>= 0)))
159 bTopToBottom
= FALSE
;
163 /* Make Well Ordered to start */
164 OutputRect
= *prclDest
;
165 RECTL_vMakeWellOrdered(&OutputRect
);
166 *prclDest
= OutputRect
;
168 if (Rop4
== ROP4_NOOP
)
170 /* Copy destination onto itself: nop */
175 /* Determine clipping type */
176 if (ClipRegion
== (CLIPOBJ
*) NULL
)
178 clippingType
= DC_TRIVIAL
;
182 clippingType
= ClipRegion
->iDComplexity
;
185 OutputRect
= *prclDest
;
186 if (OutputRect
.right
< OutputRect
.left
)
188 OutputRect
.left
= prclDest
->right
;
189 OutputRect
.right
= prclDest
->left
;
191 if (OutputRect
.bottom
< OutputRect
.top
)
193 OutputRect
.top
= prclDest
->bottom
;
194 OutputRect
.bottom
= prclDest
->top
;
203 InputRect
= *prclSrc
;
205 if (! IntEngEnter(&EnterLeaveSource
, psoSource
, &InputRect
, TRUE
,
206 &Translate
, &psoInput
))
211 InputRect
.left
+= Translate
.x
;
212 InputRect
.right
+= Translate
.x
;
213 InputRect
.top
+= Translate
.y
;
214 InputRect
.bottom
+= Translate
.y
;
219 InputRect
.right
= OutputRect
.right
- OutputRect
.left
;
221 InputRect
.bottom
= OutputRect
.bottom
- OutputRect
.top
;
225 if (NULL
!= ClipRegion
)
227 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
229 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
230 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
232 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
234 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
235 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
237 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
239 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
240 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
242 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
244 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
245 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
249 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
251 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
255 IntEngLeave(&EnterLeaveSource
);
260 if (! IntEngEnter(&EnterLeaveDest
, psoDest
, &OutputRect
, FALSE
, &Translate
, &psoOutput
))
264 IntEngLeave(&EnterLeaveSource
);
269 OutputRect
.left
+= Translate
.x
;
270 OutputRect
.right
+= Translate
.x
;
271 OutputRect
.top
+= Translate
.y
;
272 OutputRect
.bottom
+= Translate
.y
;
276 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
277 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
281 AdjustedBrushOrigin
= Translate
;
284 BltRectFunc
= CallDibStretchBlt
;
286 DstHeight
= OutputRect
.bottom
- OutputRect
.top
;
287 DstWidth
= OutputRect
.right
- OutputRect
.left
;
288 SrcHeight
= InputRect
.bottom
- InputRect
.top
;
289 SrcWidth
= InputRect
.right
- InputRect
.left
;
291 DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight
, bTopToBottom
);
293 switch (clippingType
)
298 lTmp
= OutputRect
.left
;
299 OutputRect
.left
= OutputRect
.right
;
300 OutputRect
.right
= lTmp
;
305 lTmp
= OutputRect
.top
;
306 OutputRect
.top
= OutputRect
.bottom
;
307 OutputRect
.bottom
= lTmp
;
310 DPRINT("About to call CallDibStretchBlt: OutputRect: (%d,%d)-(%d,%d)\n",
311 OutputRect
.left
, OutputRect
.top
, OutputRect
.right
, OutputRect
.bottom
);
313 Ret
= (*BltRectFunc
)(psoOutput
, psoInput
, Mask
,
314 ColorTranslation
, &OutputRect
, &InputRect
, MaskOrigin
,
315 pbo
, &AdjustedBrushOrigin
, Rop4
);
318 // Clip the blt to the clip rectangle
319 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
320 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
321 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
322 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
323 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
325 InputToCombinedRect
.top
= InputRect
.top
+ (CombinedRect
.top
- OutputRect
.top
) * SrcHeight
/ DstHeight
;
326 InputToCombinedRect
.bottom
= InputRect
.top
+ (CombinedRect
.bottom
- OutputRect
.top
) * SrcHeight
/ DstHeight
;
327 InputToCombinedRect
.left
= InputRect
.left
+ (CombinedRect
.left
- OutputRect
.left
) * SrcWidth
/ DstWidth
;
328 InputToCombinedRect
.right
= InputRect
.left
+ (CombinedRect
.right
- OutputRect
.left
) * SrcWidth
/ DstWidth
;
332 lTmp
= CombinedRect
.left
;
333 CombinedRect
.left
= CombinedRect
.right
;
334 CombinedRect
.right
= lTmp
;
339 lTmp
= CombinedRect
.top
;
340 CombinedRect
.top
= CombinedRect
.bottom
;
341 CombinedRect
.bottom
= lTmp
;
344 DPRINT("About to call CallDibStretchBlt: CombinedRect: (%d,%d)-(%d,%d)\n",
345 CombinedRect
.left
, CombinedRect
.top
, CombinedRect
.right
, CombinedRect
.bottom
);
347 Ret
= (*BltRectFunc
)(psoOutput
, psoInput
, Mask
,
350 &InputToCombinedRect
,
353 &AdjustedBrushOrigin
,
358 if (psoOutput
== psoInput
)
360 if (OutputRect
.top
< InputRect
.top
)
362 Direction
= OutputRect
.left
< InputRect
.left
?
363 CD_RIGHTDOWN
: CD_LEFTDOWN
;
367 Direction
= OutputRect
.left
< InputRect
.left
?
368 CD_RIGHTUP
: CD_LEFTUP
;
375 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
378 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
),
380 for (i
= 0; i
< RectEnum
.c
; i
++)
382 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
383 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
384 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
385 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
386 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
388 InputToCombinedRect
.top
= InputRect
.top
+ (CombinedRect
.top
- OutputRect
.top
) * SrcHeight
/ DstHeight
;
389 InputToCombinedRect
.bottom
= InputRect
.top
+ (CombinedRect
.bottom
- OutputRect
.top
) * SrcHeight
/ DstHeight
;
390 InputToCombinedRect
.left
= InputRect
.left
+ (CombinedRect
.left
- OutputRect
.left
) * SrcWidth
/ DstWidth
;
391 InputToCombinedRect
.right
= InputRect
.left
+ (CombinedRect
.right
- OutputRect
.left
) * SrcWidth
/ DstWidth
;
395 lTmp
= CombinedRect
.left
;
396 CombinedRect
.left
= CombinedRect
.right
;
397 CombinedRect
.right
= lTmp
;
402 lTmp
= CombinedRect
.top
;
403 CombinedRect
.top
= CombinedRect
.bottom
;
404 CombinedRect
.bottom
= lTmp
;
407 DPRINT("About to call CallDibStretchBlt: CombinedRect: (%d,%d)-(%d,%d)\n",
408 CombinedRect
.left
, CombinedRect
.top
, CombinedRect
.right
, CombinedRect
.bottom
);
410 Ret
= (*BltRectFunc
)(psoOutput
, psoInput
, Mask
,
413 &InputToCombinedRect
,
416 &AdjustedBrushOrigin
,
425 IntEngLeave(&EnterLeaveDest
);
428 IntEngLeave(&EnterLeaveSource
);
441 IN SURFOBJ
*psoSource
,
443 IN CLIPOBJ
*ClipRegion
,
444 IN XLATEOBJ
*ColorTranslation
,
445 IN COLORADJUSTMENT
*pca
,
446 IN POINTL
*BrushOrigin
,
449 IN POINTL
*MaskOrigin
,
452 return EngStretchBltROP(
465 ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY
));
469 IntEngStretchBlt(SURFOBJ
*psoDest
,
473 XLATEOBJ
*ColorTranslation
,
474 COLORADJUSTMENT
*pca
,
483 POINTL MaskOrigin
= {0, 0};
485 //SURFACE *psurfSource = NULL;
486 RECTL InputClippedRect
;
489 BOOL UsesSource
= ROP4_USES_SOURCE(Rop4
);
490 LONG InputClWidth
, InputClHeight
, InputWidth
, InputHeight
;
491 LONG lTmp
, cxSrc
, cySrc
, cxDest
, cyDest
;
492 BOOLEAN bTopToBottom
, bLeftToRight
;
493 INT Case0000
, Case0001
, Case0010
, Case0011
;
494 INT Case0100
, Case0101
, Case0110
, Case0111
;
495 INT Case1000
, Case1001
, Case1010
, Case1011
;
496 INT Case1100
, Case1101
, Case1110
;
498 DPRINT("Source cx/cy (%d/%d) and Destination cx/cy (%d/%d).\n",
499 psoSource
->sizlBitmap
.cx
, psoSource
->sizlBitmap
.cy
, psoDest
->sizlBitmap
.cx
, psoDest
->sizlBitmap
.cy
);
501 DPRINT("Source lDelta is '%d' and Destination lDelta is '%d'.\n",
502 psoSource
->lDelta
, psoDest
->lDelta
);
505 //ASSERT(psoSource); // FIXME!
508 //ASSERT(!RECTL_bIsEmptyRect(SourceRect)); // FIXME!
510 /* If no clip object is given, use trivial one */
513 DPRINT("Using trivial clip region.\n");
514 ClipRegion
= (CLIPOBJ
*)&gxcoTrivial
;
518 DPRINT("ClipRegion->rclBounds is (%d,%d)-(%d,%d).\n",
519 ClipRegion
->rclBounds
.left
, ClipRegion
->rclBounds
.top
,
520 ClipRegion
->rclBounds
.right
, ClipRegion
->rclBounds
.bottom
);
523 psurfDest
= CONTAINING_RECORD(psoDest
, SURFACE
, SurfObj
);
526 ASSERT(IS_VALID_ROP4(Rop4
));
528 cxSrc
= SourceRect
->right
- SourceRect
->left
;
529 cySrc
= SourceRect
->bottom
- SourceRect
->top
;
530 cxDest
= DestRect
->right
- DestRect
->left
;
531 cyDest
= DestRect
->bottom
- DestRect
->top
;
533 Case1110
= ((cxDest
> 0) && (cyDest
> 0) && (cxSrc
> 0) && (cySrc
< 0));
534 Case1101
= ((cxDest
> 0) && (cyDest
> 0) && (cxSrc
< 0) && (cySrc
> 0));
535 Case1100
= ((cxDest
> 0) && (cyDest
> 0) && (cxSrc
< 0) && (cySrc
< 0));
536 Case1011
= ((cxDest
> 0) && (cyDest
< 0) && (cxSrc
> 0) && (cySrc
> 0));
537 Case1010
= ((cxDest
> 0) && (cyDest
< 0) && (cxSrc
> 0) && (cySrc
< 0));
538 Case1001
= ((cxDest
> 0) && (cyDest
< 0) && (cxSrc
< 0) && (cySrc
> 0));
539 Case1000
= ((cxDest
> 0) && (cyDest
< 0) && (cxSrc
< 0) && (cySrc
< 0));
540 Case0111
= ((cxDest
< 0) && (cyDest
> 0) && (cxSrc
> 0) && (cySrc
> 0));
541 Case0110
= ((cxDest
< 0) && (cyDest
> 0) && (cxSrc
> 0) && (cySrc
< 0));
542 Case0101
= ((cxDest
< 0) && (cyDest
> 0) && (cxSrc
< 0) && (cySrc
> 0));
543 Case0100
= ((cxDest
< 0) && (cyDest
> 0) && (cxSrc
< 0) && (cySrc
< 0));
544 Case0011
= ((cxDest
< 0) && (cyDest
< 0) && (cxSrc
> 0) && (cySrc
> 0));
545 Case0010
= ((cxDest
< 0) && (cyDest
< 0) && (cxSrc
> 0) && (cySrc
< 0));
546 Case0001
= ((cxDest
< 0) && (cyDest
< 0) && (cxSrc
< 0) && (cySrc
> 0));
547 Case0000
= ((cxDest
< 0) && (cyDest
< 0) && (cxSrc
< 0) && (cySrc
< 0));
549 /* Make DestRect & OutputRect Well Ordered to start */
550 RECTL_vMakeWellOrdered(DestRect
);
551 OutputRect
= *DestRect
;
553 /* Here we do the tests and set our conditions */
554 if (((cxSrc
< 0) && (cxDest
< 0)) || ((cxSrc
>= 0) && (cxDest
>= 0)))
555 bLeftToRight
= FALSE
;
559 if (((cySrc
< 0) && (cyDest
< 0)) || ((cySrc
>= 0) && (cyDest
>= 0)))
560 bTopToBottom
= FALSE
;
564 DPRINT("bTopToBottom is '%d' and bLeftToRight is '%d'.\n", bTopToBottom
, bLeftToRight
);
566 /* Check if source and dest size are equal */
567 if ((abs(DestRect
->right
- DestRect
->left
) == abs(SourceRect
->right
- SourceRect
->left
)) &&
568 (abs(DestRect
->bottom
- DestRect
->top
) == abs(SourceRect
->bottom
- SourceRect
->top
)))
570 DPRINT("source and dest size are equal.\n");
572 DPRINT("IntEngStretchBlt: dstRect: (%d,%d)-(%d,%d)\n",
573 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
575 if (Case0000
|| Case0001
|| Case0010
|| Case0011
) // Destinations X & Y are both negative
577 lTmp
= SourceRect
->left
;
578 SourceRect
->left
= SourceRect
->right
;
579 SourceRect
->right
= lTmp
;
581 lTmp
= SourceRect
->top
;
582 SourceRect
->top
= SourceRect
->bottom
;
583 SourceRect
->bottom
= lTmp
;
586 if (Case0100
|| Case0101
|| Case0110
|| Case0111
) // Destination X is negative and Y is positive
588 lTmp
= SourceRect
->left
;
589 SourceRect
->left
= SourceRect
->right
;
590 SourceRect
->right
= lTmp
;
593 if (Case1000
|| Case1001
|| Case1010
|| Case1011
) // Destination X is positive and Y is negative
595 lTmp
= SourceRect
->top
;
596 SourceRect
->top
= SourceRect
->bottom
;
597 SourceRect
->bottom
= lTmp
;
602 lTmp
= DestRect
->left
;
603 DestRect
->left
= DestRect
->right
;
604 DestRect
->right
= lTmp
;
609 lTmp
= DestRect
->top
;
610 DestRect
->top
= DestRect
->bottom
;
611 DestRect
->bottom
= lTmp
;
614 DPRINT("Calling IntEngBitBlt: SourceRect (%d,%d)-(%d,%d) DestRect: (%d,%d)-(%d,%d)\n",
615 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
616 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
618 /* Pass the request to IntEngBitBlt */
619 return IntEngBitBlt(psoDest
,
632 DPRINT("source and dest size are NOT equal.\n");
634 DPRINT("SourceRect: (%d,%d)-(%d,%d) and DestRect: (%d,%d)-(%d,%d)\n",
635 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
636 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
638 /* if cxSrc < 0 then we change the signs for both cxSrc and cxDest and
639 * we reverse their coordinates, because these outcomes are the same.
643 lTmp
= SourceRect
->left
;
644 SourceRect
->left
= SourceRect
->right
;
645 SourceRect
->right
= lTmp
;
646 lTmp
= DestRect
->left
;
647 DestRect
->left
= DestRect
->right
;
648 DestRect
->right
= lTmp
;
652 /* if cySrc < 0 then we change the signs for both cySrc and cyDest and
653 * we reverse their coordinates, because these outcomes are the same.
657 lTmp
= DestRect
->top
;
658 DestRect
->top
= DestRect
->bottom
;
659 DestRect
->bottom
= lTmp
;
660 lTmp
= SourceRect
->top
;
661 SourceRect
->top
= SourceRect
->bottom
;
662 SourceRect
->bottom
= lTmp
;
667 if (Case0010
|| Case0111
) // Horizontal Flips
672 if (Case0010
|| Case0111
|| Case1000
|| Case1101
) // Horizontal Flips
678 if (Case0001
|| Case0100
|| Case1011
|| Case1110
) // Vertical Flips
681 SourceRect
->bottom
--;
684 if (Case0011
|| Case0110
|| Case1001
|| Case1100
) // Horizontal and Vertical Flips
690 SourceRect
->bottom
--;
693 if (Case0000
|| Case1010
) // No Flip - Just Copy
696 SourceRect
->bottom
++;
702 if (Case0000
|| Case0101
) // No Flip - Just Copy
712 DPRINT("SourceRect: (%d,%d)-(%d,%d) and DestRect: (%d,%d)-(%d,%d)\n",
713 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
714 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
716 InputClippedRect
= *DestRect
;
717 if (InputClippedRect
.right
< InputClippedRect
.left
)
719 InputClippedRect
.left
= DestRect
->right
;
720 InputClippedRect
.right
= DestRect
->left
;
722 if (InputClippedRect
.bottom
< InputClippedRect
.top
)
724 InputClippedRect
.top
= DestRect
->bottom
;
725 InputClippedRect
.bottom
= DestRect
->top
;
728 if (NULL
== psoSource
)
730 DPRINT("Returning FALSE.\n");
733 InputRect
= *SourceRect
;
735 if (InputRect
.right
< InputRect
.left
||
736 InputRect
.bottom
< InputRect
.top
)
738 DPRINT("Returning TRUE.\n");
739 /* Everything clipped away, nothing to do */
743 DPRINT("InputRect: (%d,%d)-(%d,%d) and InputClippedRect: (%d,%d)-(%d,%d)\n",
744 InputRect
.left
, InputRect
.top
, InputRect
.right
, InputRect
.bottom
,
745 InputClippedRect
.left
, InputClippedRect
.top
, InputClippedRect
.right
, InputClippedRect
.bottom
);
747 if (ClipRegion
->iDComplexity
!= DC_TRIVIAL
)
749 if (!RECTL_bIntersectRect(&OutputRect
, &InputClippedRect
,
750 &ClipRegion
->rclBounds
))
752 DPRINT("Returning TRUE.\n");
756 DPRINT("InputClippedRect: (%d,%d)-(%d,%d) and OutputRect: (%d,%d)-(%d,%d)\n",
757 InputClippedRect
.left
, InputClippedRect
.top
, InputClippedRect
.right
, InputClippedRect
.bottom
,
758 OutputRect
.left
, OutputRect
.top
, OutputRect
.right
, OutputRect
.bottom
);
760 /* Update source rect */
761 InputClWidth
= InputClippedRect
.right
- InputClippedRect
.left
;
762 InputClHeight
= InputClippedRect
.bottom
- InputClippedRect
.top
;
763 InputWidth
= InputRect
.right
- InputRect
.left
;
764 InputHeight
= InputRect
.bottom
- InputRect
.top
;
766 InputRect
.left
+= (InputWidth
* (OutputRect
.left
- InputClippedRect
.left
)) / InputClWidth
;
767 InputRect
.right
-= (InputWidth
* (InputClippedRect
.right
- OutputRect
.right
)) / InputClWidth
;
768 InputRect
.top
+= (InputHeight
* (OutputRect
.top
- InputClippedRect
.top
)) / InputClHeight
;
769 InputRect
.bottom
-= (InputHeight
* (InputClippedRect
.bottom
- OutputRect
.bottom
)) / InputClHeight
;
773 DPRINT("Complexity = DC_TRIVIAL.\n");
774 OutputRect
= InputClippedRect
;
778 DPRINT("InputRect: (%d,%d)-(%d,%d) and OutputRect: (%d,%d)-(%d,%d)\n",
779 InputRect
.left
, InputRect
.top
, InputRect
.right
, InputRect
.bottom
,
780 OutputRect
.left
, OutputRect
.top
, OutputRect
.right
, OutputRect
.bottom
);
782 if (pMaskOrigin
!= NULL
)
784 MaskOrigin
.x
= pMaskOrigin
->x
;
785 MaskOrigin
.y
= pMaskOrigin
->y
;
793 //psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
796 /* Call the driver's DrvStretchBlt if available */
797 if (psurfDest
->flags
& HOOK_STRETCHBLTROP
)
799 DPRINT("About to call GDIDEVFUNCS(psoDest).StretchBltROP.\n");
800 /* Drv->StretchBltROP (look at http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */
801 ret
= GDIDEVFUNCS(psoDest
).StretchBltROP(psoDest
,
818 /* set OutputRect to follow flip */
821 lTmp
= OutputRect
.left
;
822 OutputRect
.left
= OutputRect
.right
;
823 OutputRect
.right
= lTmp
;
828 lTmp
= OutputRect
.top
;
829 OutputRect
.top
= OutputRect
.bottom
;
830 OutputRect
.bottom
= lTmp
;
833 DPRINT("Calling EngStretchBltROP: InputRect: (%d,%d)-(%d,%d) and OutputRect: (%d,%d)-(%d,%d)\n",
834 InputRect
.left
, InputRect
.top
, InputRect
.right
, InputRect
.bottom
,
835 OutputRect
.left
, OutputRect
.top
, OutputRect
.right
, OutputRect
.bottom
);
837 ret
= EngStretchBltROP(psoDest
,
859 IN SURFOBJ
*psoSource
,
861 IN CLIPOBJ
*ClipRegion
,
862 IN XLATEOBJ
*ColorTranslation
,
863 IN COLORADJUSTMENT
*pca
,
864 IN POINTL
*BrushOrigin
,
867 IN POINTL
*MaskOrigin
,
880 ProbeForRead(pca
, sizeof(COLORADJUSTMENT
), 1);
881 RtlCopyMemory(&ca
,pca
, sizeof(COLORADJUSTMENT
));
885 ProbeForRead(BrushOrigin
, sizeof(POINTL
), 1);
886 RtlCopyMemory(&lBrushOrigin
, BrushOrigin
, sizeof(POINTL
));
888 ProbeForRead(prclDest
, sizeof(RECTL
), 1);
889 RtlCopyMemory(&rclDest
, prclDest
, sizeof(RECTL
));
891 ProbeForRead(prclSrc
, sizeof(RECTL
), 1);
892 RtlCopyMemory(&rclSrc
, prclSrc
, sizeof(RECTL
));
894 ProbeForRead(MaskOrigin
, sizeof(POINTL
), 1);
895 RtlCopyMemory(&lMaskOrigin
, MaskOrigin
, sizeof(POINTL
));
898 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
900 _SEH2_YIELD(return FALSE
);
904 return EngStretchBlt(psoDest
, psoSource
, Mask
, ClipRegion
, ColorTranslation
, pca
, &lBrushOrigin
, &rclDest
, &rclSrc
, &lMaskOrigin
, Mode
);