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 #include "camtypes.h"
00100
00101
00102
00103 #include "saveeps.h"
00104
00105
00106
00107
00108 #include "cxftags.h"
00109
00110
00111
00112
00113 #include "nodecntr.h"
00114 #include "ncntrcnt.h"
00115
00116
00117
00118 #include "nodecont.h"
00119
00120
00121 #include "opcntr.h"
00122
00123 #include "opbevel.h"
00124 #include "objchge.h"
00125 #include "transop.h"
00126 #include "nodetext.h"
00127 #include "cutop.h"
00128 #include "textops.h"
00129 #include "ophist.h"
00130 #include "attrappl.h"
00131
00132
00133
00134 #include "lineattr.h"
00135
00136
00137
00138
00139 #include "gclips.h"
00140 #include "blobs.h"
00141 #include "nodeblnd.h"
00142
00143
00144
00145 #include "gdraw.h"
00146 #include "ppbevel.h"
00147
00148 #include "extender.h"
00149 #include "ngcore.h"
00150
00151 #include "blndhelp.h"
00152
00153 #include "nodebldr.h"
00154 #include "nodepath.h"
00155 #include "pathops.h"
00156 #include "fthrattr.h"
00157 #include "pathndge.h"
00158
00159 #include "blndtool.h"
00160 #include "cmxrendr.h"
00161 #include "attrmap.h"
00162
00163
00164 CC_IMPLEMENT_DYNCREATE(NodeContourController, NodeGroup)
00165 CC_IMPLEMENT_DYNCREATE(ContourNodeTreeFactory, CompoundNodeTreeFactory)
00166 CC_IMPLEMENT_DYNCREATE(ContourNodePathProcessor, PathProcessor)
00167 CC_IMPLEMENT_DYNCREATE(ContourRecordHandler, CamelotRecordHandler)
00168 CC_IMPLEMENT_DYNAMIC(InsetPathPathProcessor, PathProcessor);
00169
00170
00171 #define new CAM_DEBUG_NEW
00172
00173
00174
00175 #define DEFAULTCOLOURINCREASE 180
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 NodeContourController::NodeContourController()
00188 {
00189 m_Steps = 5;
00190 m_Width = 5000;
00191 m_BlendType = COLOURBLEND_FADE;
00192 m_bInsetPath = FALSE;
00193 m_pPathProc = NULL;
00194 m_PerformedExtend = FALSE;
00195
00196 #ifdef _DEBUG
00197 myContourID = -1;
00198 myContourBecomeAID = -1;
00199 #endif
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 NodeContourController::NodeContourController(Node* ContextNode,
00219 AttachNodeDirection Direction,
00220 BOOL Locked,
00221 BOOL Mangled,
00222 BOOL Marked,
00223 BOOL Selected
00224 )
00225 {
00226 m_Steps = 5;
00227 m_Width = 5000;
00228 m_BlendType = COLOURBLEND_FADE;
00229 m_bInsetPath = FALSE;
00230 m_pPathProc = NULL;
00231
00232 #ifdef _DEBUG
00233 myContourID = -1;
00234 myContourBecomeAID = -1;
00235 #endif
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 NodeContourController::~NodeContourController()
00249 {
00250 #ifdef _DEBUG
00251
00252 if (myContourID > -1)
00253 {
00254 TCHAR strId[100];
00255 camSnprintf( strId, 100, _T("Popping NodeContourController ID: %i\n"), myContourID );
00256
00257 TRACEUSER( "ChrisS", strId );
00258 }
00259
00260 #endif
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 DocRect NodeContourController::GetBoundingRect(BOOL DontUseAttrs, BOOL HitTest)
00274 {
00275
00276 if (!(!IsBoundingRectValid || DontUseAttrs))
00277 {
00278 return BoundingRectangle;
00279 }
00280
00281 NodeContour * pContour = GetContourNode();
00282
00283 DocRect dr;
00284
00285 if (!pContour)
00286 {
00287 dr = GetInsideBoundingRect();
00288
00289 if (m_Width < 0)
00290 {
00291 dr.lo.x -= -m_Width;
00292 dr.lo.y -= -m_Width;
00293 dr.hi.x += -m_Width;
00294 dr.hi.y += -m_Width;
00295 }
00296 }
00297 else
00298 {
00299 dr = pContour->GetBoundingRect(DontUseAttrs, HitTest);
00300 dr = dr.Union(GetInsideBoundingRect());
00301 }
00302
00303 IsBoundingRectValid = TRUE;
00304 BoundingRectangle = dr;
00305
00306 return dr;
00307
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 DocRect NodeContourController::GetBlobBoundingRect()
00321 {
00322 DocRect br = GetBoundingRect(FALSE, FALSE);
00323
00324
00325 BlobManager * pBlobMgr = GetApplication()->GetBlobManager();
00326
00327 INT32 Width = 0;
00328
00329 if (pBlobMgr)
00330 {
00331 Width = pBlobMgr->GetBlobSize();
00332 }
00333
00334 br.lo.x -= Width;
00335 br.lo.y -= Width;
00336 br.hi.x += Width;
00337 br.hi.y += Width;
00338
00339 return br;
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 void NodeContourController::SelectInRect(const DocRect& Rect, SelStateAction st)
00370 {
00371
00372 NodeRenderableInk* pInkChild = NULL;
00373 Node* pChild = FindFirstChild();
00374 while (pChild != NULL)
00375 {
00376 if (pChild->IsAnObject())
00377 {
00378 pInkChild = (NodeRenderableInk*)pChild;
00379 if (Rect.ContainsRect(pInkChild->GetBoundingRect()))
00380 {
00381 switch (st)
00382 {
00383 case CLEAR:
00384 if (pInkChild->MarqueeSelectNode())
00385 {
00386 pInkChild->DeSelect(TRUE);
00387 }
00388 break;
00389
00390 case SET:
00391 if (pInkChild->MarqueeSelectNode())
00392 {
00393 pInkChild->Select(TRUE);
00394 }
00395 break;
00396
00397 case TOGGLE:
00398 if (pInkChild->MarqueeSelectNode())
00399 {
00400 if (pInkChild->IsSelected())
00401 pInkChild->DeSelect(TRUE);
00402 else
00403 pInkChild->Select(TRUE);
00404 }
00405 break;
00406
00407 default:
00408 ERROR3("NodeContourController::SelectInRect; Unknown SelStateAction!\n");
00409 return;
00410 }
00411 }
00412 }
00413 pChild = pChild->FindNext();
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 void NodeContourController::Render(RenderRegion* pRender)
00430 {
00431 if (m_bInsetPath)
00432 {
00433 PathProcessor * pProc = pRender->GetFirstPathProcessor();
00434
00435 if (pProc)
00436 {
00437 if (!pProc->IS_KIND_OF(InsetPathPathProcessor))
00438 {
00439 ERROR3("Top path processor isn't an inset path processor");
00440 m_pPathProc = NULL;
00441 }
00442 else
00443 {
00444 pRender->PopPathProcessor();
00445 m_pPathProc = NULL;
00446 }
00447 }
00448 }
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 void NodeContourController::DisableInsetPathPathProcessor()
00462 {
00463 if (m_pPathProc)
00464 m_pPathProc->SetActive(FALSE);
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 void NodeContourController::EnableInsetPathPathProcessor()
00478 {
00479 if (m_pPathProc)
00480 m_pPathProc->SetActive(TRUE);
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 SubtreeRenderState NodeContourController::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip)
00496 {
00497 if (m_bInsetPath && pRender!=NULL && !pRender->IsPrinting())
00498 {
00499
00500 m_pPathProc = new InsetPathPathProcessor;
00501
00502 ERROR2IF(m_pPathProc == NULL, SUBTREE_NORENDER, _R(IDE_NOMORE_MEMORY));
00503 pRender->PushPathProcessor(m_pPathProc);
00504 }
00505
00506
00507 return NodeGroup::RenderSubtree(pRender, ppNextNode, bClip);
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 BOOL NodeContourController::DoBecomeA(BecomeA* pBecomeA)
00521 {
00522
00523 ERROR2IF_PF(pBecomeA == NULL,FALSE,("pBecomeA is NULL"));
00524
00525 if (!pBecomeA->BAPath())
00526 {
00527 return FALSE;
00528 }
00529
00530 BOOL ValidReason = (pBecomeA->GetReason() == BECOMEA_REPLACE || pBecomeA->GetReason() == BECOMEA_PASSBACK);
00531 ERROR2IF_PF(!ValidReason,FALSE,("Unkown BecomeA reason %d",pBecomeA->GetReason()));
00532
00533 UndoableOperation* pOp = pBecomeA->GetUndoOp();
00534
00535
00536 Node * pNode = NULL;
00537
00538 NodeHidden * pHidden = NULL;
00539
00540
00541 List MyList;
00542
00543
00544 NodeContour * pContour = (NodeContour *)FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
00545
00546 BOOL ok = TRUE;
00547
00548 switch (pBecomeA->GetReason())
00549 {
00550 case BECOMEA_REPLACE:
00551
00552
00553 if (!m_bInsetPath)
00554 {
00555
00556
00557 BOOL fSelectBecomeAGroup = IsParentOfSelected();
00558
00559 if (!NodeGroup::DoBecomeA(pBecomeA))
00560 return FALSE;
00561
00562
00563 NodeGroup* pGroup = BecomeAGroup(pOp);
00564
00565
00566 if (pGroup == NULL)
00567 ok = FALSE;
00568 else if (fSelectBecomeAGroup)
00569 pGroup->Select(FALSE);
00570 }
00571 else
00572 {
00573
00574 if (pContour)
00575 {
00576
00577 if (ok)
00578 {
00579 if (pOp)
00580 ok = pOp->DoLocaliseCommonAttributes(this, TRUE);
00581 else
00582 ok = LocaliseCommonAttributes(TRUE, FALSE, NULL);
00583 }
00584
00585
00586
00587
00588 if (ok) ok = pContour->DoBecomeA(pBecomeA);
00589
00590
00591 if (ok)
00592 {
00593 if (pOp)
00594 ok = pOp->DoHideNode(this, TRUE, &pHidden, TRUE);
00595 else
00596 {
00597 CascadeDelete();
00598 delete this;
00599 }
00600 }
00601 }
00602 }
00603 break;
00604 case BECOMEA_PASSBACK :
00605 if (pBecomeA->IsBlendBecomeA())
00606 {
00607 CompoundNodeBlendBecomeA MyBecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath),
00608 NULL, FALSE, this, pBecomeA);
00609
00610
00611 Node * pChild = FindFirstChild();
00612
00613 while (pChild)
00614 {
00615 if (pChild->IsAnObject() && !pChild->NeedsParent(NULL))
00616 {
00617 MyBecomeA.ResetCount();
00618
00619 if (pChild->CanBecomeA(&MyBecomeA))
00620 {
00621
00622 MyBecomeA.SetNumPathNodes(MyBecomeA.GetCount());
00623 MyBecomeA.ResetCount();
00624
00625 pChild->DoBecomeA(&MyBecomeA);
00626 }
00627 }
00628
00629 pChild = pChild->FindNext();
00630 }
00631 }
00632 else if (pBecomeA->IsCompoundBlendBecomeA ())
00633 {
00634
00635
00636
00637
00638
00639
00640 CompoundNodeBlendBecomeA MyBecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath),
00641 NULL, FALSE, this, pBecomeA);
00642
00643 Node * pChild = FindFirstChild();
00644
00645 while (pChild)
00646 {
00647 if (pChild->IsAnObject() && !pChild->NeedsParent(NULL))
00648 {
00649 MyBecomeA.ResetCount();
00650
00651 if (pChild->CanBecomeA(&MyBecomeA))
00652 {
00653
00654 MyBecomeA.SetNumPathNodes(MyBecomeA.GetCount());
00655 MyBecomeA.ResetCount();
00656
00657 pChild->DoBecomeA(&MyBecomeA);
00658 }
00659 }
00660
00661 pChild = pChild->FindNext();
00662 }
00663 }
00664 else
00665 {
00666 pNode = FindFirstChild();
00667 while (pNode != NULL)
00668 {
00669 if (pNode->CanBecomeA(pBecomeA))
00670 {
00671 if (!pNode->DoBecomeA(pBecomeA))
00672 return FALSE;
00673 }
00674
00675 pNode = pNode->FindNext();
00676 }
00677 }
00678
00679 break;
00680 default: break;
00681 }
00682
00683 return ok;
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 NodeRenderableInk* NodeContourController::GetInkNodeFromController() const
00702 {
00703
00704 Node* pKid = FindFirstChild();
00705
00706 while (pKid != NULL)
00707 {
00708 if (pKid->IsAnObject() && !pKid->IsAContour())
00709 break;
00710
00711 pKid = pKid->FindNext();
00712
00713 }
00714
00715
00716 ERROR3IF(pKid == NULL, "NodeContourController::GetInkNodeFromController; Can't find contoured node!");
00717 return (NodeRenderableInk*)pKid;
00718
00719
00720 }
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 BOOL NodeContourController::PromoteAttributeApplicationToMe(CCRuntimeClass *pAttrClass) const
00737 {
00738 if (pAttrClass == CC_RUNTIME_CLASS(AttrJoinType))
00739 return TRUE;
00740
00741 return FALSE;
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757 NodeRenderableInk *
00758 NodeContourController::CreateTreeFromNodeToBlend(NodeRenderableInk * pNode,
00759 CCAttrMap * pAttrMap)
00760 {
00761
00762 ERROR2IF(pNode->FindParent() != NULL, NULL, "Node shouldn't have parents");
00763
00764 if (pNode->IsNodePath())
00765 {
00766 pNode->CascadeDelete();
00767 }
00768
00769
00770 if (pNode->IsNodePath() && pAttrMap)
00771 {
00772 pNode->ApplyAttributes(pAttrMap, FALSE);
00773 }
00774
00775
00776 NodeContourController * pControl = NULL;
00777
00778 pControl = (NodeContourController *)this->PublicCopy();
00779 ERRORIF(pControl == NULL, _R(IDE_NOMORE_MEMORY), NULL);
00780
00781 NodeContour * pContour = (NodeContour *)FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
00782 ERROR2IF(pContour == NULL, NULL, "Can't find bevel node");
00783
00784
00785 NodeContour * pCopyContour = (NodeContour *)pContour->PublicCopy();
00786 ERRORIF(pCopyContour == NULL, _R(IDE_NOMORE_MEMORY), NULL);
00787
00788 CCAttrMap * pContourMap = CCAttrMap::MakeAppliedAttrMap(pContour);
00789
00790
00791 ERRORIF(pContourMap == NULL, _R(IDE_NOMORE_MEMORY), NULL);
00792
00793 pCopyContour->ApplyAttributes(pContourMap, FALSE);
00794
00795 delete pContourMap;
00796
00797 pNode->AttachNode(pControl, FIRSTCHILD);
00798
00799 if (m_Width < 0)
00800 {
00801 pCopyContour->AttachNode(pControl, FIRSTCHILD);
00802 }
00803 else
00804 {
00805 pCopyContour->AttachNode(pControl, LASTCHILD);
00806 }
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 return pControl;
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 BOOL NodeContourController::CanBecomeA(BecomeA* pBecomeA)
00833 {
00834
00835 if (!pBecomeA->BAPath())
00836 return FALSE;
00837
00838 if (pBecomeA->IsCounting())
00839 {
00840 NodeRenderableInk* pNode = (NodeRenderableInk*)FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk));
00841 while (pNode)
00842 {
00843 if (!pNode->NeedsParent(NULL))
00844 {
00845
00846 pNode->CanBecomeA(pBecomeA);
00847 }
00848
00849 pNode = (NodeRenderableInk*)pNode->FindNext(CC_RUNTIME_CLASS(NodeRenderableInk));
00850 }
00851 }
00852
00853 return TRUE;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 String NodeContourController::Describe(BOOL Plural, BOOL Verbose)
00867 {
00868 String Name;
00869 Name.Load(_R(IDS_CONTOUR_NODE_NAME));
00870
00871 if (Plural)
00872 {
00873 Name += _T("s");
00874 }
00875
00876 return Name;
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889 ChangeCode NodeContourController::OnChildChange(ObjChangeParam* pParam)
00890 {
00891 BOOL bRegen = TRUE;
00892 BOOL bCache = FALSE;
00893
00894 if (m_PerformedExtend)
00895 {
00896
00897
00898
00899
00900 m_PerformedExtend = FALSE;
00901 return CC_OK;
00902 }
00903
00904
00905
00906
00907
00908 UndoableOperation* pOp = NULL;
00909 if (pParam->GetOpPointer())
00910 {
00911 if (pParam->GetOpPointer()->IsKindOf(CC_RUNTIME_CLASS(UndoableOperation)))
00912 {
00913 pOp = pParam->GetOpPointer();
00914 }
00915 }
00916
00917 Document * pDoc = Document::GetCurrent();
00918
00919 Spread * pSpread = (Spread *)FindParent(CC_RUNTIME_CLASS(Spread));
00920
00921 if (!pOp)
00922 {
00923
00924 if (pDoc)
00925 {
00926 if (pParam->GetChangeFlags ().RegenerateNode)
00927 {
00928 RegenerateNode(pOp, bCache, FALSE);
00929
00930 }
00931
00932 pDoc->ForceRedraw(pSpread, GetBoundingRect(FALSE, FALSE), FALSE, this);
00933 }
00934
00935 return CC_OK;
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 List TextNodeList;
00948
00949
00950 List ChildList;
00951
00952
00953
00954 DocRect Bounds;
00955
00956
00957
00958
00959 TRACEUSER( "DavidM", _T("Contour - onchildchange\n"));
00960
00961 if (pParam->GetChangeType() == OBJCHANGE_FINISHED)
00962 {
00963
00964
00965
00966
00967
00968
00969
00970
00971 if (pOp != NULL)
00972 {
00973
00974
00975
00976
00977
00978
00979 if( pOp->IS_KIND_OF(OpPathNudge) )
00980 {
00981 bRegen = TRUE;
00982 }
00983
00984 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(TransOperation)) &&
00985 !pOp->IS_KIND_OF(OpMovePathPoint))
00986 {
00987 if (IsSelected())
00988 return CC_OK;
00989
00990 return NodeGroup::OnChildChange(pParam);
00991 }
00992 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpApplyAttrib)))
00993 {
00994 if (pSpread)
00995 {
00996 ReleaseCached();
00997 pOp->DoInvalidateRegion( pSpread, GetBoundingRect() );
00998 }
00999
01000 CCRuntimeClass * pClass = ((OpApplyAttrib *)pOp)->GetValueChangeType();
01001
01002 bRegen = FALSE;
01003
01004
01005
01006 if (pClass)
01007 {
01008
01009 if (pClass->IsKindOf(CC_RUNTIME_CLASS(AttrTxtBase)) ||
01010 pClass->IsKindOf(CC_RUNTIME_CLASS(AttrStartArrow)) ||
01011 pClass->IsKindOf(CC_RUNTIME_CLASS(AttrEndArrow)))
01012 {
01013
01014 bRegen = TRUE;
01015 }
01016 else if (pClass->IS_KIND_OF(AttrStrokeColour))
01017 {
01018 bRegen = FALSE;
01019 }
01020 else if (pClass->IsKindOf(CC_RUNTIME_CLASS(AttrLineWidth)))
01021 {
01022
01023
01024 bRegen = FALSE;
01025
01026 Range * pSel = GetApplication()->FindSelection();
01027
01028 if (pSel)
01029 {
01030 Node * pStepNode = pSel->FindFirst();
01031
01032 while (pStepNode)
01033 {
01034 if (pStepNode->IsNodePath())
01035 {
01036 if ( !((NodePath*)pStepNode)->InkPath.IsClosed() )
01037 {
01038 bRegen = TRUE;
01039 break;
01040 }
01041 }
01042
01043 pStepNode = pSel->FindNext(pStepNode);
01044 }
01045 }
01046 }
01047 else if (pClass->IS_KIND_OF(AttrJoinType))
01048 {
01049
01050
01051 if (DealWithJoinTypeChange(pOp))
01052 return CC_OK;
01053
01054 return CC_FAIL;
01055 }
01056 }
01057 }
01058
01059
01060
01061 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpReplaceAttributes)))
01062 {
01063
01064 String_256 OpName;
01065
01066 if (pSpread)
01067 {
01068 ReleaseCached();
01069 pOp->DoInvalidateRegion(pSpread, GetBoundingRect());
01070 }
01071
01072
01073 NodeAttribute * pAttr = ((OpReplaceAttributes *)pOp)->GetAttribute();
01074
01075 if (pAttr)
01076 {
01077 if (pAttr->IsAFillAttr())
01078 {
01079 bRegen = FALSE;
01080 }
01081
01082 if (pAttr->IsATranspFill())
01083 {
01084 bRegen = TRUE;
01085 }
01086 }
01087 }
01088 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpDelete)))
01089 {
01090
01091
01092 bRegen = TRUE;
01093 }
01094 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpCopy)))
01095 {
01096 bRegen = FALSE;
01097 }
01098 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpCut)))
01099 {
01100 bRegen = TRUE;
01101 }
01102 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpPaste)))
01103 {
01104 bRegen = TRUE;
01105 }
01106 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpTextFormat)))
01107 {
01108 return NodeGroup::OnChildChange(pParam);
01109 }
01110 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpDeleteTextStory)))
01111 {
01112
01113 return NodeGroup::OnChildChange(pParam);
01114 }
01115 else if (pOp->IsKindOf(CC_RUNTIME_CLASS(CarbonCopyOp)))
01116 {
01117 bRegen = FALSE;
01118 }
01119
01120 if (bRegen)
01121 {
01122
01123 if (pSpread)
01124 {
01125 ReleaseCached();
01126 pOp->DoInvalidateRegion(pSpread, BoundingRectangle);
01127 }
01128
01129 RegenerateNode(pOp, bCache, FALSE);
01130 return CC_OK;
01131
01132 }
01133 }
01134 else
01135 {
01136
01137 }
01138 }
01139
01140 return NodeGroup::OnChildChange(pParam);
01141 }
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 BOOL NodeContourController::DealWithJoinTypeChange(UndoableOperation * pOp)
01154 {
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 RegenerateNode(pOp, FALSE, TRUE);
01212 return TRUE;
01213 }
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235 BOOL NodeContourController::AllowOp(ObjChangeParam *pParam, BOOL SetOpPermissionState,
01236 BOOL DoPreTriggerEdit)
01237 {
01238 ERROR2IF(pParam==NULL,FALSE,"NodeContourController::AllowOp() - pParam==NULL");
01239
01240
01241 BOOL allowed=TRUE;
01242
01243 UndoableOperation* pOp = pParam->GetOpPointer();
01244
01245 if (pOp)
01246 {
01247
01248 if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpCreateBevel)))
01249 allowed = FALSE;
01250 else
01251 if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpRemoveBlend)))
01252 {
01253 allowed = FALSE;
01254 pParam->SetReasonForDenial(_R(IDS_CANT_REMOVE_BLEND_WHEN_CONTOURED));
01255 }
01256 }
01257
01258 if (pParam->GetDirection() != OBJCHANGE_CALLEDBYCHILD ||
01259 pParam->GetCallingChild() != NULL)
01260 {
01261 BOOL AnyAllowed = AllowOp_AccountForCompound( pParam,
01262 SetOpPermissionState,
01263 DoPreTriggerEdit );
01264
01265
01266 if (pParam->GetDirection() == OBJCHANGE_CALLEDBYPARENT)
01267 return AnyAllowed;
01268 }
01269
01270 Spread * pSpread = (Spread *)FindParent(CC_RUNTIME_CLASS(Spread));
01271 if (!pSpread)
01272 pSpread = Document::GetSelectedSpread();
01273
01274
01275
01276 if (allowed && Parent!=NULL && pParam->GetDirection()!=OBJCHANGE_CALLEDBYPARENT)
01277 {
01278 ObjChangeDirection OldDirection=pParam->GetDirection();
01279 pParam->SetCallingChild(this);
01280 pParam->SetDirection(OBJCHANGE_CALLEDBYCHILD);
01281 allowed=Parent->AllowOp(pParam,SetOpPermissionState,DoPreTriggerEdit);
01282 pParam->SetDirection(OldDirection);
01283 }
01284
01285
01286 if (SetOpPermissionState)
01287 {
01288
01289 if (allowed)
01290 {
01291 SetOpPermission(PERMISSION_ALLOWED, TRUE);
01292
01293 if (pParam->GetDirection()==OBJCHANGE_CALLEDBYCHILD || pParam->GetChangeFlags().Attribute)
01294 {
01295 if (pOp!=NULL)
01296 {
01297 if (allowed)
01298 allowed=pOp->DoInvalidateNodeRegion(this,TRUE);
01299 if (allowed)
01300 allowed=pOp->DoInvalidateNodeRegion((NodeContour *)this->FindFirstChild(CC_RUNTIME_CLASS(NodeContour)),TRUE);
01301 if (allowed && pSpread)
01302 allowed=pOp->DoInvalidateRegion(pSpread, GetBoundingRect());
01303 }
01304 }
01305 }
01306 else
01307 SetOpPermission(PERMISSION_DENIED,TRUE);
01308 }
01309
01310
01311
01312
01313 if (allowed && DoPreTriggerEdit)
01314 {
01315
01316 UndoableOperation* pChangeOp = pParam->GetOpPointer();
01317 if (pChangeOp != NULL && pChangeOp->MayChangeNodeBounds())
01318 {
01319 if (NameGallery::Instance())
01320 allowed = NameGallery::Instance()->PreTriggerEdit(pChangeOp, pParam, this);
01321 }
01322 }
01323
01324 return allowed;
01325 }
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339 BOOL NodeContourController::RegenerateNode(UndoableOperation * pOp, BOOL bCacheRender,
01340 BOOL bInformParents)
01341 {
01342
01343 if (IsPrinting())
01344 return FALSE;
01345
01346 Document * pDoc = Document::GetCurrent();
01347
01348 NodeContour * pContour = GetContourNode();
01349
01350
01351 if (!pContour)
01352 return FALSE;
01353
01354
01355 Spread * pSpread = (Spread *)FindParent(CC_RUNTIME_CLASS(Spread));
01356 if (!pSpread)
01357 pSpread = Document::GetSelectedSpread();
01358
01359 ERROR2IF(pSpread==NULL,FALSE,"Failed to get a spread pointer!");
01360
01361 if (!pOp)
01362 {
01363
01364 if (bInformParents)
01365 PreInformParentsOfRegenerate();
01366
01367 if (pDoc && pSpread)
01368 pDoc->ForceRedraw(pSpread, BoundingRectangle, FALSE, this);
01369
01370 pContour->GenerateContour();
01371
01372 InvalidateBoundingRect(TRUE);
01373
01374 if (pDoc)
01375 pDoc->ForceRedraw(pSpread, GetBoundingRect(TRUE, FALSE), FALSE, this);
01376
01377
01378 if (bInformParents)
01379 PostInformParentsOfRegenerate();
01380 }
01381 else
01382 {
01383 List ContList;
01384 NodeListItem * pItem = NULL;
01385 RegenerateContourAction* pRegenAction = NULL;
01386
01387 if (pOp)
01388 {
01389 ALLOC_WITH_FAIL(pItem, new NodeListItem, pOp);
01390
01391 pItem->pNode = this;
01392 ContList.AddTail(pItem);
01393
01394
01395 ReleaseCached();
01396 if (!pOp->DoInvalidateRegion(pSpread, BoundingRectangle))
01397 return FALSE;
01398
01399
01400 if (RegenerateContourAction::Init(pOp, pOp->GetUndoActionList(),&ContList,&pRegenAction,
01401 bCacheRender) == AC_FAIL)
01402 {
01403 ERROR3("RegenerateContourAction::Init failed !\n");
01404 return FALSE;
01405 }
01406 ContList.DeleteAll();
01407
01408
01409 ReleaseCached();
01410 if (!pOp->DoInvalidateRegion(pSpread, BoundingRectangle))
01411 return FALSE;
01412 }
01413 }
01414
01415
01416 GetApplication()->UpdateSelection();
01417
01418 return TRUE;
01419 }
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431 NodeContour * NodeContourController::GetContourNode()
01432 {
01433 NodeContour * pNode = (NodeContour *)FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
01434
01435
01436
01437 return pNode;
01438 }
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450 void NodeContourController::RenderEorDrag(RenderRegion * pRender)
01451 {
01452 BOOL bChildrenSelected = FALSE;
01453
01454 Node * pNode = FindFirstChild();
01455 Node * pInsideNode = NULL;
01456
01457
01458 while (pNode)
01459 {
01460 if (pNode->IsSelected() && pNode->IsAnObject())
01461 {
01462 bChildrenSelected = TRUE;
01463 }
01464
01465 pNode = pNode->FindNext();
01466 }
01467
01468 if (!bChildrenSelected)
01469 {
01470 Node * pSelParent = FindParent();
01471
01472 while (pSelParent && pSelParent->IsAnObject())
01473 {
01474 if (pSelParent->IsSelected())
01475 {
01476 bChildrenSelected = TRUE;
01477 break;
01478 }
01479
01480 pSelParent = pSelParent->FindParent();
01481 }
01482 }
01483
01484 NodeContour * pContour = GetContourNode();
01485
01486 if ((bChildrenSelected || IsSelected()))
01487 {
01488 if (GetWidth() < 0)
01489 {
01490 if (pContour)
01491 {
01492 pContour->RenderEorDrag(pRender);
01493 }
01494 }
01495 else
01496 {
01497
01498 pInsideNode = FindFirstDepthFirst();
01499
01500 while (pInsideNode && pInsideNode != this)
01501 {
01502 if (pInsideNode->IsAnObject())
01503 {
01504 ((NodeRenderableInk *)pInsideNode)->RenderEorDrag(pRender);
01505 }
01506
01507 pInsideNode = pInsideNode->FindNextDepthFirst(this);
01508 }
01509 }
01510
01511 }
01512 else
01513 {
01514
01515 pInsideNode = FindFirstDepthFirst();
01516
01517 while (pInsideNode && pInsideNode != this)
01518 {
01519 if (pInsideNode->IsSelected() && pInsideNode->IsAnObject())
01520 {
01521 ((NodeRenderableInk *)pInsideNode)->RenderEorDrag(pRender);
01522 }
01523
01524 pInsideNode = pInsideNode->FindNextDepthFirst(this);
01525 }
01526 }
01527 }
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539 INT32 NodeContourController::ComplexHide(UndoableOperation* pOp, Node* pNextInRange)
01540 {
01541 NodeHidden * pHidden = NULL;
01542 BOOL ok = pOp->DoHideNode(this, TRUE, &pHidden, TRUE);
01543
01544 if (ok)
01545 return 1;
01546
01547 return -1;
01548 }
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560 void NodeContourController::Transform(TransformBase &Trans)
01561 {
01562
01563 NodeGroup::Transform(Trans);
01564
01565
01566 TransformBase *pTrans = &Trans;
01567
01568 if (pTrans->IsKindOf(CC_RUNTIME_CLASS(Trans2DMatrix)))
01569 {
01570 Trans2DMatrix* pMat = (Trans2DMatrix*)pTrans;
01571 BOOL HasBeenFlipped = FALSE;
01572
01573 if(pMat->GetWorkingQuadrant() == 2 || pMat->GetWorkingQuadrant() == 4)
01574 {
01575 HasBeenFlipped = TRUE;
01576 }
01577
01578
01579 if (pMat->GetAspect().MakeDouble() == 1.0 && pMat->GetSkew() == 0 && !HasBeenFlipped)
01580 {
01581 m_Width = (MILLIPOINT)(((double)m_Width) * pMat->GetScale().MakeDouble());
01582 BoundingRectangle = GetBoundingRect();
01583 }
01584 else
01585 {
01586 RegenerateNode(NULL, FALSE);
01587 BoundingRectangle = GetBoundingRect();
01588 }
01589 }
01590 }
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604 BOOL NodeContourController::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
01605 {
01606 CXaraFileRecord Rec(TAG_CONTOURCONTROLLER, TAG_CONTOUR_CONTROLLER_SIZE);
01607
01608 BOOL ok = TRUE;
01609
01610 if (ok) ok = Rec.Init();
01611
01612 if (ok) ok = Rec.WriteINT32(m_Steps);
01613 if (ok) ok = Rec.WriteINT32(m_Width);
01614
01615 BYTE Type = (BYTE)m_BlendType;
01616
01617 if (m_bInsetPath)
01618 Type |= 128;
01619
01620 if (ok) ok = Rec.WriteBYTE(Type);
01621 if (ok) ok = Rec.WriteDOUBLE((double)m_ObjBiasGain.GetBias());
01622 if (ok) ok = Rec.WriteDOUBLE((double)m_ObjBiasGain.GetGain());
01623 if (ok) ok = Rec.WriteDOUBLE((double)m_AttrBiasGain.GetBias());
01624 if (ok) ok = Rec.WriteDOUBLE((double)m_AttrBiasGain.GetGain());
01625
01626 if (ok) ok = pFilter->Write(&Rec);
01627
01628 return ok;
01629 }
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641 BOOL NodeContourController::WritePreChildrenNative(BaseCamelotFilter* pFilter)
01642 {
01643 return WritePreChildrenWeb(pFilter);
01644 }
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668 BOOL NodeContourController::PostImport()
01669 {
01670 RegenerateNode(NULL, FALSE);
01671 return TRUE;
01672 }
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684 BOOL NodeContourController::EndBlendStep(BlendNodeParam * pParam)
01685 {
01686
01687
01688 if (!pParam->GetHandleBecomeA ())
01689 {
01690
01691
01692 BOOL okToRender = TRUE;
01693
01694
01695 if (pParam->GetPathProcessor ())
01696 {
01697 ERROR2IF(!pParam->GetPathProcessor ()->IS_KIND_OF(SumAllPathsPathProcessor),
01698 FALSE, "First path processor isn't a sum all paths path processor");
01699
01700
01701 SumAllPathsPathProcessor * pProc = (SumAllPathsPathProcessor *) pParam->GetPathProcessor ();
01702
01703 pProc->SetEnabled(FALSE);
01704
01705
01706
01707
01708
01709 Node* copy = NULL;
01710 this->NodeCopy (©);
01711
01712 NodeContourController* ptrCopy = (NodeContourController*) copy;
01713
01714 if (!ptrCopy) { return (FALSE); }
01715
01716
01717 NodeContour * pContourCopy = (NodeContour *)ptrCopy->FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
01718 ERROR2IF(pContourCopy == NULL, FALSE, "Can't find the contour node");
01719
01721
01722
01723
01724 CCAttrMap * pMap = NULL;
01725 CCAttrMap * pPrimaryContourAttrMap = NULL;
01726
01727
01728 NodeContourController * pEndControl = (NodeContourController *)FindAssociatedBlendNode(pParam);
01729
01730 if (pEndControl)
01731 {
01732
01733
01734 NodeContour * pEndContour = (NodeContour *)pEndControl->FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
01735 NodeRenderableInk * pOrigEndNode = pEndControl->GetBlendCreatedByNode();
01736
01737
01738 ERROR2IF(pOrigEndNode == NULL, FALSE, "Cant find the original contour node which this is based on");
01739 ERROR2IF(!pOrigEndNode->IS_KIND_OF(NodeContourController), FALSE, "Original node isn't a NodeContourController");
01740
01741 pOrigEndNode = (NodeContour *)pOrigEndNode->FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
01742
01743 BlendPath MyStartPath;
01744 MyStartPath.Initialise((NodeRenderableInk *)pContourCopy->PublicCopy(), -1, pContourCopy, 1, 0, NULL);
01745
01746 BlendPath MyEndPath;
01747 MyEndPath.Initialise((NodeRenderableInk *)pEndContour->PublicCopy(), -1, pOrigEndNode, 1, 0, NULL);
01748
01749 BlendNodeParam BNParam;
01750 BNParam.Init(pParam, &MyStartPath, &MyEndPath);
01751
01752 pMap = new CCAttrMap(30);
01753
01754 BlendHelpers * pHelp = new BlendHelpers;
01755 ERRORIF(pHelp == NULL, _R(IDE_NOMORE_MEMORY), FALSE);
01756
01757
01758 if (!pHelp->BlendAttributes(&BNParam, pMap))
01759 {
01760 pParam->GetRenderRegion()->PopPathProcessor();
01761 okToRender = FALSE;
01762 }
01763
01764 delete pHelp;
01765
01766
01767 ptrCopy->BlendParameters ((NodeContourController*) m_pBlendCreatedByNode, (NodeContourController*) pOrigEndNode->FindParent(), pParam->GetAttrBlendRatio ());
01768 }
01769 else
01770 {
01771
01772
01773
01774
01775
01776
01777
01778 NodeContour * pContour = (NodeContour *) FindFirstChild (CC_RUNTIME_CLASS (NodeContour));
01779
01780 ERROR2IF (pContour == NULL, FALSE, "Can't find Contour node");
01781
01782
01783 pPrimaryContourAttrMap = CCAttrMap::MakeAppliedAttrMap(pContour);
01784
01785
01786 ptrCopy->BlendParameters ((NodeContourController *) m_pBlendCreatedByNode, pParam->GetAttrBlendRatio ());
01787 }
01788
01789
01790 NodePath* currentPath = (NodePath *)ptrCopy->FindFirstChild(CC_RUNTIME_CLASS(NodePath));
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801 if (currentPath)
01802 {
01803 currentPath->CascadeDelete ();
01804 delete (currentPath);
01805 currentPath = NULL;
01806
01807 NodeGroup* newGroup = new NodeGroup ();
01808
01809 ListItem* pItem = pProc->GetList ()->GetHead ();
01810
01811 Path* blendPath = NULL;
01812 CCAttrMap* blendMap = NULL;
01813
01814 while (pItem)
01815 {
01816 blendPath = ((SumAllPathsElem *) pItem)->GetPath ();
01817 blendMap = ((SumAllPathsElem *) pItem)->GetAttrMap ();
01818
01819 NodePath* newPath = new NodePath ();
01820 INT32 numCoords = blendPath->GetNumCoords ();
01821 newPath->InkPath.ClearPath ();
01822 newPath->InkPath.Initialise (numCoords);
01823 newPath->InkPath.CopyPathDataFrom (blendPath);
01824 blendMap->ApplyAttributesToNode (newPath);
01825 newPath->AttachNode(newGroup, LASTCHILD);
01826
01827 pItem = pProc->GetList ()->GetNext (pItem);
01828 delete ((SumAllPathsElem *) pProc->GetList()->RemoveHead ());
01829 }
01830
01831 if (ptrCopy->m_Width < 0)
01832 {
01833 newGroup->AttachNode(pContourCopy, NEXT);
01834 }
01835 else if (ptrCopy->m_Width > 0)
01836 {
01837 newGroup->AttachNode(pContourCopy, PREV);
01838 }
01839 }
01840
01841
01842
01843 if (pMap)
01844 {
01845 pMap->ApplyAttributesToNode (pContourCopy);
01846 }
01847
01848 if (pPrimaryContourAttrMap)
01849 {
01850 pPrimaryContourAttrMap->ApplyAttributesToNode (pContourCopy);
01851 }
01852
01853
01854
01855 if (!pContourCopy->GenerateContour())
01856 {
01857 okToRender = FALSE;
01858 }
01859
01860
01861
01862 if (okToRender)
01863 {
01864
01865
01866
01867 Node* parent = FindParent ();
01868
01869 if (parent != NULL)
01870 {
01871 if (!IS_A (parent, NodeShadowController))
01872 {
01873 RenderRegion* pRegion = pParam->GetRenderRegion();
01874
01875
01876 if (pRegion)
01877 pRegion->RenderTreeNoCache(ptrCopy);
01878 }
01879 else
01880 {
01881
01882 SetShadowDeleteThisNode (ptrCopy);
01883 }
01884 }
01885 else
01886 {
01887 RenderRegion* pRegion = pParam->GetRenderRegion();
01888
01889
01890 if (pRegion)
01891 pRegion->RenderTreeNoCache(ptrCopy);
01892 }
01893 }
01894
01895 if (pMap)
01896 {
01897 pMap->DeleteAttributes ();
01898 delete pMap;
01899 }
01900
01901 if (pPrimaryContourAttrMap)
01902 {
01903 delete pPrimaryContourAttrMap;
01904 }
01905
01906
01907
01908 Node* parent = FindParent ();
01909
01910 if (parent != NULL)
01911 {
01912 if (!(IS_A (parent, NodeShadowController)))
01913 {
01914 ptrCopy->CascadeDelete ();
01915 delete (ptrCopy);
01916 }
01917 }
01918 else
01919 {
01920 ptrCopy->CascadeDelete ();
01921 delete (ptrCopy);
01922 }
01923 }
01924 }
01925 else
01926 {
01927
01928 if (pParam->GetPathProcessor ())
01929 {
01930 ERROR2IF(!pParam->GetPathProcessor ()->IS_KIND_OF(SumAllPathsPathProcessor),
01931 FALSE, "First path processor isn't a sum all paths path processor");
01932
01933
01934 SumAllPathsPathProcessor * pProc = (SumAllPathsPathProcessor *)pParam->GetPathProcessor ();
01935
01936 pProc->SetEnabled(FALSE);
01937
01938
01939
01940
01941
01942 Node* copy = NULL;
01943 this->NodeCopy (©);
01944
01945 NodeContourController* ptrCopy = (NodeContourController*) copy;
01946
01947 if (!ptrCopy) { return (FALSE); }
01948
01949
01950 NodeContour * pContourCopy = (NodeContour *)ptrCopy->FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
01951 ERROR2IF(pContourCopy == NULL, FALSE, "Can't find the contour node");
01952
01954
01955
01956
01957 CCAttrMap * pMap = NULL;
01958 CCAttrMap * pPrimaryContourAttrMap = NULL;
01959
01960
01961 NodeContourController * pEndControl = (NodeContourController *)FindAssociatedBlendNode(pParam);
01962
01963 if (pEndControl)
01964 {
01965
01966
01967 NodeContour * pEndContour = (NodeContour *)pEndControl->FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
01968 NodeRenderableInk * pOrigEndNode = pEndControl->GetBlendCreatedByNode();
01969
01970
01971 ERROR2IF(pOrigEndNode == NULL, FALSE, "Cant find the original contour node which this is based on");
01972 ERROR2IF(!pOrigEndNode->IS_KIND_OF(NodeContourController), FALSE, "Original node isn't a NodeContourController");
01973
01974 pOrigEndNode = (NodeContour *)pOrigEndNode->FindFirstChild(CC_RUNTIME_CLASS(NodeContour));
01975
01976 BlendPath MyStartPath;
01977 MyStartPath.Initialise((NodeRenderableInk *)pContourCopy->PublicCopy(), -1, pContourCopy, 1, 0, NULL);
01978
01979 BlendPath MyEndPath;
01980 MyEndPath.Initialise((NodeRenderableInk *)pEndContour->PublicCopy(), -1, pOrigEndNode, 1, 0, NULL);
01981
01982 BlendNodeParam BNParam;
01983 BNParam.Init(pParam, &MyStartPath, &MyEndPath);
01984
01985 pMap = new CCAttrMap(30);
01986
01987 BlendHelpers * pHelp = new BlendHelpers;
01988 ERRORIF(pHelp == NULL, _R(IDE_NOMORE_MEMORY), FALSE);
01989
01990
01991 if (!pHelp->BlendAttributes(&BNParam, pMap))
01992 {
01993 pParam->GetRenderRegion()->PopPathProcessor();
01994 }
01995
01996 delete pHelp;
01997
01998
01999 ptrCopy->BlendParameters ((NodeContourController*) m_pBlendCreatedByNode, (NodeContourController*) pOrigEndNode->FindParent(), pParam->GetAttrBlendRatio ());
02000 }
02001 else
02002 {
02003
02004
02005
02006
02007
02008
02009
02010 NodeContour * pContour = (NodeContour *) FindFirstChild (CC_RUNTIME_CLASS (NodeContour));
02011
02012 ERROR2IF (pContour == NULL, FALSE, "Can't find Contour node");
02013
02014
02015 pPrimaryContourAttrMap = CCAttrMap::MakeAppliedAttrMap(pContour);
02016
02017
02018 ptrCopy->BlendParameters ((NodeContourController *) m_pBlendCreatedByNode, pParam->GetAttrBlendRatio ());
02019 }
02020
02021
02022 NodePath* currentPath = (NodePath *)ptrCopy->FindFirstChild(CC_RUNTIME_CLASS(NodePath));
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033 std::list<NodePath*> pathPtrs;
02034
02035 if (currentPath)
02036 {
02037 currentPath->CascadeDelete ();
02038 delete (currentPath);
02039 currentPath = NULL;
02040
02041 NodeGroup* newGroup = new NodeGroup ();
02042
02043 ListItem* pItem = pProc->GetList ()->GetHead ();
02044
02045 Path* blendPath = NULL;
02046 CCAttrMap* blendMap = NULL;
02047
02048 while (pItem)
02049 {
02050 blendPath = ((SumAllPathsElem *) pItem)->GetPath ();
02051 blendMap = ((SumAllPathsElem *) pItem)->GetAttrMap ();
02052
02053 NodePath* newPath = new NodePath ();
02054 INT32 numCoords = blendPath->GetNumCoords ();
02055 newPath->InkPath.ClearPath ();
02056 newPath->InkPath.Initialise (numCoords);
02057 newPath->InkPath.CopyPathDataFrom (blendPath);
02058 blendMap->ApplyAttributesToNode (newPath);
02059 newPath->AttachNode(newGroup, LASTCHILD);
02060
02061 pathPtrs.push_back (newPath);
02062
02063 pItem = pProc->GetList ()->GetNext (pItem);
02064 delete ((SumAllPathsElem *) pProc->GetList()->RemoveHead ());
02065 }
02066
02067 if (ptrCopy->m_Width < 0)
02068 {
02069 newGroup->AttachNode(pContourCopy, NEXT);
02070 }
02071 else if (ptrCopy->m_Width > 0)
02072 {
02073 newGroup->AttachNode(pContourCopy, PREV);
02074 }
02075
02076
02077 }
02078
02079
02080
02081 if (pMap)
02082 {
02083 pMap->ApplyAttributesToNode (pContourCopy);
02084 }
02085
02086 if (pPrimaryContourAttrMap)
02087 {
02088 pPrimaryContourAttrMap->ApplyAttributesToNode (pContourCopy);
02089 }
02090
02091
02092
02093 pContourCopy->GenerateContour();
02094
02095
02096
02097 BecomeA* accessPtr = pParam->GetHandleBecomeA ()->GetBecomeA ();
02098 UndoableOperation* pUndoOp = accessPtr->GetUndoOp ();
02099
02100 Node* parent = NULL;
02101 NodeRenderableInk* pCreator = GetBlendCreatedByNode ();
02102 ERROR2IF(pCreator == NULL, FALSE, "Cant find the original bevel node which this is based on");
02103
02104 parent = pCreator->FindParent (CC_RUNTIME_CLASS (NodeShadowController));
02105
02106
02107
02108 Node* pBlenderParent = NULL;
02109 Node* pBlender = pParam->GetNodeBlend ();
02110 ERROR2IF(pBlender == NULL, FALSE, "Cant find the original node blend which this node is based on!");
02111
02112 pBlenderParent = pBlender->FindParent (CC_RUNTIME_CLASS (NodeShadowController));
02113
02114 BOOL parentIsNodeShadow = FALSE;
02115
02116 if (parent)
02117 {
02118 if (!pBlenderParent)
02119 {
02120 parentIsNodeShadow = TRUE;
02121 }
02122
02123 }
02124
02125
02126 if (accessPtr->GetReason () == BECOMEA_REPLACE)
02127 {
02128 if (!parentIsNodeShadow)
02129 {
02130 if (!pUndoOp->DoInsertNewNode (ptrCopy,pParam->GetHandleBecomeA ()->GetContextNode (),PREV,TRUE,FALSE,FALSE,TRUE))
02131 {
02132 return FALSE;
02133 }
02134
02135
02136
02137 pContourCopy->NormaliseAttributes ();
02138
02139 std::list<NodePath*>::iterator i;
02140
02141 for (i = pathPtrs.begin (); i != pathPtrs.end (); i++)
02142 {
02143 (*i)->NormaliseAttributes ();
02144 }
02145
02146
02147
02148
02149 if (accessPtr->GetInsertComplexBlendStepsAsPaths ())
02150 {
02151 ptrCopy->DoBecomeA (accessPtr);
02152 }
02153 }
02154 else
02155 {
02156 SetShadowThisNode (ptrCopy);
02157
02158 }
02159 }
02160
02161 else if (accessPtr->GetReason () == BECOMEA_PASSBACK)
02162 {
02163 if (parentIsNodeShadow)
02164 {
02165 SetShadowThisNode (ptrCopy);
02166
02167 }
02168 ptrCopy->DoBecomeA (accessPtr);
02169 ptrCopy->SetBlenderNode (pParam->GetNodeBlend ());
02170
02171
02172
02173 if (AllocatedBlendConsList (LT_BECOMEA_CONTOURSLIST))
02174 {
02175 BlendConsListInsert (LT_BECOMEA_CONTOURSLIST, ptrCopy);
02176 }
02177 else
02178 {
02179 AllocBlendConsList (LT_BECOMEA_CONTOURSLIST);
02180 BlendConsListInsert (LT_BECOMEA_CONTOURSLIST, ptrCopy);
02181 }
02182 }
02183
02184 if (pMap)
02185 {
02186 pMap->DeleteAttributes ();
02187 delete pMap;
02188 }
02189
02190 if (pPrimaryContourAttrMap)
02191 {
02192 delete pPrimaryContourAttrMap;
02193 }
02194 }
02195 }
02196
02197 return TRUE;
02198 }
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217 BOOL NodeContourController::BlendParameters (NodeContourController * pStart, NodeContourController * pEnd, double Scale)
02218 {
02219
02220
02221 NodeContour * pStartContour = (NodeContour *) pStart->GetContour ();
02222 ERROR2IF(!pStartContour, FALSE, "Can't find Contour child node for start");
02223
02224 NodeContour * pEndContour = (NodeContour *) pEnd->GetContour ();
02225 ERROR2IF(!pEndContour, FALSE, "Can't find Contour child node for end");
02226
02227 NodeContour * pThisContour = (NodeContour *) GetContour();
02228 ERROR2IF(!pThisContour, FALSE, "Can't find Contour child node for blend node");
02229
02230
02231
02232 double startSteps = pStart->m_Steps;
02233 double endSteps = pEnd->m_Steps;
02234
02235 double newSteps = ((endSteps - startSteps) * Scale) + startSteps;
02236
02237
02238 if (newSteps < 0) { newSteps = 1; }
02239
02240 UINT32 temp = (UINT32) newSteps;
02241 double remainder = (double) (newSteps - temp);
02242 if (remainder <= 0.5) { m_Steps = temp; }
02243 else { m_Steps = temp + 1; }
02244
02245 if (m_Steps <= 0) { m_Steps = 1; }
02246
02247
02248
02249 double startWidth = pStart->m_Width;
02250 double endWidth = pEnd->m_Width;
02251
02252 double newWidth = ((endWidth - startWidth) * Scale) + startWidth;
02253 m_Width = (INT32) newWidth;
02254
02255
02256
02257 double StartBias = pStart->m_AttrBiasGain.GetBias();
02258 double EndBias = pEnd->m_AttrBiasGain.GetBias();
02259 double NewBias = ((EndBias - StartBias) * Scale) + StartBias;
02260
02261 double StartGain = pStart->m_AttrBiasGain.GetGain();
02262 double EndGain = pEnd->m_AttrBiasGain.GetGain();
02263 double NewGain = ((EndGain - StartGain) * Scale) + StartGain;
02264
02265 m_AttrBiasGain.SetBiasGain (NewBias, NewGain);
02266
02267 StartBias = pStart->m_ObjBiasGain.GetBias();
02268 EndBias = pEnd->m_ObjBiasGain.GetBias();
02269 NewBias = ((EndBias - StartBias) * Scale) + StartBias;
02270
02271 StartGain = pStart->m_ObjBiasGain.GetGain();
02272 EndGain = pEnd->m_ObjBiasGain.GetGain();
02273 NewGain = ((EndGain - StartGain) * Scale) + StartGain;
02274
02275 m_ObjBiasGain.SetBiasGain (NewBias, NewGain);
02276
02277 return (TRUE);
02278 }
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295 BOOL NodeContourController::BlendParameters(NodeContourController * pStart, double Scale)
02296 {
02297
02298
02299 NodeContour * pStartContour = (NodeContour *) pStart->GetContour ();
02300 ERROR2IF(!pStartContour, FALSE, "Can't find Contour child node for start");
02301
02302 NodeContour * pThisContour = (NodeContour *) GetContour();
02303 ERROR2IF(!pThisContour, FALSE, "Can't find Contour child node for blend node");
02304
02305
02306
02307 double startSteps = pStart->m_Steps;
02308 double endSteps = 0;
02309
02310 double startSteps2 = pStart->m_Steps;
02311 double endSteps2 = 0;
02312
02313
02314
02315 double newSteps = -((endSteps - startSteps) * Scale);
02316 double newSteps2 = -((endSteps2 - startSteps2) * (1-Scale));
02317
02318
02319 newSteps = newSteps2 - newSteps;
02320
02321 if (newSteps < 0) { newSteps = 1; }
02322
02323 UINT32 temp = (UINT32) newSteps;
02324 double remainder = (double) (newSteps - temp);
02325 if (remainder <= 0.5) { m_Steps = temp; }
02326 else { m_Steps = temp + 1; }
02327
02328 if (m_Steps <= 0) { m_Steps = 1; }
02329
02330
02331
02332 double startWidth = pStart->m_Width;
02333 double endWidth = 0;
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343 double newWidth = ((endWidth - startWidth) * Scale) + startWidth;
02344 m_Width = (INT32) newWidth;
02345
02346
02347
02348 CProfileBiasGain defaultBiasGain;
02349
02350 double StartBias = pStart->m_AttrBiasGain.GetBias();
02351 double EndBias = defaultBiasGain.GetBias();
02352 double NewBias = ((EndBias - StartBias) * Scale) + StartBias;
02353
02354 double StartGain = pStart->m_AttrBiasGain.GetGain();
02355 double EndGain = defaultBiasGain.GetGain();
02356 double NewGain = ((EndGain - StartGain) * Scale) + StartGain;
02357
02358 m_AttrBiasGain.SetBiasGain (NewBias, NewGain);
02359
02360 StartBias = pStart->m_ObjBiasGain.GetBias();
02361 EndBias = defaultBiasGain.GetBias();
02362 NewBias = ((EndBias - StartBias) * Scale) + StartBias;
02363
02364 StartGain = pStart->m_ObjBiasGain.GetGain();
02365 EndGain = defaultBiasGain.GetGain();
02366 NewGain = ((EndGain - StartGain) * Scale) + StartGain;
02367
02368 m_ObjBiasGain.SetBiasGain (NewBias, NewGain);
02369
02370 return (TRUE);
02371 }
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384 NodeContour* NodeContourController::GetContour ()
02385 {
02386 NodeContour* pBob = (NodeContour*) FindFirstChild (CC_RUNTIME_CLASS (NodeContour));
02387
02388 return pBob;
02389 }
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402 Node* NodeContourController::SimpleCopy()
02403 {
02404 NodeContourController* pNode = new NodeContourController;
02405 ERRORIF(pNode == NULL, _R(IDE_NOMORE_MEMORY), NULL);
02406
02407 if (pNode)
02408 {
02409 CopyNodeContents(pNode);
02410 }
02411
02412 return pNode;
02413 }
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425 void NodeContourController::CopyNodeContents(NodeContourController* pNewNode)
02426 {
02427 pNewNode->m_Steps = m_Steps;
02428 pNewNode->m_Width = m_Width;
02429 pNewNode->m_BlendType = m_BlendType;
02430 pNewNode->m_AttrBiasGain = m_AttrBiasGain;
02431 pNewNode->m_ObjBiasGain = m_ObjBiasGain;
02432 pNewNode->m_bInsetPath = m_bInsetPath;
02433 pNewNode->m_PerformedExtend = m_PerformedExtend;
02434
02435 if (pNewNode->m_pPathProc)
02436 delete pNewNode->m_pPathProc;
02437 pNewNode->m_pPathProc = NULL;
02438
02439
02440 pNewNode->m_bBlendStartNode = m_bBlendStartNode;
02441 pNewNode->m_bBlendEndNode = m_bBlendEndNode;
02442 pNewNode->m_pBlendCreatedByNode = m_pBlendCreatedByNode;
02443
02444 NodeGroup::CopyNodeContents(pNewNode);
02445 }
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462 void NodeContourController::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
02463 {
02464 ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
02465 ENSURE(IS_A(pNodeCopy, NodeContourController), "PolyCopyNodeContents given wrong dest node type");
02466
02467 if (IS_A(pNodeCopy, NodeContourController))
02468 CopyNodeContents((NodeContourController*)pNodeCopy);
02469 }
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484 BOOL NodeContourController::AreOpenPathsInChildren()
02485 {
02486 Node * pNode = FindFirstChild();
02487
02488 while (pNode)
02489 {
02490 if (pNode->IsNodePath())
02491 {
02492 if (!((NodePath *)pNode)->InkPath.IsSubPathClosed(0))
02493 {
02494 return TRUE;
02495 }
02496 }
02497
02498 pNode = pNode->FindNext();
02499 }
02500
02501 return FALSE;
02502 }
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526 DocRect NodeContourController::ValidateExtend(const ExtendParams& ExtParams)
02527 {
02528 Node* pBob = GetContourNode();
02529 DocRect drMinExtend(INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX), drThisMinExtend;
02530 for ( Node* pChildNode = FindFirstChild();
02531 pChildNode != NULL;
02532 pChildNode = pChildNode->FindNext() )
02533 {
02534 if (pChildNode == pBob)
02535 continue;
02536
02537 drThisMinExtend = pChildNode->ValidateExtend(ExtParams);
02538 if (drMinExtend.lo.x < drThisMinExtend.lo.x) drMinExtend.lo.x = drThisMinExtend.lo.x;
02539 if (drMinExtend.lo.y < drThisMinExtend.lo.y) drMinExtend.lo.y = drThisMinExtend.lo.y;
02540 if (drMinExtend.hi.x < drThisMinExtend.hi.x) drMinExtend.hi.x = drThisMinExtend.hi.x;
02541 if (drMinExtend.hi.y < drThisMinExtend.hi.y) drMinExtend.hi.y = drThisMinExtend.hi.y;
02542 }
02543 return drMinExtend;
02544 }
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567 void NodeContourController::Extend(const ExtendParams& ExtParams)
02568 {
02569 Node* pBob = GetContourNode();
02570 for ( Node* pChildNode = FindFirstChild();
02571 pChildNode != NULL;
02572 pChildNode = pChildNode->FindNext() )
02573 {
02574 if (pChildNode == pBob)
02575 continue;
02576
02577 pChildNode->Extend(ExtParams);
02578 }
02579
02580
02581
02582
02583 m_PerformedExtend = TRUE;
02584 RegenerateNode(ExtParams.pOp, FALSE, FALSE);
02585 }
02586
02587
02588
02589 void NodeContourController::PreExportRender(RenderRegion* pRegion)
02590 {
02591 #ifdef DO_EXPORT
02592 if (pRegion->IsKindOf(CC_RUNTIME_CLASS(EPSRenderRegion)))
02593 {
02594
02595 EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC();
02596 pDC->OutputToken(_T("u"));
02597 pDC->OutputNewLine();
02598 }
02599 PORTNOTE("cmx", "Removed use of CMXRenderRegion")
02600 #ifndef EXCLUDE_FROM_XARALX
02601 else if(pRegion->IsKindOf(CC_RUNTIME_CLASS(CMXRenderRegion)))
02602 {
02603
02604 CMXExportDC *pDC = (CMXExportDC *) pRegion->GetRenderDC();
02605 DocRect BBox = GetBoundingRect();
02606 pDC->StartGroup(&BBox);
02607 }
02608 #endif
02609 #endif
02610 }
02611
02612 BOOL NodeContourController::ExportRender(RenderRegion* pRegion)
02613 {
02614 #ifdef DO_EXPORT
02615 if (pRegion->IsKindOf(CC_RUNTIME_CLASS(EPSRenderRegion)))
02616 {
02617
02618 EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC();
02619 pDC->OutputToken(_T("U"));
02620 pDC->OutputNewLine();
02621
02622
02623 return TRUE;
02624 }
02625 PORTNOTE("cmx", "Removed use of CMXRenderRegion")
02626 #ifndef EXCLUDE_FROM_XARALX
02627 else if(pRegion->IsKindOf(CC_RUNTIME_CLASS(CMXRenderRegion)))
02628 {
02629
02630 CMXExportDC *pDC = (CMXExportDC *) pRegion->GetRenderDC();
02631 pDC->EndGroup();
02632
02633 return TRUE;
02634 }
02635 #endif
02636 #endif
02637
02638 return FALSE;
02639 }
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653 void NodeContourController::RenderTinyBlobs(RenderRegion* pRegion)
02654 {
02655 #if !defined(EXCLUDE_FROM_RALPH)
02656
02657 Node* pNode = FindLastChild();
02658 while (pNode != NULL && !pNode->IsAnObject())
02659 pNode = pNode->FindPrevious();
02660
02661
02662 if (pNode == NULL)
02663 {
02664 ERROR3("NodeGroup::RenderTinyBlobs; This group is empty! Shouldn't be!");
02665 return;
02666 }
02667 else
02668 {
02669 ((NodeRenderableInk*)pNode)->RenderTinyBlobs(pRegion);
02670 }
02671
02672 #endif
02673 }
02674
02675
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688 ContourNodeTreeFactory::ContourNodeTreeFactory()
02689 {
02690 m_Steps = 5;
02691 m_Width = 5000;
02692 m_pMap = NULL;
02693 m_bInsetPath = FALSE;
02694 }
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706 ContourNodeTreeFactory::~ContourNodeTreeFactory()
02707 {
02708 if (m_pMap)
02709 {
02710 delete m_pMap;
02711 m_pMap = NULL;
02712 }
02713 }
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725 NodeCompound * ContourNodeTreeFactory::CreateNode(List * pList, UndoableOperation * pOp)
02726 {
02727 ERROR2IF(pList == NULL, NULL, "List is null");
02728 ERROR2IF(pList->IsEmpty(), NULL, "List is empty");
02729
02730 String_256 StatusString;
02731 StatusString.Load(_R(IDS_CONTOUR_CREATE_STATUS_STRING));
02732 GetApplication()->UpdateStatusBarText(&StatusString, FALSE);
02733 PORTNOTE("status","Removed UpdateStatusLineFont usage")
02734 #ifndef EXCLUDE_FROM_XARALX
02735 GetApplication()->GetpCCStatusBar()->UpdateStatusLineFont();
02736 #endif
02737
02738 NodeContourController * pController = NULL;
02739 ALLOC_WITH_FAIL(pController, new NodeContourController, pOp);
02740
02741 pController->SetNumberOfSteps(m_Steps);
02742 pController->SetWidth(m_Width);
02743 pController->SetInsetPathFlag(m_bInsetPath);
02744
02745 NodeContour * pContour = NULL;
02746
02747 NodeListItem * pItem = (NodeListItem *)pList->GetHead();
02748
02749 CCAttrMap * pMap = m_pMap;
02750
02751 if (!m_pMap)
02752 {
02753 if (!pItem->pNode->IS_KIND_OF(NodeBlend))
02754 {
02755 pMap = CCAttrMap::MakeAppliedAttrMap((NodeRenderableInk *)pItem->pNode);
02756 }
02757 else
02758 {
02759 pMap = CCAttrMap::MakeAppliedAttrMap((NodeRenderableInk *)
02760 (pItem->pNode->FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk))));
02761 }
02762
02763 if (!pMap)
02764 {
02765 ERROR3("can't create attribute map");
02766 return NULL;
02767 }
02768 }
02769
02770 List AttrList;
02771
02772 pMap->BuildListOfAttributes(&AttrList);
02773
02774
02775 BOOL bOK = TRUE;
02776
02777
02778 ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
02779 flgs.RegenerateNode = TRUE;
02780 ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pItem->pNode, pOp, OBJCHANGE_CALLEDBYOP);
02781
02782
02783
02784 Node * pNodeCopy = NULL;
02785
02786 DocColour *pStartColour = NULL;
02787
02788
02789
02790
02791
02792 INT32 H = 0;
02793 INT32 S = 0;
02794 INT32 V = 0;
02795
02796 BOOL bFoundColourFill = FALSE;
02797
02798
02799 if (pOp && pItem)
02800 {
02801
02802 bFoundColourFill = FALSE;
02803 if (pItem->pNode->AllowOp(&OP, FALSE))
02804 {
02805 if (bOK)
02806 {
02807 bOK = pOp->DoInsertNewNode(pController, pItem->pNode, PREV, TRUE, FALSE, FALSE, TRUE);
02808 }
02809
02810 while (pItem && bOK)
02811 {
02812 bOK = pOp->DoMoveNode(pItem->pNode, pController, LASTCHILD);
02813
02814 if (pItem->pNode->IsAnObject() && bOK)
02815 {
02816 bOK = pOp->DoSelectNode((NodeRenderableInk *)pItem->pNode);
02817 }
02818
02819 pItem = (NodeListItem *)pList->GetNext(pItem);
02820 }
02821
02822 if (bOK)
02823 {
02824 ALLOC_WITH_FAIL(pContour, new NodeContour, pOp);
02825
02826 if (!pContour)
02827 {
02828 ERROR3("cant' create contour node");
02829 return NULL;
02830 }
02831
02832
02833 pItem = (NodeListItem *)AttrList.GetHead();
02834
02835 while (pItem && bOK)
02836 {
02837
02838
02839 NodeAttribute * pNodeAttr = (NodeAttribute *)pItem->pNode;
02840 if (pNodeAttr->IsAColourFill() || pNodeAttr->IsATranspFill() ||
02841 pNodeAttr->IsAStrokeColour() || pNodeAttr->IsAStrokeTransp() ||
02842 pNodeAttr->IS_KIND_OF(AttrLineWidth) ||
02843 pNodeAttr->IS_KIND_OF(AttrJoinType) ||
02844 pNodeAttr->IS_KIND_OF(AttrFillMapping) ||
02845 pNodeAttr->IS_KIND_OF(AttrTranspFillMapping))
02846 {
02847 pItem->pNode->NodeCopy(&pNodeCopy);
02848
02849 if (pNodeCopy)
02850 {
02851 if (((NodeAttribute *)pNodeCopy)->IsAColourFill() &&
02852 !((NodeAttribute *)pNodeCopy)->IsATranspFill())
02853 {
02854
02855 pStartColour = ((AttrFillGeometry *)pNodeCopy)->GetStartColour();
02856
02857 if (pStartColour)
02858 {
02859 if (!pStartColour->IsTransparent())
02860 {
02861 bFoundColourFill = TRUE;
02862
02863 pStartColour->GetHSVValue(&H, &S, &V);
02864
02865 if (!m_bInsetPath)
02866 {
02867 V = (4 * (255 - V) / 5) + V;
02868
02869 S = S / 5;
02870 }
02871
02872 pStartColour->SetHSVValue(H,S,V);
02873 }
02874 }
02875 }
02876
02877 pNodeCopy->AttachNode(pContour, FIRSTCHILD, FALSE, FALSE);
02878 }
02879 else
02880 {
02881 bOK = FALSE;
02882 }
02883 }
02884
02885
02886 pItem = (NodeListItem *)AttrList.GetNext(pItem);
02887 }
02888
02889 AttrList.DeleteAll();
02890
02891
02892 AttrWindingRule * pWinding = (AttrWindingRule *)pContour->FindFirstChild(
02893 CC_RUNTIME_CLASS(AttrWindingRule));
02894
02895 if (pWinding)
02896 {
02897 pWinding->Value.WindingRule = NegativeWinding;
02898 }
02899
02900 if (bOK)
02901 {
02902
02903
02904 if (pController->GetWidth() < 0)
02905 {
02906 Node * pInsertNode = pController->FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk));
02907
02908 if (pInsertNode)
02909 bOK = pOp->DoInsertNewNode(pContour, pInsertNode, PREV, TRUE, FALSE, FALSE, TRUE);
02910 else
02911 ERROR2(NULL, "No insertion node !");
02912 }
02913 else
02914 {
02915 bOK = pOp->DoInsertNewNode(pContour, pController, LASTCHILD, TRUE, FALSE, FALSE, TRUE);
02916 }
02917
02918 }
02919 }
02920
02921 if (bOK && !bFoundColourFill)
02922 {
02923
02924
02925 Node * pColourNode = pController->FindFirstDepthFirst();
02926
02927 while (pColourNode && pColourNode != pController)
02928 {
02929 if (pColourNode->IsAnAttribute())
02930 {
02931
02932
02933 if (((NodeAttribute *)pColourNode)->IsAColourFill() &&
02934 !((NodeAttribute *)pColourNode)->IsATranspFill())
02935 {
02936
02937 pColourNode->NodeCopy(&pNodeCopy);
02938 pStartColour = ((AttrFillGeometry *)pNodeCopy)->GetStartColour();
02939
02940 if (pStartColour)
02941 {
02942 if (!pStartColour->IsTransparent())
02943 {
02944 bFoundColourFill = TRUE;
02945 pStartColour->GetHSVValue(&H, &S, &V);
02946
02947 if (!m_bInsetPath)
02948 {
02949 V = (4 * (255 - V) / 5) + V;
02950
02951 S = S / 5;
02952 }
02953
02954 pStartColour->SetHSVValue(H,S,V);
02955 }
02956
02957 pNodeCopy->AttachNode(pContour, FIRSTCHILD, FALSE, FALSE);
02958
02959 break;
02960 }
02961 else
02962 {
02963 delete pNodeCopy;
02964 }
02965 }
02966 }
02967
02968 pColourNode = pColourNode->FindNextDepthFirst(pController);
02969 }
02970 }
02971
02972 if (bOK)
02973 {
02974
02975 bOK = pOp->DoFactorOutCommonChildAttributes(pController, TRUE);
02976 }
02977
02978 if (bOK)
02979 {
02980
02981
02982
02983
02984
02985
02986 if (pController->GetWidth() > 0)
02987 {
02988 MILLIPOINT MaxWidth = ContourNodePathProcessor::GetMaxInnerContourWidth(pController);
02989 if (pController->GetWidth() > MaxWidth)
02990 {
02991 pController->SetWidth(MaxWidth);
02992 }
02993 }
02994
02995 pController->RegenerateNode(pOp, FALSE);
02996 }
02997
02998 if (bOK)
02999 {
03000 bOK = pOp->DoInvalidateNodeRegion(pController, TRUE);
03001 }
03002 }
03003 }
03004
03005 AttrList.DeleteAll();
03006
03007 if (m_bInsetPath)
03008 {
03009
03010 pController->SetSelected(FALSE);
03011 pContour->SetSelected(TRUE);
03012 }
03013
03014 GetApplication()->UpdateSelection();
03015
03016 if (pMap)
03017 {
03018 delete pMap;
03019 m_pMap = NULL;
03020 }
03021
03022 if (bOK)
03023 return pController;
03024
03025 return NULL;
03026 }
03027
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040 ContourNodePathProcessor::ContourNodePathProcessor()
03041 {
03042 TRACEUSER( "DavidM", _T("Created a contour node path processor\n"));
03043 m_bActive = TRUE;
03044 m_bLineWidthTest = TRUE;
03045 m_bPrinting = FALSE;
03046 m_bRespectJoinType = FALSE;
03047
03048 }
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060 ContourNodePathProcessor::~ContourNodePathProcessor()
03061 {
03062 TRACEUSER( "DavidM", _T("Killed a contour node path processor\n"));
03063 }
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080 void ContourNodePathProcessor::ProcessPath ( Path * pPath,
03081 RenderRegion * pRegion,
03082 PathShape ShapePath )
03083 {
03084 UINT32 StrokeWidth = 0;
03085
03086 if (m_bActive && pPath->IsClosed())
03087 {
03088
03089
03090 MILLIPOINT PixelWidth = pRegion->GetScaledPixelWidth();
03091
03092 if (m_bPrinting)
03093 {
03094 PixelWidth = pRegion->GetPixelWidth();
03095 }
03096
03097 StrokeWidth = PixelWidth * 2;
03098
03099 BOOL bStrokePath = FALSE;
03100
03101
03102
03103 if (m_bLineWidthTest)
03104 {
03105 LineWidthAttribute * pLineWidth = (LineWidthAttribute *)pRegion->GetCurrentAttribute(ATTR_LINEWIDTH);
03106
03107 if (pLineWidth)
03108 {
03109 if (pLineWidth->LineWidth < PixelWidth)
03110 {
03111 StrokeWidth = PixelWidth;
03112 bStrokePath = TRUE;
03113 }
03114 }
03115
03116 StrokeColourAttribute * pLineColour =
03117 (StrokeColourAttribute *)pRegion->GetCurrentAttribute(ATTR_STROKECOLOUR);
03118
03119 if (pLineColour)
03120 {
03121 DocColour * pDocColourLine = pLineColour->GetStartColour();
03122
03123 if (pDocColourLine)
03124 {
03125 if (pDocColourLine->IsTransparent())
03126 {
03127 bStrokePath = TRUE;
03128 }
03129 }
03130 }
03131 }
03132 else
03133 {
03134 bStrokePath = TRUE;
03135 }
03136
03137
03138 if (bStrokePath)
03139 {
03140 pRegion->SaveContext();
03141
03142 Path StrokedPath;
03143 StrokedPath.Initialise();
03144
03145 pPath->StrokePathToPath(StrokeWidth,
03146 LineCapRound,
03147 RoundJoin,
03148 NULL,
03149 &StrokedPath,
03150 200,
03151 FALSE);
03152
03153 StrokedPath.TryToClose();
03154 StrokedPath.IsFilled = TRUE;
03155 StrokedPath.IsStroked = TRUE;
03156
03157 pRegion->SetLineColour(COLOUR_NONE);
03158
03159 pRegion->DrawPath(&StrokedPath, this, ShapePath);
03160 pRegion->RestoreContext();
03161 }
03162 }
03163
03164 pRegion->DrawPath(pPath, this, ShapePath);
03165 }
03166
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179 ContourRecordHandler::ContourRecordHandler()
03180 {
03181
03182 }
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194 ContourRecordHandler::~ContourRecordHandler()
03195 {
03196 }
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207 UINT32* ContourRecordHandler::GetTagList()
03208 {
03209 static UINT32 TagList[] = { TAG_CONTOURCONTROLLER,
03210 TAG_CONTOUR,
03211 CXFRH_TAG_LIST_END};
03212
03213 return (UINT32*)&TagList;
03214 }
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226 BOOL ContourRecordHandler::HandleRecord(CXaraFileRecord* pCXaraFileRecord)
03227 {
03228 INT32 Steps = 0;
03229 INT32 Width = 0;
03230 BYTE Type = 0;
03231
03232 BOOL ok = TRUE;
03233
03234 double ObjBias = 0;
03235 double ObjGain = 0;
03236 double AttrBias = 0;
03237 double AttrGain = 0;
03238
03239 if (pCXaraFileRecord->GetTag() == TAG_CONTOURCONTROLLER)
03240 {
03241 ok = pCXaraFileRecord->ReadINT32(&Steps);
03242
03243 if (ok) ok = pCXaraFileRecord->ReadINT32(&Width);
03244 if (ok) ok = pCXaraFileRecord->ReadBYTE(&Type);
03245 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&ObjBias);
03246 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&ObjGain);
03247 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&AttrBias);
03248 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&AttrGain);
03249
03250 NodeContourController * pNode = new NodeContourController;
03251
03252 if (!pNode)
03253 {
03254 ERROR3("Can't create contour controller");
03255 return FALSE;
03256 }
03257
03258 pNode->SetWidth(Width);
03259 pNode->SetNumberOfSteps(Steps);
03260
03261 if ((Type & 128) != 0)
03262 {
03263 Type = Type - 128;
03264 pNode->SetInsetPathFlag(TRUE);
03265 }
03266
03267 pNode->SetColourBlendType((ColourBlendType)Type);
03268
03269 pNode->SetObjectProfile( CProfileBiasGain( (AFp)ObjBias, (AFp)ObjGain ) );
03270 pNode->SetAttrProfile( CProfileBiasGain( (AFp)AttrBias, (AFp)AttrGain ) );
03271
03272 if (ok)
03273 {
03274 InsertNode(pNode);
03275 }
03276 }
03277 else if (pCXaraFileRecord->GetTag() == TAG_CONTOUR)
03278 {
03279 NodeContour * pNode = new NodeContour;
03280
03281 if (!pNode)
03282 {
03283 ERROR3("Can't create NodeContour");
03284 return FALSE;
03285 }
03286
03287 InsertNode(pNode);
03288 }
03289 else
03290 {
03291 ERROR3("Contour file record handler - unrecognised tag");
03292 ok = FALSE;
03293 }
03294
03295 return ok;
03296 }
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308 MILLIPOINT ContourNodePathProcessor::GetMaxInnerContourWidth(NodeCompound * pCompound)
03309 {
03310 Node * pNode = pCompound->FindFirstDepthFirst();
03311
03312 DocRect dr;
03313
03314 MILLIPOINT MaxInnerBevel = -1;
03315 MILLIPOINT Len = 0;
03316
03317 while (pNode && pNode != pCompound)
03318 {
03319
03320 if (pNode->IsAnObject() && !pNode->NeedsParent(NULL) && !pNode->IsCompound())
03321 {
03322 dr = ((NodeRenderableInk *)pNode)->GetBoundingRect(FALSE, FALSE);
03323
03324
03325 if (dr.Width() > dr.Height())
03326 {
03327 Len = dr.Width();
03328 }
03329 else
03330 {
03331 Len = dr.Height();
03332 }
03333
03334 Len /= 2;
03335
03336 if (MaxInnerBevel < 0)
03337 {
03338 MaxInnerBevel = Len;
03339 }
03340 else if (MaxInnerBevel < Len)
03341 {
03342 MaxInnerBevel = Len;
03343 }
03344 }
03345
03346 pNode = pNode->FindNextDepthFirst(pCompound);
03347 }
03348
03349 return MaxInnerBevel;
03350 }
03351
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365 InsetPathPathProcessor::InsetPathPathProcessor()
03366 {
03367 m_bActive = TRUE;
03368 }
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380 InsetPathPathProcessor::~InsetPathPathProcessor()
03381 {
03382
03383 }
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397 void InsetPathPathProcessor::ProcessPath(Path *pPath,
03398 RenderRegion *pRender,
03399 PathShape ShapePath)
03400 {
03401 if (m_bActive)
03402 return;
03403
03404 pRender->DrawPath( pPath, this );
03405 }