home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
TOOLKIT
/
PM
/
BMPSAMP
/
MISC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-17
|
33KB
|
867 lines
/******************************************************************************
*
* File Name : MISC.C
*
* Description : miscellaneous Jigsaw functions
*
* Entry Points:
* CreateBitmapHdcHps()
* SegListUpdate()
* SetDVTransform()
* SetRect()
* SegListGet()
* DrawPiece()
* DoDraw()
* CalcBounds()
* CalcTransform()
* Redraw()
* Correlate()
* MarkIsland()
*
* Copyright (C) 1992 IBM Corporation
*
* DISCLAIMER OF WARRANTIES. The following [enclosed] code is
* sample code created by IBM Corporation. This sample code is not
* part of any standard or IBM product and is provided to you solely
* for the purpose of assisting you in the development of your
* applications. The code is provided "AS IS", without
* warranty of any kind. IBM shall not be liable for any damages
* arising out of your use of the sample code, even if they have been
* advised of the possibility of such damages. *
*
******************************************************************************/
#include "jigsaw.h"
#include "globals.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/******************************************************************************/
/* */
/* Create a memory DC and an associated PS. */
/* */
/******************************************************************************/
BOOL CreateBitmapHdcHps( phdc, phps)
PHDC phdc;
PHPS phps;
{
SIZEL sizl;
HDC hdc;
HPS hps;
hdc = DevOpenDC( habMain, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULLHANDLE);
if( !hdc)
return( FALSE);
sizl.cx = sizl.cy = 1L;
if ((hps = GpiCreatePS( habMain
, hdc
, &sizl
, PU_PELS | GPIA_ASSOC | GPIT_MICRO )) == GPI_ERROR)
DispError(habMain,hwndClient);
if( !hps)
return( FALSE);
*phdc = hdc;
*phps = hps;
return( TRUE);
}
/*****************************************************************************/
/* */
/* Add (at head or tail) or delete a specified segment list member. */
/* */
/******************************************************************************/
PSEGLIST SegListUpdate(USHORT usOperation,PSEGLIST pslUpdate)
{
PSEGLIST psl;
switch( usOperation)
{
case ADD_HEAD_SEG:
if( pslHead == NULL)
{
DosAllocMem((PPVOID)&pslHead,(ULONG)sizeof(SEGLIST),(ULONG)PAG_READ | PAG_WRITE | PAG_COMMIT);
if( pslHead == NULL)
return( NULL);
*pslHead = *pslUpdate;
pslHead->pslPrev = NULL;
pslHead->pslNext = NULL;
pslTail = pslHead;
} else
{
DosAllocMem((PPVOID)&psl,(ULONG)sizeof(SEGLIST),(ULONG)PAG_READ | PAG_WRITE | PAG_COMMIT);
if( psl == NULL)
return( NULL);
*psl = *pslUpdate;
pslHead->pslPrev = psl;
psl->pslNext = pslHead;
psl->pslPrev = NULL;
pslHead = psl;
}
return( pslHead);
break;
case ADD_TAIL_SEG:
if( pslTail == NULL)
{
DosAllocMem((PPVOID)&pslHead,(ULONG)sizeof(SEGLIST),(ULONG)PAG_READ | PAG_WRITE |
PAG_COMMIT);
if( pslHead == NULL)
return( NULL);
*pslHead = *pslUpdate;
pslHead->pslPrev = NULL;
pslHead->pslNext = NULL;
pslTail = pslHead;
} else
{
DosAllocMem((PPVOID)&psl,(ULONG)sizeof(SEGLIST),(ULONG)PAG_READ | PAG_WRITE |
PAG_COMMIT);
if( psl == NULL)
return( NULL);
*psl = *pslUpdate;
pslTail->pslNext = psl;
psl->pslPrev = pslTail;
psl->pslNext = NULL;
pslTail = psl;
}
return( pslTail);
break;
case MAKE_TAIL_SEG:
if( pslUpdate == pslTail)
return( pslTail);
if( pslUpdate == pslHead)
{
pslHead = pslHead->pslNext;
pslHead->pslPrev = NULL;
} else
{
pslUpdate->pslPrev->pslNext = pslUpdate->pslNext;
pslUpdate->pslNext->pslPrev = pslUpdate->pslPrev;
}
pslTail->pslNext = pslUpdate;
pslUpdate->pslPrev = pslTail;
pslTail = pslUpdate;
pslTail->pslNext = NULL;
return( pslTail);
break;
case MAKE_HEAD_SEG:
if( pslUpdate == pslHead)
return( pslHead);
if( pslUpdate == pslTail)
{
pslTail = pslTail->pslPrev;
pslTail->pslNext = NULL;
} else
{
pslUpdate->pslPrev->pslNext = pslUpdate->pslNext;
pslUpdate->pslNext->pslPrev = pslUpdate->pslPrev;
}
pslHead->pslPrev = pslUpdate;
pslUpdate->pslNext = pslHead;
pslHead = pslUpdate;
pslHead->pslPrev = NULL;
return( pslHead);
break;
case DEL_SEG:
for( psl = pslHead; psl != NULL; psl = psl->pslNext)
{
if( psl->lSegId == pslUpdate->lSegId)
{
if( psl == pslHead)
{
pslHead = psl->pslNext;
if( pslHead == NULL)
pslTail = NULL;
else
pslHead->pslPrev = NULL;
}else if( psl == pslTail)
{
pslTail = psl->pslPrev;
pslTail->pslNext = NULL;
} else
{
(psl->pslPrev)->pslNext = psl->pslNext;
(psl->pslNext)->pslPrev = psl->pslPrev;
}
DosFreeMem( psl);
return( psl);
break;
}
}
return( NULL);
break;
default:
return( NULL);
}
}
/******************************************************************************/
/* */
/* set the default viewing transform */
/* */
/******************************************************************************/
VOID SetDVTransform( fx11, fx12, fx21, fx22, l31, l32, lType)
FIXED fx11;
FIXED fx12;
FIXED fx21;
FIXED fx22;
FIXED l31;
FIXED l32;
FIXED lType;
{
MATRIXLF matlf;
matlf.fxM11 = fx11;
matlf.fxM12 = fx12;
matlf.lM13 = 0L;
matlf.fxM21 = fx21;
matlf.fxM22 = fx22;
matlf.lM23 = 0L;
matlf.lM31 = l31;
matlf.lM32 = l32;
matlf.lM33 = 1L;
if (GpiSetDefaultViewMatrix( hpsClient, 9L, &matlf, lType) == GPI_ERROR)
DispError(habMain,hwndClient);
}
/******************************************************************************/
/* */
/* Determine the bounding rect of a segment. */
/* */
/* Use special knowledge that the only non-identity part of the segment */
/* transform is the translation part. */
/******************************************************************************/
VOID SetRect( psl)
PSEGLIST psl;
{
psl->rclCurrent = psl->rclBitBlt; /* world space bounding rect */
psl->rclCurrent.xLeft += psl->ptlModelXlate.x;
psl->rclCurrent.yBottom += psl->ptlModelXlate.y;
psl->rclCurrent.xRight += psl->ptlModelXlate.x;
psl->rclCurrent.yTop += psl->ptlModelXlate.y;
}
/******************************************************************************/
/* */
/* Return a pointer to a segment list member, based on segment id. */
/* */
/******************************************************************************/
PSEGLIST SegListGet( lSeg)
LONG lSeg;
{
PSEGLIST psl;
for( psl = pslHead; psl != NULL; psl = psl->pslNext)
if( psl->lSegId == lSeg)
return( psl);
return( NULL);
}
/******************************************************************************
*
* Name : DrawPiece
*
* Description : Draw one piece.
*
* Concepts :
*
* API's :
*
* Parameters : HPS hps
* PSEGLIST psl
* BOOL fFill
*
* Return : VOID
*
******************************************************************************/
VOID DrawPiece(HPS hps, PSEGLIST psl, BOOL fFill)
{
POINTL aptl[4];
APIRET rc;
if(psl->fVisible) /* don't bother if not visible */
{
/*
* Setup source and target points based on model transform of this peice
*/
aptl[2].x = aptl[2].y = 0L; /* source: lower left */
aptl[3] = psl->aptlBitBlt[3]; /* source: upper right */
/* target: */
aptl[0].x = psl->rclBitBlt.xLeft + psl->ptlModelXlate.x; /* lower left */
aptl[0].y = psl->rclBitBlt.yBottom + psl->ptlModelXlate.y;
rc =
GpiConvert(hpsClient, CVTC_MODEL, CVTC_DEVICE, 1L, aptl);
if (rc == GPI_ERROR)
DispError(habMain,hwndClient);
aptl[1].x = aptl[0].x + aptl[3].x; /* target: upper right */
aptl[1].y = aptl[0].y + aptl[3].y; /* (equal to source size) */
/*
* Punch a hole
*/
rc =
GpiBitBlt(
hps, /* target presentation-space handle */
psl->hpsHole, /* source presentation-space handle */
4L, /* number of points in array */
aptl, /* address of array */
ROP_SRCAND, /* mixing method */
BBO_IGNORE); /* line/column-compression flag */
if (rc == GPI_ERROR)
DispError(habMain,hwndClient);
if (fFill)
{
/*
* Fill the hole
*/
rc =
GpiBitBlt(
hps, /* target presentation-space handle */
psl->hpsFill, /* source presentation-space handle */
4L, /* number of points in array */
aptl, /* address of array */
ROP_SRCPAINT, /* mixing method */
BBO_IGNORE); /* line/column-compression flag */
if (rc == GPI_ERROR)
DispError(habMain,hwndClient);
} /* end if (fFill) */
} /* end if(psl->fVisible) */
} /* end DrawPiece() */
/******************************************************************************/
/* */
/* Draw the picture, using the passed region for clipping. */
/* Intersect the bounding box used for the clip region with the client rect. */
/* Test each segment to see if its bounding box intersects the bounding box */
/* of the clipping region. Draw only if there is an intersection. */
/* */
/******************************************************************************/
BOOL DoDraw(HPS hps,HRGN hrgn,BOOL fPaint)
{
HRGN hrgnOld;
RECTL rcl, rclRegion, rclDst, rclClient;
PSEGLIST psl;
ULONG ulPostCt;
if( fPaint && !fFirstLoad)
{
if (GpiSetColor( hps, CLR_BACKGROUND) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiPaintRegion( hps, hrgn) == GPI_ERROR) /* erase region */
DispError(habMain,hwndClient);
}
if (GpiQueryRegionBox( hps, hrgn, &rclRegion) == RGN_ERROR)
DispError(habMain,hwndClient);
WinQueryWindowRect( hwndClient, &rclClient);
if( !WinIntersectRect( habAsync, &rclRegion, &rclRegion, &rclClient))
return( FALSE); /* not in client window */
if (GpiSetClipRegion( hps, hrgn, &hrgnOld) == RGN_ERROR) /* make the clip region */
DispError(habMain,hwndClient);
for( psl = pslHead; psl != NULL; psl = psl->pslNext) /* scan all pieces */
{
/**************************************************************************/
/* get the piece bounding box in device coordinates */
/**************************************************************************/
rcl = psl->rclCurrent;
if (GpiConvert( hpsClient, CVTC_MODEL, CVTC_DEVICE, 2L, (PPOINTL)&rcl) == GPI_ERROR)
DispError(habMain,hwndClient);
rcl.xRight++;
rcl.yTop++;
/**************************************************************************/
/* if the piece might be visible, and drawing allowed, draw the piece */
/**************************************************************************/
if( WinIntersectRect( habAsync, &rclDst, &rcl, &rclRegion))
{
DosQueryEventSem( hevDrawOn, &ulPostCt); /* drawing enabled? */
if( ulPostCt) /* yes */
DrawPiece( hps, psl, TRUE);
else
break; /* drawing is disabled; don't draw piece */
}
}
if (GpiSetClipRegion( hps, NULLHANDLE, &hrgnOld) == RGN_ERROR)
DispError(habMain,hwndClient);
DosQueryEventSem( hevDrawOn, &ulPostCt);
if( ulPostCt) /* drawing is enabled */
if (GpiSetRegion( hpsClient, hrgnInvalid, 0L, NULL) == RGN_ERROR)
DispError(habMain,hwndClient);
return( TRUE);
} /* end DoDraw() */
/******************************************************************************/
/* */
/* get bounding rect of whole picture in model coordinates */
/* */
/******************************************************************************/
VOID CalcBounds(VOID)
{
PSEGLIST psl;
RECTL rclOld;
ULONG ulPostKillDraw, ulPostCt;
if( !pslHead)
return;
rclBounds = rclOld = pslHead->rclCurrent;
/*
* get start killdraw post count
*/
DosQueryEventSem(hevKillDraw, &ulPostKillDraw);
for( psl = pslHead->pslNext; psl != NULL; psl = psl->pslNext) {
DosQueryEventSem(hevKillDraw, &ulPostCt);
if (ulPostKillDraw != ulPostCt) {
rclBounds = rclOld;
return;
}
WinUnionRect(habAsync, &rclBounds, &rclBounds, &(psl->rclCurrent));
}
}
/******************************************************************************/
/* */
/* Calculate and set the default viewing transform based on zoom and scroll */
/* */
/******************************************************************************/
VOID CalcTransform( hwnd)
HWND hwnd;
{
RECTL rclClient;
POINTL ptlCenter, ptlTrans, ptlScale, aptl[4], ptlOrg, aptlSides[12];
PSEGLIST psl;
LONG l;
MATRIXLF matlf;
ULONG ulPostCt, ulPostKillDraw;
/*
* get start killdraw post count
*/
DosQueryEventSem(hevKillDraw, &ulPostKillDraw);
/****************************************************************************/
/* from bounding rect of picture get center of picture */
/****************************************************************************/
ptlCenter.x = (rclBounds.xLeft + rclBounds.xRight) / 2;
ptlCenter.y = (rclBounds.yBottom + rclBounds.yTop ) / 2;
/****************************************************************************/
/* translate center of picture to origin */
/****************************************************************************/
SetDVTransform( (FIXED)UNITY
, (FIXED)0
, (FIXED)0
, (FIXED)UNITY
, -ptlCenter.x
, -ptlCenter.y
, TRANSFORM_REPLACE);
/****************************************************************************/
/* scale down to 1:1 of bitmap in file */
/****************************************************************************/
if (pbmp2BitmapFile->cbFix == sizeof(BITMAPINFOHEADER))
{
ptlScale.x = UNITY * ((PBITMAPINFOHEADER)pbmp2BitmapFile)->cx
/ (ptlTopRight.x - ptlBotLeft.x);
ptlScale.y = UNITY * ((PBITMAPINFOHEADER)pbmp2BitmapFile)->cy
/ (ptlTopRight.y - ptlBotLeft.y);
}
else
{
ptlScale.x = UNITY * pbmp2BitmapFile->cx
/ (ptlTopRight.x - ptlBotLeft.x);
ptlScale.y = UNITY * pbmp2BitmapFile->cy
/ (ptlTopRight.y - ptlBotLeft.y);
}
/****************************************************************************/
/* add in zoom scale */
/****************************************************************************/
ptlScale.x += ptlScale.x * lScale / (ZOOM_MAX + 1);
ptlScale.y += ptlScale.y * lScale / (ZOOM_MAX + 1);
SetDVTransform( (FIXED)ptlScale.x
, (FIXED)0
, (FIXED)0
, (FIXED)ptlScale.y
, 0L
, 0L
, TRANSFORM_ADD);
/****************************************************************************/
/* translate center of picture to center of client window */
/****************************************************************************/
WinQueryWindowRect( hwnd, &rclClient);
ptlTrans.x = (rclClient.xRight - rclClient.xLeft) / 2;
ptlTrans.y = (rclClient.yTop - rclClient.yBottom) / 2;
/****************************************************************************/
/* add in horizontal and vertical scrolling factors */
/****************************************************************************/
ptlTrans.x -= ptsScrollPos.x - ptsHalfScrollMax.x;
ptlTrans.y += ptsScrollPos.y - ptsHalfScrollMax.y;
SetDVTransform( (FIXED)UNITY
, (FIXED)0
, (FIXED)0
, (FIXED)UNITY
, ptlTrans.x
, ptlTrans.y
, TRANSFORM_ADD);
if (GpiQueryDefaultViewMatrix( hpsClient, 9L, &matlf) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiSetDefaultViewMatrix( hpsClient, 9L, &matlf, TRANSFORM_REPLACE) == GPI_ERROR)
DispError(habMain,hwndClient);
/****************************************************************************/
/* create bitmaps for pieces */
/****************************************************************************/
ptlOffset = ptlBotLeft; /* BottomLeft corner in dev coord */
if (GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 1L, &ptlOffset) == GPI_ERROR)
DispError(habMain,hwndClient);
if( (ptlScale.x != ptlScaleRef.x) || (ptlScale.y != ptlScaleRef.y))
{
ptlScaleRef = ptlScale;
/**************************************************************************/
/* create a shadow bitmap of the original, sized to current output size */
/**************************************************************************/
aptl[0] = ptlBotLeft; /* current output rect, dev coord */
aptl[1] = ptlTopRight;
if (GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 2L, aptl) == GPI_ERROR)
DispError(habMain,hwndClient);
aptl[0].x -= ptlOffset.x; /* put bottom left at (0,0) */
aptl[0].y -= ptlOffset.y;
aptl[1].x -= ptlOffset.x;
aptl[1].y -= ptlOffset.y;
#ifdef fred
aptl[1].x -= ptlOffset.x - 1; /* correct for coordinate convert */
aptl[1].y -= ptlOffset.y - 1;
#endif
aptl[2].x = 0L;
aptl[2].y = 0L;
if (pbmp2BitmapFile->cbFix == sizeof(BITMAPINFOHEADER))
{
aptl[3].x = ((PBITMAPINFOHEADER)pbmp2BitmapFile)->cx; /*bitmap dimensions */
aptl[3].y = ((PBITMAPINFOHEADER)pbmp2BitmapFile)->cy;
}
else
{
aptl[3].x = pbmp2BitmapFile->cx; /* bitmap dimensions */
aptl[3].y = pbmp2BitmapFile->cy;
}
if (GpiSetBitmap( hpsBitmapSize, hbmBitmapSize) == (HBITMAP)BMB_ERROR)
DispError(habMain,hwndClient);
if (GpiBitBlt( hpsBitmapSize /* copy the bitmap */
, hpsBitmapFile
, 4L
, aptl
, ROP_SRCCOPY
, BBO_IGNORE) == GPI_ERROR)
DispError(habMain,hwndClient);
for( psl = pslHead; psl != NULL; psl = psl->pslNext)
{
DosQueryEventSem( hevTerminate, &ulPostCt);
if( ulPostCt) /* exit if quit */
break;
DosQueryEventSem( hevKillDraw, &ulPostCt);
if( ulPostCt != ulPostKillDraw) {
break;
}
aptl[0].x = psl->rclBitBlt.xLeft; /* bounding rect in world space */
aptl[0].y = psl->rclBitBlt.yBottom;
aptl[1].x = psl->rclBitBlt.xRight;
aptl[1].y = psl->rclBitBlt.yTop;
aptl[2] = aptl[0];
aptl[3] = aptl[1];
if (GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 2L, &aptl[2]) == GPI_ERROR)
DispError(habMain,hwndClient);
ptlOrg = aptl[2];
aptl[3].x -= ptlOrg.x - 1; /* bitmap rect of piece */
aptl[3].y -= ptlOrg.y - 1;
aptl[2].x = 0L;
aptl[2].y = 0L;
psl->aptlBitBlt[0] = aptl[0];
psl->aptlBitBlt[1] = aptl[1];
psl->aptlBitBlt[2] = aptl[2];
psl->aptlBitBlt[3] = aptl[3];
/************************************************************************/
/* compute the piece control points */
/************************************************************************/
for ( l = 0; l < 12; l++)
aptlSides[l] = psl->aptlSides[l];
if (GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 12L, aptlSides) == GPI_ERROR)
DispError(habMain,hwndClient);
for ( l = 0; l < 12; l++)
{
aptlSides[l].x -= ptlOrg.x;
aptlSides[l].y -= ptlOrg.y;
}
/************************************************************************/
/* prepare the mask to punch a hole in the output bitmap */
/************************************************************************/
if (GpiSetClipPath( psl->hpsHole, 0L, SCP_RESET)== GPI_ERROR)/* no clip path */
DispError(habMain,hwndClient);
if (GpiBitBlt( psl->hpsHole /* fill with 1's */
, NULLHANDLE
, 2L
, &psl->aptlBitBlt[2]
, ROP_ONE
, BBO_IGNORE) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiBeginPath( psl->hpsHole, 1L) == GPI_ERROR) /* define a clip path */
DispError(habMain,hwndClient);
if (GpiMove( psl->hpsHole, &aptlSides[11]) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiPolySpline( psl->hpsHole, 12L, aptlSides) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiEndPath( psl->hpsHole) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiSetClipPath( psl->hpsHole, 1L, SCP_AND) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiBitBlt( psl->hpsHole /* fill with 0's */
, NULLHANDLE
, 2L
, &psl->aptlBitBlt[2]
, ROP_ZERO
, BBO_IGNORE) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiSetClipPath( psl->hpsHole, 0L, SCP_RESET) == GPI_ERROR) /* clear the clip path */
DispError(habMain,hwndClient);
/************************************************************************/
/* prepare the mask to fill the hole in the output bitmap */
/************************************************************************/
aptl[0] = psl->aptlBitBlt[2];
aptl[1] = psl->aptlBitBlt[3];
aptl[2] = aptl[0];
if (GpiBitBlt( psl->hpsFill /* make inverse of hole */
, psl->hpsHole
, 3L
, aptl
, ROP_NOTSRCCOPY
, BBO_IGNORE) == GPI_ERROR)
DispError(habMain,hwndClient);
aptl[0] = psl->aptlBitBlt[2];
aptl[1] = psl->aptlBitBlt[3];
aptl[2].x = ptlOrg.x - ptlOffset.x; /* pick the right part */
aptl[2].y = ptlOrg.y - ptlOffset.y; /* of the sized bitmap */
if (GpiBitBlt( psl->hpsFill /* fill with data */
, hpsBitmapSize
, 3L
, aptl
, ROP_SRCAND
, BBO_IGNORE) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiSetClipPath( psl->hpsFill, 0L, SCP_RESET) == GPI_ERROR) /* clear the clip path */
DispError(habMain,hwndClient);
if (GpiSetColor( psl->hpsFill, CLR_RED) == GPI_ERROR)/* draw the outline */
DispError(habMain,hwndClient);
if (GpiMove( psl->hpsFill, &aptlSides[11]) == GPI_ERROR)
DispError(habMain,hwndClient);
if (GpiPolySpline( psl->hpsFill, 12L, aptlSides) == GPI_ERROR)
DispError(habMain,hwndClient);
DrawPiece( hpsClient, psl, TRUE);
}
}
}
/******************************************************************************/
/* */
/* Redraw the entire client window. */
/* */
/******************************************************************************/
VOID Redraw(VOID)
{
RECTL rclInvalid;
HRGN hrgnUpdt;
POINTL aptlUpdtNew[3];
WinQueryWindowRect( hwndClient, &rclInvalid);
hrgnUpdt = GpiCreateRegion( hpsBitmapBuff, 1L, &rclInvalid);
DoDraw( hpsBitmapBuff, hrgnUpdt, TRUE);
if (GpiDestroyRegion( hpsBitmapBuff, hrgnUpdt) == GPI_ERROR)
DispError(habMain,hwndClient);
aptlUpdtNew[0].x = rclInvalid.xLeft;
aptlUpdtNew[0].y = rclInvalid.yBottom;
aptlUpdtNew[1].x = rclInvalid.xRight;
aptlUpdtNew[1].y = rclInvalid.yTop;
ROUND_DOWN_MOD( aptlUpdtNew[0].x, lByteAlignX); /* round down */
ROUND_DOWN_MOD( aptlUpdtNew[0].y, lByteAlignY); /* round down */
ROUND_UP_MOD( aptlUpdtNew[1].x, lByteAlignX); /* round up */
ROUND_UP_MOD( aptlUpdtNew[1].y, lByteAlignY); /* round up */
aptlUpdtNew[2] = aptlUpdtNew[0];
if (!fFirstLoad)
{
if (GpiBitBlt( hpsClient
, hpsBitmapBuff
, 3L
, aptlUpdtNew
, ROP_SRCCOPY
, BBO_IGNORE ) == GPI_ERROR)
DispError(habMain,hwndClient);
} /* end if (!fFirstLoad) */
}
/******************************************************************************
*
* Name : CorrelatePPOINTL
*
* Description : perform bitmap-based correlation
*
* Concepts :
*
* API's :
*
* Parameters : PPOINTL pptl
*
* Return : PSEGLIST
*
******************************************************************************/
PSEGLIST Correlate(PPOINTL pptl)
{
PSEGLIST psl;
POINTL aptl[2];
LONG lColor;
RECTL rcl;
APIRET rc; /* return code from APIs */
aptl[0] = aptl[1] = *pptl; /* target lower-left point */
aptl[1].x++; /* target bitmap upper-right point */
aptl[1].y++;
/*
* Set all hpsBitmapSave pels to 1. We're doing this so we can draw
* the correlated segment (if any) overtop of it. Then, if the color
* didn't change, we know that we hit a clipped part of the segment
* (piece).
*/
rc =
GpiBitBlt(
hpsBitmapSave, /* target presentation-space handle */
NULLHANDLE, /* source presentation-space handle */
2L, /* number of points in array */
aptl, /* address of array */
ROP_ONE, /* mixing method */
BBO_IGNORE); /* line/column-compression flag */
if (rc == GPI_ERROR)
DispError(habMain,hwndClient);
/*
* Retrieve color attribute for correlation point
*/
lColor = /* should return 0 */
GpiQueryPel(hpsBitmapSave, pptl);
if (lColor == GPI_ALTERROR)
DispError(habMain,hwndClient);
/*
* Do a manual correlation by determining if the correlation point
* intersects the region occupied be each segment (piece).
*/
for( psl = pslTail; psl != NULL; psl = psl->pslPrev)
{
/*
* get device coordinates for current segment (peice) bounding box
*/
rcl = psl->rclCurrent;
rc =
GpiConvert(
hpsClient, /* presentation-space handle */
CVTC_MODEL, /* source coordinate space */
CVTC_DEVICE, /* target coordinate space */
2L, /* number of coordinate pairs in structure */
(PPOINTL)&rcl); /* address of structure for coordinate pairs */
if (rc == GPI_ERROR)
DispError(habMain,hwndClient);
rcl.xRight++;
rcl.yTop++;
/*
* Does the point fall inside this segment's (peice's) bounding box?
* If so, did the color of the pel change when we drew the piece? If
* so, we selected a point inside this piece (segment) which isn't
* clipped. Return it.
*/
if (WinPtInRect(habAsync, &rcl, pptl))
{
DrawPiece( hpsBitmapSave, psl, FALSE); /* draw clipped bitmap */
if(GpiQueryPel( hpsBitmapSave, pptl) != lColor) /* color change? */
break; /* got a hit */
}
} /* end for(all segments in our linked list) */
return( psl);
} /* end Correlate() */
/******************************************************************************/
/* */
/* mark a whole island */
/* */
/******************************************************************************/
VOID MarkIsland(PSEGLIST pslMark,BOOL fMark)
{
PSEGLIST psl;
BOOL fFirst;
for( psl = pslMark, fFirst = TRUE
; (psl != pslMark) || fFirst
; psl = psl->pslNextIsland, fFirst = FALSE )
psl->fIslandMark = fMark; /* mark as island member */
}
/******************************** END MISC.C *******************************/