BOOL CChromaMask::JoinChromaMask(LPIMAGE lpImage, LPRECT lpUpdateRect) { LPOBJECT lpBase; LPMASK lpMask; RECT rDummy; RECT rMask; BOOL fNewMask = NO; BOOL fCreateMask = NO; UNDO_TYPE Type; AstralSetRectEmpty(lpUpdateRect); if (ImgGetMask(lpImage)) Type = UT_ALPHA; else { fNewMask = TRUE; Type = UT_CREATEMASK; } // get mask, create one if one does not exist lpMask = ImgGetMaskEx(lpImage, iMode==SHAPE_SUBTRACT ? OFF : ON, Control.NoUndo, &fNewMask, lpUpdateRect); if (!lpMask) return(FALSE); // if not new mask and we are allowed to create undo, initialize undo lpBase = ImgGetBase(lpImage); if (!ImgEditInit(lpImage, ET_OBJECT,Type, lpBase)) return(FALSE); EnableMarqueeEx( lpImage, NO ); // add Chroma to mask MaskAddChroma(lpImage, lpMask, &rMask, !fNewMask); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rMask); // if using undo, indicate in-place editing has occurred ImgEditedObject(lpImage, lpBase, IDS_CHROMA_APPLY, fNewMask ? NULL : &rMask); // after subtractive masks we dont know area if (iMode!=SHAPE_ADD) MaskRectUpdate(lpMask, &rDummy); // get area that needs to be redisplayed, may be larger // than rUpdate because of slime if (ImgGetMaskUpdateRect(lpImage, fNewMask, NO, &rMask)) AstralUnionRect(lpUpdateRect, lpUpdateRect, &rMask); EnableMarqueeEx(lpImage, YES); return(TRUE); }
void CChromaDlg::ShowChromaPreview() { HWND hDlg = GetSafeHwnd(); RECT rMask; HWND hActiveWnd; LPIMAGE lpImage = GetImage(); hActiveWnd = m_pView->GetSafeHwnd(); if (!hActiveWnd) return; lpChromaMask->iMode = ImgGetViewMode(lpImage); ImgSetViewMode(lpImage, VM_SLIME); if (ImgGetMask(lpImage)) ImgGetMaskRect(lpImage, &rMask); else ImgGetSelObjectRect(lpImage, &rMask, NO); File2DispRect(hActiveWnd, &rMask, &rMask); if (Tool.id == IDC_CHROMA) AstralUnionRect(&rMask, &rMask, &rPreview); ImgGetMaskRect(lpImage, &rPreview); File2DispRect(hActiveWnd, &rPreview, &rPreview); SetMaskHook(hActiveWnd, (LPMASKHOOK)lpChromaMask); AstralCursor( IDC_WAIT ); ::InvalidateRect(hActiveWnd, &rMask, FALSE); AstralUpdateWindow(hActiveWnd); ControlEnable(hDlg, IDC_RESET, YES ); AstralCursor(NULL); }
LOCAL poly_get_bounds(LPCPoly lpPoly, LPRECT lpRect) { RECT rNew; lpPoly->GetBounds(&rNew); AstralUnionRect(lpRect, lpRect, &rNew); return(TRUE); }
void CImage::GetGroupRect(LPOBJECT lpObject, LPRECT lpRect) { LPOBJECT lpNextObject; AstralSetRectEmpty( lpRect ); lpNextObject = GetBase(); while( lpNextObject = GetSelObject( lpNextObject ) ) { if( lpObject->wGroupID == lpNextObject->wGroupID ) AstralUnionRect( lpRect, lpRect, &lpNextObject->rObject ); } }
BOOL CImage::GetFloatingObjectsRect( LPRECT lpRect ) { LPOBJECT lpObject; AstralSetRectEmpty( lpRect ); if ( !(lpObject = GetNextObject(GetBase(), YES, NO) )) return( NO ); while ( lpObject ) { AstralUnionRect( lpRect, lpRect, &lpObject->rObject ); lpObject = GetNextObject(lpObject, YES, NO); } return( YES ); }
BOOL PosObjects( LPIMAGE lpImage, LPPOSOBJECTS_PARMS lpPosParms ) /************************************************************************/ { RECT bRect, uRect; LPOBJECT lpObject; int res; int x,y; if( !( lpImage ) ) return( FALSE ); if( !( lpObject = ImgGetBase( lpImage ) ) ) return( FALSE ); ImgEditInit( lpImage, ET_SELOBJECTS, UT_OBJECTRECT, lpObject ); ImgGetInfoEx(lpImage, NULL, NULL, NULL, NULL, &res); x = lpPosParms->XOffset; y = lpPosParms->YOffset; ResConvertUL(lpPosParms->iBaseRes, res, &x, &y); ImgGetSelObjectRect( lpImage, &bRect, YES ); x -= bRect.left; y -= bRect.top; while ( lpObject = ImgGetSelObject(lpImage, lpObject) ) { if( lpObject->wGroupID ) { if( !( IsGroupLocked( lpObject->wGroupID ) ) ) { ImgEditedObject( lpImage, lpObject, IDS_UNDOOBJPOS, NULL ); OffsetRect( &lpObject->rObject, x, y); } } else if (!lpObject->bLocked) { ImgEditedObject( lpImage, lpObject, IDS_UNDOOBJPOS, NULL ); OffsetRect( &lpObject->rObject, x, y); } } ImgGetSelObjectRect( lpImage, &uRect, YES ); AstralUnionRect( &uRect, &uRect, &bRect ); UpdateImage( lpImage, &uRect, YES ); return( TRUE ); }
void DoReset(HWND hDlg, LPALIGNOBJECTS_PARMS lpAlignParms) { RECT uRect; LPIMAGE lpImage = GetActiveImage(); LPRECT pRect; LPOBJECT lpObject; if(!lpImage) return; HWND hWnd = GetDlgItem(hDlg, IDC_ALIGN_GRID); int x,y,i, wind; RECT cRect; for( i = 0, wind = GW_CHILD; i < ALIGN_NUM_OBJECTS; i++, wind = GW_HWNDNEXT ) { hWnd = GetWindow( hWnd, wind ); GetClientRect( hWnd, &cRect ); cRect.right -= 1; cRect.bottom -= 1; ShowWindow( hWnd, SW_HIDE ); x = InitPos[i].x - cRect.left; y = InitPos[i].y - cRect.top; OffsetRect( &cRect, x, y); MoveWindow( hWnd, cRect.left, cRect.top, RectWidth( &cRect ), RectHeight( &cRect ), TRUE ); UpdateWindow( GetDlgItem( hDlg, IDC_ALIGN_GRID ) ); ShowWindow( hWnd, SW_SHOWNA ); } lpAlignParms->HorzAlign = HA_NONE; lpAlignParms->VertAlign = VA_NONE; if( lpAlignParms->bPreview ) { pRect = lpAlignParms->lpRect; if( !( lpObject = ImgGetBase(lpImage))) return; while ( lpObject = ImgGetSelObject( lpImage, lpObject) ) { AstralUnionRect(&uRect, &uRect, &lpObject->rObject); lpObject->rObject = *pRect++; } AlignObjects( GetActiveImage(), lpAlignParms ); } EnableWindow( GetDlgItem( hDlg, IDC_PREVIEW ), TRUE ); lpAlignParms->bPreview = FALSE; UpdateImage(lpImage, &uRect, YES); }
BOOL CImage::GetSelObjectRect( LPRECT lpRect, BOOL bExcludeBase ) { LPOBJECT lpObject; BOOL bFoundOne; AstralSetRectEmpty( lpRect ); bFoundOne = NO; lpObject = ( bExcludeBase ? GetBase() : NULL ); while ( lpObject = GetSelObject(lpObject) ) { AstralUnionRect( lpRect, lpRect, &lpObject->rObject ); bFoundOne = YES; } return( bFoundOne ); }
void CImage::EditUndo( BOOL fEditUndo, BOOL fMaskUndo, LPUPDATE_TYPE lpUpdateType, LPRECT lpUpdateRect) { RECT rUndo, rUndoMask, rTemp; LPOBJECT lpBase, lpObject, lpNext; BOOL fNewSize, fSetupMiniViews, fRemoveMarquee, fUndoDelete, fColorMapChanged; BOOL fUndoAlpha, fUndoData; int nDeleted; LPMASK lpMask; EDIT_TARGET Target; AstralSetRectEmpty(lpUpdateRect); // Initialize things for updating the display fNewSize = fSetupMiniViews = fUndoDelete = fColorMapChanged = NO; AstralSetRectEmpty(&rUndo); AstralSetRectEmpty(&rUndoMask); // loop through objects doing undo lpBase = GetBase(); lpObject = NULL; // get the target of the last edit Target = EditTarget; while (lpObject = GetNextObject(lpObject, NO, NO, fEditUndo)) { // See if this is an object we are undoing if (fEditUndo) { // check for special undo processing of a deleted object if (lpObject->fDeleted) continue; // do no undo processing for a deleted object // { // if (Control.UndoObjects && !IsSelectedObject(lpBase)) // continue; // } else // if target is not the entire image and we are in undo // object mode and the object is not selected then // skip this object if (Target != ET_ALLOBJECTS && Control.UndoObjects && !IsSelectedObject(lpObject)) continue; } // Only handle mask undo for the base object if (fMaskUndo) { if (lpObject != lpBase || lpObject->fBothDirty || !lpObject->AlphaDirty) continue; } fUndoData = fUndoAlpha = NO; // Do preprocess for doing a data undo if (fEditUndo) { if (lpObject->DataDirty) fUndoData = YES; // See if we need to undo the alpha for this object if ((lpObject != lpBase) && lpObject->lpAlpha && lpObject->AlphaDirty) fUndoAlpha = YES; if (!fUndoData && !fUndoAlpha) continue; // check to see and undoing/redoing deleted objects will change // the select state, if so undraw the object marquee if (lpObject == lpBase && lpObject->DataUndoType & UT_DELETEOBJECTS) { fUndoDelete = YES; fRemoveMarquee = NO; nDeleted = 0; lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, YES)) { if (lpNext->fUndoDeleted) ++nDeleted; else if (lpNext->fDeleted && lpNext->fSelected) { fRemoveMarquee = YES; break; } } if (GetSelObject(NULL) == lpBase && !fRemoveMarquee) { if (CountObjects() - nDeleted <= 1) fRemoveMarquee = YES; } if (fRemoveMarquee) { GetObjectMarqueeRect(this, &rTemp); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp); } } } else // fMaskUndo if (!lpObject->AlphaDirty) continue; else fUndoAlpha = YES; // do a preprocess for undoing the mask caused either by // a mask undo or by an edit function that also edits the mask if (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) || fMaskUndo) { if ( lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) ) { // if the undo is going to delete the mask, // we need to undraw the mask if (GetMask()) { GetMaskMarqueeRect(this, &rTemp); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp); if (GetMaskUpdateRect(YES, NO, &rTemp)) AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp); } // if the undo is going to create the mask, // we need to undraw the object marquees if // not in mask and object marquee mode else { if (!Control.UseMaskAndObjects) { GetObjectMarqueeRect(this, &rTemp); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp); } } } } // Actually do the undo ObjEditUndo(lpObject, fUndoData, fUndoAlpha); // do a postprocess for undoing the mask if ((lpMask = GetMask()) && (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) || fMaskUndo)) { // if the undo is going to add the mask, we need to redraw the mask if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) ) { if (GetMaskUpdateRect(YES, NO, &rTemp)) AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp); } else // just redraw the undo area for the mask AstralUnionRect(&rUndoMask, &rUndoMask, &lpMask->Pixmap.UndoRect); } // Setup rectangle for undoing deletion of objects // Handled specially so that moved objects will still undo // and redo properly if (fEditUndo) { if (lpObject == lpBase && lpObject->DataUndoType & UT_DELETEOBJECTS) { lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, YES)) { if (lpNext->fDeleted || lpNext->fUndoDeleted) AstralUnionRect(&rUndo, &rUndo, &lpNext->rObject); } fSetupMiniViews = YES; } if (lpObject->DataUndoType & UT_COLORMAP) fColorMapChanged = YES; if (lpObject->Pixmap.fNewFrame) { /* if new frame, cause window to be redisplayed */ if (lpObject == lpBase) fNewSize = YES; else { if (!fNewSize) { AstralUnionRect(&rUndo, &rUndo, &lpObject->rObject); AstralUnionRect(&rUndo, &rUndo, &lpObject->rUndoObject); } } } else { AstralSetRectEmpty(&rTemp); if (fUndoData) AstralUnionRect(&rTemp, &rTemp, &lpObject->Pixmap.UndoRect); if (fUndoAlpha) AstralUnionRect(&rTemp, &rTemp, &lpObject->lpAlpha->Pixmap.UndoRect); if (rTemp.right >= rTemp.left) { if (!fNewSize) { OffsetRect(&rTemp, lpObject->rObject.left, lpObject->rObject.top); AstralUnionRect(&rUndo, &rUndo, &rTemp); } } if( lpObject->DataUndoType & UT_OBJECTRECT ) { AstralUnionRect( &rUndo, &rUndo, &lpObject->rObject ); AstralUnionRect( &rUndo, &rUndo, &lpObject->rUndoObject ); } } } } // now redisplay whatever changes are necessary for the undo if (fColorMapChanged) { ImgColorMapChanged(this); *lpUpdateType |= UT_DATATYPE; } if (fNewSize) { *lpUpdateType |= UT_DATATYPE; if (lpBase->Pixmap.UndoFrame) { if ((FrameXSize(lpBase->Pixmap.UndoFrame) == FrameXSize(lpBase->Pixmap.EditFrame)) && (FrameYSize(lpBase->Pixmap.UndoFrame) == FrameYSize(lpBase->Pixmap.EditFrame))) fNewSize = NO; } if (fNewSize) *lpUpdateType |= UT_SIZE; else { int dx, dy; GetInfo(&dx, &dy, NULL, NULL); SetRect(lpUpdateRect, 0, 0, dx-1, dy-1); } } else { if (!AstralIsRectEmpty(lpUpdateRect)) *lpUpdateType |= UT_ACTIVEAREA; if (rUndoMask.right >= rUndoMask.left) { *lpUpdateType |= UT_ACTIVEAREA; AstralUnionRect(lpUpdateRect, lpUpdateRect, &rUndoMask); } if (rUndo.right >= rUndo.left) { *lpUpdateType |= UT_AREA; AstralUnionRect(lpUpdateRect, lpUpdateRect, &rUndo); } } }
BOOL AlignObjects( LPIMAGE lpImage, LPALIGNOBJECTS_PARMS lpAlignParms ) /************************************************************************/ { RECT bRect, gRect, uRect; LPOBJECT lpObject, lpGroupObject; int xOffset, yOffset, gXOffset, gYOffset, nWidth, nHeight, nCount; LFIXED hSpace, vSpace, fx, fy; WORD wGroupIDs[NUM_GROUPS]; if( !( lpImage ) ) return( FALSE ); if( !( lpObject = ImgGetBase( lpImage ) ) ) return( FALSE ); if( !( lpAlignParms->bPreview ) ) { if( !( ImgEditInit( lpImage, ET_SELOBJECTS, UT_OBJECTRECT, lpObject ) ) ) return( FALSE ); } if( lpAlignParms->RectAlign == RA_IMAGE ) { ImgGetImageRect( lpImage, &bRect ); } else { if( lpAlignParms->RectAlign == RA_MASK ) ImgGetMaskRect( lpImage, &bRect ); else ImgGetSelObjectRect( lpImage, &bRect, YES ); } ImgGetSelObjectRect( lpImage, &uRect, YES ); nWidth = RectWidth( &bRect ); nHeight = RectHeight( &bRect ); nCount = 0; InitGroupList( wGroupIDs ); while ( lpObject = ImgGetSelObject(lpImage, lpObject) ) { if( lpObject->wGroupID ) { if( !( IsPrevGroup( lpObject->wGroupID, wGroupIDs ) ) && !( IsGroupLocked( lpObject->wGroupID ) ) ) { SetGroupList( lpObject->wGroupID, wGroupIDs ); lpImage->GetGroupRect( lpObject, &gRect ); nWidth -= RectWidth( &gRect ); nHeight -= RectHeight( &gRect ); ++nCount; } } else if (!lpObject->bLocked) { nWidth -= RectWidth( &lpObject->rObject ); nHeight -= RectHeight( &lpObject->rObject ); ++nCount; } } if( nCount == 0 ) return( FALSE ); hSpace = FGET( nWidth, nCount - 1 ); vSpace = FGET( nHeight, nCount - 1 ); fx = fy = 0; InitGroupList( wGroupIDs ); lpObject = ImgGetBase( lpImage ); while ( lpObject = ImgGetSelObject(lpImage, lpObject) ) { if( lpObject->wGroupID ) { if( !( IsPrevGroup( lpObject->wGroupID, wGroupIDs ) ) && !( IsGroupLocked( lpObject->wGroupID ) ) ) { SetGroupList( lpObject->wGroupID, wGroupIDs ); lpImage->GetGroupRect( lpObject, &gRect ); ObjAlign( &bRect, &gRect, lpAlignParms, vSpace, hSpace, &gXOffset, &gYOffset, &fx, &fy ); lpGroupObject = ImgGetBase( lpImage ); while( lpGroupObject = ImgGetSelObject( lpImage, lpGroupObject ) ) { if( lpObject->wGroupID == lpGroupObject->wGroupID ) { if( !( lpAlignParms->bPreview ) ) ImgEditedObject( lpImage, lpGroupObject, IDS_UNDOOBJALIGN, NULL ); OffsetRect( &lpGroupObject->rObject, gXOffset, gYOffset ); } } } } else if (!lpObject->bLocked) { ObjAlign( &bRect, &lpObject->rObject, lpAlignParms, vSpace, hSpace, &xOffset, &yOffset, &fx, &fy ); if( !( lpAlignParms->bPreview ) ) ImgEditedObject( lpImage, lpObject, IDS_UNDOOBJALIGN, NULL ); OffsetRect( &lpObject->rObject, xOffset, yOffset ); } } ImgGetSelObjectRect( lpImage, &bRect, YES ); AstralUnionRect( &uRect, &uRect, &bRect ); UpdateImage( lpImage, &uRect, YES ); return( TRUE ); }
void ImgEditUndo( LPIMAGE lpImage, BOOL fEditUndo, BOOL fMaskUndo ) /***********************************************************************/ { RECT rUndo, rUndoMask, rTemp; LPOBJECT lpBase, lpObject, lpNext; BOOL fNewSize, fSetupMiniViews, fRemoveMarquee, fUndoDelete; BOOL fUndoAlpha, fUndoData; int nDeleted; LPMASK lpMask; if (!lpImage) return; // Initialize things for updating the display fNewSize = fSetupMiniViews = fUndoDelete = NO; AstralSetRectEmpty(&rUndo); AstralSetRectEmpty(&rUndoMask); // loop through objects doing undo lpBase = ImgGetBase(lpImage); lpObject = NULL; while (lpObject = ImgGetNextObjectEx(lpImage, lpObject, NO, NO, fEditUndo)) { // See if this is an object we are undoing if (fEditUndo) { // check for special undo processing of a deleted object if (lpObject->fDeleted) { if (Control.UndoObjects && !ImgIsSelectedObject(lpImage, lpBase)) continue; } else if (Control.UndoObjects && !ImgIsSelectedObject(lpImage, lpObject)) continue; } // Only handle mask undo for the base object if (fMaskUndo) { if (lpObject != lpBase || lpObject->fBothDirty || !lpObject->AlphaDirty) continue; } fUndoData = fUndoAlpha = NO; // Do preprocess for doing a data undo if (fEditUndo) { if (lpObject->DataDirty) fUndoData = YES; // See if we need to undo the alpha for this object if ((lpObject != lpBase) && lpObject->lpAlpha && lpObject->AlphaDirty) fUndoAlpha = YES; if (!fUndoData && !fUndoAlpha) continue; // check to see and undoing/redoing deleted objects will change // the select state, if so undraw the object marquee if (lpObject == lpBase && lpObject->DataUndoType & UT_DELETEOBJECTS) { fUndoDelete = YES; fRemoveMarquee = NO; nDeleted = 0; lpNext = lpObject; while (lpNext = ImgGetNextObjectEx(lpImage, lpNext, YES, NO, YES)) { if (lpNext->fUndoDeleted) ++nDeleted; else if (lpNext->fDeleted && lpNext->fSelected) { fRemoveMarquee = YES; break; } } if (ImgGetSelObject(lpImage, NULL) == lpBase && !fRemoveMarquee) { if (ImgCountObjects(lpImage) - nDeleted <= 1) fRemoveMarquee = YES; } if (fRemoveMarquee) RemoveObjectMarqueeEx(lpImage, NO); } } else // fMaskUndo if (!lpObject->AlphaDirty) continue; else fUndoAlpha = YES; // do a preprocess for undoing the mask caused either by // a mask undo or by an edit function that also edits the mask if (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) || fMaskUndo) { if ( lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) ) { // if the undo is going to delete the mask, // we need to undraw the mask if (ImgGetMask(lpImage)) { RemoveMaskMarquee(lpImage); if (ImgGetMaskUpdateRect(lpImage, YES, NO, &rTemp)) AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp); } // if the undo is going to create the mask, // we need to undraw the object marquees if // not in mask and object marquee mode else { if (!Control.UseMaskAndObjects) RemoveObjectMarqueeEx(lpImage, NO); } } } // Actually do the undo ObjEditUndo(lpImage, lpObject, fUndoData, fUndoAlpha); // do a postprocess for undoing the mask if ((lpMask = ImgGetMask(lpImage)) && (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) || fMaskUndo)) { // if the undo is going to add the mask, we need to redraw the mask if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) ) { if (ImgGetMaskUpdateRect(lpImage, YES, NO, &rTemp)) AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp); } else // just redraw the undo area for the mask AstralUnionRect(&rUndoMask, &rUndoMask, &lpMask->Pixmap.UndoRect); } // Setup rectangle for undoing deletion of objects // Handled specially so that moved objects will still undo // and redo properly if (fEditUndo) { if (lpObject == lpBase && lpObject->DataUndoType & UT_DELETEOBJECTS) { lpNext = lpObject; while (lpNext = ImgGetNextObjectEx(lpImage, lpNext, YES, NO, YES)) { if (lpNext->fDeleted || lpNext->fUndoDeleted) AstralUnionRect(&rUndo, &rUndo, &lpNext->rObject); } fSetupMiniViews = YES; } if (lpObject->Pixmap.fNewFrame) { /* if new frame, cause window to be redisplayed */ if (lpObject == lpBase) fNewSize = YES; else { if (!fNewSize) { AstralUnionRect(&rUndo, &rUndo, &lpObject->rObject); AstralUnionRect(&rUndo, &rUndo, &lpObject->rUndoObject); } } } else { AstralSetRectEmpty(&rTemp); if (fUndoData) AstralUnionRect(&rTemp, &rTemp, &lpObject->Pixmap.UndoRect); if (fUndoAlpha) AstralUnionRect(&rTemp, &rTemp, &lpObject->lpAlpha->Pixmap.UndoRect); if (rTemp.right >= rTemp.left) { if (!fNewSize) { OffsetRect(&rTemp, lpObject->rObject.left, lpObject->rObject.top); AstralUnionRect(&rUndo, &rUndo, &rTemp); } } } } } // now redisplay whatever changes are necessary for the undo if (fNewSize) { SetupImagePalette(lpImage, NO, YES); if (lpBase->Pixmap.UndoFrame) { if ((FrameXSize(lpBase->Pixmap.UndoFrame) == FrameXSize(lpBase->Pixmap.EditFrame)) && (FrameYSize(lpBase->Pixmap.UndoFrame) == FrameYSize(lpBase->Pixmap.EditFrame))) fNewSize = NO; } if (fNewSize) UpdateImageSize(); else UpdateImageEx(lpImage, NULL, YES, YES, YES); if ( Tool.hRibbon ) SendMessage( Tool.hRibbon, WM_CONTROLENABLE, 0, 0L ); } else { if (rUndoMask.right >= rUndoMask.left) { File2DispRect(&rUndoMask, &rUndoMask); AstralToWindowsRect(&rUndoMask); InvalidateRect(lpImage->hWnd, NULL, NO); } if (rUndo.right >= rUndo.left) AnimateUndo( &rUndo ); } if (fUndoDelete) if ( Tool.hRibbon ) SendMessage( Tool.hRibbon, WM_CONTROLENABLE, 0, 0L ); if (fSetupMiniViews) SetupMiniViews(NULL, NO); }
BOOL CImage::CombineObjects(BOOL fNoUndo, BOOL fCreateMask, BOOL fForceIt, ITEMID idDirty, LPRECT lpUpdateRect) { LPOBJECT lpBase, lpObject; int iWidth, iHeight, depth, y, iImageWidth, iImageHeight; LPTR lpDataBuf, lpMaskPtr; RECT rFloaters, rMask, rTemp; BOOL fNewMask; LPMASK lpMask; UNDO_TYPE UndoType; AstralSetRectEmpty(lpUpdateRect); // get rectangle for all floating objects if (!GetFloatingObjectsRect(&rFloaters)) return(FALSE); // Get base object lpBase = GetBase(); // get pixmap information PixmapGetInfo(&lpBase->Pixmap, PMT_EDIT, &iImageWidth, &iImageHeight, &depth, NULL); BoundRect(&rFloaters, 0, 0, iImageWidth-1, iImageHeight-1); iWidth = RectWidth(&rFloaters); iHeight = RectHeight(&rFloaters); // allocate buffer for alpha channel combining if (!(lpDataBuf = Alloc((long)iWidth*depth))) { Message(IDS_EMEMALLOC); return(FALSE); } lpMask = NULL; if (fCreateMask) { lpMask = GetMaskEx(OFF, Control.NoUndo, &fNewMask, &rTemp); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp); } // do it to it ProgressBegin(lpMask != NULL ? 2 : 1, idDirty-IDS_UNDOFIRST+IDS_PROGFIRST); if (!fNoUndo) { UndoType = UT_DATA|UT_DELETEOBJECTS; if (lpMask) { if (fNewMask) UndoType |= UT_CREATEMASK; else UndoType |= UT_ALPHA; } if (!ImgEditInit(this, ET_OBJECT, UndoType, lpBase)) { if (!fForceIt) { ProgressEnd(); FreeUp(lpDataBuf); return(FALSE); } } } // do it to it ProgressBegin(1, 0); for (y = rFloaters.top; y <= rFloaters.bottom; ++y) { AstralClockCursor(y-rFloaters.top, iHeight, NO); ImgGetLine(this, NULL, rFloaters.left, y, iWidth, lpDataBuf); PixmapWrite(&lpBase->Pixmap, PMT_EDIT, rFloaters.left, y, iWidth, lpDataBuf, iWidth); } ProgressEnd(); if (lpMask && (lpObject = GetNextObject(lpBase, YES, NO))) { ProgressBegin(1, 0); for (y = rFloaters.top; y <= rFloaters.bottom; ++y) { AstralClockCursor(y-rFloaters.top, iHeight, NO); lpMaskPtr = PixmapPtr(&lpMask->Pixmap, PMT_EDIT, rFloaters.left, y, YES); if (!lpMaskPtr) continue; ImgMaskLoad(this, lpObject, NULL, rFloaters.left, y, iWidth, lpDataBuf, NO, CR_OR, 0, 0); CombineData(lpDataBuf, lpMaskPtr, iWidth, NO, CR_OR); } MaskRectUpdate(lpMask, &rMask); ProgressEnd(); } FreeUp(lpDataBuf); GetObjectMarqueeRect(this, &rTemp); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp); lpObject = lpBase; while (lpObject = GetNextObject(lpObject, YES, NO)) { // always let undo stuff initialize this // lpObject->fUndoDeleted = NO; lpObject->fDeleted = YES; } //DeleteObjects((LPOBJECT)lpBase->lpNext, NO); if (!fNoUndo) ImgEditedObject(this, lpBase, idDirty, &rFloaters); else fChanged = YES; //if ( Tool.hRibbon ) // SendMessage( Tool.hRibbon, WM_CONTROLENABLE, 0, 0L ); ProgressEnd(); //SetupMiniViews(NULL, NO); return(TRUE); }
long DoCommand( HWND hWindow, WPARAM wParam, LPARAM lParam ) /***********************************************************************/ { FNAME szFileName; LPFRAME lpFrame; LPOBJECT lpObject, lpBase; RECT rect, rMask, rTemp, rAll; HWND hWnd; STRING szString; int i, idFileType, x, y, dx, dy; BOOL fDoZoom, bPrint, fHasZoom; LPSTR lpszCmdLine; HGLOBAL hMem; ITEMID idDataType; DWORD dwReturn; int NewShape; UINT wID; SoundStartID( wParam, NO/*bLoop*/, NULL/*hInstance*/ ); /* WIN16: ID = wParam ctrl handle = LOWORD(lParam) notify code = HIWORD(lParam) WIN32: ID = LOWORD(wParam) ctrl handle = lParam notify code = HIWORD(wParam) */ #ifdef WIN32 wID = LOWORD(wParam); #else wID = wParam; #endif switch (wID) { case IDM_EXIT: DeactivateTool(); PostMessage( hWndAstral, WM_CLOSE, 0, 0L); Delay (750); break; case IDM_CLOSE: DeactivateTool(); /* Check to see if the image needs to be saved */ if ( !ConfirmClose(NO,NO) ) break; CloseImage( NO, lpImage ); // Close the active image break; case IDM_ABOUT: /* Bring up the modal 'About' dialog box */ AstralDlg( NO|2, hInstAstral, hWindow, IDD_ABOUT, DlgAboutProc); break; case IDM_NEXTPAGE: if ( !lpImage ) break; DeactivateTool(); SendMessage( lpImage->hWnd, WM_SYSCOMMAND, SC_NEXTWINDOW, 0L ); break; case IDM_NEW: DeactivateTool(); SoundStartResource( "magic01", NO, NULL ); AstralCursor( IDC_WAIT ); New( Control.NewWidth, Control.NewHeight, Control.NewResolution, Control.NewDepth ); AstralCursor( NULL ); break; case IDM_OPEN: DeactivateTool(); /* Bring up the modal 'File Open' box */ if ( !(dwReturn = DoOpenDlg( hWindow, IDD_OPEN, Save.FileType, szFileName, NO )) ) break; idFileType = LOWORD( dwReturn ); Save.FileType = idFileType; PutDefaultInt( "FileType", idFileType - IDN_TIFF ); AstralImageLoad( idFileType, szFileName, MAYBE, YES ); break; case IDM_ALTOPEN: DeactivateTool(); // Command line sent from a second instance prior to it closing /* If the caller passed in a file name, try to load it or print it */ if ( !(lpszCmdLine = (LPSTR)lParam) ) break; HandleCommandLine( hWindow, lpszCmdLine, &bPrint ); break; case IDM_SAVE: DeactivateTool(); HandleSaveCommand(hWindow, wID, YES); break; case IDM_SAVEAS: DeactivateTool(); HandleSaveCommand(hWindow, wID, YES); break; case IDM_SAVESPECIAL: DeactivateTool(); HandleSaveCommand(hWindow, wID, YES); break; case IDM_SAVEWALLPAPER: DeactivateTool(); SaveWallpaper( "CRAYOLA", NO/*fTiled*/ ); break; case IDM_REVERT: if ( !lpImage ) break; DeactivateTool(); if ( lpImage->fUntitled ) // If the picture doesn't have a name, get out break; if ( ImgChanged(lpImage) ) { /* Check to see if its OK to trash changes */ if ( AstralOKCancel(IDS_OKTOREVERT, (LPSTR)lpImage->CurFile) == IDCANCEL ) break; } lstrcpy( szFileName, lpImage->CurFile ); idFileType = lpImage->FileType; fDoZoom = IsZoomed(lpImage->hWnd); fHasZoom = Window.fHasZoom; CloseImage( NO, lpImage ); // Close the active image if ( !AstralImageLoad( idFileType, szFileName, fDoZoom, YES ) ) break; break; case IDM_RECALLIMAGE0: case IDM_RECALLIMAGE1: case IDM_RECALLIMAGE2: case IDM_RECALLIMAGE3: case IDM_RECALLIMAGE4: case IDM_RECALLIMAGE5: case IDM_RECALLIMAGE6: case IDM_RECALLIMAGE7: case IDM_RECALLIMAGE8: case IDM_RECALLIMAGE9: DeactivateTool(); GetMenuString( GetMenu(hWindow), wID, szFileName, sizeof(szFileName), MF_BYCOMMAND ); i = 0; while ( szFileName[i] && szFileName[i] != ' ' ) i++; // Skip over the numeric id in the string (3. junk.tif) lstrcpy(szString, &szFileName[i+1]); GetRecallFileName(szString); AstralImageLoad( NULL, szString, MAYBE, YES ); break; case IDM_PRINT: if ( !lpImage ) break; DeactivateTool(); AstralCursor( IDC_WAIT ); DoPrintSizeInits(); SoundStartResource( "print", YES, NULL ); PrintFile( hWindow, filename(lpImage->CurFile), YES, lpImage, NULL ); SoundStop(); AstralCursor( NULL ); break; case IDM_PRINTSETUP: /* Bring up the setup dialog box for the active printer */ AstralDlg( NO|2, hInstAstral, hWindow, IDD_PRINTSETUP, DlgPrintSetupProc); break; case IDC_SOUND: SoundToggle(); break; case IDM_UNDO: if ( !lpImage ) break; DeactivateTool(); ImgEditUndo(lpImage, YES, NO); break; case IDM_CUT: case IDM_COPY: if ( !lpImage ) break; DeactivateTool(); // Create the clipboard files from the image ProgressBegin(1, IDS_PROGCOPY); if ( !ImgWriteClipOut( lpImage, NULL, NULL, &rMask, lpImage->DataType ) ) { ProgressEnd(); Message(IDS_EMEMALLOC); break; } ProgressEnd(); OpenClipboard(hWindow); EmptyClipboard(); // Passing a NULL data handle in SetClipboardData() means that // the data will be requested in a WM_RENDERFORMAT message hMem = ConstructObject( lpImage, IsRectEmpty(&rMask)? (LPRECT)NULL : (LPRECT)&rMask ); if ( pOLE ) { // Any data put on before Native will become staticly copied SetClipboardData( pOLE->cfNative, NULL ); SetClipboardData( pOLE->cfOwnerLink, hMem ); } SetClipboardData( CF_DIB, NULL ); if ( Control.DoPicture ) SetClipboardData( CF_METAFILEPICT, NULL ); if ( Control.DoBitmap ) SetClipboardData( CF_BITMAP, NULL ); SetClipboardData( CF_PALETTE, NULL ); SetClipboardData( Control.cfImage, NULL ); if ( pOLE && wID == IDM_COPY && !lpImage->fUntitled ) { // ObjectLink is retrieved during a Paste Link... SetClipboardData( pOLE->cfObjectLink, hMem ); } CloseClipboard(); if ( wID == IDM_COPY ) break; // else fall through to IDM_DELETE case IDM_DELETE: if ( !lpImage ) break; { COLORINFO ColorInfo; DeactivateTool(); ColorInfo.gray = 255; SetColorInfo( &ColorInfo, &ColorInfo, CS_GRAY ); TintFill( lpImage, &ColorInfo, 255, MM_NORMAL, wID == IDM_CUT ? IDS_UNDOCUT : IDS_UNDODELETE ); } break; case IDM_PASTE: if ( !lpImage ) break; case IDM_PASTEASNEW: if ( !OpenClipboard(hWndAstral) ) { Message( IDS_ECLIPOPEN ); break; } if ( !IsClipboardFormatAvailable(CF_DIB) && !IsClipboardFormatAvailable(CF_BITMAP) && !IsClipboardFormatAvailable(Control.cfImage) ) { Message( IDS_ECLIPOPEN ); CloseClipboard(); break; } CloseClipboard(); DeactivateTool(); // First put clipboard contents into a file(s) AstralCursor(IDC_WAIT); if ( !PasteFromClipboard( hWindow, (wID == IDM_PASTE) /*fNeedMask*/ ) ) { AstralCursor(NULL); Message(IDS_EMEMALLOC); break; } if ( wID == IDM_PASTE ) { ProgressBegin(1, IDS_PROGPASTECLIP); TransformObjectsStart( YES/*fNewObject*/ ); if ( ImgCreateClipInObject( lpImage, NO ) ) ; ProgressEnd(); } else if ( wID == IDM_PASTEASNEW ) { if ( lpFrame = AstralFrameLoad( Names.PasteImageFile, -1, &idDataType, &idFileType) ) { if ( NewImageWindow( NULL, // lpOldFrame NULL, // Name lpFrame, // lpNewFrame idFileType, // lpImage->FileType idDataType, // lpImage->DataType FALSE, // New view? IMG_DOCUMENT, // lpImage->DocumentType NULL, // lpImage->ImageName MAYBE ) ) lpImage->fChanged = YES; } } break; case IDM_ESCAPE: if (!lpImage) break; if (lpImage->hWnd == hZoomWindow) break; if ( Tool.bActive && Tool.lpToolProc ) DestroyProc( lpImage->hWnd, 1L ); break; case IDM_SIZEUP: case IDM_SIZEDOWN: if (!Retouch.hBrush) break; SetFocus( hWindow ); // Take focus away from any controls if ( Retouch.BrushShape == IDC_BRUSHCUSTOM ) break; if ( wID == IDM_SIZEUP ) { if( bHexBrush && ( Retouch.BrushSize % 2 == 0 ) && ( Retouch.BrushSize > 6 )) Retouch.BrushSize += 2; else Retouch.BrushSize++; } else { if( bHexBrush && ( Retouch.BrushSize % 2 == 0 ) && ( Retouch.BrushSize > 6 )) Retouch.BrushSize -= 2; else Retouch.BrushSize--; } if ( Retouch.BrushSize < 1 || Retouch.BrushSize > MAX_BRUSH_SIZE ) { Retouch.BrushSize = bound( Retouch.BrushSize, 1,MAX_BRUSH_SIZE); MessageBeep(0); break; } if (lpImage) DisplayBrush(0, 0, 0, OFF); SetMgxBrushSize(Retouch.hBrush, Retouch.BrushSize); if (lpImage && Window.hCursor == Window.hNullCursor) DisplayBrush(lpImage->hWnd, 32767, 32767, ON); if ( Tool.hRibbon ) SetSlide( Tool.hRibbon, IDC_BRUSHSIZE, Retouch.BrushSize ); break; case IDM_SHAPEUP: case IDM_SHAPEDOWN: if (!Retouch.hBrush) break; SetFocus( hWindow ); // Take focus away from any controls NewShape = Retouch.BrushShape; if ( wID == IDM_SHAPEUP ) NewShape++; else NewShape--; if ( NewShape > IDC_BRUSHCUSTOM ) NewShape = IDC_BRUSHCIRCLE; if ( NewShape < IDC_BRUSHCIRCLE ) NewShape = IDC_BRUSHCUSTOM; if (lpImage) DisplayBrush(0, 0, 0, OFF); if (!SetMgxBrushShape(Retouch.hBrush, NewShape, Names.CustomBrush)) { NewShape = IDC_BRUSHCIRCLE; SetMgxBrushShape(Retouch.hBrush, NewShape, Names.CustomBrush); } Retouch.BrushShape = NewShape; if (lpImage && Window.hCursor == Window.hNullCursor) DisplayBrush(lpImage->hWnd, 32767, 32767, ON); if ( Tool.hRibbon ) { CheckComboItem( Tool.hRibbon, IDC_BRUSHSHAPE, IDC_BRUSHCIRCLE, IDC_BRUSHCUSTOMNEW, Retouch.BrushShape ); SendMessage( Tool.hRibbon, WM_CONTROLENABLE, 0, 0L ); } break; case IDM_MOVEUP: case IDM_MOVEDOWN: case IDM_MOVELEFT: case IDM_MOVERIGHT: if (!lpImage) break; lpBase = ImgGetBase(lpImage); if (ImgGetSelObject(lpImage, NULL) == lpBase) break; dx = dy = 0; if (wID == IDM_MOVEUP) --dy; if (wID == IDM_MOVEDOWN) ++dy; if (wID == IDM_MOVELEFT) --dx; if (wID == IDM_MOVERIGHT) ++dx; lpObject = NULL; while (lpObject = ImgGetSelObject(lpImage, lpObject)) { rect = lpObject->rObject; OffsetRect(&rect, dx, dy); if (!AstralIntersectRect(&rTemp, &lpBase->rObject, &rect)) break; } if (lpObject) break; AstralSetRectEmpty(&rAll); lpObject = NULL; while (lpObject = ImgGetSelObject(lpImage, lpObject)) { rect = lpObject->rObject; OffsetRect(&lpObject->rObject, dx, dy); AstralUnionRect(&rAll, &rAll, &lpObject->rObject); if (!lpObject->Pixmap.fNewFrame && EqualRect(&rect, &lpObject->rUndoObject)) lpObject->rUndoObject = lpObject->rObject; UpdateImage(&rect, TRUE); UpdateImage(&lpObject->rObject, TRUE); } if (wID == IDM_MOVEUP) { x = (rAll.left + rAll.right)/2; y = rAll.top; } else if (wID == IDM_MOVEDOWN) { x = (rAll.left + rAll.right)/2; y = rAll.bottom; } else if (wID == IDM_MOVELEFT) { x = rAll.left; y = (rAll.top + rAll.bottom)/2; } else if (wID == IDM_MOVERIGHT) { x = rAll.right; y = (rAll.top + rAll.bottom)/2; } File2Display(&x, &y); AutoScroll(lpImage->hWnd, x, y); AstralUpdateWindow(lpImage->hWnd); DisplayInfo(-1, &rAll); break; case IDM_LASTTOOL: DeactivateTool(); if ( Tool.idLast && (hWnd = AstralDlgGet(IDD_MAIN)) ) SendMessage( hWnd, WM_COMMAND, Tool.idLast, 2L); break; case IDM_PREF: // prevent problems if running animations and they change // the wave mix dll setting in preferences StopAnimation(); AstralDlg( NO|2, hInstAstral, hWindow, IDD_PREF, DlgPrefProc ); break; case IDC_VIEWLAST: // duplicate of function in the view ribbon if ( !lpImage ) break; RevertLastView(); break; // case IDC_VIEWFULL: // duplicate of function in the view ribbon // if ( !lpImage ) // break; // AstralDlg( NO, hInstAstral, hWindow, IDD_VIEWFULL, DlgFullScreenViewProc ); // break; case IDC_VIEWALL: // duplicate of function in the view ribbon if ( !lpImage ) break; ViewAll(); break; case IDC_ZOOMIN: // duplicate of function in the view ribbon if ( !lpImage ) break; if (!lpImage->lpDisplay) break; if (!lpImage->lpDisplay->ViewPercentage) break; x = ( lpImage->lpDisplay->FileRect.left + lpImage->lpDisplay->FileRect.right ) / 2; y = ( lpImage->lpDisplay->FileRect.top + lpImage->lpDisplay->FileRect.bottom ) / 2; SaveLastView(); Zoom(x,y, +100, YES, ( View.ZoomWindow ^ CONTROL ) ); break; case IDC_ZOOMOUT: // duplicate of function in the view ribbon if ( !lpImage ) break; if (!lpImage->lpDisplay) break; if (!lpImage->lpDisplay->ViewPercentage) break; x = ( lpImage->lpDisplay->FileRect.left + lpImage->lpDisplay->FileRect.right ) / 2; y = ( lpImage->lpDisplay->FileRect.top + lpImage->lpDisplay->FileRect.bottom ) / 2; SaveLastView(); Zoom(x,y, -100, YES,( View.ZoomWindow ^ CONTROL ) ); break; case IDM_HELP: Control.Hints = !Control.Hints; PutDefInt (Control.Hints,Control.Hints); break; default: return( FALSE ); } return( TRUE ); }