2020-09-30 17:12:29 +02:00

1840 lines
77 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
STARTOP.C
$Log: S:\products\msprods\oiwh\display\startop.c_v $
*
* Rev 1.44 10 May 1996 14:48:30 BEG06016
* Added OiOpAbortOperation.
*
* Rev 1.43 22 Apr 1996 10:28:46 BEG06016
* Cleaned up error checking.
*
* Rev 1.42 16 Apr 1996 10:28:50 BEG06016
* Fixed attach-a-note marks.
*
* Rev 1.41 11 Apr 1996 15:13:06 BEG06016
* Optimized named block access some.
*
* Rev 1.40 09 Jan 1996 14:06:28 BLJ
* Fixed rendering.
*
* Rev 1.39 05 Jan 1996 13:59:40 BLJ
* Fixed startop optimization.
*
* Rev 1.38 04 Jan 1996 14:45:48 BLJ
* Fixed the startop optimization.
*
* Rev 1.37 04 Jan 1996 14:27:58 BLJ
* Sped up startop.
*
* Rev 1.36 02 Jan 1996 10:33:18 BLJ
* Changed alot of UINTs to ints.
* Changed IMG structure to include the image data.
* Changed lp prefix to p.
*
* Rev 1.35 22 Dec 1995 11:11:10 BLJ
* Added a parameter for zero init'ing to some memory manager calls.
*
* Rev 1.34 14 Dec 1995 09:56:08 BLJ
* Fixed 5580 - Unable to select right and bottom pixels.
*
* Rev 1.33 04 Dec 1995 10:49:04 RC
* Check for left and top of point with image dimensions to ensure point is
* on the image (top of startoperation)
*
* Rev 1.32 03 Nov 1995 14:01:30 BLJ
* Add optimization to display.
*
* Rev 1.31 03 Nov 1995 11:58:50 BLJ
* Add optimization to display.
*
* Rev 1.30 02 Nov 1995 10:13:20 BLJ
* Adding Undo functionality.
*
****************************************************************************/
#include "privdisp.h"
/****************************************************************************
FUNCTION: OIOpStartOperation
PURPOSE: This routine starts the creation of an annotation.
****************************************************************************/
int WINAPI OiOpStartOperation(HWND hWnd, LPOIOP_START_OPERATION_STRUCT pStartStruct,
POINT ptPoint, WPARAM fwKeys, int nFlags){
int nStatus;
PWINDOW pWindow;
PANO_IMAGE pAnoImage;
PIMAGE pImage;
int nNamedBlockIndex;
int nMarkIndex;
PMARK pMark;
PMARK pDefMark;
PMARK pMark2=0;
int nLoop;
LRECT lrRect;
LRECT lrRectPoint;
BITMAP bm;
HANDLE hBitmap = 0;
HANDLE hDib = 0;
PBITMAPINFOHEADER pDib = 0;
long lWidth;
long lHeight;
long lHorzFudge;
long lVertFudge;
PAN_POINTS pPoints = 0;
BOOL bSelected;
HDC hDC = 0;
RECT rClientRect;
LRECT lrClientRect;
LRECT lrFullsizeClientRect;
BOOL bDeleteMark = FALSE;
BOOL bMarkComplete = FALSE;
BOOL bRepaint = FALSE;
BOOL bDone;
PSTR pTemp;
int nHandle;
BOOL bFirstLevel = TRUE;
CLIP_COPY_STRUCT ClipCopy;
int nIndex;
LPLRECT plrRect;
BOOL bPointNearMark;
BOOL bLeaveSelbyPt=FALSE;
LRECT lrWndRectPoint;
POINT *pWndPoint=0;
int nTempMarkIndex;
int nHScale;
int nVScale;
CheckError2( Init(hWnd, &pWindow, &pAnoImage, FALSE, TRUE));
if (!(pImage = pAnoImage->pBaseImage)){
goto Exit; // Not an error.
}
if (!pStartStruct){
nStatus = Error(DISPLAY_NULLPOINTERINVALID);
goto Exit;
}
if (!pStartStruct->Attributes.uType){
nStatus = Error(DISPLAY_INVALID_OPTIONS);
goto Exit;
}
CheckError2( TranslateScale(pWindow->nScale, pImage->nHRes, pImage->nVRes, &nHScale, &nVScale));
// lrWndRectPoint saves the point in window coordinates to avoid
// round off errors at mark selection time
SetLRect(lrWndRectPoint, ptPoint.x, ptPoint.y, ptPoint.x, ptPoint.y);
if (nFlags & PARM_SCALED){
ConvertRect(pWindow, &lrWndRectPoint, CONV_SCALED_TO_WINDOW);
}else if (!(nFlags & PARM_WINDOW)){ // Default to window.
ConvertRect(pWindow, &lrWndRectPoint, CONV_FULLSIZE_TO_WINDOW);
}
SetLRect(lrRectPoint, ptPoint.x, ptPoint.y, ptPoint.x, ptPoint.y);
if (nFlags & PARM_SCALED){
ConvertRect(pWindow, &lrRectPoint, CONV_SCALED_TO_FULLSIZE);
}else if (!(nFlags & PARM_FULLSIZE)){ // Default to window.
ConvertRect(pWindow, &lrRectPoint, CONV_WINDOW_TO_FULLSIZE);
}
// All operations must set ptPoint to a valid value.
// Operations like OIOP_COPY and OIOP_CUT that don't nse it should set it to 0.
if (lrRectPoint.left >= pImage->nWidth
|| lrRectPoint.top >= pImage->nHeight){
nStatus = Error(DISPLAY_INVALIDRECT);
goto Exit;
}
hDC = GetDC(hWnd);
GetClientRect(hWnd, &rClientRect);
CopyRect(lrFullsizeClientRect, rClientRect);
ConvertRect(pWindow, &lrFullsizeClientRect, CONV_WINDOW_TO_FULLSIZE);
// Clip client rect to image rect.
if (lrFullsizeClientRect.right > pImage->nWidth
|| lrFullsizeClientRect.bottom > pImage->nHeight){
lrFullsizeClientRect.right = lmin(lrFullsizeClientRect.right, pImage->nWidth);
lrFullsizeClientRect.bottom = lmin(lrFullsizeClientRect.right, pImage->nHeight);
CopyRect(lrClientRect, lrFullsizeClientRect);
ConvertRect(pWindow, &lrClientRect, CONV_FULLSIZE_TO_WINDOW);
}
// Check for operation in progress.
if (pAnoImage->Annotations.ppMarks){
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
if (pMark){
if ((int) pMark->Attributes.uType != OIOP_PASTE
|| pStartStruct->Attributes.uType != OIOP_PASTE){
OiOpEndOperation(hWnd);
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
if (pMark){
OiOpEndOperation(hWnd);
}
}else{
bFirstLevel = FALSE;
}
}
}
if (bFirstLevel){
// Save nndo info.
switch (pStartStruct->Attributes.uType){
case OIOP_SELECT_BY_POINT_OR_RECT:
case OIOP_SELECT_BY_RECT_FIXED:
case OIOP_SELECT_BY_RECT_VARIABLE:
case OIOP_SELECT_BY_POINT:
case OIOP_COPY:
if (UndoSaveSelectionState(pAnoImage)){
goto Exit;
}
if (UndoSavelpAnnotations(pAnoImage)){
goto Exit;
}
break;
case OIOP_DELETE:
case OIOP_CUT:
case OIOP_PASTE:
if (UndoSaveSelectionState(pAnoImage)){
goto Exit;
}
if (UndoSavelpAnnotations(pAnoImage)){
goto Exit;
}
if (UndoSavelpBaseImage(pAnoImage)){
goto Exit;
}
break;
case OIOP_ACTIVATE:
case OIOP_AN_LINE:
case OIOP_AN_FREEHAND:
case OIOP_AN_HOLLOW_RECT:
case OIOP_AN_FILLED_RECT:
case OIOP_AN_TEXT:
case OIOP_AN_TEXT_FROM_A_FILE:
case OIOP_AN_TEXT_STAMP:
case OIOP_AN_ATTACH_A_NOTE:
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
if (UndoSavelpAnnotations(pAnoImage)){
goto Exit;
}
break;
default:
break;
}
// Find next available mark.
CheckError2( ReAllocateMemory(sizeof(PMARK) * (pAnoImage->Annotations.nMarks + 2),
(PPSTR) &pAnoImage->Annotations.ppMarks, ZERO_INIT));
CheckError2( AllocateMemory(sizeof(MARK),
(PPSTR) &pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks], ZERO_INIT));
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
pMark->Attributes = pStartStruct->Attributes;
pMark->Attributes.dwPermissions = ACL_ALL;
// copy default named blocks.
switch (pStartStruct->Attributes.uType){
case OIOP_SELECT_BY_POINT_OR_RECT:
case OIOP_SELECT_BY_RECT_FIXED:
case OIOP_SELECT_BY_RECT_VARIABLE:
case OIOP_SELECT_BY_POINT:
case OIOP_COPY:
case OIOP_DELETE:
case OIOP_CUT:
case OIOP_PASTE:
case OIOP_ACTIVATE:
break;
default:
if (pDefMark = pAnoImage->Annotations.pDefMark){
for (nNamedBlockIndex = 0; nNamedBlockIndex <
pDefMark->nNamedBlocks; nNamedBlockIndex++){
pTemp = 0;
CheckError2( AddAMarkNamedBlock(pMark, pDefMark->ppNamedBlock[nNamedBlockIndex]->szName,
(PPSTR) &pTemp, pDefMark->ppNamedBlock[nNamedBlockIndex]->lSize));
memcpy(pTemp, pDefMark->ppNamedBlock[nNamedBlockIndex]->pBlock,
pDefMark->ppNamedBlock[nNamedBlockIndex]->lSize);
}
if (pDefMark->pOiAnoDat){
pTemp = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiAnoDat,
(PPSTR) &pTemp, pDefMark->nOiAnoDatSize));
memcpy(pTemp, pDefMark->pOiAnoDat, pDefMark->nOiAnoDatSize);
}
if (pDefMark->pOiGroup){
pTemp = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiGroup,
(PPSTR) &pTemp, pDefMark->nOiGroupSize));
memcpy(pTemp, pDefMark->pOiGroup, pDefMark->nOiGroupSize);
}
if (pDefMark->pOiSelect){
pTemp = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiSelect,
(PPSTR) &pTemp, pDefMark->nOiSelectSize));
memcpy(pTemp, pDefMark->pOiSelect, pDefMark->nOiSelectSize);
}
if (pDefMark->pOiIndex){
pTemp = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiIndex,
(PPSTR) &pTemp, pDefMark->nOiIndexSize));
memcpy(pTemp, pDefMark->pOiIndex, pDefMark->nOiIndexSize);
strcpy(Buff1, pDefMark->pOiIndex);
nIndex = atoi(Buff1);
nIndex++;
_itoa(nIndex, Buff1, 10);
strcpy(pDefMark->pOiIndex, Buff1);
}
}
break;
}
pMark->Attributes.bVisible = TRUE;
}
lHorzFudge = lmax (1, SELECTION_FUDGE * SCALE_DENOMINATOR / nHScale);
lVertFudge = lmax (1, SELECTION_FUDGE * SCALE_DENOMINATOR / nVScale);
CopyRect(pMark->Attributes.lrBounds, lrRectPoint);
pAnoImage->nStartOpFlags = nFlags;
pAnoImage->nStartOpFwKeys = fwKeys;
switch ((int) pMark->Attributes.uType){
case OIOP_SELECT_BY_POINT_OR_RECT:
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (pMark2->Attributes.uType == OIOP_AN_FORM){
continue;
}
CheckError2( IsPointNearMark(lrRectPoint, pMark2,
lHorzFudge, lVertFudge, &bPointNearMark, &nHandle));
if (bPointNearMark){
(int) pMark->Attributes.uType = OIOP_SELECT_BY_POINT;
goto OiOpSelectByPoint;
}
}
(int) pMark->Attributes.uType = OIOP_SELECT_BY_RECT_VARIABLE;
goto OiOpSelectByRectVariable;
case OIOP_SELECT_BY_RECT_FIXED:
pWndPoint = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiAnoDat,
(PPSTR) &pWndPoint, sizeof(POINT)));
pWndPoint->x = (int)lrWndRectPoint.left;
pWndPoint->y = (int)lrWndRectPoint.top;
plrRect = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiCurPt, (PPSTR) &plrRect, sizeof(LRECT)));
CopyRect(*plrRect, lrRectPoint);
// First try nsing the current selection rect.
GetSelectBox(pAnoImage, &lrRect);
if (lrRect.right != lrRect.left && lrRect.bottom != lrRect.top){
if (lrRectPoint.left >= lrRect.left - lHorzFudge
&& lrRectPoint.left <= lrRect.right - lHorzFudge
&& lrRectPoint.top >= lrRect.top - lVertFudge
&& lrRectPoint.top <= lrRect.bottom - lHorzFudge){
// We are dragging not selecting.
CopyRect(pAnoImage->lrSelectBoxOrg, lrRect);
pAnoImage->Annotations.bMoving = TRUE;
pAnoImage->Annotations.bMoved = FALSE;
break;
}else{
lWidth = lrRect.right - lrRect.left;
lHeight = lrRect.bottom - lrRect.top;
lrRect.left = max(0L, min( (pImage->nWidth - 1) - lWidth,
lrRectPoint.right - (lWidth / 2)));
lrRect.right = lrRect.left + lWidth;
lrRect.top = max(0L, min( (pImage->nHeight - 1) - lHeight,
lrRectPoint.bottom - (lHeight / 2)));
lrRect.bottom = lrRect.top + lHeight;
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
CopyRect(pAnoImage->lrSelectBoxOrg, lrRect);
pAnoImage->Annotations.bMoving = TRUE;
pAnoImage->Annotations.bMoved = TRUE;
break;
}
}
// Deselect all marks.
if (!(fwKeys & MK_CONTROL) && !(fwKeys & MK_SHIFT)){
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
pMark2->bSelected = FALSE;
}
}
// Next try the clipboard.
if (OpenClipboard(hWnd)){
hBitmap = GetClipboardData(CF_BITMAP);
hDib = GetClipboardData(CF_DIB);
CloseClipboard();
if (hDib){
if (!(pDib = (PBITMAPINFOHEADER) GlobalLock(hDib))){
nStatus = Error(DISPLAY_CANTLOCK);
goto Exit;
}
lWidth = (int) pDib->biWidth;
lHeight = (int) pDib->biHeight;
lrRect.left = max(0L, min( pImage->nWidth - lWidth,
lrRectPoint.right - (lWidth / 2)));
lrRect.right = lrRect.left + lWidth;
lrRect.top = max(0L, min( pImage->nHeight - lHeight,
lrRectPoint.bottom - (lHeight / 2)));
lrRect.bottom = lrRect.top + lHeight;
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
CopyRect(pAnoImage->lrSelectBoxOrg, lrRect);
GlobalUnlock(hDib);
pAnoImage->Annotations.bMoving = TRUE;
pAnoImage->Annotations.bMoved = TRUE;
break;
}else if (hBitmap){
GetObject(hBitmap, sizeof(BITMAP), (PSTR)&bm);
lWidth = (int) pDib->biWidth;
lHeight = (int) pDib->biHeight;
lrRect.left = max(0L, min( pImage->nWidth - lWidth,
lrRectPoint.right - (lWidth / 2)));
lrRect.right = lrRect.left + lWidth;
lrRect.top = max(0L, min( pImage->nHeight - lHeight,
lrRectPoint.bottom - (lHeight / 2)));
lrRect.bottom = lrRect.top + lHeight;
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
CopyRect(pAnoImage->lrSelectBoxOrg, lrRect);
pAnoImage->Annotations.bMoving = TRUE;
pAnoImage->Annotations.bMoved = TRUE;
break;
}
}
// Last of all, fall through to variable selection.
// This is not to finish a fixed selection but to perform a
// variable selection because you can not perform a fixed selection.
(int) pMark->Attributes.uType = OIOP_SELECT_BY_RECT_VARIABLE;
OiOpSelectByRectVariable:
case OIOP_SELECT_BY_RECT_VARIABLE:
pWndPoint = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pWndPoint, sizeof(POINT)));
pWndPoint->x = (int)lrWndRectPoint.left;
pWndPoint->y = (int)lrWndRectPoint.top;
pAnoImage->nHandle = 0;
plrRect = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiCurPt, (PPSTR) &plrRect, sizeof(LRECT)));
CopyRect(*plrRect, lrRectPoint);
GetSelectBox(pAnoImage, &lrRect);
if (lrRect.right != lrRect.left && lrRect.bottom != lrRect.top){
if (lrRectPoint.left >= lrRect.left - lHorzFudge
&& lrRectPoint.left <= lrRect.right - lHorzFudge
&& lrRectPoint.top >= lrRect.top - lVertFudge
&& lrRectPoint.top <= lrRect.bottom - lHorzFudge){
// We are dragging not selecting.
CopyRect(pAnoImage->lrSelectBoxOrg, lrRect);
pAnoImage->Annotations.bMoving = TRUE;
pAnoImage->Annotations.bMoved = FALSE;
break;
}
}
// Deselect all marks.
if (!(fwKeys & MK_CONTROL) && !(fwKeys & MK_SHIFT)){
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (pMark2->bSelected){
pMark2->bSelected = FALSE;
bRepaint = TRUE;
}
}
}
IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRectPoint, PARM_FULLSIZE);
break;
OiOpSelectByPoint:
case OIOP_SELECT_BY_POINT:
pWndPoint = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pWndPoint, sizeof(POINT)));
pWndPoint->x = (int)lrWndRectPoint.left;
pWndPoint->y = (int)lrWndRectPoint.top;
// If ctrl not active, then deselect all marks.
pAnoImage->Annotations.bMoving = TRUE;
pAnoImage->Annotations.bMoved = FALSE;
if (!(fwKeys & MK_CONTROL) && !(fwKeys & MK_SHIFT)){
// Deselect by rect.
SetLRect(lrRect, 0,0,0,0);
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
// this is to check if a selected mark is being acted npon
for (nMarkIndex = pAnoImage->Annotations.nMarks - 1;
(int) nMarkIndex >= 0; nMarkIndex--){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (!pMark2->bSelected){
continue;
}
if ((nHandle = IsPointNearHandle(pMark2,
lrRectPoint, lHorzFudge, lVertFudge)) > 8){
goto Exit;
}
if (!(pMark->Attributes.dwPermissions & ACL_MODIFY_MARK)){
nStatus = Error(DISPLAY_RESTRICTED_ACCESS);
goto Exit;
}
pAnoImage->nHandle = nHandle;
// this will break out of the for loop since we are
// on a handle of some mark
if (nHandle >0 && nHandle <= 8){
bRepaint = TRUE;
break;
}
}
// if we find we are on a handle, then remember that mark
// so we can deselect all other marks and then get out of
// the switch statement
if (nHandle >0 && nHandle <= 8){
nTempMarkIndex = nMarkIndex;
bLeaveSelbyPt = TRUE;
}
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
if (nMarkIndex == (int) nTempMarkIndex && bLeaveSelbyPt){
continue;
}
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (pMark2->bSelected){
pMark2->bSelected = FALSE;
bRepaint = TRUE;
}
}
if (bLeaveSelbyPt){
break;
}
}
GetSelectBox(pAnoImage, &lrRect);
CopyRect(pAnoImage->lrSelectBoxOrg, lrRect);
// Select the new mark by point.
bSelected = FALSE;
pAnoImage->nHandle = 0;
for (nMarkIndex = pAnoImage->Annotations.nMarks - 1;
(int) nMarkIndex >= 0 && !bSelected; nMarkIndex--){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
CheckError2( IsPointNearMark(lrRectPoint, pMark2, lHorzFudge,
lVertFudge, &bPointNearMark, &nHandle));
if (!bPointNearMark){
continue;
}
if ((fwKeys & MK_CONTROL)){
pMark2->bSelected ^= TRUE;
}else{
pMark2->bSelected = TRUE;
}
if (!(pMark2->Attributes.dwPermissions & ACL_MODIFY_MARK)){
nStatus = Error(DISPLAY_RESTRICTED_ACCESS);
goto Exit;
}
pAnoImage->nHandle = nHandle;
bSelected = TRUE;
bRepaint = TRUE;
break;
}
break;
case OIOP_DELETE:
bDone = FALSE;
if (!ptPoint.x && !ptPoint.y){
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks;){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (IsMarkSelected(pWindow, pMark2)){
if (pMark2->Attributes.uType == OIOP_AN_FORM){
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, TRUE));
}
CheckError2( DeleteMark(pAnoImage, nMarkIndex));
bDone = TRUE;
}else{
nMarkIndex++;
}
}
GetSelectBox(pAnoImage, &lrRect);
if (lrRect.right - lrRect.left && lrRect.bottom - lrRect.top){
CheckError2( ClearImage(pWindow, pImage, &lrRect));
bRepaint = TRUE;
}
}else{
// Delete the mark by point instead of selection.
for (nMarkIndex = pAnoImage->Annotations.nMarks - 1;
(int) nMarkIndex >= 0 && !bDone; nMarkIndex--){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (pMark2->Attributes.uType == OIOP_DELETE){
// Don't delete the delete operation.
continue;
}
if (!IsPointNearRect(pMark2->Attributes.lrBounds,
lrRectPoint, lHorzFudge, lVertFudge)){
continue;
}
if (pMark2->Attributes.uType == OIOP_AN_LINE
|| pMark2->Attributes.uType == OIOP_AN_FREEHAND){
CheckError2( GetAMarkNamedBlock(pMark2, szOiAnoDat, (PPSTR) &pPoints));
if (!pPoints){
nStatus = Error(DISPLAY_DATACORRUPTED);
goto Exit;
}
for (nLoop = 0; nLoop < pPoints->nPoints - 1; nLoop++){
SetLRect(lrRect, pPoints->ptPoint[nLoop].x +
pMark2->Attributes.lrBounds.left,
pPoints->ptPoint[nLoop].y +
pMark2->Attributes.lrBounds.top,
pPoints->ptPoint[nLoop + 1].x +
pMark2->Attributes.lrBounds.left,
pPoints->ptPoint[nLoop + 1].y +
pMark2->Attributes.lrBounds.top);
if (!IsPointNearLine(lrRect, lrRectPoint, lHorzFudge, lVertFudge)){
continue;
}
bDone = TRUE;
}
}else if(pMark2->Attributes.uType == OIOP_AN_HOLLOW_RECT){
// Check top edge.
lrRect.left = pMark2->Attributes.lrBounds.left;
lrRect.top = pMark2->Attributes.lrBounds.top;
lrRect.right = pMark2->Attributes.lrBounds.right;
lrRect.bottom = pMark2->Attributes.lrBounds.top;
if (!IsPointNearLine(lrRect, lrRectPoint, lHorzFudge, lVertFudge)){
// Check bottom edge.
lrRect.left = pMark2->Attributes.lrBounds.left;
lrRect.top = pMark2->Attributes.lrBounds.bottom;
lrRect.right = pMark2->Attributes.lrBounds.right;
lrRect.bottom = pMark2->Attributes.lrBounds.bottom;
if (!IsPointNearLine(lrRect, lrRectPoint, lHorzFudge, lVertFudge)){
// Check left edge.
lrRect.left = pMark2->Attributes.lrBounds.left;
lrRect.top = pMark2->Attributes.lrBounds.top;
lrRect.right = pMark2->Attributes.lrBounds.left;
lrRect.bottom = pMark2->Attributes.lrBounds.bottom;
if (!IsPointNearLine(lrRect, lrRectPoint, lHorzFudge, lVertFudge)){
// Check right edge.
lrRect.left = pMark2->Attributes.lrBounds.right;
lrRect.top = pMark2->Attributes.lrBounds.top;
lrRect.right = pMark2->Attributes.lrBounds.right;
lrRect.bottom = pMark2->Attributes.lrBounds.bottom;
if (!IsPointNearLine(lrRect, lrRectPoint, lHorzFudge, lVertFudge)){
continue;
}
}
}
}
bDone = TRUE;
}else{
bDone = TRUE;
}
if (bDone){
break;
}
}
if (bDone){
if (pMark2->Attributes.uType == OIOP_AN_FORM){
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, TRUE));
}
CheckError2( DeleteMark(pAnoImage, nMarkIndex));
}
// Delete the image data.
GetSelectBox(pAnoImage, &lrRect);
if (lrRect.right != lrRect.left && lrRect.bottom != lrRect.top){
if (lrRectPoint.left >= lrRect.left - lHorzFudge
&& lrRectPoint.left <= lrRect.right - lHorzFudge
&& lrRectPoint.top >= lrRect.top - lVertFudge
&& lrRectPoint.top <= lrRect.bottom - lHorzFudge){
CheckError2( ClearImage(pWindow, pImage, &lrRect));
bRepaint = TRUE;
}
}
}
if (bDone){
pAnoImage->bArchive |= ARCHIVE_MODIFIED_ANNOTATIONS;
bRepaint = TRUE;
}
bDeleteMark = TRUE;
SetLRect(lrRect, 0,0,0,0);
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
break;
case OIOP_ACTIVATE:
// Deselect all marks.
SetLRect(lrRect, 0,0,0,0);
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (pMark2->bSelected){
pMark2->bSelected = FALSE;
bRepaint = TRUE;
}
}
// Select the new mark by point.
bSelected = FALSE;
for (nMarkIndex = pAnoImage->Annotations.nMarks - 1;
(int) nMarkIndex >= 0 && !bSelected; nMarkIndex--){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
CheckError2( IsPointNearMark(lrRectPoint, pMark2, lHorzFudge,
lVertFudge, &bPointNearMark, &nHandle));
if (!bPointNearMark){
continue;
}
pMark2->bSelected = TRUE;
if (!(pMark->Attributes.dwPermissions & ACL_ACTIVATE_MARK)){
nStatus = Error(DISPLAY_RESTRICTED_ACCESS);
goto Exit;
}
pAnoImage->nHandle = nHandle;
bSelected = TRUE;
bRepaint = TRUE;
break;
}
if (!pMark2){
bDeleteMark = TRUE;
goto Exit; //not an error, means there are no marks on image
}
switch (pMark2->Attributes.uType){
case OIOP_AN_TEXT:
case OIOP_AN_TEXT_FROM_A_FILE:
case OIOP_AN_TEXT_STAMP:
case OIOP_AN_ATTACH_A_NOTE:
CheckError2( AnTextActivate(hWnd, pStartStruct, ptPoint, fwKeys,
nFlags, pWindow, pImage, pMark2, hDC, rClientRect, lrFullsizeClientRect));
bRepaint = TRUE;
pAnoImage->bArchive |= ARCHIVE_MODIFIED_ANNOTATIONS;
break;
case OIOP_AN_LINE:
case OIOP_AN_FREEHAND:
case OIOP_AN_HOLLOW_RECT:
case OIOP_AN_FILLED_RECT:
case OIOP_AN_AUDIO:
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
default:
nStatus = Error(DISPLAY_INVALID_OPTIONS);
goto Exit;
break;
}
bDeleteMark = TRUE;
break;
case OIOP_UNDO:
// Terminate any nndo operations in progress.
if (pAnoImage->bUndoOpInProgress){
pAnoImage->nCurrentULUndo++;
pAnoImage->bUndoOpInProgress = FALSE;
}
CheckError2( DeleteMark(pAnoImage, pAnoImage->Annotations.nMarks));
if (!pAnoImage->nCurrentULUndo){
nStatus = Error(DISPLAY_NOTHING_TO_UNDO);
goto Exit;
}
pAnoImage->nCurrentULUndo--;
CheckError2( SwapUndoWithCurrent(pAnoImage, pWindow));
bDeleteMark = TRUE;
break;
case OIOP_REDO:
// Terminate any nndo operations in progress.
if (pAnoImage->bUndoOpInProgress){
pAnoImage->nCurrentULUndo++;
pAnoImage->bUndoOpInProgress = FALSE;
}
if (!pAnoImage->pULUndos){
nStatus = Error(DISPLAY_NOTHING_TO_UNDO);
goto Exit;
}
if (!((PUSER_LEVEL_UNDO) pAnoImage->pULUndos)[pAnoImage->nCurrentULUndo + 1].nSize){
nStatus = Error(DISPLAY_NOTHING_TO_UNDO);
goto Exit;
}
pAnoImage->nCurrentULUndo++;
if (!((PUSER_LEVEL_UNDO) pAnoImage->pULUndos)[pAnoImage->nCurrentULUndo].nSize){
nStatus = Error(DISPLAY_NOTHING_TO_UNDO);
goto Exit;
}
if (!pAnoImage->nCurrentULUndo){
nStatus = Error(DISPLAY_NOTHING_TO_UNDO);
goto Exit;
}
CheckError2( SwapUndoWithCurrent(pAnoImage, pWindow));
bDeleteMark = TRUE;
break;
case OIOP_AN_LINE:
case OIOP_AN_FREEHAND:
pPoints = 0;
if ((int) pMark->Attributes.uType == OIOP_AN_LINE){
CheckError2( AddAMarkNamedBlock(pMark, szOiAnoDat,
(PPSTR) &pPoints, sizeof(AN_POINTS) + (sizeof(POINT) * 1)));
pPoints->nMaxPoints = 2;
pPoints->nPoints = 2;
}else{
pPoints = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiAnoDat,
(PPSTR) &pPoints, sizeof(AN_POINTS) + (sizeof(POINT) * 99)));
pPoints->nMaxPoints = 100;
pPoints->nPoints = 1;
}
break;
case OIOP_AN_HOLLOW_RECT:
case OIOP_AN_FILLED_RECT:
break;
case OIOP_AN_TEXT:
case OIOP_AN_TEXT_FROM_A_FILE:
case OIOP_AN_TEXT_STAMP:
case OIOP_AN_ATTACH_A_NOTE:
CheckError2( StartOperationText(hWnd, pStartStruct, ptPoint, fwKeys,
nFlags, pWindow, pImage, pMark, hDC, rClientRect,
lrFullsizeClientRect, &bDeleteMark, &bMarkComplete, &bRepaint));
break;
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
CheckError2( StartOperationBitmap(hWnd, pAnoImage, pStartStruct, ptPoint,
fwKeys, nFlags, pWindow, pImage, pMark, hDC, rClientRect,
lrFullsizeClientRect, &bDeleteMark, &bMarkComplete, &bRepaint));
// this will allow the form image to be merged with the base image
if ((int) pMark->Attributes.uType == OIOP_AN_FORM){
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, TRUE));
}
break;
case OIOP_CUT:
SetLRect (ClipCopy.lRect, 0, 0, 0, 0);
ClipCopy.nScale = 1000;
ClipCopy.bUseCurrentScale = 0;
CheckError2( IMGClipboardCgbw (hWnd, CLIP_CUT, &ClipCopy, PARM_DONT_REPAINT));
bDeleteMark = TRUE;
bRepaint = TRUE;
break;
case OIOP_COPY:
SetLRect (ClipCopy.lRect, 0, 0, 0, 0);
ClipCopy.nScale = 1000;
ClipCopy.bUseCurrentScale = 0;
CheckError2( IMGClipboardCgbw (hWnd, CLIP_COPY, &ClipCopy, PARM_DONT_REPAINT));
bDeleteMark = TRUE;
bRepaint = TRUE;
break;
case OIOP_PASTE:
if (bFirstLevel){
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (pMark2->bSelected){
pMark2->bSelected = FALSE;
}
}
SetLRect(lrRect, 0,0,0,0);
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
}
pWndPoint = 0;
CheckError2( AddAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pWndPoint, sizeof(POINT)));
pWndPoint->x = (int)lrWndRectPoint.left;
pWndPoint->y = (int)lrWndRectPoint.top;
pAnoImage->nPasteFormat = *((PUINT) pStartStruct->szString);
pAnoImage->Annotations.bMoving = TRUE;
pAnoImage->Annotations.bMoved = FALSE;
if (bFirstLevel){
if (pAnoImage->nPasteFormat == nWangAnnotatedImageFormat
|| pAnoImage->nPasteFormat == nWangAnnotationFormat){
CheckError2( StartPasteAnnotatedImage(hWnd, pWindow, pAnoImage,
pImage, lrRectPoint, nFlags));
}else if (pAnoImage->nPasteFormat == CF_DIB){
CheckError2( StartPasteImage(hWnd, pWindow, pAnoImage,
pImage, lrRectPoint, nFlags));
}else{
nStatus = Error(DISPLAY_INVALID_OPTIONS);
goto Exit;
}
bRepaint = TRUE;
}
pAnoImage->Annotations.bPasteInProgress = TRUE;
break;
case OIOP_AN_AUDIO:
default:
nStatus = Error(DISPLAY_INVALID_OPTIONS);
bDeleteMark = TRUE;
goto Exit;
}
if (bDeleteMark){
CheckError2( DeleteMark(pAnoImage, pAnoImage->Annotations.nMarks));
}else{
if(bMarkComplete){
if (nStatus = CheckPermissionsMark(pWindow, pAnoImage, pMark)){
DeleteMark(pAnoImage, pAnoImage->Annotations.nMarks);
goto Exit;
}
pAnoImage->bArchive |= ARCHIVE_MODIFIED_ANNOTATIONS;
pAnoImage->Annotations.nMarks++;
}
}
if (bRepaint & !(nFlags & PARM_DONT_REPAINT)){
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, FALSE));
CheckError2(IMGRepaintDisplay(hWnd, (PRECT) -1) );
}
Exit:
if (nStatus){
if (pAnoImage){
DeleteMark(pAnoImage, pAnoImage->Annotations.nMarks);
if (pWindow){
InvalidateAllDisplayRects(pWindow, pImage, NULL, FALSE);
}
}
}
if (hDC){
ReleaseDC(hWnd, hDC);
}
DeInit(FALSE, TRUE);
return(nStatus);
}
//
/****************************************************************************
FUNCTION: OIOpContinueOperation
PURPOSE: This routine continues the annotation.
****************************************************************************/
int WINAPI OiOpContinueOperation(HWND hWnd, POINT ptPoint, int nFlags){
int nStatus;
PWINDOW pWindow;
PANO_IMAGE pAnoImage;
PIMAGE pImage;
PMARK pMark;
LRECT lrRect;
LRECT lrRectNew;
LRECT lrRectPoint;
HDC hDC = 0;
RECT rClientRect;
LRECT lrClientRect;
LRECT lrFullsizeClientRect;
int nOldROP;
HBRUSH hOldBrush;
HPEN hPen = 0;
HPEN hOldPen;
PAN_POINTS pPoints;
int nSize;
LRECT lrWndRectPoint;
int nHScale;
int nVScale;
nDontCallStartFirst++; // Prevent Startfirst from being called.
if (nStatus = Init(hWnd, &pWindow, &pAnoImage, FALSE, TRUE)){
nDontCallStartFirst--;
goto Exit;
}
nDontCallStartFirst--;
pImage = pAnoImage->pBaseImage;
CheckError2( TranslateScale(pWindow->nScale, pImage->nHRes, pImage->nVRes, &nHScale, &nVScale));
// Find current mark.
if (!pAnoImage->Annotations.ppMarks){
goto Exit; // Nothing to do.
}
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
// If there is no operation in progress, then return.
if (!pMark){
goto Exit; // Nothing to do.
}
// lrWndRectPoint saves the point in window coordinates to avoid
// round off errors at mark selection time
SetLRect(lrWndRectPoint, ptPoint.x, ptPoint.y, ptPoint.x, ptPoint.y);
if (nFlags & PARM_SCALED){
ConvertRect(pWindow, &lrWndRectPoint, CONV_SCALED_TO_WINDOW);
}else if (!(nFlags & PARM_WINDOW)){ // Default to window.
ConvertRect(pWindow, &lrWndRectPoint, CONV_FULLSIZE_TO_WINDOW);
}
SetLRect(lrRectPoint, ptPoint.x, ptPoint.y, ptPoint.x, ptPoint.y);
if (nFlags & PARM_SCALED){
ConvertRect(pWindow, &lrRectPoint, CONV_SCALED_TO_FULLSIZE);
}else if (!(nFlags & PARM_FULLSIZE)){ // Default to window.
ConvertRect(pWindow, &lrRectPoint, CONV_WINDOW_TO_FULLSIZE);
}
// Clip lrRectPoint to image rect.
lrRectPoint.left = lmax(0, lmin(lrRectPoint.left, pImage->nWidth));
lrRectPoint.right = lrRectPoint.left;
lrRectPoint.top = lmax(0, lmin(lrRectPoint.top, pImage->nHeight));
lrRectPoint.bottom = lrRectPoint.top;
hDC = GetDC(hWnd);
GetClientRect(hWnd, &rClientRect);
CopyRect(lrClientRect, rClientRect);
CopyRect(lrFullsizeClientRect, rClientRect);
ConvertRect(pWindow, &lrFullsizeClientRect, CONV_WINDOW_TO_FULLSIZE);
// Clip client rect to image rect.
if (lrFullsizeClientRect.right > pImage->nWidth
|| lrFullsizeClientRect.bottom > pImage->nHeight){
lrFullsizeClientRect.right = lmin(lrFullsizeClientRect.right, pImage->nWidth);
lrFullsizeClientRect.bottom = lmin(lrFullsizeClientRect.bottom, pImage->nHeight);
CopyRect(lrClientRect, lrFullsizeClientRect);
ConvertRect(pWindow, &lrClientRect, CONV_FULLSIZE_TO_WINDOW);
CopyRectLtoR(rClientRect, lrClientRect);
}
switch ((int) pMark->Attributes.uType){
case OIOP_SELECT_BY_RECT_VARIABLE:
case OIOP_SELECT_BY_RECT_FIXED:
case OIOP_SELECT_BY_POINT:
if (!pAnoImage->Annotations.bMoving
&& (int) pMark->Attributes.uType == OIOP_SELECT_BY_RECT_VARIABLE){
lrRectPoint.right = lmax(0, lmin(lrRectPoint.right, pImage->nWidth));
lrRectPoint.bottom = lmax(0, lmin(lrRectPoint.bottom, pImage->nHeight));
IMGGetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE);
lrRect.right = lrRectPoint.right;
lrRect.bottom = lrRectPoint.bottom;
IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE);
}
if (pAnoImage->Annotations.bMoving){
// MoveSelectedMarks will move both the marks and the selection rect
// as specified by the flags.
CheckError2( MoveSelectedMarks(hWnd, pWindow, pAnoImage, pMark, hDC,
rClientRect, lrFullsizeClientRect, lrRectPoint, lrWndRectPoint, TRUE));
}
break;
case OIOP_AN_FILLED_RECT:
if (lrRectPoint.right > pMark->Attributes.lrBounds.left){
lrRectPoint.right++;
}
if (lrRectPoint.bottom > pMark->Attributes.lrBounds.top){
lrRectPoint.bottom++;
}
// lrRect = old rect.
lrRect.left = min(pMark->Attributes.lrBounds.left, pMark->Attributes.lrBounds.right);
lrRect.top = min(pMark->Attributes.lrBounds.top, pMark->Attributes.lrBounds.bottom);
lrRect.right = lmax(pMark->Attributes.lrBounds.left, pMark->Attributes.lrBounds.right);
lrRect.bottom = lmax(pMark->Attributes.lrBounds.top, pMark->Attributes.lrBounds.bottom);
ConvertRect(pWindow, &lrRect, CONV_FULLSIZE_TO_WINDOW);
// lrRectNew = new rect.
lrRectNew.left = min(pMark->Attributes.lrBounds.left, lrRectPoint.right);
lrRectNew.top = min(pMark->Attributes.lrBounds.top, lrRectPoint.bottom);
lrRectNew.right = lmax(pMark->Attributes.lrBounds.left, lrRectPoint.right);
lrRectNew.bottom = lmax(pMark->Attributes.lrBounds.top, lrRectPoint.bottom);
ConvertRect(pWindow, &lrRectNew, CONV_FULLSIZE_TO_WINDOW);
// To avoid flicker, erase and draw only the modified parts.
nOldROP = SetROP2(hDC, R2_XORPEN);
hOldPen = SelectObject(hDC, GetStockObject(NULL_PEN));
hOldBrush = SelectObject(hDC, GetStockObject(WHITE_BRUSH));
// Erase the left part of the old rect that doesn't exsist any more.
if (lrRect.left < lrRectNew.left){
Rectangle(hDC, (int) lmax(0, lrRect.left),
(int) lmax(0, lrRect.top),
(int) min(rClientRect.right, lrRectNew.left) + 1,
(int) min(rClientRect.bottom, lrRect.bottom) + 1);
}
// Erase the right part of the old rect that doesn't exsist any more.
if (lrRect.right > lrRectNew.right){
Rectangle(hDC, (int) lmax(0, lrRectNew.right),
(int) lmax(0, lrRect.top),
(int) min(rClientRect.right, lrRect.right) + 1,
(int) min(rClientRect.bottom, lrRect.bottom) + 1);
}
// Erase the top part of the old rect that doesn't exsist any more.
if (lrRect.top < lrRectNew.top){
Rectangle(hDC, (int) lmax(0, lmax(lrRect.left, lrRectNew.left)),
(int) lmax(0, lrRect.top),
(int) min(rClientRect.right, min(lrRect.right, lrRectNew.right)) + 1,
(int) min(rClientRect.bottom, lrRectNew.top) + 1);
}
// Erase the bottom part of the old rect that doesn't exsist any more.
if (lrRect.bottom > lrRectNew.bottom){
Rectangle(hDC, (int) lmax(0, lmax(lrRect.left, lrRectNew.left)),
(int) lmax(0, lrRectNew.bottom),
(int) min(rClientRect.right, min(lrRect.right, lrRectNew.right)) + 1,
(int) min(rClientRect.bottom, lrRect.bottom) + 1);
}
// Draw the new left part of the rect that didn't exsist before.
if (lrRectNew.left < lrRect.left){
Rectangle(hDC, (int) lmax(0, lrRectNew.left),
(int) lmax(0, lmax(lrRect.top, lrRectNew.top)),
(int) min(rClientRect.right, lrRect.left) + 1,
(int) min(rClientRect.bottom, min(lrRect.bottom, lrRectNew.bottom)) + 1);
}
// Draw the new right part of the rect that didn't exsist before.
if (lrRectNew.right > lrRect.right){
Rectangle(hDC, (int) lmax(0, lrRect.right),
(int) lmax(0, lmax(lrRect.top, lrRectNew.top)),
(int) min(rClientRect.right, lrRectNew.right) + 1,
(int) min(rClientRect.bottom, min(lrRect.bottom, lrRectNew.bottom)) + 1);
}
// Draw the new top part of the rect that didn't exsist before.
if (lrRectNew.top < lrRect.top){
Rectangle(hDC, (int) lmax(0, lrRectNew.left),
(int) lmax(0, lrRectNew.top),
(int) min(rClientRect.right, lrRectNew.right) + 1,
(int) min(rClientRect.bottom, lrRect.top) + 1);
}
// Draw the new bottom part of the rect that didn't exsist before.
if (lrRectNew.bottom > lrRect.bottom){
Rectangle(hDC, (int) lmax(0, lrRectNew.left),
(int) lmax(0, lrRect.bottom),
(int) min(rClientRect.right, lrRectNew.right) + 1,
(int) min(rClientRect.bottom, lrRectNew.bottom) + 1);
}
pMark->Attributes.lrBounds.right = lrRectPoint.right;
pMark->Attributes.lrBounds.bottom = lrRectPoint.bottom;
SelectObject(hDC, hOldBrush);
SelectObject(hDC, hOldPen);
SetROP2(hDC, nOldROP);
break;
case OIOP_AN_HOLLOW_RECT:
// Erase the old XORed mark.
CheckError2( PaintAnnotation(hWnd, hDC, pWindow, pImage,
pMark, rClientRect, lrFullsizeClientRect, PAINT_MODE_XOR,
pWindow->nScale, nHScale, nVScale, pWindow->lHOffset,
pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES));
// Update rectangle.
pMark->Attributes.lrBounds.right = lrRectPoint.right;
pMark->Attributes.lrBounds.bottom = lrRectPoint.bottom;
// Draw the new XORed mark.
CheckError2( PaintAnnotation(hWnd, hDC, pWindow, pImage,
pMark, rClientRect, lrFullsizeClientRect, PAINT_MODE_XOR,
pWindow->nScale, nHScale, nVScale, pWindow->lHOffset,
pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES));
break;
case OIOP_AN_LINE:
CheckError2( GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pPoints));
if (!pPoints){
nStatus = Error(DISPLAY_DATACORRUPTED);
goto Exit;
}
// Erase the old XORed mark.
CheckError2( PaintAnnotation(hWnd, hDC, pWindow, pImage,
pMark, rClientRect, lrFullsizeClientRect, PAINT_MODE_XOR,
pWindow->nScale, nHScale, nVScale, pWindow->lHOffset,
pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES));
// Update the line segment.
pPoints->ptPoint[pPoints->nPoints - 1].x
= (int)(lrRectPoint.left - pMark->Attributes.lrBounds.left);
pPoints->ptPoint[pPoints->nPoints - 1].y
= (int)(lrRectPoint.top - pMark->Attributes.lrBounds.top);
// Draw the new XORed mark.
CheckError2( PaintAnnotation(hWnd, hDC, pWindow, pImage,
pMark, rClientRect, lrFullsizeClientRect, PAINT_MODE_XOR,
pWindow->nScale, nHScale, nVScale, pWindow->lHOffset,
pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES));
break;
case OIOP_AN_FREEHAND:
CheckError2( GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pPoints));
if (!pPoints){
nStatus = Error(DISPLAY_DATACORRUPTED);
goto Exit;
}
if (pPoints->nPoints == pPoints->nMaxPoints){
// We exceeded the max number of line segments.
pPoints->nMaxPoints += 100;
CheckError2( ReAllocateAMarkNamedBlock(pMark, szOiAnoDat,
(PPSTR) &pPoints, sizeof(AN_POINTS) + (sizeof(POINT)
* (pPoints->nMaxPoints - 1))));
}
pPoints->ptPoint[pPoints->nPoints].x
= (int)(lrRectPoint.left - pMark->Attributes.lrBounds.left);
pPoints->ptPoint[pPoints->nPoints].y
= (int)(lrRectPoint.top - pMark->Attributes.lrBounds.top);
// Draw the line segment.
nSize = max(1, (pMark->Attributes.uLineSize
* pWindow->nScale / SCALE_DENOMINATOR));
if (pMark->Attributes.bHighlighting){
nOldROP = SetROP2(hDC, R2_MASKPEN);
}else{
nOldROP = SetROP2(hDC, R2_COPYPEN);
}
hPen = CreatePen(PS_SOLID, nSize,
RGB(pMark->Attributes.rgbColor1.rgbRed,
pMark->Attributes.rgbColor1.rgbGreen,
pMark->Attributes.rgbColor1.rgbBlue));
hOldPen = SelectObject(hDC, hPen);
hOldBrush = SelectObject(hDC, GetStockObject(NULL_BRUSH));
SetLRect(lrRect, pPoints->ptPoint[pPoints->nPoints - 1].x
+ pMark->Attributes.lrBounds.left,
pPoints->ptPoint[pPoints->nPoints - 1].y
+ pMark->Attributes.lrBounds.top,
pPoints->ptPoint[pPoints->nPoints].x
+ pMark->Attributes.lrBounds.left,
pPoints->ptPoint[pPoints->nPoints].y
+ pMark->Attributes.lrBounds.top);
ConvertRect(pWindow, &lrRect, CONV_FULLSIZE_TO_WINDOW);
if (ReduceLineToLRect(&lrRect, lrClientRect)){
MoveToEx(hDC, (int) lrRect.left, (int) lrRect.top, NULL);
LineTo(hDC, (int) lrRect.right, (int) lrRect.bottom);
}
pPoints->nPoints++;
SelectObject(hDC, hOldBrush);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
SetROP2(hDC, nOldROP);
break;
case OIOP_AN_TEXT:
case OIOP_AN_TEXT_FROM_A_FILE:
case OIOP_AN_TEXT_STAMP:
case OIOP_AN_ATTACH_A_NOTE:
CheckError2( ContinueOperationText(hWnd, ptPoint,
nFlags, pWindow, pImage, pMark, hDC, rClientRect,
lrFullsizeClientRect));
break;
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
CheckError2( ContinueOperationBitmap(hWnd, ptPoint, nFlags, pWindow,
pImage, pMark, hDC, rClientRect, lrFullsizeClientRect));
break;
case OIOP_PASTE:
if (pAnoImage->Annotations.bPasteInProgress){
CheckError2( MoveSelectedMarks(hWnd, pWindow, pAnoImage,
pMark, hDC, rClientRect, lrFullsizeClientRect,
lrRectPoint, lrWndRectPoint, FALSE));
}
break;
case OIOP_AN_AUDIO:
default:
break;
}
Exit:
if (hDC){
ReleaseDC(hWnd, hDC);
}
DeInit(FALSE, TRUE);
return(nStatus);
}
//
/****************************************************************************
FUNCTION: OIOpEndOperation
PURPOSE: This routine Ends the annotation.
****************************************************************************/
int WINAPI OiOpEndOperation(HWND hWnd){
int nStatus;
PWINDOW pWindow;
PANO_IMAGE pAnoImage;
PIMAGE pImage = 0;
int nMarkIndex;
int nMarkIndex2;
PMARK pMark = 0;
PMARK pMark2;
PMARK pTempMark;
int nLoop;
HDC hDC = 0;
RECT rClientRect;
LRECT lrFullsizeClientRect;
PAN_POINTS pPoints;
long lHOffset;
long lVOffset;
BOOL bDeleteMark = FALSE;
BOOL bRepaint = FALSE;
LRECT lrRect;
LRECT lrMarkBounds;
BOOL bMarkComplete = TRUE;
PSTR pBlock;
PBITMAPINFOHEADER pDib = 0;
PAN_NEW_ROTATE_STRUCT pAnRotation =0;
PAN_IMAGE_STRUCT pAnImage = 0;
PBITMAPINFOHEADER pFormDib = 0;
BOOL bInvalidateAllDisplayRects = FALSE;
BOOL bInvalidateAllDisplayRectsFlag = FALSE;
long lTemp;
int nHScale;
int nVScale;
CheckError2( Init(hWnd, &pWindow, &pAnoImage, FALSE, TRUE));
pImage = pAnoImage->pBaseImage;
CheckError2( TranslateScale(pWindow->nScale, pImage->nHRes, pImage->nVRes, &nHScale, &nVScale));
// Find next available mark.
if (!pAnoImage->Annotations.ppMarks){
goto Exit; // Nothing to do.
}
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
// If there is no operation in progress, then return.
if (!pMark){
goto Exit; // Nothing to do.
}
hDC = GetDC(hWnd);
GetClientRect(hWnd, &rClientRect);
CopyRect(lrFullsizeClientRect, rClientRect);
ConvertRect(pWindow, &lrFullsizeClientRect, CONV_WINDOW_TO_FULLSIZE);
switch ((int) pMark->Attributes.uType){
case OIOP_SELECT_BY_RECT_VARIABLE:
case OIOP_SELECT_BY_RECT_FIXED:
case OIOP_SELECT_BY_POINT:
if (pAnoImage->Annotations.bMoving && !pAnoImage->Annotations.bMoved){
// Erase the selection rect if it is still there.
SetLRect(lrRect, 0, 0, 0, 0);
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
}
if (!pAnoImage->Annotations.bMoving
&& (int) pMark->Attributes.uType != OIOP_SELECT_BY_POINT
&& !(pAnoImage->nStartOpFlags & OIOP_IMAGE_ONLY)){
// Change the selection state of all marks inside the rect.
GetSelectBox(pAnoImage, &lrRect);
if (lrRect.right == lrRect.left || lrRect.bottom == lrRect.top){
// Erase the selection rect if it contains no space.
SetLRect(lrRect, 0, 0, 0, 0);
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
}
if (lrRect.right && lrRect.bottom){
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
CopyRect(lrMarkBounds, pMark2->Attributes.lrBounds);
// If the mark is aligned with the right or bottom
// edge of the image, we must fudge the selection
// rect to be able to select it.
if (lrMarkBounds.right >= (int) pImage->nWidth ||
lrMarkBounds.bottom >= (int) pImage->nHeight){
if (lrMarkBounds.left >= lrRect.left && lrMarkBounds.right <= (lrRect.right + 2)
&& lrMarkBounds.top >= lrRect.top && lrMarkBounds.bottom <= (lrRect.bottom + 2)){
if (pAnoImage->nStartOpFwKeys & MK_CONTROL){
pMark2->bSelected ^= TRUE;
}else{
pMark2->bSelected = TRUE;
}
}
}else{
if (lrMarkBounds.left >= lrRect.left && lrMarkBounds.right <= lrRect.right
&& lrMarkBounds.top >= lrRect.top && lrMarkBounds.bottom <= lrRect.bottom){
if (pAnoImage->nStartOpFwKeys & MK_CONTROL){
pMark2->bSelected ^= TRUE;
}else{
pMark2->bSelected = TRUE;
}
}
}
}
}
}
if (pAnoImage->Annotations.bMoved){
lHOffset = pMark->Attributes.lrBounds.right - pMark->Attributes.lrBounds.left;
lVOffset = pMark->Attributes.lrBounds.bottom - pMark->Attributes.lrBounds.top;
if (lHOffset || lVOffset){
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (!pMark2->bSelected){
continue;
}
CheckError2( ResizeMark(pMark2, pAnoImage->nHandle, lHOffset, lVOffset));
pAnoImage->bArchive |= ARCHIVE_MODIFIED_ANNOTATIONS;
// swap bounds if mark has flipped over on itself
if (pMark2->Attributes.lrBounds.top >
pMark2->Attributes.lrBounds.bottom){
lTemp = pMark2->Attributes.lrBounds.top;
pMark2->Attributes.lrBounds.top = pMark2->Attributes.lrBounds.bottom;
pMark2->Attributes.lrBounds.bottom = lTemp;
}
if (pMark2->Attributes.lrBounds.left >
pMark2->Attributes.lrBounds.right){
lTemp = pMark2->Attributes.lrBounds.left;
pMark2->Attributes.lrBounds.left = pMark2->Attributes.lrBounds.right;
pMark2->Attributes.lrBounds.right = lTemp;
}
}
}
if (pAnoImage->pBasePlusFormImg != pImage->pImg){
pAnoImage->nBPFValidLines = 0;
FreeImgBuf (&pAnoImage->pBasePlusFormImg);
bInvalidateAllDisplayRectsFlag = TRUE;
}
}
if ((pAnoImage->nStartOpFlags & OIOP_ANNOTATIONS_ONLY)){
SetLRect(lrRect, 0, 0, 0, 0);
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SELECTION_BOX, &lrRect, PARM_FULLSIZE));
}
// if a form mark is moved, the BPF buffer must be regenerated
if (pAnoImage->Annotations.bMoved &&
pAnoImage->Annotations.ppMarks[0]->Attributes.uType == OIOP_AN_FORM &&
pAnoImage->Annotations.ppMarks[0]->bSelected){
bInvalidateAllDisplayRectsFlag = TRUE;
}
bRepaint = TRUE;
bDeleteMark = TRUE;
pAnoImage->Annotations.bMoving = FALSE;
pAnoImage->Annotations.bMoved = FALSE;
break; // All done.
case OIOP_AN_FILLED_RECT:
case OIOP_AN_HOLLOW_RECT:
if (pMark->Attributes.lrBounds.left == pMark->Attributes.lrBounds.right
&& pMark->Attributes.lrBounds.top == pMark->Attributes.lrBounds.bottom){
bDeleteMark = TRUE;
break; // All done.
}
JustifyLRect(&pMark->Attributes.lrBounds);
// Erase the XORed mark.
CheckError2( PaintAnnotation(hWnd, hDC, pWindow, pImage,
pMark, rClientRect, lrFullsizeClientRect, PAINT_MODE_XOR,
pWindow->nScale, nHScale, nVScale, pWindow->lHOffset,
pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES));
// Draw the correct mark.
CheckError2( PaintAnnotation(hWnd, hDC, pWindow, pImage,
pMark, rClientRect, lrFullsizeClientRect, PAINT_MODE_NORMAL,
pWindow->nScale, nHScale, nVScale, pWindow->lHOffset,
pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES));
bInvalidateAllDisplayRectsFlag = FALSE;
bRepaint = TRUE;
break;
case OIOP_AN_LINE:
case OIOP_AN_FREEHAND:
CheckError2( GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pPoints));
if (!pPoints){
bDeleteMark = TRUE;
break; // All done.
}
if (!pPoints->nPoints){
bDeleteMark = TRUE;
break; // All done.
}
// Make the left and top of the bounding rect correct.
lHOffset = pPoints->ptPoint[0].x;
lVOffset = pPoints->ptPoint[0].y;
for (nLoop = 0; nLoop < pPoints->nPoints; nLoop++){
lHOffset = min(lHOffset, pPoints->ptPoint[nLoop].x);
lVOffset = min(lVOffset, pPoints->ptPoint[nLoop].y);
}
pMark->Attributes.lrBounds.left += lHOffset;
pMark->Attributes.lrBounds.top += lVOffset;
// Reset all line segments to the new offsets.
for (nLoop = 0; nLoop < pPoints->nPoints; nLoop++){
pPoints->ptPoint[nLoop].x -= (int) lHOffset;
pPoints->ptPoint[nLoop].y -= (int) lVOffset;
}
// Make right and bottom correct.
lHOffset = 0;
lVOffset = 0;
for (nLoop = 0; nLoop < pPoints->nPoints; nLoop++){
lHOffset = lmax(lHOffset, pPoints->ptPoint[nLoop].x);
lVOffset = lmax(lVOffset, pPoints->ptPoint[nLoop].y);
}
pMark->Attributes.lrBounds.right
= pMark->Attributes.lrBounds.left + lHOffset;
pMark->Attributes.lrBounds.bottom
= pMark->Attributes.lrBounds.top + lVOffset;
if ((int) pMark->Attributes.uType == OIOP_AN_LINE){
// Erase the XORed mark.
CheckError2( PaintAnnotation(hWnd, hDC, pWindow, pImage,
pMark, rClientRect, lrFullsizeClientRect, PAINT_MODE_XOR,
pWindow->nScale, nHScale, nVScale, pWindow->lHOffset,
pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES));
// Draw the correct mark.
CheckError2( PaintAnnotation(hWnd, hDC, pWindow, pImage,
pMark, rClientRect, lrFullsizeClientRect, PAINT_MODE_NORMAL,
pWindow->nScale, nHScale, nVScale, pWindow->lHOffset,
pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES));
}
bInvalidateAllDisplayRectsFlag = FALSE;
bRepaint = TRUE;
break;
case OIOP_AN_TEXT:
case OIOP_AN_TEXT_FROM_A_FILE:
case OIOP_AN_TEXT_STAMP:
case OIOP_AN_ATTACH_A_NOTE:
CheckError2( EndOperationText(hWnd, pWindow, pImage, pMark,
hDC, rClientRect, lrFullsizeClientRect, &bDeleteMark,
&bRepaint));
break;
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
CheckError2( EndOperationBitmap(hWnd, pWindow, pImage, pMark,
hDC, rClientRect, lrFullsizeClientRect, &bDeleteMark, &bRepaint));
// if form, move it to the top of the mark array
if (!bDeleteMark && (pMark != 0) && ((int) pMark->Attributes.uType
== OIOP_AN_FORM) && (pAnoImage->Annotations.nMarks > 0)){
pTempMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
for (nMarkIndex = pAnoImage->Annotations.nMarks; nMarkIndex > 0; nMarkIndex--){
pAnoImage->Annotations.ppMarks[nMarkIndex] =
pAnoImage->Annotations.ppMarks[nMarkIndex - 1];
}
pAnoImage->Annotations.ppMarks[0] = pTempMark;
}
// force form to be redrawn at new position
if ((int) pMark->Attributes.uType == OIOP_AN_FORM){
bInvalidateAllDisplayRectsFlag = TRUE;
bRepaint = TRUE;
}
break;
case OIOP_PASTE:
if (pAnoImage->Annotations.bPasteInProgress){
if (pAnoImage->Annotations.bMoved){
lHOffset = pMark->Attributes.lrBounds.right - pMark->Attributes.lrBounds.left;
lVOffset = pMark->Attributes.lrBounds.bottom - pMark->Attributes.lrBounds.top;
if (lHOffset || lVOffset){
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (!pMark2->bSelected){
continue;
}
CheckError2( ResizeMark(pMark2, pAnoImage->nHandle, lHOffset, lVOffset));
}
}
}
pAnoImage->Annotations.bPasteInProgress = FALSE;
bMarkComplete = FALSE;
}else{
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (!pMark2->bSelected){
continue;
}
if (pMark2->Attributes.uType == OIOP_AN_IMAGE){
CheckError2( GetAMarkNamedBlock(pMark2, szOiAnoDat, (PPSTR) &pAnRotation));
if (pAnRotation->bFormMark && !pAnoImage->pFormImage){
pMark2->Attributes.uType = OIOP_AN_FORM;
pMark2->Attributes.bTransparent = FALSE;
pAnRotation->bClipboardOp = FALSE;
// if form, move it to the top of the mark array
if (pAnoImage->Annotations.nMarks > 0){
for (nMarkIndex2 = nMarkIndex;
nMarkIndex2 > 0; nMarkIndex2--){
pAnoImage->Annotations.ppMarks[nMarkIndex2]
= pAnoImage->Annotations.ppMarks[nMarkIndex2 - 1];
}
pAnoImage->Annotations.ppMarks[0] = pMark2;
}
// Load pAnoImage->pFormImage, pAnoImage->pFormMark.
CheckError2( AllocateMemory(sizeof(IMAGE),
(PPSTR) &pAnoImage->pFormImage, ZERO_INIT));
CheckError2( AllocateMemory(sizeof(IMG),
(PPSTR) pAnoImage->pFormImage->pImg, ZERO_INIT));
CheckError2( GetAMarkNamedBlock(pMark2, szOiDIB,
(PPSTR) &pAnImage));
if (pAnImage){
pFormDib = (PBITMAPINFOHEADER) pAnImage;
}else{
Error (DISPLAY_DATACORRUPTED);
goto Exit;
}
pAnoImage->pFormImage->nHeight = pFormDib->biHeight;
pAnoImage->pFormImage->nWidth = pFormDib->biWidth;
pAnoImage->pFormImage->nHRes = pAnRotation->nOrigHRes;
pAnoImage->pFormImage->nVRes = pAnRotation->nOrigVRes;
CheckError2( DibToIpNoPal(&pAnoImage->pFormImage->pImg, pFormDib));
pAnoImage->pFormMark = pMark2;
CheckError2( DeleteAMarkNamedBlock (pMark2, szOiDIB));
// Regenerate BasePlusForm image.
if (pAnoImage->pBasePlusFormImg != pImage->pImg){
pAnoImage->nBPFValidLines = 0;
FreeImgBuf (&pAnoImage->pBasePlusFormImg);
bInvalidateAllDisplayRectsFlag = TRUE;
}
}else if (pAnRotation->bFormMark && pAnoImage->pFormImage){
pMark2->Attributes.uType = OIOP_AN_IMAGE_BY_REFERENCE;
}
pAnRotation->bFormMark = FALSE;
CheckError2( GetAMarkNamedBlock(pMark2, szOiBaseIm, (PPSTR) &pBlock));
if (pBlock){
if ((pAnoImage->nPasteFormat == nWangAnnotatedImageFormat) ||
(pAnoImage->nPasteFormat == CF_DIB)){
// This mark is supposed to be put into the base image.
CheckError2( GetAMarkNamedBlock(pMark2, szOiZDpDIB, (PPSTR) &pDib));
CheckError2( RenderDibToImage(&pAnoImage->pBaseImage->pImg,
pDib, 1000, 1000, pMark2->Attributes.lrBounds));
CheckError2( DeleteMark(pAnoImage, nMarkIndex));
// Regenerate BasePlusForm image.
if (pAnoImage->pBasePlusFormImg != pImage->pImg){
pAnoImage->nBPFValidLines = 0;
CheckError2( FreeImgBuf (&pAnoImage->pBasePlusFormImg));
bInvalidateAllDisplayRectsFlag = TRUE;
}
nMarkIndex--;
pImage->bArchive |= ARCHIVE_MODIFIED_ANNOTATIONS;
continue;
}
if (pAnoImage->nPasteFormat == nWangAnnotationFormat){
CheckError2( DeleteAMarkNamedBlock(pMark2, szOiBaseIm));
}
}
}
pAnoImage->bArchive |= ARCHIVE_MODIFIED_ANNOTATIONS;
}
CheckError2( CheckPermissions(pWindow, pAnoImage));
bDeleteMark = TRUE;
bInvalidateAllDisplayRectsFlag = TRUE;
}
bRepaint = TRUE;
pAnoImage->Annotations.bMoving = FALSE;
pAnoImage->Annotations.bMoved = FALSE;
break;
case OIOP_AN_AUDIO:
default:
bDeleteMark = TRUE;
bRepaint = TRUE;
break;
}
if (bDeleteMark){
CheckError2( DeleteMark(pAnoImage, pAnoImage->Annotations.nMarks));
}else{
if (bMarkComplete){
if (nStatus = CheckPermissionsMark(pWindow, pAnoImage, pMark)){
CheckError2( DeleteMark(pAnoImage, pAnoImage->Annotations.nMarks));
goto Exit;
}
pAnoImage->bArchive |= ARCHIVE_MODIFIED_ANNOTATIONS;
pAnoImage->Annotations.nMarks++;
}
}
// if the current window needs repaint, repaint all associated windows
if (bRepaint){
bInvalidateAllDisplayRects = TRUE;
}
if (bInvalidateAllDisplayRects){
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, bInvalidateAllDisplayRectsFlag));
}
if (!bRepaint && !bDeleteMark){
GetSelectBox(pAnoImage, &lrRect);
if (pMark->Attributes.lrBounds.left >= lrRect.left
&& pMark->Attributes.lrBounds.top >= lrRect.top
&& pMark->Attributes.lrBounds.right <= lrRect.right
&& pMark->Attributes.lrBounds.bottom <= lrRect.bottom){
bRepaint = TRUE;
}
}
if (hWnd != pWindow->hImageWnd || pWindow->hDisplayWnd[0]){
bRepaint = TRUE;
}
if (bRepaint & !(pAnoImage->nStartOpFlags & PARM_DONT_REPAINT)){
CheckError2( IMGRepaintDisplay(hWnd, (PRECT) -1));
}
Exit:
// if we error out of paste, delete the marks that were going to be pasted
if (pMark){
if (nStatus && ((int) pMark->Attributes.uType == OIOP_PASTE)){
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks; nMarkIndex++){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (pMark2->bSelected){
DeleteMark(pAnoImage, nMarkIndex);
nMarkIndex--;
}
}
}
}
if (nStatus && pImage){
if (pImage){
DeleteMark(pAnoImage, pAnoImage->Annotations.nMarks);
if (pWindow){
InvalidateAllDisplayRects(pWindow, pImage, NULL, TRUE);
}
}
}
if (hDC){
ReleaseDC(hWnd, hDC);
}
DeInit(FALSE, TRUE);
return(nStatus);
}
//
/****************************************************************************
FUNCTION: OIOpEndOperation
PURPOSE: This routine Ends the annotation.
****************************************************************************/
int WINAPI OiOpAbortOperation(HWND hWnd, int nFlags){
int nStatus;
PWINDOW pWindow;
PANO_IMAGE pAnoImage;
PIMAGE pImage = 0;
int nMarkIndex;
BOOL bArchive;
PMARK pMark;
PMARK pMark2;
CheckError2( Init(hWnd, &pWindow, &pAnoImage, FALSE, TRUE));
pImage = pAnoImage->pBaseImage;
// Find next available mark.
if (!pAnoImage->Annotations.ppMarks){
goto Exit; // Nothing to do.
}
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
// If there is no operation in progress, then return.
if (!pMark){
goto Exit; // Nothing to do.
}
bArchive = pAnoImage->bArchive;
switch ((int) pMark->Attributes.uType){
case OIOP_PASTE:
CheckError2( DeleteMark(pAnoImage, pAnoImage->Annotations.nMarks));
for (nMarkIndex = 0; nMarkIndex < (int) pAnoImage->Annotations.nMarks;){
pMark2 = pAnoImage->Annotations.ppMarks[nMarkIndex];
if (IsMarkSelected(pWindow, pMark2)){
if (pMark2->Attributes.uType == OIOP_AN_FORM){
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, TRUE));
}
CheckError2( DeleteMark(pAnoImage, nMarkIndex));
}else{
nMarkIndex++;
}
}
pAnoImage->Annotations.bPasteInProgress = FALSE;
pAnoImage->Annotations.bMoving = FALSE;
pAnoImage->Annotations.bMoved = FALSE;
break;
default:
break;
}
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, TRUE));
pAnoImage->bArchive = bArchive;
if (!(nFlags & PARM_DONT_REPAINT)){
CheckError2( IMGRepaintDisplay(hWnd, (PRECT) -1));
}
Exit:
// if we error out of paste, delete the marks that were going to be pasted
DeInit(FALSE, TRUE);
return(nStatus);
}