#include <opliveeffects.h>
Inheritance diagram for OpLiveEffect:
Public Member Functions | |
OpLiveEffect () | |
Constructor. | |
~OpLiveEffect () | |
Destructor. | |
virtual void | Do (OpDescriptor *pOpDesc) |
virtual void | DoWithParam (OpDescriptor *pOpDesc, OpParam *pOpParam) |
ListRange * | GetLiveEffectList () |
virtual void | DoEndEdit (BOOL bChangingSelection=FALSE, BOOL bBroadcast=TRUE, BOOL bCancelled=FALSE, BOOL bEmpty=FALSE) |
BOOL | GetPreviewQuality () const |
void | SetPreviewQuality (BOOL bNew) |
Protected Member Functions | |
ListRange * | DoApplyLiveEffect (Range *pSel, String_256 strEffectID, String_64 strDisplayName, double dResolution, IXMLDOMDocumentPtr pEditsList=NULL, BOOL bMakeLocked=FALSE, BOOL bDetectDirectBitmaps=FALSE) |
virtual ListRange * | DoApplyLockedEffect (Range *pSel, String_256 strEffectID, String_64 strDisplayName, double dResolution, IXMLDOMDocumentPtr pEditsList=NULL, BOOL bDetectDirectBitmaps=FALSE) |
BOOL | EnsureLiveEffectOriginalBitmaps () |
Ensure that all NodeBitmapEffects in the current selection have original bitmaps ready and wait for us to pick up. | |
BOOL | GenerateBitmap (NodeBitmapEffect *pBitmapEffect, double dResolution, LPBITMAPINFO *ppInfo, LPBYTE *ppBits, DocRect *prectBounds) |
BOOL | SetChanged (BOOL bNewState) |
BOOL | HasChanged () |
Detect whether any of the LiveEffect nodes created/edited by this operation have actually been changed/do anything useful... | |
BOOL | IsTopOfStack (EffectsStack *pPPStack, INT32 iStackPos) |
virtual BOOL | DoEffectOp (ListRange *pLevelRange, OpLiveEffectParam *pLEOpParam) |
virtual BOOL | AllowEmptySelection () const |
virtual BOOL | CheckEffectOpParam (OpLiveEffectParam *pLEOpParam) |
virtual BOOL | DoEffectRangeOp (UINT32 idsProgress, Range *pLevel, OpLiveEffectParam *pParam) |
virtual BOOL | DoEffectNodeOp (NodeEffect *pEffect, OpLiveEffectParam *pParam, NodeBitmapEffect **ppNewEffect) |
Protected Attributes | |
ListRange * | m_pLERange |
BOOL | m_bAppliedNewEffects |
String_256 | m_strEffectID |
INT32 | m_iStackPos |
BOOL | m_bPreviewQuality |
Private Member Functions | |
CC_DECLARE_DYNCREATE (OpLiveEffect) | |
Static Private Member Functions | |
static BOOL | Init () |
static BOOL | UpdateCurrentEditor () |
Reset the current Op to refer to the new PPStack and tell the running XPE edit that things are changing. | |
static BOOL | DoCopyPPStackToSelection (UndoableOperation *pOp, EffectsStack *pPPStack, Document *pSrcDoc, Document *pDestDoc) |
Copy the specified LiveEffect stack onto the selection Used by Paste Attributes. | |
static BOOL | DoLocaliseLiveEffects (UndoableOperation *pOp, Node *pNode) |
Copy the specified LiveEffect stack onto the selection Used by Paste Attributes. | |
static BOOL | DoLocaliseEffectAttrs (UndoableOperation *pOp, Node *pNode) |
Copy the Effect attributes from the specified node down to lower nodes, remaining effect attrs where possible but becoming normal attrs if that's not possible Used by ungroup. | |
static BOOL | DoCopyEffectAttr (UndoableOperation *pOp, NodeAttribute *pAttr, Node *pNode) |
Copy the Effect attributes from the specified node down to lower nodes, remaining effect attrs where possible but becoming normal attrs if that's not possible Used by ungroup. | |
static Node * | DoDeleteAllPostProcessors (UndoableOperation *pOp, NodeRenderableInk *pNode, BOOL bDeleteOldControllers=FALSE, BOOL bDeleteBelowLocked=FALSE) |
static BOOL | DoDeletePostProcessor (UndoableOperation *pOp, Range *pRange) |
static BOOL | DoDeletePostProcessor (UndoableOperation *pOp, NodeEffect *pLE, BOOL bMoveEffectAttrs=FALSE) |
static ListRange * | DoApplyFeatherEffect (UndoableOperation *pOp, Range *pSel, String_256 strEffectID, String_64 strDisplayName, MILLIPOINT FeatherSize, CProfileBiasGain Profile) |
static NodeFeatherEffect * | DoApplyFeatherEffectNode (UndoableOperation *pOp, Node *pSel, String_256 strEffectID, String_64 strDisplayName, MILLIPOINT FeatherSize, CProfileBiasGain Profile) |
static BOOL | DoCopyEffectsStack (UndoableOperation *pOp, Node *pDestNode, ListRange *pEffectsStack, Document *pSrcDoc, Document *pDestDoc) |
Copy the specified LiveEffect stack onto the selection Used by Paste Attributes and OpCombineShapes. | |
static NodeBitmapEffect * | DoApplyLiveEffect (UndoableOperation *pOp, Node *pNode, String_256 strEffectID, String_64 strDisplayName, double dResolution, IXMLDOMDocumentPtr pEditsList=NULL, BOOL bMakeLocked=FALSE) |
static BOOL | DoCopyAttributes (UndoableOperation *pOp, Node *pSrcNode, Node *pDestNode, BOOL bEffectsOnly, Document *pSrcDoc, Document *pDestDoc) |
Copy the specified LiveEffect stack onto the selection Used by Paste Attributes Assumes that only simple attributes will be copied in simple situations I.e. attrs that aren't optimsed so much. |
Definition at line 229 of file opliveeffects.h.
|
Constructor.
Definition at line 168 of file opliveeffects.cpp. 00169 { 00170 m_pLERange=NULL; 00171 m_bAppliedNewEffects = FALSE; 00172 m_iStackPos = 0; 00173 m_bPreviewQuality = FALSE; 00174 }
|
|
Destructor.
Definition at line 189 of file opliveeffects.cpp. 00190 { 00191 if (m_pLERange) 00192 { 00193 delete m_pLERange; 00194 m_pLERange = NULL; 00195 } 00196 }
|
|
Reimplemented in OpEditLiveEffect. Definition at line 307 of file opliveeffects.h. 00307 { return FALSE; }
|
|
|
|
Reimplemented in OpDeleteAllLiveEffect, and OpEffectLockAll. Definition at line 2615 of file opliveeffects.cpp. 02616 { 02617 if (pLEOpParam->StackPosition==-1) 02618 { 02619 ERROR3("OpLiveEffect must be given a valid position in the LiveEffects Stack"); 02620 return FALSE; 02621 } 02622 02623 // ERROR3IF(pLEOpParam->pPPStack==NULL, "Can't find EffectsStack"); 02624 if (pLEOpParam->pPPStack==NULL) 02625 return FALSE; 02626 02627 return TRUE; 02628 }
|
|
Reimplemented from Operation. Definition at line 2464 of file opliveeffects.cpp. 02465 { 02466 // ERROR3("Why are you doing this? You need params, boy, params!"); 02467 DoWithParam(pOpDesc, NULL); 02468 }
|
|
Definition at line 585 of file opliveeffects.cpp. 00591 { 00592 ENSURE(pSel, "DoApplyFeatherEffect not given a useful range"); 00593 ENSURE(strEffectID!=String(""), "DoApplyFeatherEffect given blank effect name string"); 00594 00595 ListRange* pLERange = new ListRange(); 00596 ENSURE(pLERange, "DoApplyEffect can't create a ListRange"); 00597 if (pLERange==NULL) 00598 return NULL; 00599 00600 Node* pNode = pSel->FindFirst(); 00601 BOOL bOK = TRUE; 00602 while (pNode && bOK) 00603 { 00604 NodeFeatherEffect* pEffect = DoApplyFeatherEffectNode(pOp, pNode, strEffectID, strDisplayName, FeatherSize, Profile); 00605 if (pEffect) 00606 { 00607 pLERange->AddNode(pEffect); 00608 00609 // Make sure the attributes are optimised correctly 00610 bOK = pOp->DoFactorOutCommonChildAttributes(pEffect); 00611 } 00612 else 00613 bOK = FALSE; 00614 00615 pNode = pSel->FindNext(pNode); 00616 } 00617 00618 if (pLERange->FindFirst()==NULL || bOK==FALSE) 00619 { 00620 // Don't let an empty list of LiveEffect nodes hang around 00621 delete pLERange; 00622 pLERange = NULL; 00623 } 00624 00625 return pLERange; 00626 }
|
|
Definition at line 650 of file opliveeffects.cpp. 00656 { 00657 ENSURE(pNode, "DoApplyFeatherEffectNode not given a useful node"); 00658 ENSURE(strEffectID!=String(""), "DoApplyFeatherEffectNode given blank effect name string"); 00659 00660 BOOL bSelectInside = pNode->IsSelected() || pNode->IsParentOfSelected(); 00661 00662 // create a new NodeLiveEffect, which we will shortly insert into the tree; 00663 // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong. 00664 NodeFeatherEffect* pBmpFXNode = NULL; 00665 ALLOC_WITH_FAIL(pBmpFXNode, new NodeFeatherEffect, pOp); 00666 if (pBmpFXNode == NULL) 00667 return NULL; 00668 00669 // put an action to hide the NodeClipViewController onto the undo action-list, 00670 // so that if the user presses undo then it will be hidden. 00671 pBmpFXNode->SetPostProcessorID(strEffectID); 00672 pBmpFXNode->SetDisplayName(strDisplayName); 00673 pBmpFXNode->m_FeatherSize = FeatherSize; 00674 pBmpFXNode->m_Profile = Profile; 00675 00676 HideNodeAction* pUndoHideNodeAction = NULL; 00677 ActionCode ac = HideNodeAction::Init(pOp, 00678 pOp->GetUndoActions(), 00679 pBmpFXNode, 00680 FALSE, // don't include subtree size 00681 (Action**)&pUndoHideNodeAction, 00682 FALSE); // don't tell subtree when undone 00683 if (ac == AC_FAIL) 00684 { 00685 delete pBmpFXNode; 00686 return NULL; 00687 } 00688 00689 // right! we've got our node, we've got our action - lets stick it in the tree 00690 // (at a position just next to the last node which will go in the group). 00691 pBmpFXNode->AttachNode(pNode, NEXT); 00692 00693 // Move the node below the newly inserted LiveEffect 00694 BOOL bOK = pOp->DoMoveNode(pNode, pBmpFXNode, FIRSTCHILD); 00695 if (!bOK) 00696 return NULL; 00697 00698 // Deselect the node and select the live effect instead 00699 ((NodeRenderable*)pNode)->DeSelect(FALSE); 00700 pBmpFXNode->Select(FALSE); 00701 00702 // Set the OpPersmission flags in the newly inserted node 00703 // Otherwise the tree scanner in UpdateChangedNodes won't go below this node 00704 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE); // ReplaceNode & RegenerateNode 00705 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, pOp); 00706 pBmpFXNode->AllowOp(&ObjChange); 00707 00708 return pBmpFXNode; 00709 }
|
|
Definition at line 365 of file opliveeffects.cpp. 00366 { 00367 ENSURE(pSel, "DoApplyLiveEffect not given a useful range"); 00368 ENSURE(strEffectID!=String(""), "DoApplyLiveEffect given blank effect name string"); 00369 00370 ListRange* pLERange = new ListRange(); 00371 ENSURE(pLERange, "DoApplyEffect can't create a ListRange"); 00372 if (pLERange==NULL) 00373 return NULL; 00374 00375 Node* pNode = pSel->FindFirst(); 00376 while (pNode) 00377 { 00378 // create a new NodeLiveEffect, which we will shortly insert into the tree; 00379 // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong. 00380 NodeBitmapEffect* pBmpFXNode = NULL; 00381 pBmpFXNode = DoApplyLiveEffect(this, pNode, strEffectID, strDisplayName, dResolution, pEditsList, bMakeLocked); 00382 00383 if (pBmpFXNode) 00384 { 00385 // If the node we're applying to can supply DirectBitmaps and we can accept them 00386 // Then change res to be "automatic" 00387 if (bDetectDirectBitmaps && 00388 pNode->IsAnObject() && 00389 ((NodeRenderableInk*)pNode)->CanSupplyDirectBitmap() && 00390 dResolution != 0 00391 ) 00392 { 00393 // Child node can supply a DirectBitmap so it would be better if we were in 00394 // "Automatic" mode. 00395 pBmpFXNode->SetPixelsPerInch(0); // Set "Automatic" 00396 00397 // We can only test EnableDirectCapture after we have set the res to automatic 00398 // Otherwise it may return FALSE because the stored res (dResolution) may not match that 00399 // of the DirectBitmap child. 00400 // If it fails, then reset resolution back to what was specified. 00401 if (!pBmpFXNode->EnableDirectCapture()) 00402 pBmpFXNode->SetPixelsPerInch(dResolution); 00403 } 00404 00405 // Deselect the node and select the live effect instead 00406 // TODO: Really? 00407 ((NodeRenderable*)pNode)->DeSelect(FALSE); 00408 pBmpFXNode->Select(FALSE); 00409 00410 pLERange->AddNode(pBmpFXNode); 00411 00412 // Make sure the attributes are optimised correctly 00413 BOOL ok = DoFactorOutCommonChildAttributes(pBmpFXNode); 00414 if (!ok) 00415 pBmpFXNode = NULL; 00416 } 00417 00418 if (!pBmpFXNode) 00419 { 00420 if (pLERange->FindFirst()==NULL) 00421 { 00422 // Don't let an empty list of LiveEffect nodes hang around 00423 delete pLERange; 00424 pLERange = NULL; 00425 } 00426 return pLERange; 00427 } 00428 00429 pNode = pSel->FindNext(pNode); 00430 } 00431 00432 if (pLERange->FindFirst()==NULL) 00433 { 00434 // Don't let an empty list of LiveEffect nodes hang around 00435 delete pLERange; 00436 pLERange = NULL; 00437 } 00438 00439 return pLERange; 00440 }
|
|
Definition at line 469 of file opliveeffects.cpp. 00476 { 00477 ERROR2IF(pOp==NULL, NULL, "Missing Op pointer"); 00478 ERROR2IF(pNode==NULL, NULL, "Missing Node pointer"); 00479 ERROR2IF(strEffectID==String(""), NULL, "DoApplyLiveEffect given blank effect name string"); 00480 ERROR2IF(strDisplayName==String(""), NULL, "DoApplyLiveEffect given blank display name string"); 00481 00482 BOOL bSelectInside = pNode->IsSelected() || pNode->IsParentOfSelected(); 00483 00484 // Possible solution to issue of Bitmap with Feather attr under DirectBitmap effects 00485 // Detect that state, delete the feather attr, apply a feather effect with the same values 00486 //pNode = ApplyDirectFeatherBodge(pNode); 00487 00488 // create a new NodeLiveEffect, which we will shortly insert into the tree; 00489 // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong. 00490 NodeBitmapEffect* pBmpFXNode = NULL; 00491 if (bMakeLocked) 00492 { 00493 ALLOC_WITH_FAIL(pBmpFXNode, new NodeLockedEffect, pOp); 00494 } 00495 else 00496 { 00497 ALLOC_WITH_FAIL(pBmpFXNode, new NodeLiveEffect, pOp); 00498 } 00499 if (pBmpFXNode==NULL) 00500 return NULL; 00501 00502 // Get details from XPE so that displayname gets translated into 00503 // locale language if not already 00504 BOOL bDestructive = FALSE; 00505 XPEHost::GetEffectDetails(strEffectID, &strDisplayName, &bDestructive); 00506 ERROR3IF(bDestructive, "DoApplyLiveEffect asked to apply destructive effect!!!"); 00507 if (bDestructive) 00508 return NULL; 00509 00510 // Set effect params 00511 pBmpFXNode->SetPostProcessorID(strEffectID); 00512 pBmpFXNode->SetDisplayName(strDisplayName); 00513 pBmpFXNode->SetPixelsPerInch(dResolution); 00514 if (pEditsList) 00515 { 00516 pBmpFXNode->SetEditList(pEditsList); 00517 } 00518 else if (!pBmpFXNode->SetDefaultEditList()) 00519 { 00520 return NULL; 00521 } 00522 00523 if (pBmpFXNode->IsLockedEffect()) 00524 ((NodeLockedEffect*)pBmpFXNode)->SetLockPermanence(bDestructive); 00525 00526 // put an action to hide the NodeLiveEffect onto the undo action-list, 00527 // so that if the user presses undo then it will be hidden. 00528 HideNodeAction* pUndoHideNodeAction = NULL; 00529 ActionCode ac = HideNodeAction::Init(pOp, 00530 pOp->GetUndoActionList(), 00531 pBmpFXNode, 00532 FALSE, // don't include subtree size 00533 (Action**)&pUndoHideNodeAction, 00534 FALSE); // don't tell subtree when undone 00535 if (ac == AC_FAIL) 00536 return NULL; 00537 00538 // right! we've got our node, we've got our action - lets stick it in the tree 00539 // (at a position just next to the last node which will go in the group). 00540 pBmpFXNode->AttachNode(pNode, NEXT); 00541 00542 // Move the node below the newly inserted LiveEffect 00543 BOOL ok = pOp->DoMoveNode(pNode, pBmpFXNode, FIRSTCHILD); 00544 if (!ok) 00545 return NULL; 00546 00547 // Set the OpPersmission flags in the newly inserted node 00548 // Otherwise the tree scanner in UpdateChangedNodes won't go below this node 00549 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE); // ReplaceNode & RegenerateNode 00550 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, pOp); 00551 pBmpFXNode->AllowOp(&ObjChange); 00552 00553 // Deselect the node and select the live effect instead 00554 // TODO: Really? 00555 // ((NodeRenderable*)pNode)->DeSelect(FALSE); 00556 // pBmpFXNode->Select(FALSE); 00557 00558 return pBmpFXNode; 00559 }
|
|
Definition at line 737 of file opliveeffects.cpp. 00743 { 00744 ENSURE(pSel, "DoApplyLockedEffect not given a useful range"); 00745 ENSURE(strEffectID!=String(""), "DoApplyLockedEffect given blank effect name string"); 00746 00747 ListRange* pLERange = new ListRange(); 00748 ENSURE(pLERange, "DoApplyEffect can't create a ListRange"); 00749 if (pLERange==NULL) 00750 return NULL; 00751 00752 // we need to insert the controller node at the position of the highest 00753 // selected node in the z-order, ie last in the selection, so find it. 00754 Node* pFirstNode = pSel->FindFirst(); 00755 Node* pNode = pFirstNode; 00756 Node* pLastNode = NULL; 00757 while (pNode != NULL) 00758 { 00759 pLastNode = pNode; 00760 pNode = pSel->FindNext(pLastNode); 00761 } // loop terminates with pNode == NULL, pLastNode == last-node-in-sel. 00762 00763 // create a new NodeClipViewController, which we will shortly insert into the tree; 00764 // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong. 00765 NodeLockedEffect* pBmpFXNode = NULL; 00766 ALLOC_WITH_FAIL(pBmpFXNode, new NodeLockedEffect, this); 00767 BOOL ok = (pBmpFXNode != NULL); 00768 00769 if (ok) 00770 { 00771 // Get details from XPE so that displayname gets translated into 00772 // locale language if not already and destructive state is updated 00773 // for the current machine (shouldn't really change, though) 00774 BOOL bDestructive = TRUE; 00775 XPEHost::GetEffectDetails(strEffectID, &strDisplayName, &bDestructive); 00776 00777 pBmpFXNode->SetPostProcessorID(strEffectID); 00778 pBmpFXNode->SetDisplayName(strDisplayName); 00779 pBmpFXNode->SetPixelsPerInch(dResolution); 00780 if (pEditsList) 00781 { 00782 pBmpFXNode->SetEditList(pEditsList); 00783 } 00784 else if (!pBmpFXNode->SetDefaultEditList()) 00785 { 00786 delete pBmpFXNode; 00787 00788 // Don't let an empty list of LiveEffect nodes hang around 00789 delete pLERange; 00790 pLERange = NULL; 00791 return pLERange; 00792 } 00793 pBmpFXNode->SetLockPermanence(bDestructive); 00794 00795 // put an action to hide the NodeClipViewController onto the undo action-list, 00796 // so that if the user presses undo then it will be hidden. 00797 HideNodeAction* pUndoHideNodeAction = NULL; 00798 ActionCode ac = HideNodeAction::Init(this, 00799 &UndoActions, 00800 pBmpFXNode, 00801 FALSE, // don't include subtree size 00802 (Action**)&pUndoHideNodeAction, 00803 FALSE); // don't tell subtree when undone 00804 if (ac == AC_FAIL) 00805 { 00806 delete pBmpFXNode; 00807 00808 // Don't let an empty list of LiveEffect nodes hang around 00809 delete pLERange; 00810 pLERange = NULL; 00811 return pLERange; 00812 } 00813 else 00814 { 00815 // right! we've got our node, we've got our action - lets stick it in the tree 00816 // (at a position just next to the last node which will go in the group). 00817 pBmpFXNode->AttachNode(pLastNode, NEXT); 00818 pLERange->AddNode(pBmpFXNode); 00819 } 00820 } 00821 00822 // move each item from the selection into our ClipView group, 00823 // remembering to deselect them as we go. 00824 // TODO: 00825 // sneaky suspicion I should be putting this in a Do fn in UndoableOperation... 00826 if (ok) 00827 { 00828 pNode = pSel->FindNext(pFirstNode); // the node we're moving now. 00829 00830 // if (pFirstNode->IsAnObject()) 00831 // ok = DoLocaliseCommonAttributes((NodeRenderableInk*)pFirstNode); 00832 00833 ok = DoMoveNode(pFirstNode, pBmpFXNode, FIRSTCHILD); 00834 if (ok) 00835 ((NodeRenderable*)pFirstNode)->DeSelect(FALSE, TRUE); 00836 } 00837 00838 Node* pNextNode = NULL; // the next node to move. 00839 Node* pAnchorNode = pFirstNode; // the node we've just moved. 00840 while (ok && pNode != NULL) 00841 { 00842 // get the next node to move. 00843 pNextNode = pSel->FindNext(pNode); 00844 00845 // now move the current node next to the anchor and deselect it. 00846 // if (pNode->IsAnObject()) 00847 // ok = DoLocaliseCommonAttributes((NodeRenderableInk*)pNode); 00848 00849 ok = DoMoveNode(pNode, pAnchorNode, NEXT); 00850 if (ok) 00851 ((NodeRenderable*)pNode)->DeSelect(FALSE, TRUE); 00852 00853 // get the new anchor node and the next node to move. 00854 pAnchorNode = pNode; 00855 pNode = pNextNode; 00856 } 00857 00858 // If we're applied to a single node and that node can supply DirectBitmaps and we can accept them 00859 // Then change res to be same as child node 00860 NodeRenderableInk* pInkNode = pBmpFXNode->GetInkNodeFromController(); 00861 if (bDetectDirectBitmaps && 00862 pInkNode && 00863 pInkNode->CanSupplyDirectBitmap() 00864 ) 00865 { 00866 // Child node can supply a DirectBitmap so it would be better if we had same resolution 00867 // as the child node... 00868 double dDirectRes = 0; 00869 pInkNode->GetDirectBitmap(NULL, NULL, NULL, NULL, NULL, &dDirectRes); 00870 if (dDirectRes!=0) 00871 { 00872 pBmpFXNode->SetPixelsPerInch(dDirectRes); // Set res 00873 00874 // We can only test EnableDirectCapture after we have set the res correctly 00875 // Otherwise it may return FALSE because the stored res (dResolution) may not match that 00876 // of the DirectBitmap child. 00877 // If it fails, then reset resolution back to what was specified. 00878 if (!pBmpFXNode->EnableDirectCapture()) 00879 pBmpFXNode->SetPixelsPerInch(dResolution); 00880 } 00881 } 00882 00883 if (ok) 00884 { 00885 // select the new destructive effect, but don't draw any blobs yet. 00886 pBmpFXNode->Select(FALSE); 00887 00888 // factor out any common attributes. 00889 DoFactorOutCommonChildAttributes(pBmpFXNode); 00890 00891 // Set the OpPersmission flags in the newly inserted node 00892 // Otherwise the tree scanner in UpdateChangedNodes won't go below this node 00893 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE); // ReplaceNode & RegenerateNode 00894 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, this); 00895 pBmpFXNode->AllowOp(&ObjChange); 00896 } 00897 00898 if (pLERange->FindFirst()==NULL) 00899 { 00900 // Don't let an empty list of LiveEffect nodes hang around 00901 delete pLERange; 00902 pLERange = NULL; 00903 } 00904 00905 return pLERange; 00906 }
|
|
Copy the specified LiveEffect stack onto the selection Used by Paste Attributes Assumes that only simple attributes will be copied in simple situations I.e. attrs that aren't optimsed so much.
Definition at line 1692 of file opliveeffects.cpp. 01693 { 01694 if (!pDestNode->IsBounded() || !pSrcNode->IsBounded()) 01695 return TRUE; 01696 01697 ((NodeRenderableBounded*)pDestNode)->InvalidateBoundingRect(); 01698 DocRect NodeBounds = ((NodeRenderableBounded*)pDestNode)->GetBoundingRect(TRUE); 01699 Node* pNode = pSrcNode->FindFirstChild(); 01700 while (pNode) 01701 { 01702 if (pNode->IsAnAttribute()) 01703 { 01704 NodeAttribute* pAttr = (NodeAttribute*)pNode; 01705 if (!bEffectsOnly || pAttr->IsEffectAttribute()) 01706 { 01707 if (pAttr->CanBeAppliedToObject()) 01708 { 01709 NodeAttribute* pAttrCopy = NULL; 01710 pAttr->NodeCopy((Node **)(&pAttrCopy)); 01711 01712 if (pAttrCopy->IsAFillAttr()) 01713 { 01714 // Set the bounds of the attribute. (Why is this wrong here?) 01715 ((AttrFillGeometry*)pAttrCopy)->SetBoundingRect(((NodeRenderableBounded*)pSrcNode)->GetBoundingRect()); 01716 01717 // I'm not sure if this is neccessary but Will does it when making an attribute 01718 // current. 01719 if (pAttrCopy->IsAFractalFill()) 01720 { 01721 // The attr, should always use the default DPI for fractals. 01722 ((AttrFillGeometry*)pAttrCopy)->SetFractalDPI(AttrFillGeometry::FractalDPI); 01723 } 01724 } 01725 01726 pAttrCopy->TransformToNewBounds(NodeBounds); 01727 pAttrCopy->AttachNode(pDestNode, LASTCHILD); 01728 pAttrCopy->LinkToGeometry(pDestNode); 01729 01730 if (pAttrCopy->IsAFillAttr()) 01731 { 01732 // Now the Attribute is in the tree, we need to tell the fill 01733 // attribute to check that it's control points are valid. 01734 // Unless the fill we transformed above, this will usually 01735 // involve the fill 'centring' itself within the bounds of its 01736 // parent. 01737 ((AttrFillGeometry*)pAttrCopy)->AttributeChanged(); 01738 } 01739 01740 // Inform all DocComponents in the destination doc that a copy is about to take place 01741 BOOL ok; 01742 CALL_WITH_FAIL((pDestDoc->StartComponentCopy()), pOp, ok) 01743 if (ok) 01744 { 01745 if (!pAttrCopy->CopyComponentData(pSrcDoc, pDestDoc)) 01746 { 01747 pDestDoc->AbortComponentCopy(); // Cancel all data which has been copied 01748 ok = FALSE; // stop what were doing 01749 } 01750 01751 if (ok) 01752 ok = pDestDoc->EndComponentCopy(); 01753 } 01754 01755 // Remove similar nodes in this level 01756 Node* pCurrent = pDestNode->FindFirstChild(); 01757 Node* pNext; 01758 CCRuntimeClass* pAttrType = pAttrCopy->GetAttributeType(); 01759 while (pCurrent) 01760 { 01761 pNext = pCurrent->FindNext(); 01762 // Determine if the Current node is to be hidden 01763 if (pCurrent!=pAttrCopy && pCurrent->IsKindOf(CC_RUNTIME_CLASS(NodeAttribute))) 01764 { 01765 { 01766 if (((NodeAttribute*)pCurrent)->GetAttributeType() == pAttrType) 01767 { 01768 pCurrent->CascadeDelete(); 01769 delete pCurrent; 01770 } 01771 } 01772 } 01773 pCurrent = pNext; 01774 } 01775 } 01776 } 01777 } 01778 01779 pNode = pNode->FindNext(); 01780 } 01781 01782 return TRUE; 01783 }
|
|
Copy the Effect attributes from the specified node down to lower nodes, remaining effect attrs where possible but becoming normal attrs if that's not possible Used by ungroup.
Definition at line 1969 of file opliveeffects.cpp. 01970 { 01971 Node* pChildNode = pNode->FindFirstChild(); 01972 while (pChildNode) 01973 { 01974 if (pChildNode->IsAnObject()) 01975 { 01976 NodeRenderableInk* pInkNode = (NodeRenderableInk*)pChildNode; 01977 if (pInkNode->IsValidEffectAttr(pAttr)) 01978 { 01979 NodeAttribute* pExistingAttr = pInkNode->FindAppliedAttribute(pAttr->GetRuntimeClass()); 01980 if (pExistingAttr==NULL || pExistingAttr->FindParent()!=pInkNode) 01981 { 01982 // We can copy our effect attr to pInkNode as an effect attr 01983 // Make a copy of this LiveEffect 01984 NodeAttribute* pCopyAttr = NULL; 01985 BOOL bOK = FALSE; 01986 CALL_WITH_FAIL(pCopyAttr = (NodeAttribute*)pAttr->SimpleCopy(), pOp, bOK); 01987 if (!bOK) return FALSE; // No room to take a copy of the node 01988 01989 // pOp->DoInsertNewNode(pCopyAttr, pInkNode, LASTCHILD, FALSE, FALSE, FALSE, FALSE); 01990 01991 // Create a hide node action to hide the node when we undo 01992 pCopyAttr->AttachNode(pInkNode, LASTCHILD); 01993 HideNodeAction* UndoHideNodeAction; 01994 if (HideNodeAction::Init(pOp, pOp->GetUndoActions(), pCopyAttr, TRUE, (Action**)(&UndoHideNodeAction)) 01995 == AC_FAIL) 01996 { 01997 pCopyAttr->CascadeDelete(); 01998 delete pCopyAttr; 01999 return FALSE; 02000 } 02001 } 02002 } 02003 else 02004 { 02005 NodeAttribute* pExistingAttr = pInkNode->FindAppliedAttribute(pAttr->GetRuntimeClass()); 02006 if (pExistingAttr==NULL || pExistingAttr->FindParent()!=pInkNode) 02007 { 02008 // We can copy our effect attrs to pInkNode as a normal attr 02009 NodeAttribute* pCopyAttr = NULL; 02010 BOOL bOK = FALSE; 02011 CALL_WITH_FAIL(pCopyAttr = (NodeAttribute*)pAttr->SimpleCopy(), pOp, bOK); 02012 if (!bOK) return FALSE; // No room to take a copy of the node 02013 02014 // pOp->DoInsertNewNode(pCopyAttr, pInkNode, FIRSTCHILD, FALSE, FALSE, FALSE, FALSE); 02015 02016 // Create a hide node action to hide the node when we undo 02017 pCopyAttr->AttachNode(pInkNode, FIRSTCHILD); 02018 HideNodeAction* UndoHideNodeAction; 02019 if (HideNodeAction::Init(pOp, pOp->GetUndoActions(), pCopyAttr, TRUE, (Action**)(&UndoHideNodeAction)) 02020 == AC_FAIL) 02021 { 02022 pCopyAttr->CascadeDelete(); 02023 delete pCopyAttr; 02024 return FALSE; 02025 } 02026 02027 // if (UndoHideNodeAction) 02028 // UndoHideNodeAction->DontPanic(); 02029 02030 // Remove any deeper attributes of the same type to make a consistent structure 02031 pOp->DoRemoveAttrTypeFromSubtree(pInkNode, pAttr->GetRuntimeClass(), pCopyAttr); 02032 } 02033 } 02034 } 02035 02036 pChildNode = pChildNode->FindNext(); 02037 } 02038 02039 return TRUE; 02040 }
|
|
Copy the specified LiveEffect stack onto the selection Used by Paste Attributes and OpCombineShapes.
Definition at line 1530 of file opliveeffects.cpp. 01531 { 01532 ERROR2IF(pOp==NULL, FALSE, "No Op given to DoCopyEffectsStack\n"); 01533 ERROR2IF(pEffectsStack==NULL || pEffectsStack->IsEmpty(), FALSE, "No stack/empty stack given to DoCopyEffectsStack\n"); 01534 ERROR2IF(pDestNode==NULL, FALSE, "No destination node given to DoCopyEffectsStack\n"); 01535 01536 //----------------------------------------------------------------------------- 01537 // Remove all current LiveEffects on the selection 01538 // 01539 if (pDestNode->IsAnObject() && !pDestNode->NeedsParent(pDestNode->FindParent())) 01540 pDestNode = DoDeleteAllPostProcessors(pOp, (NodeRenderableInk*)pDestNode, FALSE, TRUE); // TRUE means delete all effects in stack, even those below pDestNode 01541 01542 //----------------------------------------------------------------------------- 01543 // Apply new LiveEffects from the specified stack 01544 // 01545 BOOL bWasSelected = pDestNode->IsSelected() || pDestNode->IsParentOfSelected(); 01546 Node* pSelectNode = pDestNode; 01547 if (pDestNode->IsNodeRenderableClass()) 01548 ((NodeRenderable*)pDestNode)->DeSelect(FALSE, TRUE); 01549 01550 Node* pTopNode = pDestNode; 01551 01552 NodeEffect* pEffect = (NodeEffect*)pEffectsStack->FindFirst(); 01553 while (pEffect) 01554 { 01555 // Test for legacy effect special cases first 01556 // Shadow ------------------------------------------------------------- 01557 if (pEffect->IsAShadowController()) 01558 { 01559 if (pTopNode->NeedsParent(pTopNode->FindParent())) 01560 { 01561 if (pTopNode->IsAShadow()) 01562 { 01563 // TODO: Copy shadow properties here? 01564 } 01565 } 01566 else 01567 { 01568 NodeShadowController* pController = (NodeShadowController*)pEffect; 01569 01570 NodeShadowParam param(pController->GetShadowType(), 01571 pController->GetFloorShadowAngle(), 01572 pController->GetFloorShadowHeight(), 01573 pController->GetOffsetX(), 01574 pController->GetOffsetY(), 01575 pController->GetPenumbraWidth(), 01576 pController->GetShadow()->GetDarkness(), 01577 pController->GetWallShadowScale(), 01578 pController->GetGlowWidth(), 01579 pController->GetShadow()->GetBiasGain(), 01580 TRUE); 01581 param.strOpUnique = pEffect->GetPostProcessorID(); 01582 param.StackPosition = STACKPOS_INSERT_TOP; 01583 pTopNode = OpApplyShadow::DoApplyShadow(pOp, pTopNode, ¶m, FALSE); 01584 // BOOL ok = pOp->DoFactorOutCommonChildAttributes(pShadControl); 01585 if (pTopNode == NULL) 01586 { 01587 pOp->FailAndExecute(); 01588 return FALSE; 01589 } 01590 01591 // Copy attributes applied to Shadow node 01592 NodeShadow* pShadow = pController->GetShadow(); 01593 NodeShadow* pNewShadow = NULL; 01594 if (pTopNode->IsAShadowController()) 01595 pNewShadow = ((NodeShadowController*)pTopNode)->GetShadow(); 01596 ERROR3IF(pShadow==NULL || pNewShadow==NULL, "ShadowController doesn't seem to have a shadow"); 01597 if (pShadow && pNewShadow) 01598 { 01599 DoCopyAttributes(pOp, pShadow, pNewShadow, FALSE, pSrcDoc, pDestDoc); 01600 } 01601 01602 delete param.pPPStack; 01603 } 01604 } 01605 // Feather ----------------------------------------------------------------- 01606 else if (pEffect->IsFeatherEffect()) 01607 { 01608 NodeFeatherEffect* pFeather = (NodeFeatherEffect*)pEffect; 01609 String_64 strDisplayName; 01610 XPEHost::GetEffectDetails(pEffect->GetPostProcessorID(), &strDisplayName); 01611 pTopNode = DoApplyFeatherEffectNode(pOp, pTopNode, pEffect->GetPostProcessorID(), strDisplayName, pFeather->GetFeatherSize(), pFeather->GetProfile()); 01612 if (pTopNode == NULL) 01613 { 01614 pOp->FailAndExecute(); 01615 return FALSE; 01616 } 01617 } 01618 // LiveEffects ------------------------------------------------------------- 01619 else if (pEffect->IsBitmapEffect()) 01620 { 01621 if (pEffect->IsLockedEffect() && ((NodeLockedEffect*)pEffect)->CanBeUnlocked()) 01622 { 01623 String_64 strDisplayName; 01624 XPEHost::GetEffectDetails(pEffect->GetPostProcessorID(), &strDisplayName); 01625 pTopNode = DoApplyLiveEffect(pOp, pTopNode, pEffect->GetPostProcessorID(), strDisplayName, ((NodeBitmapEffect*)pEffect)->GetPixelsPerInchValue(), ((NodeBitmapEffect*)pEffect)->GetEditList(), TRUE); // MakeLocked 01626 if (pTopNode == NULL) 01627 { 01628 pOp->FailAndExecute(); 01629 return FALSE; 01630 } 01631 } 01632 else if (!pEffect->IsLockedEffect()) 01633 { 01634 String_64 strDisplayName; 01635 XPEHost::GetEffectDetails(pEffect->GetPostProcessorID(), &strDisplayName); 01636 pTopNode = DoApplyLiveEffect(pOp, pTopNode, pEffect->GetPostProcessorID(), strDisplayName, ((NodeBitmapEffect*)pEffect)->GetPixelsPerInchValue(), ((NodeBitmapEffect*)pEffect)->GetEditList(), FALSE); 01637 if (pTopNode == NULL) 01638 { 01639 pOp->FailAndExecute(); 01640 return FALSE; 01641 } 01642 } 01643 if (pTopNode->IsEffect() && ((NodeEffect*)pTopNode)->IsLockedEffect()) 01644 { 01645 // Don't allow anything to be selected inside a Locked effect! 01646 pSelectNode = pTopNode; 01647 } 01648 } 01649 01650 // Copy effect attributes that might be applied to this level 01651 if (pTopNode) 01652 { 01653 DoCopyAttributes(pOp, pEffect, pTopNode, TRUE, pSrcDoc, pDestDoc); 01654 } 01655 01656 // ---------------------------------------------------------------------- 01657 pEffect = (NodeEffect*)pEffectsStack->FindNext(pEffect); 01658 } 01659 01660 if (pSelectNode && bWasSelected && pSelectNode->IsNodeRenderableClass()) 01661 { 01662 ((NodeRenderable*)pSelectNode)->Select(FALSE); 01663 } 01664 01665 return TRUE; 01666 }
|
|
Copy the specified LiveEffect stack onto the selection Used by Paste Attributes.
Definition at line 1464 of file opliveeffects.cpp. 01465 { 01466 ERROR2IF(pPPStack==NULL || pPPStack->IsEmpty(), FALSE, "No stack/empty stack given to DoCopyPPStackToSelection\n"); 01467 01468 SelRange* pRange = GetApplication()->FindSelection(); 01469 ERROR2IF(pRange==NULL, FALSE, "Can't find SelRange\n"); 01470 01471 if (pPPStack==NULL) 01472 return TRUE; // That was easy! 01473 01474 // Convert the pPPStack into a simple ListRange for DoCopyEffectsStack 01475 ListRange EffectsStack; 01476 INT32 l = 0; 01477 PPStackLevel* pLevel = pPPStack->GetLevel(l); 01478 while (pLevel) 01479 { 01480 ERROR3IF(pLevel->pPPNode==NULL, "PPStack has a badly formed level in it"); 01481 01482 if (pLevel->pPPNode->CanBeUnlocked()) 01483 EffectsStack.AddNode(pLevel->pPPNode); 01484 01485 pLevel = pPPStack->GetLevel(++l); 01486 } 01487 01488 pOp->DoInvalidateNodesRegions(*pRange, TRUE, FALSE); 01489 01490 // Now loop through the selection 01491 if (!EffectsStack.IsEmpty()) 01492 { 01493 Node* pNode = pRange->FindFirst(); 01494 Node* pNextNode = NULL; 01495 while (pNode) 01496 { 01497 pNextNode = pRange->FindNext(pNode); 01498 01499 DoCopyEffectsStack(pOp, pNode, &EffectsStack, pSrcDoc, pDestDoc); 01500 01501 pNode = pNextNode; 01502 } 01503 } 01504 01505 pOp->DoInvalidateNodesRegions(*pRange, TRUE, FALSE); 01506 01507 return TRUE; 01508 }
|
|
Definition at line 2060 of file opliveeffects.cpp. 02061 { 02062 BOOL bOK = TRUE; 02063 02064 // First, find pointer to child node to be moved into place as the LiveEffects stack is deleted 02065 Node* pNewBaseNode = pNode; 02066 if (pNode->IsEffect()) 02067 { 02068 ENSURE(((NodeEffect*)pNode)->IsLockedEffect(), "Only destructive LiveEffects should be selectable"); 02069 // Find the first ink node that's a child of this LiveEffect 02070 if (bDeleteBelowLocked) 02071 { 02072 // Locked effects can have several children - GetInkNodeFC only returns non-NULL 02073 // when there is a single node below the locked effect 02074 if (((NodeEffect*)pNewBaseNode)->GetInkNodeFromController()==NULL) 02075 pNewBaseNode = pNewBaseNode->FindFirstChild(); 02076 else 02077 { 02078 Node* pChild = pNewBaseNode; 02079 while (pChild && pChild->IsEffect()) 02080 { 02081 pChild = ((NodeEffect*)pChild)->GetInkNodeFromController(); 02082 02083 if (pChild) 02084 pNewBaseNode = pChild; 02085 } 02086 } 02087 } 02088 } 02089 02090 Node* pHighestLE = NULL; 02091 Node* pEffectScanBase = NULL; 02092 02093 /* // [Phil, 22/08/2005] There must be a better way to arrange the following logic! 02094 // 02095 // Push common attributes down into the nodes we're going to retain 02096 Node* pAncestor = pChild->FindParent(); 02097 if (pAncestor && !pAncestor->IsAnObject()) 02098 pAncestor = NULL; 02099 if (pAncestor) 02100 { 02101 bOK = pOp->DoLocaliseCommonAttributes((NodeRenderableInk*)pAncestor, FALSE, TRUE); 02102 if (!bOK) return FALSE; 02103 } 02104 02105 // If there are old style controller nodes applied to the object before any effects 02106 // Then get rid of them... 02107 if (bDeleteOldControllers) 02108 { 02109 while (pAncestor && pAncestor->IsController() && !pAncestor->IsEffect()) 02110 { 02111 pHighestLE = pAncestor; 02112 pAncestor = pAncestor->FindParent(); 02113 } 02114 } 02115 else 02116 { 02117 // Move the BaseNode pointer above the old controllers that we are not deleting 02118 while (pAncestor && pAncestor->IsController() && !pAncestor->IsEffect()) 02119 { 02120 pNewBaseNode = pAncestor; 02121 pAncestor = pAncestor->FindParent(); 02122 } 02123 } 02124 02125 // Delete all LiveEffects from pChild upwards 02126 while (pAncestor && pAncestor->IsEffect()) 02127 { 02128 pHighestLE = pAncestor; 02129 pAncestor = pAncestor->FindParent(); 02130 } 02131 */ 02132 // ------------------------------------------------------------------ 02133 // Deal with old style controllers 02134 { 02135 Node* pAncestor = pNewBaseNode->FindParent(); 02136 Node* pHighestOldController = NULL; 02137 pEffectScanBase = pNewBaseNode; 02138 while (pAncestor && pAncestor->IsController() && !pAncestor->IsEffect()) 02139 { 02140 pHighestOldController = pAncestor; 02141 pAncestor = pAncestor->FindParent(); 02142 } 02143 02144 if (pHighestOldController) 02145 { 02146 if (bDeleteOldControllers) 02147 pEffectScanBase = pHighestOldController; // Leave base node pointer alone and tell scanner to start above the old controllers 02148 else 02149 { 02150 pEffectScanBase = pHighestOldController; // Tell scanner to start above the old controllers 02151 pNewBaseNode = pHighestOldController; // but Reset base node pointer to refer to it so we leave it in the tree 02152 } 02153 } 02154 } 02155 02156 // ------------------------------------------------------------------ 02157 // Find highest Effect above the base node 02158 { 02159 Node* pAncestor = pEffectScanBase->FindParent(); 02160 while (pAncestor && pAncestor->IsEffect()) 02161 { 02162 pHighestLE = pAncestor; 02163 pAncestor = pAncestor->FindParent(); 02164 } 02165 } 02166 02167 // ------------------------------------------------------------------ 02168 // Push common attributes down into the nodes we're going to retain (the base node) 02169 { 02170 Node* pAncestor = pNewBaseNode->FindParent(); 02171 if (pAncestor && pAncestor->IsAnObject()) 02172 { 02173 bOK = pOp->DoLocaliseCommonAttributes((NodeRenderableInk*)pAncestor, FALSE, TRUE); 02174 if (!bOK) return NULL; 02175 } 02176 } 02177 02178 // ------------------------------------------------------------------ 02179 // If we have found Effects above the selected node (then we can 02180 // get rid of them) 02181 if (pHighestLE) 02182 { 02183 // Loop around all the children of the LiveEffect moving them up 02184 // (but note that only Destructive effects can have multiple children...) 02185 // (Er, but note again that effect attributes can be left in the tree...) 02186 Node* pInsertNode = pHighestLE; 02187 Node* pNextChild = NULL; 02188 Node* pChild = pNewBaseNode; 02189 while (pChild) 02190 { 02191 pNextChild = pChild->FindNext(); // Find next child before we move it! 02192 02193 if (pChild->IsAnObject()) 02194 { 02195 // Only move pChild if it's not linked to the PostProcessor above it! 02196 // (Otherwise leave it in place so it gets hidden along with the PostPros) 02197 if (!((NodeRenderableInk*)pChild)->NeedsParent(pChild->FindParent())) // Controlled? 02198 { 02199 bOK = pOp->DoMoveNode(pChild, pInsertNode, NEXT); 02200 if (!bOK) return NULL; 02201 02202 ((NodeRenderableInk*)pChild)->Select(FALSE); 02203 02204 if (pChild->IsAnObject()) 02205 pOp->DoFactorOutCommonAttributes((NodeRenderableInk*)pChild); 02206 02207 pInsertNode = pChild; 02208 } 02209 } 02210 02211 pChild = (NodeRenderableInk*)pNextChild; 02212 } 02213 02214 // Now that all the children are moved outside all the LE nodes 02215 // we can delete all the LE nodes (by hiding the root node and thus 02216 // hiding the entire stack at one go!) 02217 if (pHighestLE->IsRenderable()) 02218 ((NodeRenderable*)pHighestLE)->DeSelect(FALSE); 02219 bOK = pOp->DoHideNode(pHighestLE, FALSE, NULL, FALSE); 02220 } 02221 02222 return pNewBaseNode; 02223 }
|
|
Definition at line 2284 of file opliveeffects.cpp. 02285 { 02286 BOOL ok = FALSE; 02287 02288 // We should have a decent list of LiveEffect nodes... 02289 ERROR2IF(pLE==NULL, FALSE, "DoDeletePostProcessor given NULL node"); 02290 02291 // Go through all the LiveEffects, move their children up to be siblings and then 02292 // "delete" the LiveEffect nodes by hiding them. 02293 // 02294 BOOL bSelected = pLE->IsSelected(); 02295 02296 pOp->DoLocaliseCommonAttributes(pLE); 02297 02298 // Loop around all the children of the LiveEffect moving them up 02299 // (but note that only Destructive effects can have multiple children...) 02300 // (Er, but note again that effect attributes can be left in the tree...) 02301 Node* pInsertNode = pLE; 02302 Node* pNextChild = NULL; 02303 Node* pParent = pLE->FindParent(); 02304 NodeEffect* pParentEffect = NULL; 02305 if (pParent && pParent->IsEffect()) 02306 pParentEffect = (NodeEffect*)pLE->FindParent(); 02307 NodeRenderableInk* pChild = (NodeRenderableInk*)pLE->FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk)); 02308 02309 while (pChild) 02310 { 02311 pNextChild = pChild->FindNext(); // Find next child before we move it! 02312 02313 if (pChild->IsAnObject()) 02314 { 02315 // Only move pChild if it's not linked to the PostProcessor above it! 02316 // (Otherwise leave it in place so it gets hidden along with the PostPros) 02317 if (!((NodeRenderableInk*)pChild)->NeedsParent(pChild->FindParent())) // Controlled? 02318 { 02319 pOp->DoMoveNode(pChild, pInsertNode, NEXT); 02320 if (bSelected) 02321 pChild->Select(FALSE); 02322 if (pChild->IsAnObject()) 02323 pOp->DoFactorOutCommonAttributes((NodeRenderableInk*)pChild); 02324 02325 pInsertNode = pChild; 02326 } 02327 } 02328 02329 if (bMoveEffectAttrs && pParentEffect && pChild->IsAnAttribute() && ((NodeAttribute*)pChild)->IsEffectAttribute()) 02330 { 02331 if (pParentEffect->IsValidEffectAttr((NodeAttribute*)pChild)) 02332 { 02333 pOp->DoMoveNode(pChild, pInsertNode, NEXT); 02334 pInsertNode = pChild; 02335 } 02336 } 02337 02338 pChild = (NodeRenderableInk*)pNextChild; 02339 } 02340 02341 pLE->ReleaseCached(TRUE, FALSE, FALSE, FALSE); 02342 if (bSelected) 02343 pLE->DeSelect(FALSE); 02344 pOp->DoHideNode(pLE, FALSE, NULL, FALSE); 02345 02346 return TRUE; 02347 }
|
|
Definition at line 2242 of file opliveeffects.cpp. 02243 { 02244 BOOL ok = FALSE; 02245 02246 // We should have a decent list of LiveEffect nodes... 02247 ERROR2IF(pRange==NULL, FALSE, "DoDeletePostProcessor given an empty range"); 02248 02249 // Go through all the LiveEffects, move their children up to be siblings and then 02250 // "delete" the LiveEffect nodes by hiding them. 02251 // 02252 Node* pNode = pRange->FindFirst(); 02253 while (pNode) 02254 { 02255 if (pNode->IsEffect()) 02256 { 02257 NodeEffect* pLE = (NodeEffect*)pNode; 02258 DoDeletePostProcessor(pOp, pLE); 02259 } 02260 02261 pNode = pRange->FindNext(pNode); 02262 } 02263 02264 return TRUE; 02265 }
|
|
Reimplemented in OpEffectRes, and OpEffectLock. Definition at line 310 of file opliveeffects.h.
|
|
Reimplemented in OpEditLiveEffect, OpDeleteLiveEffect, OpDeleteAllLiveEffect, OpEffectRes, OpEffectLock, and OpEffectLockAll. Definition at line 306 of file opliveeffects.h. 00306 { return TRUE; }
|
|
Definition at line 2366 of file opliveeffects.cpp. 02367 { 02368 BOOL ok = FALSE; 02369 Progress progress(idsProgress, pRange->Count(), FALSE); 02370 02371 // We should have a decent list of LiveEffect nodes... 02372 ERROR2IF(pRange==NULL, FALSE, "DoEffectRangeOp given an empty range"); 02373 02374 // Go through all the LiveEffects, move their children up to be siblings and then 02375 // "delete" the LiveEffect nodes by hiding them. 02376 // 02377 INT32 iCount = 0; 02378 INT32 iChanges = 0; 02379 Node* pNode = pRange->FindFirst(); 02380 while (pNode && progress.Update(iCount, TRUE) && !OpHasFailed()) 02381 { 02382 if (pNode->IsEffect()) 02383 { 02384 // -------------------------------------------- 02385 // This is the core of this function, 02386 // Call overridden specialist function to perform 02387 // the Op on this node alone 02388 NodeEffect* pLE = (NodeEffect*)pNode; 02389 NodeBitmapEffect* pNewEffect = NULL; 02390 BOOL bChanged = DoEffectNodeOp(pLE, pParam, &pNewEffect); 02391 // -------------------------------------------- 02392 02393 if (bChanged) 02394 { 02395 iChanges++; 02396 02397 // Invalidate the region we just changed 02398 // (Rely on DoEffectNodeop to have released the cache if it thinks it needs to 02399 if (!DoInvalidateNodeRegion(pNewEffect, TRUE, FALSE, FALSE, FALSE)) 02400 { 02401 FailAndExecute(); 02402 End(); 02403 return FALSE; 02404 } 02405 02406 // Update the view inside our progress indication so the user gets 02407 // better idea of where we are... 02408 DocView* pDocView = GetWorkingDocView(); 02409 if (pDocView) 02410 { 02411 // Update just the working view immediately 02412 pDocView->FlushRedraw(); 02413 GetApplication()->ServiceRendering(); 02414 } 02415 } 02416 } 02417 02418 iCount++; 02419 pNode = pRange->FindNext(pNode); 02420 } 02421 02422 // If we aborted with nodes remaining to be done 02423 // Then abort the whole Operation! 02424 if (pNode) 02425 { 02426 FailAndExecute(); 02427 End(); 02428 return FALSE; 02429 } 02430 02431 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE); 02432 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, cFlags, NULL, this); 02433 ok = UpdateChangedNodes(&ObjChange); 02434 02435 // If we didn't change anything then don't add this op to the undo history 02436 if (iChanges==0) 02437 { 02438 SucceedAndDiscard(); 02439 End(); 02440 return FALSE; 02441 } 02442 02443 End(); 02444 return FALSE; // We don't need any of the normal tidy up to occur 02445 }
|
|
Definition at line 1356 of file opliveeffects.cpp. 01357 { 01358 BOOL ok = FALSE; 01359 BOOL bRecache = FALSE; 01360 01361 // If the are no changes in any of the LiveEffect nodes as a result of this edit 01362 // And we only just created new LiveEffects in this Op 01363 // Then remove them from the tree because they are redundant 01364 if (bCancelled || (m_bAppliedNewEffects && (!HasChanged() || bEmpty))) 01365 { 01366 if (bChangingSelection) 01367 FailAndExecuteIgnoreSelActions(); 01368 else 01369 FailAndExecute(); 01370 // Tell the selrange that things have changed! 01371 GetApplication()->FindSelection()->Update(); 01372 End(); 01373 return; 01374 } 01375 01376 // If we were editing but we are told that the edit has resulted in a NULL effect 01377 // Then we can remove the effect to keep things neat and tidy 01378 if (bEmpty && !m_bAppliedNewEffects && m_pLERange!=NULL) 01379 { 01380 BOOL bOK = DoDeletePostProcessor(this, m_pLERange); 01381 if (!bOK) 01382 { 01383 FailAndExecute(); 01384 // Tell the selrange that things have changed! 01385 GetApplication()->FindSelection()->Update(); 01386 End(); 01387 return; 01388 } 01389 } 01390 01391 // We have finished with the range of edited nodes now so we should delete it 01392 // to reduce memory usage while this object sits on the undo/redo lists 01393 if (m_pLERange) 01394 { 01395 delete m_pLERange; 01396 m_pLERange = NULL; 01397 } 01398 01399 // Check whether XPE's state machine ended up in the correct state 01400 if (GetPreviewQuality()) 01401 { 01402 ERROR3("We would expect XPE to have ended with at least one non-preview bitmap!"); 01403 SetPreviewQuality(FALSE); 01404 bRecache = TRUE; 01405 } 01406 01407 Tool* pTool = Tool::GetCurrent(); 01408 01409 // Update the LiveEffect Tool's permanent status 01410 if (pTool->GetID()==TOOLID_LIVEEFFECT) 01411 { 01412 ((LiveEffectsTool*)pTool)->SetCurrentEffectID(m_strEffectID); 01413 ((LiveEffectsTool*)pTool)->SetCurrentStackPos(m_iStackPos); 01414 } 01415 01416 // render blobs off for tools which don't automatically redraw their blobs. 01417 Spread* pSpread = Document::GetSelectedSpread(); 01418 01419 // invalidate the (new) region bounding the selection. 01420 if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE, bRecache)) 01421 { 01422 End(); 01423 return; 01424 } 01425 01426 // render blobs back on if the current tool doesn't automatically redraw its blobs. 01427 if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) 01428 pTool->RenderToolBlobs(pSpread, NULL); 01429 01430 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE); 01431 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, cFlags, NULL, this); 01432 ok = UpdateChangedNodes(&ObjChange); 01433 01434 if (bBroadcast) 01435 { 01436 BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::EFFECTSTACKCHANGED)); 01437 } 01438 01439 // Tell the selrange that things have changed! 01440 GetApplication()->FindSelection()->Update(); 01441 01442 End(); 01443 }
|
|
Copy the Effect attributes from the specified node down to lower nodes, remaining effect attrs where possible but becoming normal attrs if that's not possible Used by ungroup.
Definition at line 1901 of file opliveeffects.cpp. 01902 { 01903 // From top of stack 01904 // find effect attr 01905 // Copy it down to children of specified node 01906 // If node can cope with effect attr 01907 // Then copy as effect attr 01908 // Else 01909 // If object already has that type of attr 01910 // Then do nothing 01911 // Else copy attribute into place and delete attrs in subtree 01912 01913 ListRange* pPPStack = EffectsStack::GetEffectsStackFromNode(pNode, FALSE, TRUE, TRUE); 01914 if (pPPStack) 01915 { 01916 Node* pEffectNode = pPPStack->FindLast(); 01917 while (pEffectNode) 01918 { 01919 NodeAttribute* pAttr = NodeAttribute::FindFirstAppliedAttr(pEffectNode); 01920 while (pAttr && pAttr->IsEffectAttribute() && pAttr->FindParent()==pEffectNode) 01921 { 01922 if (!pAttr->HasEquivalentDefaultValue(TRUE)) // Only copy attr if it doesn't look like the default 01923 DoCopyEffectAttr(pOp, pAttr, pNode); 01924 01925 pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr); 01926 } 01927 01928 pEffectNode = pPPStack->FindPrev(pEffectNode); 01929 } 01930 } 01931 01932 // Finally, do the same thing for the node itself... 01933 NodeAttribute* pAttr = NodeAttribute::FindFirstAppliedAttr(pNode); 01934 while (pAttr && pAttr->IsEffectAttribute() && pAttr->FindParent()==pNode) 01935 { 01936 if (!pAttr->HasEquivalentDefaultValue(TRUE)) // Only copy attr if it doesn't look like the default 01937 DoCopyEffectAttr(pOp, pAttr, pNode); 01938 01939 pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr); 01940 } 01941 01942 delete pPPStack; 01943 01944 return TRUE; 01945 }
|
|
Copy the specified LiveEffect stack onto the selection Used by Paste Attributes.
Definition at line 1803 of file opliveeffects.cpp. 01804 { 01805 ListRange* pPPStack = EffectsStack::GetEffectsStackFromNode(pNode, FALSE, TRUE, TRUE); 01806 if (pPPStack==NULL) 01807 return TRUE; 01808 01809 NodeRenderableInk* pChild = pNode->FindFirstChildInk(); 01810 while (pChild) 01811 { 01812 NodeRenderableInk* pNextChild = pChild->FindNextInk(); 01813 01814 // Don't localise into "controlled" nodes 01815 if (pChild->GetParentController()==NULL) 01816 { 01817 NodeRenderableInk* pInsertContext = pChild; 01818 NodeBitmapEffect* pLENode = (NodeBitmapEffect*)pPPStack->FindFirst(); 01819 ERROR2IF(!pLENode->CanBeUnlocked(), FALSE, "Can't localise Destructive effects"); 01820 while (pLENode) 01821 { 01822 // Make a copy of this LiveEffect 01823 NodeBitmapEffect* pCopy = NULL; 01824 BOOL bOK = FALSE; 01825 CALL_WITH_FAIL(pCopy = (NodeBitmapEffect*)pLENode->SimpleCopy(), pOp, bOK); 01826 if (!bOK) return FALSE; // No room to take a copy of the node 01827 01828 // Can't insert directly as parent because of restrictions with HiddenNode 01829 // So insert as sibling and then move context node into sibling 01830 bOK = pOp->DoInsertNewNode(pCopy, pInsertContext, NEXT, TRUE, FALSE, FALSE, FALSE); 01831 if (!bOK) return FALSE; 01832 01833 bOK = pOp->DoMoveNode(pInsertContext, pCopy, FIRSTCHILD); 01834 if (!bOK) return FALSE; 01835 01836 pInsertContext = pCopy; 01837 01838 // Copy any necessary children of the LiveEffect 01839 // This could be much more developed, possibly using a virtual function 01840 // on the node that's just been copied to copy it's necessary parts 01841 // or ComplexCopy 01842 // But this works well enough for now (NodeShadowControllers and NodeShadows) 01843 Node* pNode = pLENode->FindFirstChild(); 01844 AttachNodeDirection dir = FIRSTCHILD; 01845 while (pNode) 01846 { 01847 if (pNode->NeedsParent(pNode->FindParent()) && pNode->IsBounded()) 01848 { 01849 // Make a copy of this "Needed" node 01850 NodeRenderableBounded* pCopy = NULL; 01851 BOOL bOK = FALSE; 01852 CALL_WITH_FAIL(pNode->NodeCopy((Node**)&pCopy), pOp, bOK); // Copy node and subtree 01853 if (!bOK) return FALSE; // No room to take a copy of the node 01854 01855 bOK = pOp->DoInsertNewNode(pCopy, pInsertContext, dir, TRUE, FALSE, FALSE, FALSE); 01856 if (!bOK) return FALSE; 01857 } 01858 01859 pNode = pNode->FindNext(); 01860 } 01861 01862 pLENode = (NodeBitmapEffect*)pPPStack->FindNext(pLENode); 01863 } 01864 } 01865 01866 pChild = pNextChild; 01867 } 01868 01869 delete pPPStack; 01870 01871 //----------------------------------------------------------------------------- 01872 // Remove all current LiveEffects on the selection 01873 // 01874 if (pNode->IsAnObject()) 01875 return (OpLiveEffect::DoDeleteAllPostProcessors(pOp, (NodeRenderableInk*)pNode)!=NULL); 01876 else 01877 return TRUE; 01878 }
|
|
Reimplemented from Operation. Reimplemented in OpApplyLiveEffect, and OpApplyFeatherEffect. Definition at line 2487 of file opliveeffects.cpp. 02488 { 02489 BOOL ok = FALSE; 02490 02491 OpLiveEffectParam* pLEOpParam = NULL; 02492 if (pOpParam && pOpParam->IsKindOf(CC_RUNTIME_CLASS(OpLiveEffectParam))) 02493 pLEOpParam = (OpLiveEffectParam*) pOpParam; 02494 02495 if (!CheckEffectOpParam(pLEOpParam)) 02496 { 02497 End(); 02498 return; 02499 } 02500 02501 // Remember some details for later on when the Op ends successfully (?) 02502 if (pLEOpParam) 02503 { 02504 m_strEffectID = pLEOpParam->strOpUnique; 02505 m_iStackPos = pLEOpParam->StackPosition; 02506 } 02507 02508 // obtain the current selection. 02509 Range Sel(*(GetApplication()->FindSelection())); 02510 RangeControl rc = Sel.GetRangeControlFlags(); 02511 rc.PromoteToParent = TRUE; 02512 Sel.Range::SetRangeControl(rc); 02513 02514 if (!AllowEmptySelection() && Sel.FindFirst()==NULL) 02515 { 02516 End(); 02517 return; 02518 } 02519 02520 // render blobs off for tools which don't automatically redraw their blobs. 02521 Tool* pTool = Tool::GetCurrent(); 02522 Spread* pSpread = Document::GetSelectedSpread(); 02523 if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) 02524 pTool->RenderToolBlobs(pSpread, NULL); 02525 02526 // record the current selection state and if required, render off any selection blobs. 02527 if (!DoStartSelOp(FALSE, FALSE)) 02528 { 02529 End(); 02530 return; 02531 } 02532 02533 // Ask the range whether it's OK to do the transform... 02534 // Get an ObjChangeParam ready, so we can ask op permission from nodes. 02535 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE); // ReplaceNode & RegenerateNode 02536 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, this); 02537 BOOL bOK = Sel.AllowOp(&ObjChange); 02538 if (!bOK) 02539 { 02540 End(); 02541 return; 02542 } 02543 02544 // invalidate the region bounding the selection. 02545 if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE, FALSE)) 02546 { 02547 End(); 02548 return; 02549 } 02550 02551 // Get a list of the LiveEffects we will be working on 02552 ListRange* pLERange = NULL; 02553 if (pLEOpParam && pLEOpParam->pPPStack) 02554 { 02555 pLERange = pLEOpParam->pPPStack->GetLevelRange(&pLEOpParam->StackPosition); // We don't own the returned range 02556 // Make a local copy in case the original dies during selection processing 02557 if (pLERange) 02558 pLERange = new ListRange(pLERange); 02559 } 02560 m_bAppliedNewEffects = FALSE; 02561 02562 // ------------------------------------------------------------------- 02563 // Call virtual function of derived Ops to do the specialised function 02564 BOOL bEndNormally = DoEffectOp(pLERange, pLEOpParam); 02565 // ------------------------------------------------------------------- 02566 02567 if (pLERange) 02568 { 02569 delete pLERange; 02570 pLERange = NULL; 02571 } 02572 02573 if (bEndNormally) 02574 { 02575 // invalidate the (new) region bounding the selection. 02576 if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE, FALSE)) 02577 { 02578 End(); 02579 return; 02580 } 02581 02582 // render blobs back on if the current tool doesn't automatically redraw its blobs. 02583 if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) 02584 pTool->RenderToolBlobs(pSpread, NULL); 02585 02586 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE); 02587 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, cFlags, NULL, this); 02588 BOOL ok = UpdateChangedNodes(&ObjChange); 02589 02590 BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::EFFECTSTACKCHANGED)); 02591 02592 // Tell the selrange that things have changed! 02593 GetApplication()->FindSelection()->Update(); 02594 02595 End(); 02596 } 02597 }
|
|
Ensure that all NodeBitmapEffects in the current selection have original bitmaps ready and wait for us to pick up.
Definition at line 949 of file opliveeffects.cpp. 00950 { 00951 if (m_pLERange==NULL) 00952 return TRUE; 00953 00954 BOOL bRenderingNeeded = FALSE; 00955 DocView* pDocView = DocView::GetSelected(); 00956 00957 bRenderingNeeded = FALSE; 00958 Node* pNode = m_pLERange->FindFirst(); 00959 while (pNode) 00960 { 00961 ENSURE(pNode->IsBitmapEffect(), "LiveEffects list contains non-LiveEffect in EnsureLiveEffectOriginalBitmaps"); 00962 NodeBitmapEffect* pLE = (NodeBitmapEffect*)pNode; 00963 if (!pLE->GetOriginalBitmap(NULL, NULL, NULL) && pLE->CanGenerateBitmap()) 00964 { 00965 // We need to forcibly render this node to get its original 00966 // bitmap set up 00967 // 00968 // Version2 Bitmap Generation 00969 // 00970 // Grab bitmap without using on screen rendering 00971 // This is more efficient than rendering the whole tree and 00972 // allows parameters to be controlled independently from screen view 00973 // 00974 // Ideally: 00975 // Start a render into a RenderRegion 00976 // Don't allow the RenderRegion to grab bitmap of its own - NOT DONE 00977 // Don't allow the RenderRegion to blit captures into it's own bitmap - NOT DONE 00978 // Ensure only the effect and it's children are rendered - DONE! 00979 // Just let the effect rendering functions create their capture bitmap - DONE! 00980 00981 // Create a new GRenderDIB region 00982 // Most of the parameters here are immaterial because we are not really 00983 // interested in the results of the rendered region - just the capture 00984 pLE->ReleaseCached(TRUE, FALSE); // We will change so tell parents to uncache 00985 00986 // Bodge? Ensure that locked effects will render their children 00987 // because they don't respond to ReleaseCached... 00988 if (pLE->IsLockedEffect()) 00989 pLE->SetProcessedBitmap(NULL, NULL, DocRect(), 0, 0, 0, 0); 00990 00991 View* pView = View::GetCurrent(); 00992 Spread* pSpread = Document::GetSelectedSpread(); 00993 Matrix Mat = pView->ConstructScaledRenderingMatrix(pSpread, 1.0); 00994 FIXED16 Scale; 00995 Mat.Decompose(&Scale); 00996 double dpi = 0.0; // use screen dpi (ie PIXELS_PER_INCH) 00997 GRenderDIB* pNewGRR = new GRenderDIB(pLE->GetBoundingRect(), Mat, Scale, 32, dpi); 00998 ERROR2IF(pNewGRR == NULL, FALSE, "Failed to create a GRenderDIB!"); 00999 01000 // State flags + pixel width calculations 01001 if (!pNewGRR->AttachDevice(pView, NULL, pSpread)) // view and spread from previous RR rather than Current - nb in create bitmap copy case 01002 { 01003 ERROR3("Cannot attach devices"); 01004 01005 delete pNewGRR; 01006 pNewGRR = NULL; 01007 01008 return FALSE; 01009 } 01010 01011 pNewGRR->m_DoCompression = FALSE; 01012 pNewGRR->InitDevice(); 01013 pNewGRR->InitAttributes(); 01014 pNewGRR->SetLineAttributes(); 01015 pNewGRR->SetFillAttributes(); 01016 pNewGRR->SetBackmostChangedNode(pSpread); // Don't allow any cached 24BPP bitmaps to be used! 01017 01018 // NB following call gets GRendRegion to create the bitmap into which GDraw will render 01019 BOOL Started = pNewGRR->StartRender(); 01020 01021 if (Started) 01022 { 01023 // Setup attribute state outside this subtree 01024 CCAttrMap* pAttrMap = new CCAttrMap; 01025 if (pAttrMap!=NULL) 01026 { 01027 pLE->FindAppliedAttributes(pAttrMap, 5000, NULL, FALSE, FALSE); 01028 pAttrMap->Render(pNewGRR); 01029 delete pAttrMap; 01030 } 01031 01032 // This is the important bit - force top quality rendering 01033 // so that effects capture is done properly regardless of 01034 // the current document/view quality 01035 pNewGRR->RRQuality.SetQuality(QUALITY_MAX); 01036 pNewGRR->SetQualityLevel(); 01037 01038 pNewGRR->SetImmediateRender(TRUE); 01039 01040 pNewGRR->RenderTree(pLE, FALSE, FALSE); 01041 pNewGRR->StopRender(); 01042 01043 } 01044 01045 // Sanity check 01046 // We really should have generated an original bitmap by now! 01047 ERROR2IF(!pLE->GetOriginalBitmap(NULL, NULL, NULL), FALSE, "EnsureLiveEffectOriginalBitmaps failed to generate an original bitmap"); 01048 01049 delete pNewGRR; 01050 pNewGRR = NULL; 01051 } 01052 01053 pNode = m_pLERange->FindNext(pNode); 01054 } 01055 01056 return TRUE; 01057 }
|
|
Definition at line 1080 of file opliveeffects.cpp. 01085 { 01086 // We need to forcibly render this node to get its original 01087 // bitmap set up 01088 // 01089 // Version2 Bitmap Generation 01090 // 01091 // Grab bitmap without using on screen rendering 01092 // This is more efficient than rendering the whole tree and 01093 // allows parameters to be controlled independently from screen view 01094 // 01095 // Ideally: 01096 // Start a render into a RenderRegion 01097 // Don't allow the RenderRegion to grab bitmap of its own - NOT DONE 01098 // Don't allow the RenderRegion to blit captures into it's own bitmap - NOT DONE 01099 // Ensure only the effect and it's children are rendered - DONE! 01100 // Just let the effect rendering functions create their capture bitmap - DONE! 01101 01102 // Create a new GRenderDIB region 01103 // Most of the parameters here are immaterial because we are not really 01104 // interested in the results of the rendered region - just the capture 01105 View* pView = View::GetCurrent(); 01106 Spread* pSpread = Document::GetSelectedSpread(); 01107 Matrix Mat = pView->ConstructScaledRenderingMatrix(pSpread, 1.0); 01108 FIXED16 Scale; 01109 Mat.Decompose(&Scale); 01110 GRenderDIB* pNewGRR = new GRenderDIB(pBitmapEffect->GetBoundingRect(), Mat, Scale, 32, dResolution); 01111 ERROR2IF(pNewGRR == NULL, FALSE, "Failed to create a GRenderDIB!"); 01112 01113 // State flags + pixel width calculations 01114 if (!pNewGRR->AttachDevice(pView, NULL, pSpread)) // view and spread from previous RR rather than Current - nb in create bitmap copy case 01115 { 01116 ERROR3("Cannot attach devices"); 01117 01118 delete pNewGRR; 01119 pNewGRR = NULL; 01120 01121 *ppInfo = NULL; 01122 *ppBits = NULL; 01123 01124 *prectBounds = DocRect(); 01125 01126 return FALSE; 01127 } 01128 01129 pNewGRR->m_DoCompression = TRUE; // We do want transparency 01130 pNewGRR->InitDevice(); 01131 pNewGRR->InitAttributes(); 01132 pNewGRR->SetLineAttributes(); 01133 pNewGRR->SetFillAttributes(); 01134 01135 // NB following call gets GRendRegion to create the bitmap into which GDraw will render 01136 BOOL Started = pNewGRR->StartRender(); 01137 01138 if (Started) 01139 { 01140 // Setup attribute state outside this subtree 01141 CCAttrMap* pAttrMap = new CCAttrMap; 01142 if (pAttrMap!=NULL) 01143 { 01144 pBitmapEffect->FindAppliedAttributes(pAttrMap, 5000, NULL, FALSE, FALSE); 01145 pAttrMap->Render(pNewGRR); 01146 delete pAttrMap; 01147 } 01148 01149 // This is the important bit - force top quality rendering 01150 // so that effects capture is done properly regardless of 01151 // the current document/view quality 01152 pNewGRR->RRQuality.SetQuality(QUALITY_MAX); 01153 pNewGRR->SetQualityLevel(); 01154 01155 pNewGRR->RenderTree(pBitmapEffect, FALSE, FALSE); 01156 pNewGRR->StopRender(); 01157 } 01158 01159 *prectBounds = pNewGRR->GetClipRect(); // Get pixel-aligned rect 01160 pNewGRR->GetBitmapPointers(ppInfo, ppBits); // Get the bitmap data out of the region, converting T channel 01161 pNewGRR->SetBitmapPointers(NULL, NULL); // We own the bitmap now, it will not be deallocated by 01162 // the following renderegion deleteion 01163 delete pNewGRR; 01164 pNewGRR = NULL; 01165 01166 return TRUE; 01167 }
|
|
Definition at line 275 of file opliveeffects.h. 00275 {return m_pLERange;}
|
|
Definition at line 280 of file opliveeffects.h. 00280 {return m_bPreviewQuality;}
|
|
Detect whether any of the LiveEffect nodes created/edited by this operation have actually been changed/do anything useful...
Definition at line 1225 of file opliveeffects.cpp. 01226 { 01227 if (m_pLERange==NULL) 01228 return FALSE; 01229 01230 Node* pNode = m_pLERange->FindFirst(); 01231 while (pNode) 01232 { 01233 ENSURE(pNode->IsBitmapEffect(), "LiveEffects list contains non-LiveEffect in EnsureLiveEffectOriginalBitmaps"); 01234 NodeBitmapEffect* pLE = (NodeBitmapEffect*)pNode; 01235 01236 if (pLE->HasChanged()) 01237 return TRUE; 01238 01239 pNode = m_pLERange->FindNext(pNode); 01240 } 01241 01242 return FALSE; 01243 }
|
|
Reimplemented from SimpleCCObject. Definition at line 214 of file opliveeffects.cpp. 00215 { 00216 BOOL bOK = TRUE; 00217 // Use an ParamOpDescriptor to allow OpApplyLiveEffect to receive extra information 00218 // about the menu item that invoked it... 00219 ParamOpDescriptor* pOD = NULL; 00220 pOD = new ParamOpDescriptor(OPTOKEN_APPLY_LIVEEFFECT, 00221 CC_RUNTIME_CLASS(OpApplyLiveEffect), 00222 OpApplyLiveEffect::GetParamState); 00223 bOK = bOK && (pOD!=NULL); 00224 00225 pOD = new ParamOpDescriptor(OPTOKEN_EDIT_LIVEEFFECT, 00226 CC_RUNTIME_CLASS(OpEditLiveEffect), 00227 OpEditLiveEffect::GetParamState); 00228 bOK = bOK && (pOD!=NULL); 00229 00230 pOD = new ParamOpDescriptor(OPTOKEN_EDIT_LEGACYEFFECT, 00231 CC_RUNTIME_CLASS(OpEditLegacyEffect), 00232 OpEditLegacyEffect::GetParamState); 00233 bOK = bOK && (pOD!=NULL); 00234 00235 #ifdef FEATHER_EFFECT 00236 pOD = new ParamOpDescriptor(OPTOKEN_APPLY_FEATHEREFFECT, 00237 CC_RUNTIME_CLASS(OpApplyFeatherEffect), 00238 OpApplyFeatherEffect::GetParamState); 00239 bOK = bOK && (pOD!=NULL); 00240 #endif 00241 00242 /* bOK = bOK && RegisterOpDescriptor(0, // Tool ID 00243 _R(IDS_EDIT_LIVEEFFECT), // String resource ID 00244 CC_RUNTIME_CLASS(OpEditLiveEffect), // Runtime class 00245 OPTOKEN_EDIT_LIVEEFFECT, // Token string 00246 OpEditLiveEffect::GetState, // GetState function 00247 0, // Help ID 00248 _R(IDBBL_EDIT_LIVEEFFECT), // Bubble ID 00249 0, // Resource ID 00250 0, // Control ID 00251 SYSTEMBAR_ILLEGAL, // Bar ID 00252 TRUE, // Receive system messages 00253 FALSE, // Smart duplicate operation 00254 FALSE, // Clean operation 00255 0, // No vertical counterpart 00256 GREY_WHEN_NO_CURRENT_DOC | 00257 DONT_GREY_WHEN_SELECT_INSIDE); // automatic state checking. 00258 */ 00259 bOK = bOK && RegisterOpDescriptor(0, // Tool ID 00260 _R(IDS_DELETE_LIVEEFFECT), // String resource ID 00261 CC_RUNTIME_CLASS(OpDeleteLiveEffect), // Runtime class 00262 OPTOKEN_DELETE_LIVEEFFECT, // Token string 00263 OpDeleteLiveEffect::GetState, // GetState function 00264 0, // Help ID 00265 _R(IDBBL_DELETE_LIVEEFFECT), // Bubble ID 00266 0, // Resource ID 00267 0, // Control ID 00268 SYSTEMBAR_ILLEGAL, // Bar ID 00269 TRUE, // Receive system messages 00270 FALSE, // Smart duplicate operation 00271 FALSE, // Clean operation 00272 0, // No vertical counterpart 00273 GREY_WHEN_NO_CURRENT_DOC | 00274 DONT_GREY_WHEN_SELECT_INSIDE); // automatic state checking. 00275 00276 bOK = bOK && RegisterOpDescriptor(0, // Tool ID 00277 _R(IDS_DELETEALL_LIVEEFFECT), // String resource ID 00278 CC_RUNTIME_CLASS(OpDeleteAllLiveEffect), // Runtime class 00279 OPTOKEN_DELETEALL_LIVEEFFECT, // Token string 00280 OpDeleteAllLiveEffect::GetState, // GetState function 00281 0, // Help ID 00282 _R(IDBBL_DELETEALL_LIVEEFFECT), // Bubble ID 00283 0, // Resource ID 00284 0, // Control ID 00285 SYSTEMBAR_ILLEGAL, // Bar ID 00286 TRUE, // Receive system messages 00287 FALSE, // Smart duplicate operation 00288 FALSE, // Clean operation 00289 0, // No vertical counterpart 00290 GREY_WHEN_NO_CURRENT_DOC | 00291 DONT_GREY_WHEN_SELECT_INSIDE); // automatic state checking. 00292 00293 bOK = bOK && RegisterOpDescriptor(0, // Tool ID 00294 _R(IDS_CHANGE_EFFECT_RES), // String resource ID 00295 CC_RUNTIME_CLASS(OpEffectRes), // Runtime class 00296 OPTOKEN_CHANGE_EFFECT_RES, // Token string 00297 OpEffectRes::GetState, // GetState function 00298 0, // Help ID 00299 _R(IDBBL_CHANGE_EFFECT_RES), // Bubble ID 00300 0, // Resource ID 00301 0, // Control ID 00302 SYSTEMBAR_ILLEGAL, // Bar ID 00303 TRUE, // Receive system messages 00304 FALSE, // Smart duplicate operation 00305 FALSE, // Clean operation 00306 0, // No vertical counterpart 00307 GREY_WHEN_NO_CURRENT_DOC | 00308 DONT_GREY_WHEN_SELECT_INSIDE); // automatic state checking. 00309 00310 bOK = bOK && RegisterOpDescriptor(0, // Tool ID 00311 _R(IDS_CHANGE_EFFECT_LOCK), // String resource ID 00312 CC_RUNTIME_CLASS(OpEffectLock), // Runtime class 00313 OPTOKEN_CHANGE_EFFECT_LOCK, // Token string 00314 OpEffectLock::GetState, // GetState function 00315 0, // Help ID 00316 _R(IDBBL_CHANGE_EFFECT_LOCK), // Bubble ID 00317 0, // Resource ID 00318 0, // Control ID 00319 SYSTEMBAR_ILLEGAL, // Bar ID 00320 TRUE, // Receive system messages 00321 FALSE, // Smart duplicate operation 00322 FALSE, // Clean operation 00323 0, // No vertical counterpart 00324 GREY_WHEN_NO_CURRENT_DOC | 00325 DONT_GREY_WHEN_SELECT_INSIDE); // automatic state checking. 00326 00327 bOK = bOK && RegisterOpDescriptor(0, // Tool ID 00328 _R(IDS_CHANGE_EFFECT_LOCKALL), // String resource ID 00329 CC_RUNTIME_CLASS(OpEffectLockAll), // Runtime class 00330 OPTOKEN_CHANGE_EFFECT_LOCKALL, // Token string 00331 OpEffectLockAll::GetState, // GetState function 00332 0, // Help ID 00333 _R(IDBBL_CHANGE_EFFECT_LOCKALL), // Bubble ID 00334 0, // Resource ID 00335 0, // Control ID 00336 SYSTEMBAR_ILLEGAL, // Bar ID 00337 TRUE, // Receive system messages 00338 FALSE, // Smart duplicate operation 00339 FALSE, // Clean operation 00340 0, // No vertical counterpart 00341 GREY_WHEN_NO_CURRENT_DOC | 00342 DONT_GREY_WHEN_SELECT_INSIDE); // automatic state checking. 00343 00344 return bOK; 00345 }
|
|
Definition at line 926 of file opliveeffects.cpp.
|
|
Definition at line 1186 of file opliveeffects.cpp. 01187 { 01188 if (m_pLERange==NULL) 01189 return TRUE; 01190 01191 Node* pNode = m_pLERange->FindFirst(); 01192 while (pNode) 01193 { 01194 ENSURE(pNode->IsBitmapEffect(), "LiveEffects list contains non-LiveEffect in EnsureLiveEffectOriginalBitmaps"); 01195 NodeBitmapEffect* pLE = (NodeBitmapEffect*)pNode; 01196 01197 pLE->SetChanged(bNewState); 01198 01199 pNode = m_pLERange->FindNext(pNode); 01200 } 01201 01202 return TRUE; 01203 }
|
|
Definition at line 281 of file opliveeffects.h. 00281 {m_bPreviewQuality = bNew;}
|
|
Reset the current Op to refer to the new PPStack and tell the running XPE edit that things are changing.
Definition at line 1258 of file opliveeffects.cpp. 01259 { 01260 OpLiveEffect* pCurrentOp = XPEHost::GetCurrentLEOp(); 01261 01262 // If we haven't got a list of editors yet then get one 01263 if (pCurrentOp==NULL) 01264 return FALSE; 01265 01266 // TODO: May need to force a redraw if the current op is in preview mode at the moment 01267 ENSURE(pCurrentOp->GetPreviewQuality()==FALSE, "We can't leave the bitmaps in the tree in preview mode!"); 01268 01269 // Read the current op's details... 01270 String_256 strEffectID = pCurrentOp->m_strEffectID; 01271 INT32 iStackPos = pCurrentOp->m_iStackPos; 01272 01273 // Stop the current Op and commit all of its changes 01274 // Disconnect it from the XPE system so that, just for the moment at least, other routines 01275 // think that there's no running edit session 01276 pCurrentOp->DoEndEdit(TRUE, TRUE); // Sends ScreenChangeMsg - and thus releases pPPStack 01277 XPEHost::SetCurrentLEOp(NULL); // Tells UpdateCurrentEditor not to try to update dying editor 01278 01279 // Reset pPPStack in LiveEffectTool to reset the Tool after the ScreenChangeMsg sent above 01280 // (prevent idle handler looping forever calling this function) 01281 EffectsStack* pPPStack = EffectsStack::GetEffectsStackFromSelection(); 01282 01283 // Try to find the same effect in the new stack 01284 // If found then invoke a new Op to use the running editor on that effect 01285 BOOL bOK = pPPStack->FindBestProcessor(&strEffectID, &iStackPos); 01286 01287 // Decide which sort of Operation we need to use instead... 01288 OpDescriptor* pOp = NULL; 01289 if (bOK) 01290 { 01291 // We found the right sort of Effect in the stack so we'll just edit that 01292 pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_EDIT_LIVEEFFECT); 01293 } 01294 else 01295 { 01296 // We didn't find the right sort of effect so we'll apply a brand new one! 01297 // At the top of the stack 01298 pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_APPLY_LIVEEFFECT); 01299 iStackPos = STACKPOS_INSERT_TOP; 01300 } 01301 01302 // Start a new Op but tell it to use the existing edit session instead of making a new one 01303 if (pOp) 01304 { 01305 OpLiveEffectParam Param; 01306 Param.strOpUnique = strEffectID; 01307 Param.StackPosition = iStackPos; 01308 Param.pPPStack = pPPStack; 01309 Param.bReUseEditor = TRUE; // This is the important param! 01310 BOOL bValid = XPEHost::GetEffectDetails(strEffectID, &Param.strMenuText, &Param.bIsDestructive); 01311 01312 String_256 strDummy; 01313 if (bValid && pOp->GetOpsState(&strDummy).Greyed==FALSE) 01314 { 01315 pOp->Invoke(&Param); 01316 01317 // Reset the Tool's current stack pointer now so that it doesn't need 01318 // to be updated under idle events with the consequent call to this function 01319 // and infinite loop... 01320 Tool* pTool = Tool::GetCurrent(); 01321 if (pTool->GetID()==TOOLID_LIVEEFFECT) 01322 ((LiveEffectsTool*)pTool)->UpdatePPStack(FALSE); 01323 01324 // If that successfully set up a new editor op then we're fine to carry on 01325 if (XPEHost::GetCurrentLEOp()!=NULL) 01326 { 01327 delete pPPStack; 01328 return TRUE; 01329 } 01330 } 01331 } 01332 01333 // If we get here then we must have failed in some way so close down the running editor 01334 XPEHost::EndEditLiveEffect(); 01335 delete pPPStack; 01336 return FALSE; 01337 }
|
|
Definition at line 314 of file opliveeffects.h. |
|
Definition at line 317 of file opliveeffects.h. |
|
Definition at line 316 of file opliveeffects.h. |
|
Definition at line 313 of file opliveeffects.h. |
|
Definition at line 315 of file opliveeffects.h. |