|
|
1.1 ! root 1: #include "jigsaw.h" ! 2: #include "globals.h" ! 3: #include <stdlib.h> ! 4: #include <stdio.h> ! 5: #include <string.h> ! 6: ! 7: /******************************************************************************/ ! 8: /* */ ! 9: /* Create a memory DC and an associated PS. */ ! 10: /* */ ! 11: /******************************************************************************/ ! 12: BOOL CreateBitmapHdcHps( phdc, phps) ! 13: PHDC phdc; ! 14: PHPS phps; ! 15: { ! 16: SIZEL sizl; ! 17: HDC hdc; ! 18: HPS hps; ! 19: ! 20: hdc = DevOpenDC( habMain, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL); ! 21: if( !hdc) ! 22: return( FALSE); ! 23: ! 24: sizl.cx = sizl.cy = 1L; ! 25: hps = GpiCreatePS( habMain ! 26: , hdc ! 27: , &sizl ! 28: , PU_PELS | GPIA_ASSOC | GPIT_MICRO ); ! 29: if( !hps) ! 30: return( FALSE); ! 31: ! 32: *phdc = hdc; ! 33: *phps = hps; ! 34: return( TRUE); ! 35: } ! 36: ! 37: /*****************************************************************************/ ! 38: /* */ ! 39: /* Add (at head or tail) or delete a specified segment list member. */ ! 40: /* */ ! 41: /******************************************************************************/ ! 42: PSEGLIST SegListUpdate( usOperation, pslUpdate) ! 43: USHORT usOperation; ! 44: PSEGLIST pslUpdate; ! 45: { ! 46: PSEGLIST psl; ! 47: ! 48: switch( usOperation) ! 49: { ! 50: case ADD_HEAD_SEG: ! 51: if( pslHead == NULL) ! 52: { ! 53: DosAllocMem( &pslHead, sizeof( SEGLIST), PAG_READ | PAG_WRITE | PAG_COMMIT); ! 54: if( pslHead == NULL) ! 55: return( NULL); ! 56: *pslHead = *pslUpdate; ! 57: pslHead->pslPrev = NULL; ! 58: pslHead->pslNext = NULL; ! 59: pslTail = pslHead; ! 60: } else ! 61: { ! 62: DosAllocMem( &psl, sizeof( SEGLIST), PAG_READ | PAG_WRITE | PAG_COMMIT); ! 63: if( psl == NULL) ! 64: return( NULL); ! 65: *psl = *pslUpdate; ! 66: pslHead->pslPrev = psl; ! 67: psl->pslNext = pslHead; ! 68: psl->pslPrev = NULL; ! 69: pslHead = psl; ! 70: } ! 71: return( pslHead); ! 72: break; ! 73: ! 74: case ADD_TAIL_SEG: ! 75: if( pslTail == NULL) ! 76: { ! 77: DosAllocMem( &pslHead, sizeof( SEGLIST), PAG_READ | PAG_WRITE | ! 78: PAG_COMMIT); ! 79: if( pslHead == NULL) ! 80: return( NULL); ! 81: *pslHead = *pslUpdate; ! 82: pslHead->pslPrev = NULL; ! 83: pslHead->pslNext = NULL; ! 84: pslTail = pslHead; ! 85: } else ! 86: { ! 87: DosAllocMem( &psl, sizeof( SEGLIST), PAG_READ | PAG_WRITE | ! 88: PAG_COMMIT); ! 89: if( psl == NULL) ! 90: return( NULL); ! 91: *psl = *pslUpdate; ! 92: pslTail->pslNext = psl; ! 93: psl->pslPrev = pslTail; ! 94: psl->pslNext = NULL; ! 95: pslTail = psl; ! 96: } ! 97: return( pslTail); ! 98: break; ! 99: ! 100: case MAKE_TAIL_SEG: ! 101: if( pslUpdate == pslTail) ! 102: return( pslTail); ! 103: if( pslUpdate == pslHead) ! 104: { ! 105: pslHead = pslHead->pslNext; ! 106: pslHead->pslPrev = NULL; ! 107: } else ! 108: { ! 109: pslUpdate->pslPrev->pslNext = pslUpdate->pslNext; ! 110: pslUpdate->pslNext->pslPrev = pslUpdate->pslPrev; ! 111: } ! 112: pslTail->pslNext = pslUpdate; ! 113: pslUpdate->pslPrev = pslTail; ! 114: pslTail = pslUpdate; ! 115: pslTail->pslNext = NULL; ! 116: return( pslTail); ! 117: break; ! 118: ! 119: case MAKE_HEAD_SEG: ! 120: if( pslUpdate == pslHead) ! 121: return( pslHead); ! 122: if( pslUpdate == pslTail) ! 123: { ! 124: pslTail = pslTail->pslPrev; ! 125: pslTail->pslNext = NULL; ! 126: } else ! 127: { ! 128: pslUpdate->pslPrev->pslNext = pslUpdate->pslNext; ! 129: pslUpdate->pslNext->pslPrev = pslUpdate->pslPrev; ! 130: } ! 131: pslHead->pslPrev = pslUpdate; ! 132: pslUpdate->pslNext = pslHead; ! 133: pslHead = pslUpdate; ! 134: pslHead->pslPrev = NULL; ! 135: return( pslHead); ! 136: break; ! 137: ! 138: case DEL_SEG: ! 139: for( psl = pslHead; psl != NULL; psl = psl->pslNext) ! 140: { ! 141: if( psl->lSegId == pslUpdate->lSegId) ! 142: { ! 143: if( psl == pslHead) ! 144: { ! 145: pslHead = psl->pslNext; ! 146: if( pslHead == NULL) ! 147: pslTail = NULL; ! 148: else ! 149: pslHead->pslPrev = NULL; ! 150: }else if( psl == pslTail) ! 151: { ! 152: pslTail = psl->pslPrev; ! 153: pslTail->pslNext = NULL; ! 154: } else ! 155: { ! 156: (psl->pslPrev)->pslNext = psl->pslNext; ! 157: (psl->pslNext)->pslPrev = psl->pslPrev; ! 158: } ! 159: DosFreeMem( psl); ! 160: return( psl); ! 161: break; ! 162: } ! 163: } ! 164: return( NULL); ! 165: break; ! 166: ! 167: default: ! 168: return( NULL); ! 169: } ! 170: } ! 171: ! 172: /******************************************************************************/ ! 173: /* */ ! 174: /* set the default viewing transform */ ! 175: /* */ ! 176: /******************************************************************************/ ! 177: VOID SetDVTransform( fx11, fx12, fx21, fx22, l31, l32, lType) ! 178: FIXED fx11; ! 179: FIXED fx12; ! 180: FIXED fx21; ! 181: FIXED fx22; ! 182: FIXED l31; ! 183: FIXED l32; ! 184: FIXED lType; ! 185: { ! 186: MATRIXLF matlf; ! 187: ! 188: matlf.fxM11 = fx11; ! 189: matlf.fxM12 = fx12; ! 190: matlf.lM13 = 0L; ! 191: matlf.fxM21 = fx21; ! 192: matlf.fxM22 = fx22; ! 193: matlf.lM23 = 0L; ! 194: matlf.lM31 = l31; ! 195: matlf.lM32 = l32; ! 196: matlf.lM33 = 1L; ! 197: GpiSetDefaultViewMatrix( hpsClient, 9L, &matlf, lType); ! 198: } ! 199: ! 200: /******************************************************************************/ ! 201: /* */ ! 202: /* Determine the bounding rect of a segment. */ ! 203: /* */ ! 204: /* Use special knowledge that the only non-identity part of the segment */ ! 205: /* transform is the translation part. */ ! 206: /******************************************************************************/ ! 207: VOID SetRect( psl) ! 208: PSEGLIST psl; ! 209: { ! 210: psl->rclCurrent = psl->rclBitBlt; /* world space bounding rect */ ! 211: psl->rclCurrent.xLeft += psl->ptlModelXlate.x; ! 212: psl->rclCurrent.yBottom += psl->ptlModelXlate.y; ! 213: psl->rclCurrent.xRight += psl->ptlModelXlate.x; ! 214: psl->rclCurrent.yTop += psl->ptlModelXlate.y; ! 215: } ! 216: ! 217: /******************************************************************************/ ! 218: /* */ ! 219: /* Return a pointer to a segment list member, based on segment id. */ ! 220: /* */ ! 221: /******************************************************************************/ ! 222: PSEGLIST SegListGet( lSeg) ! 223: LONG lSeg; ! 224: { ! 225: PSEGLIST psl; ! 226: ! 227: for( psl = pslHead; psl != NULL; psl = psl->pslNext) ! 228: if( psl->lSegId == lSeg) ! 229: return( psl); ! 230: return( NULL); ! 231: } ! 232: ! 233: /******************************************************************************/ ! 234: /* */ ! 235: /* Draw one piece. */ ! 236: /* */ ! 237: /******************************************************************************/ ! 238: VOID DrawPiece( hps, psl, fFill) ! 239: HPS hps; ! 240: PSEGLIST psl; ! 241: BOOL fFill; ! 242: { ! 243: POINTL aptl[4]; ! 244: ! 245: if( psl->fVisible) ! 246: { ! 247: aptl[2].x = aptl[2].y = 0L; ! 248: aptl[3] = psl->aptlBitBlt[3]; ! 249: aptl[0].x = psl->rclBitBlt.xLeft + psl->ptlModelXlate.x; ! 250: aptl[0].y = psl->rclBitBlt.yBottom + psl->ptlModelXlate.y; ! 251: GpiConvert( hpsClient, CVTC_MODEL, CVTC_DEVICE, 1L, aptl); ! 252: aptl[1].x = aptl[0].x + aptl[3].x; ! 253: aptl[1].y = aptl[0].y + aptl[3].y; ! 254: GpiBitBlt( hps /* punch a hole */ ! 255: , psl->hpsHole ! 256: , 4L ! 257: , aptl ! 258: , ROP_SRCAND ! 259: , BBO_IGNORE ); ! 260: if( fFill) ! 261: GpiBitBlt( hps /* fill the hole */ ! 262: , psl->hpsFill ! 263: , 4L ! 264: , aptl ! 265: , ROP_SRCPAINT ! 266: , BBO_IGNORE ); ! 267: } ! 268: } ! 269: ! 270: /******************************************************************************/ ! 271: /* */ ! 272: /* Draw the picture, using the passed region for clipping. */ ! 273: /* Intersect the bounding box used for the clip region with the client rect. */ ! 274: /* Test each segment to see if its bounding box intersects the bounding box */ ! 275: /* of the clipping region. Draw only if there is an intersection. */ ! 276: /* */ ! 277: /******************************************************************************/ ! 278: BOOL DoDraw( hps, hrgn, fPaint) ! 279: HPS hps; ! 280: HRGN hrgn; ! 281: BOOL fPaint; ! 282: { ! 283: HRGN hrgnOld; ! 284: RECTL rcl, rclRegion, rclDst, rclClient; ! 285: PSEGLIST psl; ! 286: ULONG ulPostCt; ! 287: ! 288: if( fPaint) ! 289: { ! 290: GpiSetColor( hps, CLR_BACKGROUND); ! 291: GpiPaintRegion( hps, hrgn); /* erase region */ ! 292: } ! 293: GpiQueryRegionBox( hps, hrgn, &rclRegion); ! 294: WinQueryWindowRect( hwndClient, &rclClient); ! 295: if( !WinIntersectRect( habAsync, &rclRegion, &rclRegion, &rclClient)) ! 296: return( FALSE); /* not in client window */ ! 297: GpiSetClipRegion( hps, hrgn, &hrgnOld); /* make the clip region */ ! 298: for( psl = pslHead; psl != NULL; psl = psl->pslNext) /* scan all pieces */ ! 299: { ! 300: /**************************************************************************/ ! 301: /* get the piece bounding box in device coordinates */ ! 302: /**************************************************************************/ ! 303: rcl = psl->rclCurrent; ! 304: GpiConvert( hpsClient, CVTC_MODEL, CVTC_DEVICE, 2L, (PPOINTL)&rcl); ! 305: rcl.xRight++; ! 306: rcl.yTop++; ! 307: /**************************************************************************/ ! 308: /* if the piece might be visible, and drawing allowed, draw the piece */ ! 309: /**************************************************************************/ ! 310: if( WinIntersectRect( habAsync, &rclDst, &rcl, &rclRegion)) ! 311: DosQueryEventSem( hevDrawOn, &ulPostCt); ! 312: if( ulPostCt) ! 313: DrawPiece( hps, psl, TRUE); ! 314: else ! 315: break; ! 316: } ! 317: GpiSetClipRegion( hps, NULL, &hrgnOld); ! 318: DosQueryEventSem( hevDrawOn, &ulPostCt); ! 319: if( ulPostCt) ! 320: GpiSetRegion( hpsClient, hrgnInvalid, 0L, NULL); ! 321: ! 322: return( TRUE); ! 323: } ! 324: ! 325: /******************************************************************************/ ! 326: /* */ ! 327: /* get bounding rect of whole picture in model coordinates */ ! 328: /* */ ! 329: /******************************************************************************/ ! 330: VOID CalcBounds(VOID) ! 331: { ! 332: PSEGLIST psl; ! 333: RECTL rclOld; ! 334: ULONG ulPostKillDraw, ulPostCt; ! 335: ! 336: if( !pslHead) ! 337: return; ! 338: rclBounds = rclOld = pslHead->rclCurrent; ! 339: ! 340: /* ! 341: * get start killdraw post count ! 342: */ ! 343: DosQueryEventSem(hevKillDraw, &ulPostKillDraw); ! 344: ! 345: for( psl = pslHead->pslNext; psl != NULL; psl = psl->pslNext) { ! 346: DosQueryEventSem(hevKillDraw, &ulPostCt); ! 347: if (ulPostKillDraw != ulPostCt) { ! 348: rclBounds = rclOld; ! 349: return; ! 350: } ! 351: WinUnionRect(habAsync, &rclBounds, &rclBounds, &(psl->rclCurrent)); ! 352: } ! 353: } ! 354: ! 355: /******************************************************************************/ ! 356: /* */ ! 357: /* Calculate and set the default viewing transform based on zoom and scroll */ ! 358: /* */ ! 359: /******************************************************************************/ ! 360: VOID CalcTransform( hwnd) ! 361: HWND hwnd; ! 362: { ! 363: RECTL rclClient; ! 364: POINTL ptlCenter, ptlTrans, ptlScale, aptl[4], ptlOrg, aptlSides[12]; ! 365: PSEGLIST psl; ! 366: LONG l; ! 367: MATRIXLF matlf; ! 368: ULONG ulPostCt, ulPostKillDraw; ! 369: ! 370: ! 371: /* ! 372: * get start killdraw post count ! 373: */ ! 374: DosQueryEventSem(hevKillDraw, &ulPostKillDraw); ! 375: ! 376: ! 377: /****************************************************************************/ ! 378: /* from bounding rect of picture get center of picture */ ! 379: /****************************************************************************/ ! 380: ptlCenter.x = (rclBounds.xLeft + rclBounds.xRight) / 2; ! 381: ptlCenter.y = (rclBounds.yBottom + rclBounds.yTop ) / 2; ! 382: ! 383: /****************************************************************************/ ! 384: /* translate center of picture to origin */ ! 385: /****************************************************************************/ ! 386: SetDVTransform( (FIXED)UNITY ! 387: , (FIXED)0 ! 388: , (FIXED)0 ! 389: , (FIXED)UNITY ! 390: , -ptlCenter.x ! 391: , -ptlCenter.y ! 392: , TRANSFORM_REPLACE); ! 393: ! 394: /****************************************************************************/ ! 395: /* scale down to 1:1 of bitmap in file */ ! 396: /****************************************************************************/ ! 397: ptlScale.x = UNITY * ADJUSTED_PBMP(pbmp2BitmapFile)->cx ! 398: / (ptlTopRight.x - ptlBotLeft.x); ! 399: ptlScale.y = UNITY * ADJUSTED_PBMP(pbmp2BitmapFile)->cy ! 400: / (ptlTopRight.y - ptlBotLeft.y); ! 401: ! 402: /****************************************************************************/ ! 403: /* add in zoom scale */ ! 404: /****************************************************************************/ ! 405: ptlScale.x += ptlScale.x * lScale / (ZOOM_MAX + 1); ! 406: ptlScale.y += ptlScale.y * lScale / (ZOOM_MAX + 1); ! 407: ! 408: SetDVTransform( (FIXED)ptlScale.x ! 409: , (FIXED)0 ! 410: , (FIXED)0 ! 411: , (FIXED)ptlScale.y ! 412: , 0L ! 413: , 0L ! 414: , TRANSFORM_ADD); ! 415: ! 416: /****************************************************************************/ ! 417: /* translate center of picture to center of client window */ ! 418: /****************************************************************************/ ! 419: WinQueryWindowRect( hwnd, &rclClient); ! 420: ptlTrans.x = (rclClient.xRight - rclClient.xLeft) / 2; ! 421: ptlTrans.y = (rclClient.yTop - rclClient.yBottom) / 2; ! 422: ! 423: /****************************************************************************/ ! 424: /* add in horizontal and vertical scrolling factors */ ! 425: /****************************************************************************/ ! 426: ptlTrans.x -= ptsScrollPos.x - ptsHalfScrollMax.x; ! 427: ptlTrans.y += ptsScrollPos.y - ptsHalfScrollMax.y; ! 428: SetDVTransform( (FIXED)UNITY ! 429: , (FIXED)0 ! 430: , (FIXED)0 ! 431: , (FIXED)UNITY ! 432: , ptlTrans.x ! 433: , ptlTrans.y ! 434: , TRANSFORM_ADD); ! 435: ! 436: GpiQueryDefaultViewMatrix( hpsClient, 9L, &matlf); ! 437: GpiSetDefaultViewMatrix( hpsClient, 9L, &matlf, TRANSFORM_REPLACE); ! 438: ! 439: /****************************************************************************/ ! 440: /* create bitmaps for pieces */ ! 441: /****************************************************************************/ ! 442: ! 443: ptlOffset = ptlBotLeft; /* BottomLeft corner in dev coord */ ! 444: GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 1L, &ptlOffset); ! 445: if( (ptlScale.x != ptlScaleRef.x) || (ptlScale.y != ptlScaleRef.y)) ! 446: { ! 447: ptlScaleRef = ptlScale; ! 448: ! 449: /**************************************************************************/ ! 450: /* create a shadow bitmap of the original, sized to current output size */ ! 451: /**************************************************************************/ ! 452: aptl[0] = ptlBotLeft; /* current output rect, dev coord */ ! 453: aptl[1] = ptlTopRight; ! 454: GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 2L, aptl); ! 455: ! 456: aptl[0].x -= ptlOffset.x; /* put bottom left at (0,0) */ ! 457: aptl[0].y -= ptlOffset.y; ! 458: aptl[1].x -= ptlOffset.x; ! 459: aptl[1].y -= ptlOffset.y; ! 460: #ifdef fred ! 461: aptl[1].x -= ptlOffset.x - 1; /* correct for coordinate convert */ ! 462: aptl[1].y -= ptlOffset.y - 1; ! 463: #endif ! 464: aptl[2].x = 0L; ! 465: aptl[2].y = 0L; ! 466: aptl[3].x = ADJUSTED_PBMP(pbmp2BitmapFile)->cx; /* bitmap dimensions */ ! 467: aptl[3].y = ADJUSTED_PBMP(pbmp2BitmapFile)->cy; ! 468: GpiSetBitmap( hpsBitmapSize, hbmBitmapSize); ! 469: GpiBitBlt( hpsBitmapSize /* copy the bitmap */ ! 470: , hpsBitmapFile ! 471: , 4L ! 472: , aptl ! 473: , ROP_SRCCOPY ! 474: , BBO_IGNORE); ! 475: ! 476: for( psl = pslHead; psl != NULL; psl = psl->pslNext) ! 477: { ! 478: DosQueryEventSem( hevTerminate, &ulPostCt); ! 479: if( ulPostCt) /* exit if quit */ ! 480: break; ! 481: ! 482: DosQueryEventSem( hevKillDraw, &ulPostCt); ! 483: if( ulPostCt != ulPostKillDraw) { ! 484: break; ! 485: } ! 486: ! 487: aptl[0].x = psl->rclBitBlt.xLeft; /* bounding rect in world space */ ! 488: aptl[0].y = psl->rclBitBlt.yBottom; ! 489: aptl[1].x = psl->rclBitBlt.xRight; ! 490: aptl[1].y = psl->rclBitBlt.yTop; ! 491: aptl[2] = aptl[0]; ! 492: aptl[3] = aptl[1]; ! 493: GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 2L, &aptl[2]); ! 494: ptlOrg = aptl[2]; ! 495: aptl[3].x -= ptlOrg.x - 1; /* bitmap rect of piece */ ! 496: aptl[3].y -= ptlOrg.y - 1; ! 497: aptl[2].x = 0L; ! 498: aptl[2].y = 0L; ! 499: psl->aptlBitBlt[0] = aptl[0]; ! 500: psl->aptlBitBlt[1] = aptl[1]; ! 501: psl->aptlBitBlt[2] = aptl[2]; ! 502: psl->aptlBitBlt[3] = aptl[3]; ! 503: ! 504: /************************************************************************/ ! 505: /* compute the piece control points */ ! 506: /************************************************************************/ ! 507: for ( l = 0; l < 12; l++) ! 508: aptlSides[l] = psl->aptlSides[l]; ! 509: GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 12L, aptlSides); ! 510: for ( l = 0; l < 12; l++) ! 511: { ! 512: aptlSides[l].x -= ptlOrg.x; ! 513: aptlSides[l].y -= ptlOrg.y; ! 514: } ! 515: ! 516: /************************************************************************/ ! 517: /* prepare the mask to punch a hole in the output bitmap */ ! 518: /************************************************************************/ ! 519: GpiSetClipPath( psl->hpsHole, 0L, SCP_RESET); /* no clip path */ ! 520: GpiBitBlt( psl->hpsHole /* fill with 1's */ ! 521: , NULL ! 522: , 2L ! 523: , &psl->aptlBitBlt[2] ! 524: , ROP_ONE ! 525: , BBO_IGNORE); ! 526: ! 527: GpiBeginPath( psl->hpsHole, 1L); /* define a clip path */ ! 528: GpiMove( psl->hpsHole, &aptlSides[11]); ! 529: GpiPolySpline( psl->hpsHole, 12L, aptlSides); ! 530: GpiEndPath( psl->hpsHole); ! 531: GpiSetClipPath( psl->hpsHole, 1L, SCP_AND); ! 532: GpiBitBlt( psl->hpsHole /* fill with 0's */ ! 533: , NULL ! 534: , 2L ! 535: , &psl->aptlBitBlt[2] ! 536: , ROP_ZERO ! 537: , BBO_IGNORE); ! 538: GpiSetClipPath( psl->hpsHole, 0L, SCP_RESET); /* clear the clip path */ ! 539: ! 540: /************************************************************************/ ! 541: /* prepare the mask to fill the hole in the output bitmap */ ! 542: /************************************************************************/ ! 543: aptl[0] = psl->aptlBitBlt[2]; ! 544: aptl[1] = psl->aptlBitBlt[3]; ! 545: aptl[2] = aptl[0]; ! 546: GpiBitBlt( psl->hpsFill /* make inverse of hole */ ! 547: , psl->hpsHole ! 548: , 3L ! 549: , aptl ! 550: , ROP_NOTSRCCOPY ! 551: , BBO_IGNORE); ! 552: ! 553: aptl[0] = psl->aptlBitBlt[2]; ! 554: aptl[1] = psl->aptlBitBlt[3]; ! 555: aptl[2].x = ptlOrg.x - ptlOffset.x; /* pick the right part */ ! 556: aptl[2].y = ptlOrg.y - ptlOffset.y; /* of the sized bitmap */ ! 557: GpiBitBlt( psl->hpsFill /* fill with data */ ! 558: , hpsBitmapSize ! 559: , 3L ! 560: , aptl ! 561: , ROP_SRCAND ! 562: , BBO_IGNORE); ! 563: GpiSetClipPath( psl->hpsFill, 0L, SCP_RESET); /* clear the clip path */ ! 564: ! 565: GpiSetColor( psl->hpsFill, CLR_RED); /* draw the outline */ ! 566: GpiMove( psl->hpsFill, &aptlSides[11]); ! 567: GpiPolySpline( psl->hpsFill, 12L, aptlSides); ! 568: DrawPiece( hpsClient, psl, TRUE); ! 569: } ! 570: } ! 571: } ! 572: ! 573: /******************************************************************************/ ! 574: /* */ ! 575: /* Redraw the entire client window. */ ! 576: /* */ ! 577: /******************************************************************************/ ! 578: VOID Redraw(VOID) ! 579: { ! 580: RECTL rclInvalid; ! 581: HRGN hrgnUpdt; ! 582: POINTL aptlUpdtNew[3]; ! 583: ! 584: WinQueryWindowRect( hwndClient, &rclInvalid); ! 585: hrgnUpdt = GpiCreateRegion( hpsBitmapBuff, 1L, &rclInvalid); ! 586: DoDraw( hpsBitmapBuff, hrgnUpdt, TRUE); ! 587: GpiDestroyRegion( hpsBitmapBuff, hrgnUpdt); ! 588: aptlUpdtNew[0].x = rclInvalid.xLeft; ! 589: aptlUpdtNew[0].y = rclInvalid.yBottom; ! 590: aptlUpdtNew[1].x = rclInvalid.xRight; ! 591: aptlUpdtNew[1].y = rclInvalid.yTop; ! 592: ROUND_DOWN_MOD( aptlUpdtNew[0].x, lByteAlignX); /* round down */ ! 593: ROUND_DOWN_MOD( aptlUpdtNew[0].y, lByteAlignY); /* round down */ ! 594: ROUND_UP_MOD( aptlUpdtNew[1].x, lByteAlignX); /* round up */ ! 595: ROUND_UP_MOD( aptlUpdtNew[1].y, lByteAlignY); /* round up */ ! 596: aptlUpdtNew[2] = aptlUpdtNew[0]; ! 597: GpiBitBlt( hpsClient ! 598: , hpsBitmapBuff ! 599: , 3L ! 600: , aptlUpdtNew ! 601: , ROP_SRCCOPY ! 602: , BBO_IGNORE ); ! 603: } ! 604: ! 605: /******************************************************************************/ ! 606: /* perform bitmap-based correlation */ ! 607: /******************************************************************************/ ! 608: PSEGLIST Correlate( pptl) ! 609: PPOINTL pptl; ! 610: { ! 611: PSEGLIST psl; ! 612: POINTL aptl[2]; ! 613: LONG lColor; ! 614: RECTL rcl; ! 615: ! 616: ! 617: aptl[0] = aptl[1] = *pptl; ! 618: aptl[1].x++; ! 619: aptl[1].y++; ! 620: GpiBitBlt( hpsBitmapSave, NULL, 2L, aptl, ROP_ONE, BBO_IGNORE); ! 621: lColor = GpiQueryPel( hpsBitmapSave, pptl); ! 622: for( psl = pslTail; psl != NULL; psl = psl->pslPrev) ! 623: { ! 624: rcl = psl->rclCurrent; ! 625: GpiConvert( hpsClient, CVTC_MODEL, CVTC_DEVICE, 2L, (PPOINTL)&rcl); ! 626: rcl.xRight++; ! 627: rcl.yTop++; ! 628: if( WinPtInRect( habAsync, &rcl, pptl)) /* is point in bounding box? */ ! 629: { ! 630: DrawPiece( hpsBitmapSave, psl, FALSE); ! 631: if( GpiQueryPel( hpsBitmapSave, pptl) != lColor) ! 632: break; /* got a hit */ ! 633: } ! 634: } ! 635: return( psl); ! 636: } ! 637: ! 638: /******************************************************************************/ ! 639: /* */ ! 640: /* MyMessageBox */ ! 641: /* */ ! 642: /* Displays a message box with the given string. To simplify matters, */ ! 643: /* the box will always have the same title ("Jigsaw"), will always */ ! 644: /* have a single button ("Ok"), will always have an exclamation point */ ! 645: /* icon, and will always be application modal. */ ! 646: /* */ ! 647: /******************************************************************************/ ! 648: VOID MyMessageBox( hWnd, psz) ! 649: HWND hWnd; ! 650: PSZ psz; ! 651: { ! 652: WinMessageBox( HWND_DESKTOP ! 653: , hWnd ! 654: , psz ! 655: , szTitle ! 656: , NULL ! 657: , MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL ); ! 658: } ! 659: ! 660: /******************************************************************************/ ! 661: /* */ ! 662: /* mark a whole island */ ! 663: /* */ ! 664: /******************************************************************************/ ! 665: VOID MarkIsland( pslMark, fMark) ! 666: PSEGLIST pslMark; ! 667: BOOL fMark; ! 668: { ! 669: PSEGLIST psl; ! 670: BOOL fFirst; ! 671: ! 672: for( psl = pslMark, fFirst = TRUE ! 673: ; (psl != pslMark) || fFirst ! 674: ; psl = psl->pslNextIsland, fFirst = FALSE ) ! 675: psl->fIslandMark = fMark; /* mark as island member */ ! 676: } ! 677: ! 678: ! 679: /******************************************************************************/ ! 680: /* Display Zoom factor */ ! 681: /******************************************************************************/ ! 682: VOID DisplayZoomFactor( lScaleFactor) ! 683: LONG lScaleFactor; ! 684: { ! 685: ! 686: sprintf(szZoomFact, "1:%d", -lScaleFactor + 1); ! 687: WinSetDlgItemText(hwndStatus, SID_ZOOMFACT, szZoomFact); ! 688: WinSendMsg(hwndZoomScrollBar, SBM_SETPOS, ! 689: MPFROMSHORT((USHORT) -lScaleFactor), 0L); ! 690: ! 691: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.