1840 lines
77 KiB
C
1840 lines
77 KiB
C
/****************************************************************************
|
||
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);
|
||
}
|