00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 #include "camtypes.h"
00101
00102 #include "attrappl.h"
00103
00104
00105
00106 #include "lineattr.h"
00107 #include "linwthop.h"
00108
00109 #include "nodedoc.h"
00110
00111
00112
00113
00114 #include "toollist.h"
00115
00116 #include "ndoptmz.h"
00117 #include "objchge.h"
00118
00119 #include "progress.h"
00120 #include "fillndge.h"
00121
00122 #include "nodetxtl.h"
00123
00124 #include "colormgr.h"
00125
00126 #include "nodecont.h"
00127 #include "lineattr.h"
00128 #include "opdrbrsh.h"
00129 #include "brshattr.h"
00130 #include "effects_stack.h"
00131 #include "ophist.h"
00132
00133 #include "nodetext.h"
00134 #include "ppbrush.h"
00135
00136 CC_IMPLEMENT_DYNCREATE(OpApplyAttrib, SelOperation)
00137 CC_IMPLEMENT_DYNCREATE(OpApplyAttribToSelected, OpApplyAttrib)
00138 CC_IMPLEMENT_DYNCREATE(OpApplyAttrInteractive, OpApplyAttrib)
00139 CC_IMPLEMENT_DYNCREATE(OpApplyAttribsToSelected, OpApplyAttrib)
00140 CC_IMPLEMENT_DYNCREATE(OpRepeatApplyAttribToSelected, Operation)
00141 CC_IMPLEMENT_DYNCREATE(OpApplyAttribToNode, OpApplyAttrib)
00142 CC_IMPLEMENT_DYNCREATE(OpReplaceAttributes, SelOperation)
00143 CC_IMPLEMENT_DYNCREATE(ReplaceAttributesParam, OpParam)
00144 CC_IMPLEMENT_MEMDUMP(ApplyAttribsToSelectedParam, OpParam)
00145
00146
00147 #define new CAM_DEBUG_NEW
00148
00149
00150
00151 FillBlobSelectionState OpRepeatApplyAttribToSelected::FillBlobState;
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 NodeRenderableInk * OpApplyAttrib::FindCompoundNodeWhichRequiresAttribute(
00173 NodeRenderableInk * pStartNode,
00174 CCRuntimeClass * pClass)
00175 {
00176 NodeRenderableInk * pNodeToApply = pStartNode;
00177
00178 if (!pStartNode->NeedsParent(NULL))
00179 {
00180 Node * pParent = pNodeToApply->FindParent();
00181
00182 while (pParent)
00183 {
00184 if (pParent->IsCompoundClass())
00185 {
00186 if (((NodeCompound*)pParent)->PromoteAttributeApplicationToMe(pClass))
00187 {
00188 pNodeToApply = (NodeRenderableInk *)pParent;
00189 }
00190 }
00191
00192
00193 pParent = pParent->FindParent();
00194 }
00195 }
00196
00197 return pNodeToApply;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 BOOL SelOperation::DoApply(Node* CurrentNode,
00230 NodeAttribute* Attrib,
00231 BOOL Mutate,
00232 BOOL InvalidateRegion,
00233 BOOL KeepExistingCols,
00234 BOOL* pbAttribWasRequired,
00235 BOOL* pbCanDiscardUndo
00236 )
00237 {
00238 return SelOperation::DoApply(this, CurrentNode, Attrib, Mutate, InvalidateRegion, KeepExistingCols, TRUE, pbAttribWasRequired, pbCanDiscardUndo);
00239 }
00240
00241 BOOL SelOperation::DoApply( SelOperation* pOp,
00242 Node* CurrentNode,
00243 NodeAttribute* Attrib,
00244 BOOL Mutate,
00245 BOOL InvalidateRegion,
00246 BOOL KeepExistingCols,
00247 BOOL bOptimise,
00248 BOOL* pbAttribWasRequired,
00249 BOOL* pbCanDiscardUndo
00250 )
00251 {
00252 BOOL AttributeExists = FALSE;
00253
00254 CCRuntimeClass* AttrType = Attrib->GetAttributeType();
00255
00256 ERROR3IF(!CurrentNode->IsAnObject(), "Trying to apply an attribute to a non-NodeRenderableInk");
00257
00258
00259 ERROR3IF(!(Attrib->CanBeAppliedToObject()), "Trying to apply an illegal attribute to the object");
00260
00261 if (!(Attrib->CanBeAppliedToObject()))
00262 return TRUE;
00263
00264 Node* OriginalCurrentNode = CurrentNode;
00265
00266 if (CurrentNode->IsAnObject())
00267 {
00268
00269
00270 CurrentNode = ((NodeRenderableInk*)CurrentNode)->GetObjectToApplyTo(Attrib->GetAttributeType());
00271 if (!CurrentNode)
00272 {
00273 ERROR3("OpApplyAttrib::DoApply, Unable to find object to apply to");
00274 return TRUE;
00275 }
00276 }
00277
00278
00279 BOOL bEffectRootOnly = (CurrentNode->IsAnObject() && ((NodeRenderableInk*)CurrentNode)->IsValidEffectAttr(Attrib));
00280
00281
00282
00283 if (pbCanDiscardUndo)
00284 *pbCanDiscardUndo = *pbCanDiscardUndo && CurrentNode->DiscardsAttributeChildren();
00285
00286
00287
00288
00289
00290 if (bEffectRootOnly && AttrType == CC_RUNTIME_CLASS(AttrStrokeTransp))
00291 return TRUE;
00292
00293
00294
00295 BOOL AddEvenIfMultiple = FALSE;
00296
00297
00298 if ((((NodeRenderableInk*)CurrentNode)->RequiresAttrib(Attrib)))
00299 {
00300
00301 if (pbAttribWasRequired)
00302 *pbAttribWasRequired = TRUE;
00303
00304 if (CurrentNode != OriginalCurrentNode)
00305 {
00306
00307
00308
00309
00310 ObjChangeFlags cFlags;
00311 cFlags.Attribute = TRUE;
00312 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, pOp);
00313
00314 if (!CurrentNode->AllowOp(&ObjChange))
00315 {
00316
00317 ERROR3("Doing op when no nodes will allow it");
00318 }
00319 }
00320
00321
00322
00323
00324 Node* n = CurrentNode->FindFirstChild();
00325 Node* pLastBoundedNode = NULL;
00326 if (bEffectRootOnly)
00327 {
00328 pLastBoundedNode = CurrentNode->FindLastChild(CC_RUNTIME_CLASS(NodeRenderableBounded));
00329 ERROR3IF(pLastBoundedNode==NULL, "Attempt to apply effect attr to node with no children");
00330
00331 if (pLastBoundedNode) n = pLastBoundedNode->FindNext();
00332 }
00333
00334 while (n && (n->IsOrHidesAnAttribute()))
00335 {
00336
00337
00338 if (n->IsAnAttribute())
00339 {
00340 NodeAttribute* pNdAttr = (NodeAttribute*)n;
00341
00342 if( pNdAttr->GetAttributeType() == AttrType)
00343 {
00344
00345
00346
00347
00348 BOOL LookForMultiple = FALSE;
00349
00350 if (Attrib->CanBeMultiplyApplied())
00351 {
00352
00353
00354 if (Attrib->GetAttributeClassID() == pNdAttr->GetAttributeClassID())
00355 {
00356 LookForMultiple = FALSE;
00357 AddEvenIfMultiple = FALSE;
00358 }
00359 else
00360 {
00361
00362
00363 LookForMultiple = TRUE;
00364 AddEvenIfMultiple = TRUE;
00365 }
00366 }
00367
00368
00369
00370
00371
00372 if (IS_SAME_CLASS(pNdAttr, Attrib))
00373 {
00374
00375 if ((*pNdAttr)==(*Attrib))
00376 return TRUE;
00377
00378 if (Attrib->IsABrush())
00379 ((AttrBrushType*)Attrib)->OnReplaceAttribute((AttrBrushType*)pNdAttr);
00380 }
00381
00382
00383 if (!LookForMultiple)
00384 {
00385 AttributeExists = TRUE;
00386 break;
00387 }
00388 }
00389 }
00390 n = n->FindNext();
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 if (CurrentNode->IsCompound() && !Attrib->CanBeMultiplyApplied() && !bEffectRootOnly)
00403 {
00404
00405
00406
00407
00408 if (pOp && !pOp->DoRemoveAttrTypeFromSubtree(CurrentNode, Attrib->GetAttributeType(), n))
00409 {
00410 pOp->FailAndExecute();
00411 return FALSE;
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 NodeAttribute* AttribClone = NULL;
00428 if ( !AddEvenIfMultiple && n && n->IsAnAttribute())
00429 {
00430
00431 NodeAttribute* pAttr = (NodeAttribute*)n;
00432
00433 if (Mutate)
00434 {
00435
00436 AttribClone = ((AttrFillGeometry*)n)->Mutate((AttrFillGeometry*)Attrib, bOptimise);
00437 }
00438 else
00439 {
00440
00441
00442
00443 if (pOp)
00444 ALLOC_WITH_FAIL(AttribClone ,((NodeAttribute*)Attrib->SimpleCopy()), pOp)
00445 else
00446 AttribClone = (NodeAttribute*)Attrib->SimpleCopy();
00447 if (AttribClone == NULL)
00448 return FALSE;
00449
00450
00451
00452
00453
00454 if ( KeepExistingCols && ((NodeAttribute*)n)->IsAFillAttr() )
00455 {
00456 AttrFillGeometry* NodeReplaced = (AttrFillGeometry*)n;
00457
00458
00459 if (!OpApplyAttrib::KeepExistingCharacteristics(NodeReplaced, (AttrFillGeometry*)AttribClone))
00460 return FALSE;
00461 }
00462
00463 if ( Attrib->IsATranspFill() && Attrib->IsAFlatFill())
00464 {
00465 ((AttrFillGeometry*)n)->RenderFillBlobs();
00466 }
00467 }
00468
00469
00470
00471
00472 if (AttribClone == NULL)
00473 return TRUE;
00474
00475
00476
00477
00478
00479
00480
00481
00482 ReleaseCachedForAttrApply((NodeRenderableBounded*)CurrentNode, bEffectRootOnly);
00483
00484
00485 if (InvalidateRegion)
00486 {
00487
00488 if (!InvalidateNodeRegion(pOp, (NodeRenderableBounded*)CurrentNode, Attrib, Mutate))
00489 return FALSE;
00490 }
00491
00492
00493
00494
00495
00496
00497 if (pOp && !CurrentNode->DiscardsAttributeChildren())
00498 {
00499
00500
00501
00502
00503
00504
00505 if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpApplyAttrInteractive)))
00506 {
00507 ApplyAction* pUndoApply;
00508
00509 if ( ApplyAction::Init(pOp,
00510 pOp->GetUndoActionList(),
00511 CurrentNode,
00512 pAttr,
00513 TRUE,
00514
00515 (Action**)(&pUndoApply))
00516 == AC_FAIL)
00517 {
00518 return FALSE;
00519 }
00520 pAttr->CascadeDelete();
00521 delete pAttr;
00522 pAttr = NULL;
00523 }
00524 else
00525 {
00526 if (!pOp->DoHideNode(n, TRUE))
00527 return FALSE;
00528 }
00529 }
00530 else
00531 {
00532 pAttr->CascadeDelete();
00533 delete pAttr;
00534 pAttr = NULL;
00535 }
00536
00537 }
00538 else
00539 {
00540
00541
00542 NodeAttribute* TempAttr = NULL;
00543
00544 BOOL FoundAttr = ((NodeRenderableInk*)CurrentNode)->
00545 FindAppliedAttribute(Attrib->GetAttributeType(), &TempAttr);
00546
00547 if (!FoundAttr || TempAttr == NULL)
00548 return FALSE;
00549
00550 if (Mutate)
00551 {
00552 AttribClone = ((AttrFillGeometry*)TempAttr)->Mutate((AttrFillGeometry*)Attrib, bOptimise);
00553 }
00554 else
00555 {
00556
00557 if (pOp)
00558 ALLOC_WITH_FAIL(AttribClone ,((NodeAttribute*)Attrib->SimpleCopy()), pOp)
00559 else
00560 AttribClone = (NodeAttribute*)Attrib->SimpleCopy();
00561
00562 if ( KeepExistingCols && (TempAttr->IsAFillAttr()) )
00563 {
00564 AttrFillGeometry* NodeReplaced = (AttrFillGeometry*)TempAttr;
00565
00566
00567 if (!OpApplyAttrib::KeepExistingCharacteristics(NodeReplaced, (AttrFillGeometry*)AttribClone))
00568 return FALSE;
00569 }
00570
00571 if (Attrib->IsATranspFill() && Attrib->IsAFlatFill())
00572 {
00573
00574
00575 ((AttrFillGeometry*)TempAttr)->RenderFillBlobs();
00576 }
00577 }
00578
00579 if (AttribClone)
00580 {
00581 ReleaseCachedForAttrApply((NodeRenderableBounded*)CurrentNode, bEffectRootOnly);
00582
00583 if (InvalidateRegion)
00584 {
00585
00586 if (!InvalidateNodeRegion(pOp, (NodeRenderableBounded*)CurrentNode, Attrib, Mutate))
00587 return FALSE;
00588 }
00589 }
00590 }
00591
00592
00593
00594 if (AttribClone && AttribClone->ShouldBeOptimized() && !bEffectRootOnly && bOptimise)
00595 {
00596 NodeAttribute* pAppliedAttr;
00597 if (((NodeRenderableInk*)CurrentNode)->FindAppliedAttribute(AttribClone->GetAttributeType(),
00598 &pAppliedAttr))
00599 {
00600
00601 if ((IS_SAME_CLASS(AttribClone, pAppliedAttr)))
00602 {
00603 if ((*AttribClone)==(*pAppliedAttr))
00604 {
00605 AttribClone->CascadeDelete();
00606
00607
00608
00609
00610 if (pAppliedAttr->EffectsParentBounds())
00611 {
00612 ((NodeRenderableBounded*)CurrentNode)->InvalidateBoundingRect(TRUE);
00613 }
00614
00615 delete AttribClone;
00616 AttribClone = NULL;
00617 }
00618 }
00619 }
00620 }
00621
00622
00623
00624
00625 if (AttribClone && bEffectRootOnly && AttribClone->HasEquivalentDefaultValue() && bOptimise)
00626 {
00627
00628 AttribClone->CascadeDelete();
00629 delete AttribClone;
00630 AttribClone = NULL;
00631 }
00632
00633 if (AttribClone)
00634 {
00635
00636 if (bEffectRootOnly)
00637 AttribClone->AttachNode(pLastBoundedNode, NEXT);
00638 else
00639 AttribClone->AttachNode(CurrentNode, FIRSTCHILD);
00640
00641 AttributeManager::pLastNodeAppliedTo = (NodeRenderableInk*)CurrentNode;
00642
00643
00644
00645 if (AttribClone->IsAFillAttr())
00646 {
00647 ((AttrFillGeometry*)AttribClone)->AttributeChanged();
00648 }
00649
00650 if (pOp && !CurrentNode->DiscardsAttributeChildren())
00651 {
00652
00653
00654
00655
00656
00657
00658 if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpApplyAttrInteractive)))
00659 {
00660 UnApplyAction* pUndoApply;
00661
00662 if ( UnApplyAction::Init(pOp,
00663 pOp->GetUndoActionList(),
00664 CurrentNode,
00665 AttribClone,
00666 TRUE,
00667
00668 (Action**)(&pUndoApply))
00669 == AC_FAIL)
00670 {
00671 AttribClone->CascadeDelete();
00672 delete (AttribClone);
00673 return FALSE;
00674 }
00675 }
00676 else
00677 {
00678 HideNodeAction* UndoHideNodeAction;
00679
00680 if ( HideNodeAction::Init(pOp,
00681 pOp->GetUndoActionList(),
00682 AttribClone,
00683 TRUE,
00684
00685 (Action**)(&UndoHideNodeAction))
00686 == AC_FAIL)
00687 {
00688 AttribClone->CascadeDelete();
00689 delete (AttribClone);
00690 return FALSE;
00691 }
00692 }
00693 }
00694
00695 }
00696
00697 ReleaseCachedForAttrApply((NodeRenderableBounded*)CurrentNode, bEffectRootOnly);
00698
00699 if (InvalidateRegion)
00700 {
00701
00702 if (!InvalidateNodeRegion(pOp, (NodeRenderableBounded*)CurrentNode, Attrib, Mutate))
00703 return FALSE;
00704 }
00705 }
00706
00707
00708 if (pOp)
00709 {
00710 if (!pOp->ApplyAttributeToBrush(CurrentNode, Attrib))
00711 return FALSE;
00712 }
00713 return TRUE;
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 BOOL SelOperation::ReleaseCachedForAttrApply(NodeRenderableBounded* pNode, BOOL bEffectRootOnly)
00738 {
00739 if (bEffectRootOnly)
00740 pNode->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
00741 else
00742 pNode->ReleaseCached();
00743
00744 return TRUE;
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 BOOL SelOperation::ApplyAttributeToBrush(Node* pCurrentNode, NodeAttribute* pAttr)
00771 {
00772 ERROR2IF(pCurrentNode == NULL, FALSE, "Current node is NULL");
00773 ERROR2IF(pAttr == NULL, FALSE, "Attribute is NULL");
00774
00775
00776 if (!pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrStrokeColourChange)) && !pAttr->IsATranspFill()
00777 && !pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrLineWidth)) && !pAttr->IsABrush())
00778 return TRUE;
00779
00780
00781 AttrBrushType* pAttrBrush = NULL;
00782
00783 ((NodeRenderableInk*)pCurrentNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType),
00784 (NodeAttribute**)&pAttrBrush);
00785
00786
00787 if (pAttr->IsABrush())
00788 {
00789 AttrBrushType* pNewAttrBrush = (AttrBrushType*)pAttr;
00790 return ApplyBrushAttr(pCurrentNode, pNewAttrBrush);
00791 }
00792
00793
00794
00795 if (pAttrBrush == NULL || pAttrBrush->GetBrushHandle() == BrushHandle_NoBrush)
00796 return TRUE;
00797
00798
00799 if (pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrStrokeColourChange)))
00800 {
00801
00802 AttrStrokeColourChange* pStrokeCol = static_cast<AttrStrokeColourChange*>(pAttr);
00803 DocColour* pCol = pStrokeCol->GetStartColour();
00804
00805 if (pCol->IsTransparent())
00806 return TRUE;
00807
00808 return ApplyStrokeColourToBrush(pAttrBrush, (NodeRenderableInk*)pCurrentNode);
00809 }
00810
00811
00812
00813
00814 if (pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrLineWidth)))
00815 return ApplyLineWidthToBrush(pAttrBrush, (NodeRenderableInk*)pCurrentNode, pAttr);
00816
00817
00818 pAttrBrush->ClearCachedRect();
00819
00820
00821 return TRUE;
00822 }
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 BOOL SelOperation::ApplyTransparencyToBrush(AttrBrushType* pAttrBrush, NodeRenderableInk* pBrushedNode)
00839 {
00840 ERROR2IF(pAttrBrush == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyTransparencyToBrush");
00841 ERROR2IF(pBrushedNode == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyTransparencyToBrush");
00842
00843
00844 ChangeBrushOpParam Param;
00845
00846 Param.ChangeType = CHANGEBRUSH_USELOCALTRANSP;
00847 Param.m_bNewUseLocalTransp = TRUE;
00848 ChangeBrushAction* pAction = NULL;
00849
00850 if (ChangeBrushAction::Init(this, &UndoActions, pBrushedNode, &Param, &pAction) == AC_FAIL)
00851 return FALSE;
00852
00853 return TRUE;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 BOOL SelOperation::ApplyStrokeColourToBrush(AttrBrushType* pAttrBrush, NodeRenderableInk* pBrushedNode)
00872 {
00873 ERROR2IF(pAttrBrush == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyStrokeColourToBrush");
00874 ERROR2IF(pBrushedNode == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyStrokeColourToBrush");
00875
00876
00877
00878
00879
00880 PathProcessorBrush *pPPB = pAttrBrush->GetPathProcessor();
00881 if (pPPB == NULL)
00882 return TRUE;
00883
00884 if (pPPB->GetUseLocalFillColour() || !pPPB->GetUseNamedColours())
00885 return TRUE;
00886
00887
00888 ChangeBrushOpParam Param;
00889
00890 Param.ChangeType = CHANGEBRUSH_USENAMEDCOL;
00891 Param.m_bNewUseNamed = FALSE;
00892 ChangeBrushAction* pAction = NULL;
00893
00894 if (ChangeBrushAction::Init(this, &UndoActions, pBrushedNode,
00895 &Param, &pAction) == AC_FAIL)
00896 return FALSE;
00897
00898 return TRUE;
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 BOOL SelOperation::ApplyLineWidthToBrush(AttrBrushType* pAttrBrush, NodeRenderableInk* pBrushedNode,
00922 NodeAttribute* pAttr)
00923 {
00924 ERROR2IF(pAttrBrush == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyLineWidthToBrush");
00925 ERROR2IF(pBrushedNode == NULL, FALSE, "Node pointer is NULL in OnApplyAttrib::ApplyLineWidthToBrush");
00926 ERROR2IF(pAttr == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyLineWidthToBrush");
00927
00928
00929 PathProcessorBrush* pPPB = pAttrBrush->GetPathProcessor();
00930 if (pPPB != NULL)
00931 {
00932
00933 AttrLineWidth* pLineWidth = (AttrLineWidth*)pAttr;
00934 BOOL UsesPressure = pAttrBrush->GetPressureCache() != NULL;
00935 pPPB->ScaleToValue(pLineWidth->Value.LineWidth, !UsesPressure);
00936 pPPB->AdjustSpacingForClosedPath(pBrushedNode);
00937 }
00938
00939 return TRUE;
00940 }
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 BOOL SelOperation::ApplyBrushAttr(Node* pCurrentNode, AttrBrushType* pAttrBrush)
00962 {
00963 ERROR2IF(pCurrentNode == NULL || pAttrBrush == NULL, FALSE, "Null input pointers to OpApplyAttrib::ApplyBrushAttr");
00964 ERROR2IF(!pCurrentNode->IsAnObject(), FALSE, "Input node is not an ink node in OpApplyAttrib::ApplyBrushAttr");
00965
00966
00967 if (pCurrentNode->IsCompound())
00968 return TRUE;
00969
00970 AttrLineWidth* pCurrentLineWidth = NULL;
00971 ((NodeRenderableInk*)pCurrentNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrLineWidth), (NodeAttribute**)&pCurrentLineWidth);
00972
00973 if (pCurrentLineWidth != NULL)
00974 {
00975
00976 AttrLineWidth* pDefault = (AttrLineWidth*)(AttributeManager::GetDefaultAttribute(ATTR_LINEWIDTH));
00977 if (pDefault == NULL)
00978 {
00979 ERROR3("Unable to get default line width, theres no way this can happen Jim!");
00980
00981 }
00982 else
00983 {
00984
00985 if (pCurrentLineWidth->Value.LineWidth != pDefault->Value.LineWidth-1)
00986 {
00987 delete pDefault;
00988 PathProcessorBrush* pPPB = pAttrBrush->GetPathProcessor();
00989 if (pPPB)
00990 {
00991 BOOL UsesPressure = pAttrBrush->GetPressureCache() != NULL;
00992 pPPB->ScaleToValue(pCurrentLineWidth->Value.LineWidth, !UsesPressure);
00993 pPPB->AdjustSpacingForClosedPath((NodeRenderableInk*)pCurrentNode);
00994 }
00995
00996 return TRUE;
00997 }
00998 delete pDefault;
00999 }
01000 }
01001
01002
01003
01004 MILLIPOINT LineWidth = pAttrBrush->GetDefaultLineWidth(TRUE);
01005
01006
01007 AttrLineWidth NewLineWidth;
01008
01009 NewLineWidth.Value.LineWidth = LineWidth;
01010
01011
01012 return DoApply(pCurrentNode, &NewLineWidth, FALSE, FALSE);
01013
01014 }
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 BOOL OpApplyAttrib::KeepExistingCharacteristics(AttrFillGeometry* OldAttr,
01032 AttrFillGeometry* NewAttr)
01033 {
01034 NewAttr->SetStartTransp(OldAttr->GetStartTransp());
01035 NewAttr->SetEndTransp(OldAttr->GetEndTransp());
01036
01037 NewAttr->SetTranspType(OldAttr->GetTranspType());
01038
01039 if (OldAttr->IsAFlatFill())
01040 {
01041 if (OldAttr->FindParent()->IsNodeDocument())
01042 {
01043
01044
01045 DocColour DefFillCol;
01046 AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
01047 _R(IDS_BLACKNAME), &DefFillCol);
01048 NewAttr->SetEndColour(&DefFillCol);
01049 }
01050 else
01051 NewAttr->SetEndColour(OldAttr->GetStartColour());
01052 }
01053 else
01054 {
01055 NewAttr->SetStartColour(OldAttr->GetStartColour());
01056 NewAttr->SetEndColour(OldAttr->GetEndColour());
01057 }
01058
01059 NewAttr->SetTesselation(OldAttr->GetTesselation());
01060 NewAttr->AttachBitmap(OldAttr->GetBitmap());
01061
01062 if (OldAttr->IsAFractalFill())
01063 {
01064 NewAttr->SetSeed(OldAttr->GetSeed());
01065 NewAttr->SetGraininess(OldAttr->GetGraininess());
01066 NewAttr->SetGravity(OldAttr->GetGravity());
01067 NewAttr->SetSquash(OldAttr->GetSquash());
01068 NewAttr->SetTileable(OldAttr->GetTileable());
01069 NewAttr->SetFractalDPI(AttrFillGeometry::FractalDPI);
01070 NewAttr->RecalcFractal();
01071 }
01072
01073 return TRUE;
01074 }
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 BOOL SelOperation::InvalidateNodeRegion( SelOperation* pOp,
01093 NodeRenderableBounded* CurrentNode,
01094 NodeAttribute* Attrib,
01095 BOOL Mutate)
01096 {
01097
01098 BOOL IncludeBlobs = Attrib->EffectsParentBounds();
01099
01100 if ( (Mutate && !Attrib->IsAValueChange()) ||
01101 Attrib->GetRuntimeClass() == CC_RUNTIME_CLASS(AttrBitmapDpiChange) )
01102 {
01103
01104
01105 IncludeBlobs = TRUE;
01106 }
01107
01108
01109 if (pOp)
01110 {
01111 if (!pOp->DoInvalidateNodeRegion(CurrentNode, IncludeBlobs, FALSE, FALSE, FALSE))
01112
01113 {
01114
01115 return FALSE;
01116 }
01117 }
01118 else
01119 {
01120 BaseDocument* pBaseDoc = CurrentNode->FindOwnerDoc();
01121 if (pBaseDoc && pBaseDoc->IsKindOf(CC_RUNTIME_CLASS(Document)))
01122 {
01123 Document* pDoc = (Document*)pBaseDoc;
01124 Spread* pSpread = (Spread*)CurrentNode->FindParent(CC_RUNTIME_CLASS(Spread));
01125 DocRect TempRect;
01126 TempRect = (IncludeBlobs ?
01127 (CurrentNode->GetUnionBlobBoundingRect()):
01128 (CurrentNode->GetBoundingRect())
01129 );
01130 TempRect = TempRect.Union(CurrentNode->GetEffectStackBounds());
01131 pDoc->ForceRedraw(pSpread, TempRect, TRUE, CurrentNode, FALSE);
01132 }
01133 }
01134
01135 return TRUE;
01136 }
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146