00077 {
00078 RECT rcVis;
00079 RECT rcSrc;
00080 RECT rcClip;
00081 RECT rcUnclippedSrc;
00082 RECT rcDst;
00083 RECT rcUpdate;
00084 RECT rcValid;
00085
BOOL fSrcNotEmpty;
00086
BOOL fHaveVisRgn;
00087 POINT rgpt[2];
00088
int dxLog;
00089
int dyLog;
00090
int wClip;
00091
int wClipValid;
00092
#if defined(USE_MIRRORING)
00093
BOOL bMirroredDC=
FALSE;
00094
#endif
00095
00096 fHaveVisRgn =
FALSE;
00097
00098
00099
00100
00101
00102 GreLockDisplay(
gpDispInfo->
hDev);
00103
00104
if ((wClip = GreGetClipBox(hdc, &rcVis, TRUE)) == ERROR) {
00105
00106
ErrorExit:
00107
00108 GreUnlockDisplay(
gpDispInfo->
hDev);
00109
return ERROR;
00110 }
00111
00112
CopyRect(&rcSrc, (prcSrc) ? prcSrc : &rcVis);
00113
if (prcClip) {
00114
CopyRect(&rcClip, prcClip);
00115 }
00116
00117 dxLog = dx;
00118 dyLog = dy;
00119
00120
if (fLogUnits) {
00121
00122
00123
00124
00125 GreLPtoDP(hdc, (LPPOINT)&rcVis, 2);
00126 GreLPtoDP(hdc, (LPPOINT)&rcSrc, 2);
00127
00128
#if defined(USE_MIRRORING)
00129
00130
00131
00132
00133
00134
00135
if (GreGetLayout(hdc) & LAYOUT_RTL) {
00136
int iTemp = rcVis.left;
00137 rcVis.left = rcVis.right;
00138 rcVis.right = iTemp;
00139
00140 iTemp = rcSrc.left;
00141 rcSrc.left = rcSrc.right;
00142 rcSrc.right = iTemp;
00143
00144 bMirroredDC =
TRUE;
00145 }
00146
#endif
00147
00148
if (prcClip) {
00149 GreLPtoDP(hdc, (LPPOINT)&rcClip, 2);
00150
00151
#if defined(USE_MIRRORING)
00152
00153
00154
00155
00156
00157
00158
if (bMirroredDC) {
00159
int iTemp = rcClip.left;
00160 rcClip.left = rcClip.right;
00161 rcClip.right = iTemp;
00162 }
00163
#endif
00164
}
00165
00166
00167
00168
00169
00170
00171 rgpt[0].x = rgpt[0].y = 0;
00172 rgpt[1].x = dx;
00173 rgpt[1].y = dy;
00174
00175 GreLPtoDP(hdc, rgpt, 2);
00176
00177 dx = rgpt[1].x - rgpt[0].x;
00178 dy = rgpt[1].y - rgpt[0].y;
00179 }
00180
00181
switch (wClip) {
00182
case NULLREGION:
00183
00184 NullExit:
00185
00186
if (hrgnUpdate && !
SetEmptyRgn(hrgnUpdate))
00187
goto ErrorExit;
00188
00189
if (prcUpdate) {
00190
SetRectEmpty(prcUpdate);
00191 }
00192
00193 GreUnlockDisplay(
gpDispInfo->
hDev);
00194
return NULLREGION;
00195
00196
case COMPLEXREGION:
00197
GetTrueClipRgn(hdc, ghrgnScrlVis);
00198 fHaveVisRgn =
TRUE;
00199
break;
00200 }
00201
00202
00203
00204
00205
00206
00207 rcDst.left = rcSrc.left + dx;
00208 rcDst.right = rcSrc.right + dx;
00209 rcDst.top = rcSrc.top + dy;
00210 rcDst.bottom = rcSrc.bottom + dy;
00211
00212
00213
00214
00215
if (prcClip) {
00216
00217
if ((wClip == SIMPLEREGION) &&
00218 ((hrgnInvalid ==
NULL) || (hrgnInvalid ==
HRGN_FULL))) {
00219
00220
00221
00222
00223
if (!
IntersectRect(&rcVis, &rcVis, &rcClip))
00224
goto NullExit;
00225
00226 }
else {
00227
00228
if (!fHaveVisRgn) {
00229
00230
if (
GetTrueClipRgn(hdc, ghrgnScrlVis) == ERROR)
00231
goto ErrorExit;
00232
00233 fHaveVisRgn =
TRUE;
00234 }
00235
00236
SetRectRgnIndirect(ghrgnScrl1, &rcClip);
00237 wClip =
IntersectRgn(ghrgnScrlVis, ghrgnScrl1, ghrgnScrlVis);
00238
switch (wClip) {
00239
case ERROR:
00240
goto ErrorExit;
00241
00242
case NULLREGION:
00243
goto NullExit;
00244
00245
case SIMPLEREGION:
00246
00247
00248
00249
00250
00251 GreGetRgnBox(ghrgnScrlVis, &rcVis);
00252
break;
00253
00254
case COMPLEXREGION:
00255
break;
00256 }
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
if ((wClip == SIMPLEREGION) &&
00276 ((hrgnInvalid ==
NULL) || (hrgnInvalid ==
HRGN_FULL))) {
00277
00278
00279
00280
00281
CopyRect(&rcUnclippedSrc, &rcSrc);
00282
00283
00284
00285
00286
IntersectRect(&rcDst, &rcDst, &rcVis);
00287
00288
00289
00290
00291 fSrcNotEmpty =
IntersectRect(&rcSrc, &rcSrc, &rcVis);
00292
00293
00294
00295
00296
if (hrgnInvalid ==
HRGN_FULL) {
00297
SetRectEmpty(&rcValid);
00298 }
else {
00299
00300 rcValid.left = rcSrc.left + dx;
00301 rcValid.right = rcSrc.right + dx;
00302 rcValid.top = rcSrc.top + dy;
00303 rcValid.bottom = rcSrc.bottom + dy;
00304
00305
IntersectRect(&rcValid, &rcValid, &rcDst);
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
if (!fSrcNotEmpty) {
00325
00326
00327
00328
00329
CopyRect(&rcUpdate, &rcDst);
00330
goto RectUpdate;
00331
00332 }
else if (
IntersectRect(&rcUpdate, &rcSrc, &rcDst)) {
00333
00334
00335
00336
00337
00338
if (dx == 0 || dy == 0) {
00339
00340
UnionRect(&rcUpdate, &rcSrc, &rcDst);
00341
SubtractRect(&rcUpdate, &rcUpdate, &rcValid);
00342
goto RectUpdate;
00343 }
00344
00345 }
else if (
EqualRect(&rcSrc, &rcUnclippedSrc)) {
00346
00347
00348
00349
00350
00351
CopyRect(&rcUpdate, &rcSrc);
00352 RectUpdate:
00353
if (prcUpdate) {
00354
CopyRect(prcUpdate, &rcUpdate);
00355 }
00356
00357
if (hrgnUpdate && !
SetRectRgnIndirect(hrgnUpdate, &rcUpdate)) {
00358
goto ErrorExit;
00359 }
00360
00361 wClip = SIMPLEREGION;
00362
if (rcUpdate.left >= rcUpdate.right ||
00363 rcUpdate.top >= rcUpdate.bottom)
00364
00365 wClip = NULLREGION;
00366
00367
goto DoRectBlt;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
if (hrgnUpdate ==
NULL && prcUpdate) {
00378 hrgnUpdate =
ghrgnScrl2;
00379 }
00380
00381
if (hrgnUpdate !=
NULL) {
00382
00383
00384
00385
00386
SetRectRgnIndirect(ghrgnScrl1, &rcSrc);
00387
SetRectRgnIndirect(hrgnUpdate, &rcDst);
00388
if (
UnionRgn(hrgnUpdate, hrgnUpdate, ghrgnScrl1) == ERROR)
00389
goto ErrorExit;
00390
00391
SetRectRgnIndirect(ghrgnScrl1, &rcValid);
00392 wClip =
SubtractRgn(hrgnUpdate, hrgnUpdate, ghrgnScrl1);
00393
if (wClip == ERROR)
00394
goto ErrorExit;
00395
00396
if (prcUpdate) {
00397 GreGetRgnBox(hrgnUpdate, prcUpdate);
00398 }
00399 }
00400
00401 DoRectBlt:
00402
00403
00404
00405
00406
if (rcValid.left < rcValid.right && rcValid.top < rcValid.bottom) {
00407
00408
00409
00410
00411
00412
if (fLogUnits)
00413 GreDPtoLP(hdc, (LPPOINT)&rcValid, 2);
00414
00415 GreBitBlt(hdc,
00416 rcValid.left,
00417 rcValid.top,
00418 rcValid.right - rcValid.left,
00419 rcValid.bottom - rcValid.top,
00420 hdc,
00421 rcValid.left - dxLog,
00422 rcValid.top - dyLog,
00423 SRCCOPY,
00424 0);
00425 }
00426
00427 }
else {
00428
00429
00430
00431
00432
if (!fHaveVisRgn) {
00433
00434
if (
GetTrueClipRgn(hdc, ghrgnScrlVis) == ERROR)
00435
goto ErrorExit;
00436
00437 fHaveVisRgn =
TRUE;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
SetRectRgnIndirect(ghrgnScrlSrc, &rcSrc);
00447
if (
IntersectRgn(ghrgnScrlSrc, ghrgnScrlSrc, ghrgnScrlVis) == ERROR)
00448
goto ErrorExit;
00449
00450
00451
00452
00453
SetRectRgnIndirect(ghrgnScrlDst, &rcDst);
00454
if (
IntersectRgn(ghrgnScrlDst, ghrgnScrlDst, ghrgnScrlVis) == ERROR)
00455
goto ErrorExit;
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 wClipValid = NULLREGION;
00466
if (hrgnInvalid !=
HRGN_FULL) {
00467
00468
00469
00470
00471
if (
CopyRgn(ghrgnScrlValid, ghrgnScrlSrc) == ERROR)
00472
goto ErrorExit;
00473
00474 GreOffsetRgn(ghrgnScrlValid, dx, dy);
00475 wClipValid =
IntersectRgn(ghrgnScrlValid,
00476 ghrgnScrlValid,
00477 ghrgnScrlDst);
00478
00479
00480
00481
00482
00483
if (hrgnInvalid >
HRGN_FULL) {
00484
00485
if (wClipValid != ERROR && wClipValid != NULLREGION) {
00486 POINT pt;
00487
00488
GetDCOrgOnScreen(hdc, &pt);
00489
00490
00491
00492
00493
CopyRgn(ghrgnScrl2, hrgnInvalid);
00494 GreOffsetRgn(ghrgnScrl2, -pt.x, -pt.y);
00495
00496 wClipValid =
SubtractRgn(ghrgnScrlValid,
00497 ghrgnScrlValid,
00498 ghrgnScrl2);
00499 }
00500
00501
if (wClipValid != ERROR && wClipValid != NULLREGION) {
00502 GreOffsetRgn(ghrgnScrl2, dx, dy);
00503
00504 wClipValid =
SubtractRgn(ghrgnScrlValid,
00505 ghrgnScrlValid,
00506 ghrgnScrl2);
00507 }
00508 }
00509
00510
if (wClipValid == ERROR)
00511
goto ErrorExit;
00512 }
00513
00514
00515
00516
00517
if (hrgnUpdate ==
NULL && prcUpdate) {
00518 hrgnUpdate =
ghrgnScrl2;
00519 }
00520
00521
if (hrgnUpdate !=
NULL) {
00522
00523
00524
00525
00526 wClip =
UnionRgn(hrgnUpdate, ghrgnScrlDst, ghrgnScrlSrc);
00527
if (wClip == ERROR)
00528
goto ErrorExit;
00529
00530
if (wClipValid != NULLREGION) {
00531 wClip =
SubtractRgn(hrgnUpdate, hrgnUpdate, ghrgnScrlValid);
00532 }
00533
00534
if (prcUpdate) {
00535 GreGetRgnBox(hrgnUpdate, prcUpdate);
00536 }
00537 }
00538
00539
if (wClipValid != NULLREGION) {
00540
00541
#ifdef LATER
00542
00543
00544
00545
00546 HRGN hrgnSaveVis =
CreateEmptyRgn();
00547
if (hrgnSaveVis !=
NULL) {
00548
00549
BOOL fClipped;
00550
00551 fClipped = (GreGetRandomRgn(hdc, hrgnSaveVis, 1) == 1);
00552 GreExtSelectClipRgn(hdc, ghrgnScrlValid, RGN_COPY);
00553
00554
00555
00556
00557
00558
if (fLogUnits)
00559 GreDPtoLP(hdc, (LPPOINT)&rcDst, 2);
00560
00561
00562
00563
00564
00565 GreBitBlt(hdc,
00566 rcDst.left,
00567 rcDst.top,
00568 rcDst.right - rcDst.left,
00569 rcDst.bottom - rcDst.top,
00570 hdc,
00571 rcDst.left - dxLog,
00572 rcDst.top - dyLog,
00573 SRCCOPY,
00574 0);
00575
00576 GreExtSelectClipRgn(hdc,
00577 (fClipped ? hrgnSaveVis : NULL),
00578 RGN_COPY);
00579
00580 GreDeleteObject(hrgnSaveVis);
00581 }
00582
00583
#else
00584
00585
00586
00587
00588
00589 POINT pt;
00590 GreGetDCOrg(hdc, &pt);
00591
00592 GreOffsetRgn(ghrgnScrlValid, pt.x, pt.y);
00593
00594
00595
00596
00597
00598 GreSelectVisRgn(hdc, ghrgnScrlValid, SVR_SWAP);
00599
00600
00601
00602
00603
00604
if (fLogUnits)
00605 GreDPtoLP(hdc, (LPPOINT)&rcDst, 2);
00606
00607
00608
00609
00610
00611 GreBitBlt(hdc,
00612 rcDst.left,
00613 rcDst.top,
00614 rcDst.right - rcDst.left,
00615 rcDst.bottom - rcDst.top,
00616 hdc,
00617 rcDst.left - dxLog,
00618 rcDst.top - dyLog,
00619 SRCCOPY,
00620 0);
00621
00622
00623
00624
00625
00626 GreSelectVisRgn(hdc, ghrgnScrlValid, SVR_SWAP);
00627
00628
#endif
00629
}
00630 }
00631
00632
00633
00634
00635
00636
if (fLogUnits && prcUpdate) {
00637 GreDPtoLP(hdc, (LPPOINT)prcUpdate, 2);
00638 }
00639
00640 GreUnlockDisplay(
gpDispInfo->
hDev);
00641
00642
return wClip;
00643 }