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
00101
00102
00103
00104 #include "camtypes.h"
00105
00106
00107
00108
00109
00110 #include "nodepath.h"
00111 #include "ophist.h"
00112
00113
00114 #include "lineattr.h"
00115 #include "blendatt.h"
00116 #include "qualattr.h"
00117
00118 #include "gblend.h"
00119 #include "gwinding.h"
00120
00121 #include "grnddib.h"
00122
00123 #include "ndbldpth.h"
00124
00125
00126 #include "aw_eps.h"
00127 #include "nativeps.h"
00128 #include "cameleps.h"
00129 #include "attrmap.h"
00130 #include "progress.h"
00131
00132 #include "cxftags.h"
00133
00134
00135
00136
00137 #include "nodeblnd.h"
00138 #include "nodebldr.h"
00139
00140
00141 #include "oilbitmap.h"
00142
00143 #include "brshattr.h"
00144 #include "blndhelp.h"
00145 #include "fthrattr.h"
00146 #include "nodecont.h"
00147
00148 #include "brshbeca.h"
00149 #include "strkattr.h"
00150
00151 DECLARE_SOURCE("$Revision: 1315 $");
00152
00153
00154
00155
00156 #define SWAP(type,a,b) { type x=a; a=b; b=x; }
00157
00158 #define DELPTR(p) if (p != NULL) { delete p; p = NULL; }
00159
00160
00161
00162
00163 void ListStepper::Init(UINT32 NumInStart,UINT32 NumInEnd,UINT32 Start)
00164 {
00165 if (NumInStart > NumInEnd)
00166 {
00167 Min = NumInEnd; pNextInMin = &NextInEnd;
00168 Max = NumInStart; pNextInMax = &NextInStart;
00169 }
00170 else
00171 {
00172 Min = NumInStart; pNextInMin = &NextInStart;
00173 Max = NumInEnd; pNextInMax = &NextInEnd;
00174 }
00175
00176 NextInStart = NextInEnd = Inc = 0;
00177
00178 for (INT32 dummy;Start > 0;Start--)
00179 GetNext(&dummy,&dummy);
00180 }
00181
00182 void ListStepper::GetNext(INT32* pNextInStart,INT32* pNextInEnd)
00183 {
00184 if ((*pNextInMax) < Max)
00185 {
00186 *pNextInStart = NextInStart;
00187 *pNextInEnd = NextInEnd;
00188
00189 Inc += Min;
00190 if (Inc >= Max)
00191 {
00192 Inc -= Max;
00193 (*pNextInMin)++;
00194 }
00195 (*pNextInMax)++;
00196 }
00197 else
00198 {
00199 *pNextInStart = -1;
00200 *pNextInEnd = -1;
00201 }
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 class BlendSubRenderContext: public SubRenderContext
00216 {
00217 CC_DECLARE_DYNCREATE(BlendSubRenderContext);
00218 public:
00219 BlendSubRenderContext() { BlendStep = 1; }
00220
00221 UINT32 BlendStep;
00222 };
00223
00224 CC_IMPLEMENT_DYNCREATE(BlendSubRenderContext,SubRenderContext);
00225
00226
00227
00228
00229 DECLARE_SOURCE( "$Revision: 1315 $" );
00230
00231 CC_IMPLEMENT_DYNCREATE(NodeBlender, NodeRenderableInk)
00232 CC_IMPLEMENT_MEMDUMP(BlendRef,CC_CLASS_MEMDUMP)
00233 CC_IMPLEMENT_MEMDUMP(BlendPath,ListItem)
00234
00235 CC_IMPLEMENT_MEMDUMP(BecomeA,CC_CLASS_MEMDUMP)
00236 CC_IMPLEMENT_MEMDUMP(BlendBecomeA,BecomeA)
00237 CC_IMPLEMENT_MEMDUMP(HandleBecomeA,CC_CLASS_MEMDUMP)
00238 CC_IMPLEMENT_MEMDUMP(NodeCompoundBlendBecomeA,BecomeA)
00239
00240
00241
00242
00243 #define MAX_NUM_BLEND_STEPS 999
00244 #define FLATNESS 1024
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 NodeBlender::NodeBlender(Node* ContextNode,
00290 AttachNodeDirection Direction,
00291 BOOL Locked,
00292 BOOL Mangled,
00293 BOOL Marked,
00294 BOOL Selected
00295 ):NodeRenderableInk(ContextNode, Direction, Locked, Mangled, Marked, Selected )
00296 {
00297 ResetVars();
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 NodeBlender::NodeBlender(): NodeRenderableInk()
00318 {
00319 ResetVars();
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 NodeBlender::~NodeBlender()
00333 {
00334
00335 PostBlend();
00336
00337
00338 DELPTR(m_pRefStart);
00339 DELPTR(m_pRefEnd);
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 void NodeBlender::ResetVars()
00354 {
00355 m_pRefStart = NULL;
00356 m_pRefEnd = NULL;
00357 m_pNodeStart = NULL;
00358 m_pNodeEnd = NULL;
00359 m_ObjIndexStart = -1;
00360 m_ObjIndexEnd = -1;
00361 m_PathIndexStart = -1;
00362 m_PathIndexEnd = -1;
00363
00364 m_Initialised = FALSE;
00365
00366 m_TempArraySize = 0;
00367 m_pTempCoords = NULL;
00368 m_pTempVerbs = NULL;
00369 m_pTempFlags = NULL;
00370 m_GBlendBuffSize = 0;
00371 m_pGBlendBuff = NULL;
00372
00373 m_ProportionOfPathDistStart = -1.0;
00374 m_ProportionOfPathDistEnd = -1.0;
00375
00376 m_AngleStart = 0.0;
00377 m_AngleEnd = 0.0;
00378
00379 m_Reversed = FALSE;
00380 m_BlendedOnCurve = FALSE;
00381 m_NodeBlendPathIndex = -2;
00382
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 Node* NodeBlender::SimpleCopy()
00397 {
00398
00399 NodeBlender* pCopyOfNode = new NodeBlender();
00400 if (pCopyOfNode)
00401 CopyNodeContents(pCopyOfNode);
00402
00403 return pCopyOfNode;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 void NodeBlender::CopyNodeContents(NodeBlender* pCopyOfNode)
00422 {
00423 NodeRenderableInk::CopyNodeContents(pCopyOfNode);
00424
00425
00426
00427 pCopyOfNode->m_ObjIndexStart = m_ObjIndexStart;
00428 pCopyOfNode->m_ObjIndexEnd = m_ObjIndexEnd;
00429 pCopyOfNode->m_PathIndexStart = m_PathIndexStart;
00430 pCopyOfNode->m_PathIndexEnd = m_PathIndexEnd;
00431
00432 pCopyOfNode->m_ProportionOfPathDistStart = m_ProportionOfPathDistStart;
00433 pCopyOfNode->m_ProportionOfPathDistEnd = m_ProportionOfPathDistEnd;
00434 pCopyOfNode->m_NodeBlendPathIndex = m_NodeBlendPathIndex;
00435 pCopyOfNode->m_BlendedOnCurve = m_BlendedOnCurve;
00436 pCopyOfNode->SetReversed(m_Reversed);
00437
00438 pCopyOfNode->m_AngleEnd = m_AngleEnd;
00439 pCopyOfNode->m_AngleStart = m_AngleStart;
00440
00441 pCopyOfNode->SetUninitialised();
00442 }
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 void NodeBlender::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
00459 {
00460 ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
00461 ENSURE(IS_A(pNodeCopy, NodeBlender), "PolyCopyNodeContents given wrong dest node type");
00462
00463 if (IS_A(pNodeCopy, NodeBlender))
00464 CopyNodeContents((NodeBlender*)pNodeCopy);
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 #ifdef _DEBUG
00480 void NodeBlender::ShowDebugTreeDetails() const
00481 {
00482
00483
00484 NodeRenderableInk::ShowDebugTreeDetails();
00485 }
00486 #endif
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 void NodeBlender::GetDebugDetails( StringBase* Str )
00500 {
00501 #ifdef _DEBUG
00502
00503 NodeRenderableInk::GetDebugDetails( Str );
00504
00505 (*Str) += TEXT( "\r\nBlender Data Dump\r\n" );
00506
00507 TCHAR buf[500];
00508 camSnprintf( buf, 500, _T("Blend steps = %ld\r\n")
00509 _T("m_ObjIndex start = %ld\r\n")
00510 _T("m_ObjIndex end = %ld\r\n")
00511 _T("m_ProportionOfPathDistStart = %f\r\n")
00512 _T("m_ProportionOfPathDistEnd = %f\r\n")
00513 _T("m_AngleStart = %f\r\n")
00514 _T("m_AngleEnd = %f\r\n")
00515 _T("m_NodeBlendPathIndex = %ld\r\n")
00516 _T("\r\n"),
00517 GetNumBlendSteps(),
00518 m_ObjIndexStart,
00519 m_ObjIndexEnd,
00520 m_ProportionOfPathDistStart,
00521 m_ProportionOfPathDistEnd,
00522 m_AngleStart,
00523 m_AngleEnd,
00524 m_NodeBlendPathIndex
00525 );
00526
00527 *Str += buf;
00528
00529 *Str += _T("--------- Start\r\n\r\n");
00530 GetDebugDetails(Str,m_pRefStart);
00531
00532 *Str += _T("--------- End\r\n\r\n");
00533 GetDebugDetails(Str,m_pRefEnd);
00534 #endif
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 void NodeBlender::GetDebugDetails( StringBase* Str, BlendRef* pBlendRef )
00550 {
00551 #ifdef _DEBUG
00552 String_256 TempStr;
00553
00554 TempStr._MakeMsg( _T("Num blend paths = #1%d\r\n"),pBlendRef->GetNumBlendPaths());
00555 *Str += TempStr;
00556 BlendPath* pBlendPath = pBlendRef->GetFirstBlendPath();
00557 while (pBlendPath != NULL)
00558 {
00559 Path* pPath = pBlendPath->GetPath();
00560 PathVerb* pVerbs = pPath->GetVerbArray();
00561 PathFlags* pFlags = pPath->GetFlagArray();
00562 DocCoord* pCoords = pPath->GetCoordArray();
00563
00564 TempStr._MakeMsg( _T("Original Mapping = #1%d\r\n"), pBlendPath->GetOrigMapping());
00565 *Str += TempStr;
00566
00567 for (INT32 i=0; i<pPath->GetNumCoords(); i++)
00568 {
00569
00570 TempStr._MakeMsg( TEXT("#1%d.\t#2%d\t#3%ld,\t#4%ld\t"),
00571 i, pVerbs[i], pCoords[i].x, pCoords[i].y );
00572 (*Str) += TempStr;
00573
00574 if (pFlags[i].IsEndPoint)
00575 {
00576 TempStr._MakeMsg( _T(": E\t") );
00577 (*Str) += TempStr;
00578 }
00579
00580 *Str += _T("\r\n");
00581 }
00582 pBlendPath = pBlendRef->GetNextBlendPath(pBlendPath);
00583 }
00584 #endif
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 void NodeBlender::Transform( TransformBase& Trans )
00601 {
00602 InvalidateBoundingRect();
00603 Deinit();
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 BOOL NodeBlender::HidingNode()
00632 {
00633 PostBlend();
00634 Deinit();
00635 return TRUE;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 BOOL NodeBlender::ShowingNode()
00652 {
00653 return TRUE;
00654
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 void NodeBlender::Render(RenderRegion* pRender)
00669 {
00670 pRender->SaveContext();
00671 CreateBlends(pRender,NULL);
00672 pRender->RestoreContext();
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 BOOL NodeBlender::CallBeginBlendStep(BlendNodeParam * pParam, BOOL* usingSumAllPathsPathProcessor)
00688 {
00689 if (pParam->GetRenderRegion() == NULL)
00690 {
00691
00692
00693 if (!pParam->GetHandleBecomeA ())
00694 {
00695 return TRUE;
00696 }
00697
00698 }
00699
00700 NodeRenderableInk * pCompoundStep = pParam->GetStartBlendPath()->GetBlendNode();
00701
00702 if (!pCompoundStep->IsCompound())
00703 {
00704 *usingSumAllPathsPathProcessor = FALSE;
00705 return TRUE;
00706 }
00707
00708 if (((NodeCompound *)pCompoundStep)->IsStartBlendGroupNode())
00709 {
00710 if (!((NodeCompound *)pCompoundStep)->BeginBlendStep(pParam))
00711 {
00712 return FALSE;
00713 }
00714 else
00715 {
00716
00717 *usingSumAllPathsPathProcessor = TRUE;
00718 }
00719 }
00720
00721 Node * pStep = pCompoundStep->FindFirstChild();
00722
00723 while (pStep)
00724 {
00725 if (pStep->IsCompound())
00726 {
00727 NodeCompound * pCompound = (NodeCompound *)pStep;
00728
00729 if (pCompound->IsStartBlendGroupNode())
00730 {
00731 if (!pCompound->BeginBlendStep(pParam))
00732 {
00733 return FALSE;
00734 }
00735 else
00736 {
00737 *usingSumAllPathsPathProcessor = TRUE;
00738 }
00739 }
00740 }
00741
00742 pStep = pStep->FindNext();
00743 }
00744
00745 return TRUE;
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 BOOL NodeBlender::CallEndBlendStep(BlendNodeParam * pParam)
00762 {
00763
00764 if (pParam->GetRenderRegion() == NULL)
00765 {
00766
00767
00768 if (!pParam->GetHandleBecomeA ())
00769 {
00770 return TRUE;
00771 }
00772
00773 }
00774
00775 NodeRenderableInk * pCompoundStep = pParam->GetStartBlendPath()->GetBlendNode();
00776
00777
00778
00779 if (!pCompoundStep->IsCompound())
00780 return TRUE;
00781
00782 Node * pStep = pCompoundStep->FindFirstDepthFirst();
00783
00784 while (pStep && pStep != pCompoundStep)
00785 {
00786 if (pStep->IsCompound())
00787 {
00788 NodeCompound * pCompound = (NodeCompound *)pStep;
00789
00790 if (pCompound->IsEndBlendGroupNode())
00791 {
00792 if (!pCompound->EndBlendStep(pParam))
00793 {
00794 return FALSE;
00795 }
00796 }
00797 }
00798
00799 pStep = pStep->FindNextDepthFirst(pCompoundStep);
00800 }
00801
00802 if (((NodeCompound *)pCompoundStep)->IsEndBlendGroupNode())
00803 {
00804 if (!((NodeCompound *)pCompoundStep)->EndBlendStep(pParam))
00805 {
00806 return FALSE;
00807 }
00808 }
00809
00810 return TRUE;
00811 }
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829 void NodeBlender::CreateBlends(RenderRegion* pRender,HandleBecomeA* pHandleBecomeA)
00830 {
00831 TRACEUSER( "ChrisS", _T("Entering create blends\n"));
00832
00833
00834 if (!Reinit())
00835 return;
00836 if (!m_Initialised) return;
00837
00838 if (m_pRefStart == NULL || m_pRefEnd == NULL)
00839 {
00840 ERROR3("Dodgey pRef params");
00841 return;
00842 }
00843 if (m_pNodeStart == NULL || m_pNodeEnd == NULL)
00844 {
00845 ERROR3("Dodgey m_pNodeStart and/or m_pNodeEnd params");
00846 return;
00847 }
00848
00849
00850
00851
00852 if (pRender != NULL && pRender->RRQuality.GetBlendQuality() != Quality::FullBlend)
00853 pRender = NULL;
00854
00855
00856 if (pRender == NULL && pHandleBecomeA == NULL)
00857 return;
00858
00859
00860 BOOL AllowBackgroundRender = (pRender!=NULL &&
00861 ( IS_A(pRender,GRenderDIB) ||
00862 pRender->IsHitDetect() )
00863 );
00864
00865
00866 if (AllowBackgroundRender && pRender->IsSubRenderStateLocked())
00867 AllowBackgroundRender = FALSE;
00868
00869
00870 if (AllowBackgroundRender && pRender->IsPrinting())
00871 AllowBackgroundRender = FALSE;
00872
00873
00874 if (pRender != NULL)
00875 {
00876
00877
00878 if (IsNotAntialiased() && pRender->RRQuality.GetAntialiasQuality() == Quality::FullAntialias)
00879 {
00880
00881 Quality Qual;
00882 QualityAttribute *pQualAttrVal = new QualityAttribute(Qual);
00883
00884 if (pQualAttrVal != NULL)
00885 {
00886
00887
00888 pRender->SetQuality(pQualAttrVal, TRUE);
00889 }
00890 }
00891 }
00892
00893
00894
00895 DocRect BoundsStart = m_pNodeStart->GetBoundingRect();
00896 DocRect BoundsEnd = m_pNodeEnd ->GetBoundingRect();
00897
00898 UINT32 NumBlendSteps = GetNumBlendSteps();
00899
00900
00901 if (NumBlendSteps > MAX_NUM_BLEND_STEPS)
00902 NumBlendSteps = MAX_NUM_BLEND_STEPS;
00903
00904 m_BlendStep = IsReversed() ? NumBlendSteps : 1;
00905
00906 BlendSubRenderContext* pSubRenderContext = NULL;
00907 if (pRender != NULL)
00908 {
00909 pSubRenderContext = (BlendSubRenderContext*)pRender->GetSubRenderState();
00910
00911
00912
00913
00914 if (pSubRenderContext != NULL && !IS_A(pSubRenderContext,BlendSubRenderContext))
00915 pSubRenderContext = NULL;
00916
00917 if (pSubRenderContext != NULL)
00918 {
00919 m_BlendStep = pSubRenderContext->BlendStep;
00920 }
00921 }
00922
00923
00924 UINT32 NumPathsInStart = m_pRefStart->GetNumBlendPaths();
00925 UINT32 NumPathsInEnd = m_pRefEnd ->GetNumBlendPaths();
00926 UINT32 MaxNumPaths = max(NumPathsInStart,NumPathsInEnd);
00927
00928
00929
00930 if (min(NumPathsInStart,NumPathsInEnd) == 0)
00931 {
00932 return;
00933 }
00934
00935
00936 if (pHandleBecomeA != NULL)
00937 pHandleBecomeA->SetNumPathsPerStep(MaxNumPaths);
00938
00939
00940
00941 ListStepper Stepper;
00942
00943
00944
00945 double BlendRatio;
00946 double BlendRatioStep = 1.0/(NumBlendSteps+1);
00947
00948 Path BlendedPath;
00949 if (!BlendedPath.Initialise())
00950 return;
00951
00952
00953 if (pSubRenderContext == NULL)
00954 {
00955 PreBlend();
00956
00957 }
00958
00959
00960 CCAttrMap BlendedAttrMap(30);
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970 if (AllowBackgroundRender)
00971 pRender->LockSubRenderState(TRUE);
00972
00973
00974 BOOL ContinueRender = TRUE;
00975 INT32 Counter = 1;
00976 UINT32 StopBlendStep = NumBlendSteps +1 ;
00977
00978 if (IsReversed())
00979 {
00980 Counter = -1;
00981 StopBlendStep = 0;
00982 }
00983
00984
00985
00986
00987
00988 BlendNodeParam BNParam;
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 while ( ContinueRender &&
00999 ( !IsReversed() && m_BlendStep < StopBlendStep ) ||
01000 ( IsReversed() && m_BlendStep > StopBlendStep ) )
01001 {
01002
01003
01004 double LinearBlendRatio = BlendRatioStep * m_BlendStep;
01005 BlendRatio = MapObjectBlendRatio(LinearBlendRatio);
01006
01007
01008 INT32 NextPathStart,NextPathEnd;
01009 Stepper.Init(NumPathsInStart,NumPathsInEnd,0);
01010
01011
01012 BlendPath* pPrevBlendPathStart = NULL;
01013 BlendPath* pPrevBlendPathEnd = NULL;
01014 UINT32 PrevSubPathIDStart = 0;
01015 UINT32 PrevSubPathIDEnd = 0;
01016
01017
01018 Stepper.GetNext(&NextPathStart,&NextPathEnd);
01019
01020
01021
01022 BlendPath* pCurrBlendPathStart = m_pRefStart->GetBlendPath(NextPathStart);
01023 BlendPath* pCurrBlendPathEnd = m_pRefEnd ->GetBlendPath(NextPathEnd );
01024 UINT32 CurrSubPathIDStart = pCurrBlendPathStart->GetSubPathID();
01025 UINT32 CurrSubPathIDEnd = pCurrBlendPathEnd ->GetSubPathID();
01026
01027
01028 BlendPath* pNextBlendPathStart;
01029 BlendPath* pNextBlendPathEnd;
01030 UINT32 NextSubPathIDStart;
01031 UINT32 NextSubPathIDEnd;
01032
01033
01034 BOOL BoundsIntersect = TRUE;
01035 if (pRender != NULL && pHandleBecomeA == NULL)
01036 BoundsIntersect = CheckBoundsIntersect(pRender,BoundsStart,BoundsEnd,BlendRatio);
01037
01038 DocRect RawBlendedBounds = BlendBounds(BoundsStart,BoundsEnd,BlendRatio,FALSE);
01039 DocCoord BBCentre = RawBlendedBounds.Centre();
01040
01041
01042
01043 SumAllPathsPathProcessor * ptrProc = new SumAllPathsPathProcessor (FALSE);
01044 BOOL* usingSumAllPathsPathProcessor = new BOOL;
01045 *usingSumAllPathsPathProcessor = FALSE;
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066 for (UINT32 NextPath = 0; ContinueRender && BoundsIntersect && (NextPath < MaxNumPaths); NextPath++)
01067 {
01068
01069 Stepper.GetNext(&NextPathStart,&NextPathEnd);
01070
01071
01072
01073
01074
01075
01076 BlendedAttrMap.RemoveGeometryLinkedAttrs();
01077
01078 if (NextPathStart >= 0 && NextPathEnd >= 0)
01079 {
01080
01081 pNextBlendPathStart = m_pRefStart->GetBlendPath(NextPathStart);
01082 pNextBlendPathEnd = m_pRefEnd ->GetBlendPath(NextPathEnd );
01083 NextSubPathIDStart = pNextBlendPathStart->GetSubPathID();
01084 NextSubPathIDEnd = pNextBlendPathEnd ->GetSubPathID();
01085 }
01086 else
01087 {
01088
01089 pNextBlendPathStart = NULL;
01090 pNextBlendPathEnd = NULL;
01091 NextSubPathIDStart = 0;
01092 NextSubPathIDEnd = 0;
01093 }
01094
01095
01096
01097
01098 if (pCurrBlendPathStart == NULL || pCurrBlendPathEnd == NULL)
01099 {
01100 if (AllowBackgroundRender)
01101 pRender->LockSubRenderState(FALSE);
01102 return;
01103 }
01104
01105 double AttrBlendRatio = MapAttrBlendRatio(LinearBlendRatio);
01106
01107 NodeRenderableInk * pStartBlendNode = NULL;
01108 NodeRenderableInk * pEndBlendNode = NULL;
01109
01110 if (LinearBlendRatio <= 0.5)
01111
01112
01113
01114 {
01115 BNParam.Init(GetNodeBlend (), pRender, pCurrBlendPathStart, pCurrBlendPathEnd, BlendRatio,
01116 AttrBlendRatio, m_AngleStart, m_AngleEnd, GetObjectRatio(),
01117 GetInvertedAttributeRatio(), GetColourBlendType(),
01118 pCurrBlendPathStart->GetBlendNode(), pCurrBlendPathEnd->GetBlendNode(),
01119 IsOneToOne(), GetNodeBlendPath(), pHandleBecomeA, ptrProc);
01120
01121 pStartBlendNode = pCurrBlendPathStart->GetBlendNode();
01122 pEndBlendNode = pCurrBlendPathEnd->GetBlendNode();
01123 }
01124 else
01125 {
01126 BNParam.Init(GetNodeBlend (), pRender, pCurrBlendPathEnd, pCurrBlendPathStart, 1.0 - BlendRatio,
01127 1.0 - AttrBlendRatio, m_AngleStart, m_AngleEnd, 1.0 - GetObjectRatio(),
01128 1.0 - GetInvertedAttributeRatio(), GetColourBlendType(),
01129 pCurrBlendPathEnd->GetBlendNode(), pCurrBlendPathStart->GetBlendNode(),
01130 IsOneToOne(), GetNodeBlendPath(), pHandleBecomeA, ptrProc);
01131
01132 pStartBlendNode = pCurrBlendPathEnd->GetBlendNode();
01133 pEndBlendNode = pCurrBlendPathStart->GetBlendNode();
01134 }
01135
01136 if (!CallBeginBlendStep(&BNParam, usingSumAllPathsPathProcessor))
01137 {
01138 return ;
01139 }
01140
01141 if (BlendAttributes(pRender,pCurrBlendPathStart,pCurrBlendPathEnd,&BlendedAttrMap,AttrBlendRatio, BlendRatio, GetNodeBlend ()->GetObjectProfileProcessing ()))
01142 {
01143
01144 if (BlendPaths(pCurrBlendPathStart,pCurrBlendPathEnd,BlendRatio))
01145 {
01146
01147
01148 BOOL Filled = pCurrBlendPathStart->IsFilled() || pCurrBlendPathEnd->IsFilled();
01149 BOOL Stroked = pCurrBlendPathStart->IsStroked() || pCurrBlendPathEnd->IsStroked();
01150
01151
01152
01153
01154 BOOL DontClearPath = ((CurrSubPathIDStart == PrevSubPathIDStart && pCurrBlendPathStart != pPrevBlendPathStart) ||
01155 (CurrSubPathIDEnd == PrevSubPathIDEnd && pCurrBlendPathEnd != pPrevBlendPathEnd ));
01156
01157 if (!DontClearPath)
01158 BlendedPath.ClearPath(FALSE);
01159
01160 if (!BlendedPath.MakeSpaceInPath(m_ArrayLength)) goto ExitRender;
01161 BlendedPath.MergeTwoPaths(m_pTempCoords,m_pTempVerbs,m_pTempFlags,m_ArrayLength,Filled);
01162 BlendedPath.IsFilled = Filled;
01163 BlendedPath.IsStroked = Stroked;
01164
01165
01166
01167
01168 BOOL NotACompletePath = ((CurrSubPathIDStart == NextSubPathIDStart && pCurrBlendPathStart != pNextBlendPathStart) ||
01169 (CurrSubPathIDEnd == NextSubPathIDEnd && pCurrBlendPathEnd != pNextBlendPathEnd ));
01170
01171 if (!NotACompletePath)
01172 {
01173
01174
01175
01176
01177 if (m_BlendedOnCurve)
01178 {
01179 DocCoord PointOnPath;
01180 double Angle = 0.0;
01181 if (GetPointOnNodeBlendPath(BlendRatio,&PointOnPath,&Angle))
01182 {
01183 Trans2DMatrix Translate(PointOnPath.x-BBCentre.x,PointOnPath.y-BBCentre.y);
01184 Trans2DMatrix Rotate(BBCentre,Angle);
01185
01186 if (Angle != 0.0)
01187 {
01188 Rotate.Transform( (DocCoord*)BlendedPath.GetCoordArray(), BlendedPath.GetNumCoords() );
01189 BlendedAttrMap.Transform(Rotate);
01190 }
01191
01192 Translate.Transform( (DocCoord*)BlendedPath.GetCoordArray(), BlendedPath.GetNumCoords() );
01193
01194 BlendedAttrMap.TransformForBrush(Translate);
01195 }
01196 }
01197
01198
01199
01200
01201
01202 BlendedAttrMap.PostBlendInit(&BlendedPath, GetRuntimeClass());
01203
01204
01205
01206 if (pHandleBecomeA != NULL)
01207 {
01208
01209
01210 if (!(*usingSumAllPathsPathProcessor))
01211 {
01212
01213
01214 ContinueRender = pHandleBecomeA->PassBack(&BlendedPath,&BlendedAttrMap,m_BlendStep);
01215 }
01216 else
01217 {
01218
01219
01220 if ((pHandleBecomeA->GetBecomeA ()->GetReason () == BECOMEA_REPLACE) ||
01221 (pHandleBecomeA->GetBecomeA ()->GetReason () == BECOMEA_PASSBACK)
01222 )
01223 {
01224 Path* pNewBlendedPath = new Path;
01225 pNewBlendedPath->Initialise (BlendedPath.GetNumCoords ());
01226
01227 pNewBlendedPath->CopyPathDataFrom (&BlendedPath);
01228
01229 CCAttrMap* pNewBlendedAttrMap = BlendedAttrMap.Copy ();
01230
01231 SumAllPathsElem * pElem = new SumAllPathsElem(pNewBlendedPath, pNewBlendedAttrMap);
01232
01233 ptrProc->InsertSumAllPathsElem (pElem);
01234
01235 ContinueRender = TRUE;
01236
01237 delete (pNewBlendedPath);
01238 }
01239 }
01240 }
01241
01242 if (pRender != NULL)
01243 {
01244 pRender->SaveContext();
01245
01246
01247
01248 if (!(*usingSumAllPathsPathProcessor))
01249 {
01250 RenderAttributes(pRender,&BlendedAttrMap);
01251
01252 pRender->DrawPath(&BlendedPath);
01253 }
01254 else
01255 {
01256 Path* pNewBlendedPath = new Path;
01257 pNewBlendedPath->Initialise (BlendedPath.GetNumCoords ());
01258
01259 pNewBlendedPath->CopyPathDataFrom (&BlendedPath);
01260
01261 CCAttrMap* pNewBlendedAttrMap = BlendedAttrMap.Copy ();
01262
01263 SumAllPathsElem * pElem = new SumAllPathsElem(pNewBlendedPath, pNewBlendedAttrMap);
01264
01265 ptrProc->InsertSumAllPathsElem (pElem);
01266
01267 ContinueRender = TRUE;
01268
01269 delete (pNewBlendedPath);
01270 }
01271
01272 pRender->RestoreContext();
01273 }
01274
01275
01276
01277 BlendedAttrMap.PostBlendDeinit();
01278 }
01279 }
01280 }
01281
01282 TRACEUSER( "ChrisS", _T("Blend step == %f\n"), BlendRatio);
01283
01284
01285 if (!CallEndBlendStep(&BNParam))
01286 {
01287 return ;
01288 }
01289
01290
01291
01292 PrevSubPathIDStart = CurrSubPathIDStart;
01293 PrevSubPathIDEnd = CurrSubPathIDEnd;
01294 pPrevBlendPathStart = pCurrBlendPathStart;
01295 pPrevBlendPathEnd = pCurrBlendPathEnd;
01296
01297
01298 CurrSubPathIDStart = NextSubPathIDStart;
01299 CurrSubPathIDEnd = NextSubPathIDEnd;
01300 pCurrBlendPathStart = pNextBlendPathStart;
01301 pCurrBlendPathEnd = pNextBlendPathEnd;
01302 }
01303
01304 if (usingSumAllPathsPathProcessor != NULL)
01305 {
01306 delete (usingSumAllPathsPathProcessor);
01307 }
01308
01309 if (ptrProc != NULL)
01310 {
01311 delete (ptrProc);
01312 }
01313
01314
01315
01316
01317
01318
01319 if (pRender != NULL && BoundsIntersect)
01320 {
01321 View* pView = pRender->GetRenderView();
01322 if (pView != NULL)
01323 {
01324 if (AllowBackgroundRender && (pRender->IsHitDetect() || !pRender->RenderTreeCanContinue()))
01325 {
01326
01327
01328
01329
01330 if (pSubRenderContext == NULL)
01331 {
01332
01333
01334 pSubRenderContext = new BlendSubRenderContext;
01335 if (pSubRenderContext != NULL && pRender->GetSubRenderState() != pSubRenderContext)
01336 {
01337
01338 pRender->LockSubRenderState(FALSE);
01339 pRender->SetSubRenderState(pSubRenderContext);
01340 }
01341 }
01342
01343 if (pSubRenderContext != NULL)
01344 {
01345
01346
01347 pSubRenderContext->BlendStep = m_BlendStep+Counter;
01348 goto ExitRender;
01349 }
01350 }
01351 }
01352
01353 }
01354
01355
01356 m_BlendStep+= Counter;
01357
01358 }
01359
01360 if (pRender != NULL && pSubRenderContext != NULL)
01361 {
01362
01363
01364
01365 delete pSubRenderContext;
01366 pSubRenderContext = NULL;
01367 pRender->SetSubRenderState(NULL);
01368 }
01369
01370
01371 PostBlend();
01372
01373 ExitRender:
01374
01375 BlendedAttrMap.DeleteAttributes();
01376
01377
01378 if (AllowBackgroundRender)
01379 pRender->LockSubRenderState(FALSE);
01380
01381
01382 TRACEUSER( "ChrisS", _T("Exiting create blends\n"));
01383 }
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403 BOOL NodeBlender::CheckBoundsIntersect(RenderRegion* pRender,DocRect& BoundsStart,DocRect& BoundsEnd,double BlendRatio)
01404 {
01405 BOOL Clip = TRUE;
01406
01407 if (pRender != NULL)
01408 {
01409 DocRect BlendedBounds = BlendBounds(BoundsStart,BoundsEnd,BlendRatio,TRUE);
01410 Clip = BlendedBounds.IsIntersectedWith(pRender->GetClipRect());
01411
01412 }
01413
01414 return Clip;
01415 }
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434 DocRect NodeBlender::BlendBounds(DocRect& BoundsStart,DocRect& BoundsEnd,double BlendRatio,BOOL UseBlendPath)
01435 {
01436 DocRect BlendedBounds,OldBoundsStart,OldBoundsEnd;
01437
01438 if (UseBlendPath)
01439 {
01440 OldBoundsStart = BoundsStart;
01441 OldBoundsEnd = BoundsEnd;
01442 RotateBounds(BoundsStart,-m_AngleStart);
01443 RotateBounds(BoundsEnd,-m_AngleEnd);
01444 }
01445
01446 BlendedBounds.lo.x = INT32(BoundsStart.lo.x + ((BoundsEnd.lo.x-BoundsStart.lo.x)*BlendRatio));
01447 BlendedBounds.lo.y = INT32(BoundsStart.lo.y + ((BoundsEnd.lo.y-BoundsStart.lo.y)*BlendRatio));
01448 BlendedBounds.hi.x = INT32(BoundsStart.hi.x + ((BoundsEnd.hi.x-BoundsStart.hi.x)*BlendRatio));
01449 BlendedBounds.hi.y = INT32(BoundsStart.hi.y + ((BoundsEnd.hi.y-BoundsStart.hi.y)*BlendRatio));
01450
01451 if (UseBlendPath)
01452 {
01453 DocCoord PointOnPath;
01454 double Angle = 0.0;
01455 if (GetPointOnNodeBlendPath(BlendRatio,&PointOnPath,&Angle))
01456 {
01457 DocCoord BBCentre = BlendedBounds.Centre();
01458 BlendedBounds.Translate(PointOnPath.x-BBCentre.x,PointOnPath.y-BBCentre.y);
01459
01460 RotateBounds(BlendedBounds,Angle);
01461 }
01462 }
01463
01464 if (UseBlendPath)
01465 {
01466 BoundsStart = OldBoundsStart;
01467 BoundsEnd = OldBoundsEnd;
01468 }
01469
01470 return BlendedBounds;
01471 }
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488 void NodeBlender::RotateBounds(DocRect& Bounds,double Angle)
01489 {
01490 if (Angle != 0.0)
01491 {
01492 DocCoord BBCentre = Bounds.Centre();
01493
01494 DocCoord Coords[4];
01495 Coords[0].x = Bounds.lo.x; Coords[0].y = Bounds.lo.y;
01496 Coords[1].x = Bounds.hi.x; Coords[1].y = Bounds.lo.y;
01497 Coords[2].x = Bounds.hi.x; Coords[2].y = Bounds.hi.y;
01498 Coords[3].x = Bounds.lo.x; Coords[3].y = Bounds.hi.y;
01499
01500 Trans2DMatrix Rotate(BBCentre,Angle);
01501 Rotate.Transform(Coords,4);
01502
01503 Bounds.lo.x = min(min(Coords[0].x,Coords[1].x), min(Coords[2].x,Coords[3].x));
01504 Bounds.hi.x = max(max(Coords[0].x,Coords[1].x), max(Coords[2].x,Coords[3].x));
01505 Bounds.lo.y = min(min(Coords[0].y,Coords[1].y), min(Coords[2].y,Coords[3].y));
01506 Bounds.hi.y = max(max(Coords[0].y,Coords[1].y), max(Coords[2].y,Coords[3].y));
01507 }
01508 }
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527 Trans2DMatrix* NodeBlender::GetRotateMatrix(NodeRenderableBounded* pNode,double Angle)
01528 {
01529 Trans2DMatrix* pMatrix = NULL;
01530
01531 if (pNode != NULL && fmod(Angle,360.0) != 0.0)
01532 {
01533 DocRect BoundsStart = pNode->GetBoundingRect();
01534 DocCoord Centre = BoundsStart.Centre();
01535 pMatrix = new Trans2DMatrix(Centre,Angle);
01536 }
01537
01538 return pMatrix;
01539 }
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 DocRect NodeBlender::GetUnionBlendedBounds(DocRect& BoundsStart,DocRect& BoundsEnd)
01557 {
01558 DocRect UnionBlendedBounds(0,0,0,0);
01559
01560 UINT32 NumBlendSteps = GetNumBlendSteps();
01561 double BlendRatio = 0.0;
01562 double BlendRatioStep = 1.0/(NumBlendSteps+1);
01563
01564 for (UINT32 BlendStep = 1; BlendStep <= NumBlendSteps; BlendStep++)
01565 {
01566
01567 BlendRatio = BlendRatioStep * BlendStep;
01568
01569 DocRect BlendedBounds = BlendBounds(BoundsStart,BoundsEnd,BlendRatio,TRUE);
01570
01571 if (BlendStep == 1)
01572 UnionBlendedBounds = BlendedBounds;
01573 else
01574 UnionBlendedBounds = UnionBlendedBounds.Union(BlendedBounds);
01575 }
01576
01577 return UnionBlendedBounds;
01578 }
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595 void NodeBlender::RenderAttributes(RenderRegion* pRender,CCAttrMap* pAttrMap)
01596 {
01597
01598 BOOL ok = (pRender != NULL && pAttrMap != NULL);
01599 ERROR3IF(!ok,"One or more NULL entry params");
01600 if (!ok) return;
01601
01602 CCRuntimeClass* pType;
01603 void* pVal;
01604
01605
01606 for (CMapPtrToPtr::iterator Pos = pAttrMap->GetStartPosition(); Pos != pAttrMap->GetEndPosition();)
01607 {
01608
01609 pAttrMap->GetNextAssoc(Pos,pType,pVal);
01610
01611
01612
01613 if (pType != CC_RUNTIME_CLASS(AttrQuality))
01614 {
01615
01616 NodeAttribute* pNodeAttr = (NodeAttribute *)pVal;
01617
01618
01619
01620
01621
01622
01623 if (pNodeAttr->IsABrush())
01624 {
01625
01626 PathProcessor* pPathProc = pRender->GetFirstPathProcessor();
01627 if (pPathProc != NULL && pPathProc->IsAPathProcessorBrush())
01628 continue;
01629 }
01630 pNodeAttr->Render(pRender);
01631 }
01632 }
01633 }
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661 BOOL NodeBlender::BlendAttributes(RenderRegion *pRender, BlendPath* pBlendPathStart,
01662 BlendPath* pBlendPathEnd,CCAttrMap* pBlendedAttrMap,
01663 double BlendRatio, double objectRatio,
01664 BOOL objectProfileProcessing)
01665 {
01666
01667 BOOL ok = (pBlendPathStart != NULL &&
01668 pBlendPathEnd != NULL && pBlendedAttrMap != NULL);
01669 ERROR3IF(!ok,"One or more NULL entry params");
01670 if (!ok) return FALSE;
01671
01672
01673 CCAttrMap* pAttrMapStart = m_pRefStart->FindAppliedAttributes(pBlendPathStart);
01674 CCAttrMap* pAttrMapEnd = m_pRefEnd ->FindAppliedAttributes(pBlendPathEnd);
01675
01676
01677 if (pAttrMapStart == NULL || pAttrMapEnd == NULL) return FALSE;
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688 pAttrMapStart->attrMapCreator = pBlendPathStart->GetBlendNode ();
01689 pAttrMapEnd->attrMapCreator = pBlendPathEnd->GetBlendNode ();
01690
01691 if (GetNodeBlendPath() != NULL)
01692 {
01693 Trans2DMatrix* pRotateStart = GetRotateMatrix(m_pNodeStart,360.0 - m_AngleStart);
01694 Trans2DMatrix* pRotateEnd = GetRotateMatrix(m_pNodeEnd ,360.0 - m_AngleEnd );
01695 if (pRotateStart) pAttrMapStart->Transform(*pRotateStart);
01696 if (pRotateEnd) pAttrMapEnd ->Transform(*pRotateEnd);
01697 DELPTR(pRotateStart);
01698 DELPTR(pRotateEnd);
01699 }
01700
01701
01702
01703 AttrBrushType* pBlendedAttrBrush = NULL;
01704 AttrStrokeColour* pBlendedStrokeColour = NULL;;
01705
01706
01707 CCRuntimeClass* pTypeStart;
01708 void* pValStart;
01709 void* pValEnd;
01710 double OldBlendRatio = BlendRatio;
01711
01712 CMapPtrToPtr::iterator PosStart = pAttrMapStart->GetStartPosition();
01713 while ( PosStart != pAttrMapStart->GetEndPosition() )
01714 {
01715
01716 pAttrMapStart->GetNextAssoc(PosStart,pTypeStart,pValStart);
01717 NodeAttribute* pNodeAttrStart = (NodeAttribute *)pValStart;
01718
01719 BlendRatio = OldBlendRatio;
01720
01721
01722
01723 if (pNodeAttrStart->IsAGradFill())
01724 {
01725
01726 if (!((AttrFillGeometry*)pNodeAttrStart)->IsAColourFill())
01727 {
01728
01729 BlendRatio = GetObjectRatio();
01730
01731 }
01732 else
01733 {
01734 BlendRatio = GetInvertedAttributeRatio();
01735
01736 }
01737
01738 }
01739 if (pNodeAttrStart->IsAFlatFill() || (pNodeAttrStart->GetRuntimeClass() == CC_RUNTIME_CLASS(AttrLineWidth)))
01740 {
01741 BlendRatio = GetInvertedAttributeRatio();
01742 }
01743
01744
01745 NodeAttribute* pBlendedNodeAttr = NULL;
01746
01747
01748
01749 if (pAttrMapEnd->Lookup(pTypeStart,pValEnd))
01750 {
01751
01752
01753
01754 BlendAttrParam BlendParam;
01755
01756
01757 if (BlendParam.Init(pRender,
01758 (NodeAttribute *)pValEnd,BlendRatio,objectRatio,objectProfileProcessing,GetColourBlendType(),
01759 pAttrMapStart, pAttrMapEnd) )
01760 {
01761
01762 if (pNodeAttrStart->Blend(&BlendParam))
01763 {
01764
01765
01766
01767 pBlendedNodeAttr = BlendParam.GetBlendedAttr();
01768 }
01769 else
01770 {
01771 #ifdef _DEBUG
01772 void *tmp = NULL;
01773 ENSURE(!pBlendedAttrMap->Lookup(pNodeAttrStart->GetRuntimeClass(),tmp),"Didn't blend attr, but there's still one in pBlendedAttrMap");
01774 #endif
01775 }
01776 }
01777 }
01778
01779
01780 if (pBlendedNodeAttr != NULL)
01781 {
01782
01783 CCRuntimeClass* pTypeBlend = pBlendedNodeAttr->GetAttributeType();
01784 void* pValBlend;
01785
01786
01787
01788 if (pBlendedAttrMap->Lookup(pTypeBlend,pValBlend))
01789 {
01790 if (pValBlend != NULL)
01791 {
01792 pBlendedAttrMap->RemoveKey(pTypeBlend);
01793 delete (NodeAttribute*)pValBlend;
01794 }
01795 }
01796
01797 pBlendedAttrMap->SetAt(pTypeBlend,pBlendedNodeAttr);
01798
01799
01800 if (pBlendedNodeAttr->IsAStrokeColour())
01801 pBlendedStrokeColour = (AttrStrokeColour*)pBlendedNodeAttr;
01802 if (pBlendedNodeAttr->IsABrush())
01803 pBlendedAttrBrush = (AttrBrushType*)pBlendedNodeAttr;
01804 }
01805 }
01806
01807 if (GetNodeBlendPath() != NULL)
01808 {
01809 Trans2DMatrix* pRotateStart = GetRotateMatrix(m_pNodeStart,m_AngleStart);
01810 Trans2DMatrix* pRotateEnd = GetRotateMatrix(m_pNodeEnd ,m_AngleEnd );
01811 if (pRotateStart) pAttrMapStart->Transform(*pRotateStart);
01812 if (pRotateEnd) pAttrMapEnd ->Transform(*pRotateEnd);
01813 DELPTR(pRotateStart);
01814 DELPTR(pRotateEnd);
01815 }
01816
01817
01818 if (pBlendedAttrBrush != NULL && pBlendedStrokeColour != NULL)
01819 pBlendedAttrBrush->SetBlendedStrokeColour(&(pBlendedStrokeColour->Value.Colour));
01820
01821 return TRUE;
01822 }
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850 BOOL NodeBlender::BlendPaths(BlendPath* pBlendPathStart,BlendPath* pBlendPathEnd,double BlendRatio)
01851 {
01852
01853 BOOL ok = (pBlendPathStart != NULL && pBlendPathEnd != NULL);
01854 if (ok) ok = (pBlendPathStart->GetBlendNode() != NULL && pBlendPathEnd->GetBlendNode() != NULL);
01855 ERROR3IF(!ok,"One or more NULL entry params");
01856 if (!ok) return FALSE;
01857
01858
01859 PathTypeEnum PathTypeStart = pBlendPathStart->GetPathType();
01860 PathTypeEnum PathTypeEnd = pBlendPathEnd ->GetPathType();
01861
01862
01863 BOOL Closed = (PathTypeStart == PATHTYPE_SHAPE) || (PathTypeEnd == PATHTYPE_SHAPE);
01864
01865 Path * pPathStart = NULL;
01866
01867
01868 if (pBlendPathStart->GetBlendNode()->IsNodePath())
01869 {
01870 pPathStart = &(((NodePath *)pBlendPathStart->GetBlendNode())->InkPath);
01871 }
01872 else
01873 {
01874 pPathStart = &(((NodePath *)((NodeCompound *)pBlendPathStart->GetBlendNode())->GetNodeToBlend())->InkPath);
01875 }
01876
01877 Path * pPathEnd = NULL;
01878
01879 if (pBlendPathEnd->GetBlendNode()->IsNodePath())
01880 {
01881 pPathEnd = &(((NodePath *)pBlendPathEnd->GetBlendNode())->InkPath);
01882 }
01883 else
01884 {
01885 pPathEnd = &(((NodePath *)((NodeCompound *)pBlendPathEnd->GetBlendNode())->GetNodeToBlend())->InkPath);
01886 }
01887
01888
01889 INT32 DestPathSize = ((pPathStart->GetNumCoords()+pPathEnd->GetNumCoords())*3)+500;
01890
01891
01892 DocCoord* pDestCoords = GetCoordArray(DestPathSize);
01893 PathVerb* pDestVerbs = GetVerbArray(DestPathSize);
01894 PathFlags* pDestFlags = GetFlagArray(DestPathSize);
01895 UINT32* pBuff = GetGBlendBuff(DestPathSize);
01896 if (pDestCoords == NULL || pDestVerbs == NULL || pDestFlags == NULL || pBuff == NULL)
01897 return FALSE;
01898
01899
01900
01901
01902
01903 Path Shape;
01904 if (PathTypeStart != PathTypeEnd)
01905 {
01906 BOOL ok = FALSE;
01907 if (!Shape.Initialise()) return FALSE;
01908
01909
01910 if (PathTypeStart == PATHTYPE_LINE && PathTypeEnd == PATHTYPE_SHAPE)
01911 {
01912 ok = NodeBlender::ConvertLineToShape(pPathStart,&Shape);
01913 pPathStart = &Shape;
01914 }
01915
01916
01917 if (PathTypeStart == PATHTYPE_SHAPE && PathTypeEnd == PATHTYPE_LINE)
01918 {
01919 ok = NodeBlender::ConvertLineToShape(pPathEnd,&Shape);
01920 pPathEnd = &Shape;
01921 }
01922
01923 if (!ok) return FALSE;
01924 }
01925
01926
01927
01928 BOOL OneToOne = FALSE;
01929 if (IsOneToOne())
01930 OneToOne = (pBlendPathStart->GetNumElements() == pBlendPathEnd->GetNumElements());
01931
01932
01933
01934 GBlend GBlendObj;
01935
01936
01937 GBlendObj.Define( (PPOINT)pPathStart->GetCoordArray(),
01938 pPathStart->GetVerbArray(),
01939 pPathStart->GetNumCoords(),
01940
01941 (PPOINT)pPathEnd ->GetCoordArray(),
01942 pPathEnd ->GetVerbArray(),
01943 pPathEnd ->GetNumCoords(),
01944
01945 OneToOne,
01946 FLATNESS,
01947
01948 pBuff,
01949 DestPathSize*sizeof(UINT32));
01950
01951
01952 m_ArrayLength = GBlendObj.Blend(BlendRatio,
01953 (PPOINT)pDestCoords,
01954 pDestVerbs,
01955 DestPathSize);
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973 if (pBlendPathStart->IsLine() && pBlendPathEnd->IsLine())
01974 {
01975 BlendPath* pBlendPath;
01976 if (BlendRatio <= 0.5)
01977 pBlendPath = pBlendPathStart;
01978 else
01979 pBlendPath = pBlendPathEnd;
01980
01981 if (pBlendPath->GetOrigMapping() != 0)
01982 ReversePath(pDestCoords,pDestVerbs,m_ArrayLength);
01983 }
01984
01985
01986 if (!ProcessBlendedPath(pDestCoords,pDestVerbs,pDestFlags,m_ArrayLength,Closed))
01987 return FALSE;
01988
01989 return TRUE;
01990 }
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012 void NodeBlender::ReversePath(DocCoord* pCoords,PathVerb* pVerbs,UINT32 Len)
02013 {
02014
02015 UINT32 LastPos = Len-1;
02016 UINT32 FirstPos = 0;
02017 while (FirstPos<LastPos)
02018 {
02019 SWAP(DocCoord,pCoords[FirstPos],pCoords[LastPos]);
02020
02021
02022 FirstPos++;
02023 LastPos--;
02024 }
02025
02026
02027
02028 FirstPos = 1;
02029 LastPos = Len-1;
02030 while (FirstPos<LastPos)
02031 {
02032 SWAP(PathVerb,pVerbs[FirstPos],pVerbs[LastPos]);
02033
02034
02035 FirstPos++;
02036 LastPos--;
02037 }
02038 }
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058 void NodeBlender::UpdateBlendStartAngles (Trans2DMatrix& trans)
02059 {
02060
02061 if ((m_AngleStart != 0.0 || m_AngleEnd != 0.0))
02062 {
02063 double ang = (trans.GetRotation ()).MakeDouble ();
02064
02065 m_AngleStart += ang;
02066 m_AngleEnd += ang;
02067 }
02068 }
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092 INT32 NodeBlender::EstimateNodeComplexity (OpParam* details)
02093 {
02094
02095
02096 if ((m_pNodeStart == NULL) || (m_pNodeEnd == NULL))
02097 {
02098 return (-1);
02099 }
02100
02101 INT32 complexityEstimate1 = m_pNodeStart->EstimateNodeComplexity (details);
02102 INT32 complexityEstimate2 = m_pNodeEnd->EstimateNodeComplexity (details);
02103
02104 UINT32 NumBlendStepsby2 = 0;
02105 if (!details)
02106 {
02107 NumBlendStepsby2 = GetNumBlendSteps()/2;
02108 }
02109 else
02110 {
02111 NumBlendStepsby2 = (UINT32) (INT32) details->Param1;
02112 }
02113
02114 INT32 generatedPathsEstimate = NumBlendStepsby2+1*complexityEstimate1 + NumBlendStepsby2*complexityEstimate2;
02115
02116 return (generatedPathsEstimate);
02117 }
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142 BOOL NodeBlender::ConvertLineToShape(Path* pPath,Path* pShapePath)
02143 {
02144 ERROR3IF(pPath == NULL || pShapePath == NULL,"One or more NULL entry params");
02145 if (pPath == NULL || pShapePath == NULL) return FALSE;
02146
02147 Path ReversePath;
02148 if (!ReversePath.Initialise(pPath->GetNumCoords())) return FALSE;
02149 if (!ReversePath.CopyPathDataFrom(pPath)) return FALSE;
02150
02151 PathVerb* pRevVerb = ReversePath.GetVerbArray();
02152 PathVerb* pShapeVerb = pShapePath->GetVerbArray();
02153
02154 ReversePath.Reverse();
02155 ReversePath.FindStartOfPath();
02156 ReversePath.DeleteElement();
02157
02158 pRevVerb = ReversePath.GetVerbArray();
02159 pShapeVerb = pShapePath->GetVerbArray();
02160
02161 pShapePath->ClearPath(FALSE);
02162 if (!pShapePath->MergeTwoPaths(*pPath)) return FALSE;
02163 if (!pShapePath->MergeTwoPaths(ReversePath)) return FALSE;
02164
02165 return TRUE;
02166 }
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190 BOOL NodeBlender::ProcessBlendedPath(DocCoord* pCoords,PathVerb* pVerbs,PathFlags* pFlags,UINT32 Len,BOOL Closed)
02191 {
02192 if (Len < 1)
02193 return FALSE;
02194
02195
02196 SetPathFlags(pVerbs,pFlags,Len);
02197
02198
02199 if (Closed)
02200 pVerbs[Len-1] = pVerbs[Len-1] | PT_CLOSEFIGURE;
02201
02202 return TRUE;
02203 }
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222 void NodeBlender::SetPathFlags(PathVerb* pVerbs,PathFlags* pFlags,UINT32 Len)
02223 {
02224 UINT32 n;
02225
02226
02227 PathFlags DefaultPathFlags;
02228 for (n=0; n < Len; n++)
02229 pFlags[n] = DefaultPathFlags;
02230
02231
02232 for (n=0; n < Len; n++)
02233 {
02234 PathVerb Verb = pVerbs[n] & ~PT_CLOSEFIGURE;
02235 switch (Verb)
02236 {
02237 case PT_LINETO:
02238 case PT_MOVETO:
02239 pFlags[n].IsEndPoint = TRUE;
02240 break;
02241
02242 case PT_BEZIERTO:
02243 n += 2;
02244 ERROR3IF(n>=Len,"Found a PT_BEZIERTO, but third pt is off the end of the array");
02245 pFlags[n].IsEndPoint = TRUE;
02246 break;
02247
02248 default:
02249 ERROR3_PF(("Illegal path verb found : %c",Verb));
02250 break;
02251 }
02252 }
02253 }
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271 Matrix NodeBlender::MakeMatrix(BlendPath* pBlendPathStart,BlendPath* pBlendPathEnd,double BlendRatio)
02272 {
02273
02274 BOOL ok = (pBlendPathStart != NULL && pBlendPathEnd != NULL);
02275 if (ok) ok = (pBlendPathStart->GetCreatedByNode() != NULL && pBlendPathEnd->GetCreatedByNode() != NULL);
02276 ERROR3IF(!ok,"One or more NULL entry params");
02277 if (!ok)
02278 {
02279 Matrix M;
02280 return M;
02281 }
02282
02283
02284 DocRect BoundsStart = pBlendPathStart->GetCreatedByNode()->GetBoundingRect(TRUE);
02285 DocRect BoundsEnd = pBlendPathEnd ->GetCreatedByNode()->GetBoundingRect(TRUE);
02286
02287
02288
02289
02290 double Sx0 = BoundsStart.lo.x;
02291 double Sy0 = BoundsStart.lo.y;
02292
02293 double Sx1 = BoundsStart.hi.x;
02294 double Sy1 = BoundsStart.hi.y;
02295
02296 double Dx0 = BoundsEnd.lo.x;
02297 double Dy0 = BoundsEnd.lo.y;
02298
02299 double Dx1 = BoundsEnd.hi.x;
02300 double Dy1 = BoundsEnd.hi.y;
02301
02302 double Ex0 = Sx0 + BlendRatio*(Dx0-Sx0);
02303 double Ey0 = Sy0 + BlendRatio*(Dy0-Sy0);
02304 double Ex1 = Sx1 + BlendRatio*(Dx1-Sx1);
02305 double Ey1 = Sy1 + BlendRatio*(Dy1-Sy1);
02306
02307
02308 double t0 = (Ex1-Ex0)/(Sx1-Sx0);
02309 double t1 = 0;
02310 double t2 = 0;
02311 double t3 = (Ey1-Ey0)/(Sy1-Sy0);
02312
02313 FIXED16 a(t0);
02314 FIXED16 b(t1);
02315 FIXED16 c(t2);
02316 FIXED16 d(t3);
02317
02318 INT32 e = (INT32) (Ex0-Sx0*t0);
02319 INT32 f = (INT32) (Ey0-Sy0*t3);
02320
02321 Matrix M(a,b,c,d,e,f);
02322
02323 return (M);
02324 }
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341 double NodeBlender::MapObjectBlendRatio(double BlendRatio)
02342 {
02343 NodeBlend* pNodeBlend = GetNodeBlend();
02344 if (pNodeBlend)
02345 {
02346 IProfile* pProfile = pNodeBlend->GetObjectProfile();
02347 if (pProfile)
02348 return pProfile->MapZeroToOne(BlendRatio);
02349 }
02350
02351 return BlendRatio;
02352 }
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368 double NodeBlender::MapAttrBlendRatio(double BlendRatio)
02369 {
02370 NodeBlend* pNodeBlend = GetNodeBlend();
02371 if (pNodeBlend)
02372 {
02373 IProfile* pProfile = pNodeBlend->GetAttrProfile();
02374 if (pProfile)
02375 return pProfile->MapZeroToOne(BlendRatio);
02376 }
02377
02378 return BlendRatio;
02379 }
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395 double NodeBlender::MapPositionBlendRatio(double BlendRatio)
02396 {
02397 NodeBlend* pNodeBlend = GetNodeBlend();
02398 if (pNodeBlend)
02399 {
02400 IProfile* pProfile = pNodeBlend->GetPositionProfile();
02401 if (pProfile)
02402 return pProfile->MapZeroToOne(BlendRatio);
02403 }
02404
02405 return BlendRatio;
02406 }
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422 double NodeBlender::GetObjectRatio()
02423 {
02424 UINT32 NumSteps = GetNumBlendSteps() + 1;
02425 double StepRatio = 1.0/NumSteps;
02426 double LinearRatio = StepRatio * m_BlendStep;
02427
02428 CProfileBiasGain* ObjectProfile = GetNodeBlend()->GetObjectProfile();
02429
02430 return ObjectProfile->MapZeroToOne(LinearRatio);
02431
02432 }
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451 double NodeBlender::GetInvertedAttributeRatio()
02452 {
02453 UINT32 NumSteps = GetNumBlendSteps() + 1;
02454 double StepRatio = 1.0/NumSteps;
02455 double LinearRatio = StepRatio * m_BlendStep;
02456
02457 CProfileBiasGain* AttributeProfile = GetNodeBlend()->GetAttrProfile();
02458
02459 CProfileBiasGain InvertedProfile;
02460 InvertedProfile.SetBias(-1*(AttributeProfile->GetBias()));
02461 InvertedProfile.SetGain(-1*(AttributeProfile->GetGain()));
02462
02463 AttributeProfile->MapZeroToOne(LinearRatio);
02464
02465 return InvertedProfile.MapZeroToOne(LinearRatio);
02466
02467 }
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482 void NodeBlender::RenderEorDrag( RenderRegion* pRender )
02483 {
02484 if (!Reinit()) return;
02485 }
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505 void NodeBlender::RenderBlendBlobs(RenderRegion* pRender,BOOL RenderStart,BOOL RenderEnd)
02506 {
02507 #if !defined(EXCLUDE_FROM_RALPH)
02508 if (!Reinit()) return;
02509 if (m_pRefStart == NULL || m_pRefEnd == NULL) return;
02510
02511 if (m_pRefStart->GetNumBlendPaths() == 1 && m_pRefEnd->GetNumBlendPaths() == 1)
02512 {
02513 Trans2DMatrix* pRotateStart= NULL;
02514 Trans2DMatrix* pRotateEnd = NULL;
02515
02516 if (GetNodeBlendPath() != NULL)
02517 {
02518 pRotateStart = GetRotateMatrix(m_pRefStart->GetNode(),m_AngleStart);
02519 pRotateEnd = GetRotateMatrix(m_pRefEnd ->GetNode(),m_AngleEnd );
02520 }
02521
02522 if (RenderStart) m_pRefStart->RenderBlendBlobs(pRender,pRotateStart);
02523 if (RenderEnd) m_pRefEnd ->RenderBlendBlobs(pRender,pRotateEnd);
02524
02525 BlendPath* pBlendPathStart = m_pRefStart->GetFirstBlendPath();
02526 BlendPath* pBlendPathEnd = m_pRefEnd ->GetFirstBlendPath();
02527
02528 if (pBlendPathStart != NULL && pBlendPathEnd != NULL)
02529 {
02530 DocCoord Start = pBlendPathStart->GetPathCoord(0);
02531 DocCoord End = pBlendPathEnd ->GetPathCoord(0);
02532
02533 if (pRotateStart) pRotateStart->Transform(&Start,1);
02534 if (pRotateEnd) pRotateEnd ->Transform(&End ,1);
02535
02536
02537 FIXED16 ScaledPixelWidth,
02538 ScaledPixelHeight;
02539 pRender->GetRenderView()->GetScaledPixelSize(&ScaledPixelWidth, &ScaledPixelHeight);
02540
02541 pRender->SetLineWidth((ScaledPixelWidth.MakeLong())*2);
02542 pRender->SetLineColour(COLOUR_BLACK);
02543 pRender->DrawLine(Start,End);
02544 }
02545
02546 DELPTR(pRotateStart);
02547 DELPTR(pRotateEnd);
02548 }
02549
02550 #endif
02551 }
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572 DocRect NodeBlender::GetBoundingRect(BOOL DontUseAttrs, BOOL HitTest)
02573 {
02574 if (Parent != NULL && IS_A(Parent,NodeBlend) && !((NodeBlend*)Parent)->AreBoundsValid())
02575 IsBoundingRectValid = FALSE;
02576
02577 if (!IsBoundingRectValid || DontUseAttrs)
02578 {
02579
02580 NodeRenderableInk* pStart = NULL;
02581 NodeRenderableInk* pEnd = NULL;
02582
02583
02584 if (m_pRefStart != NULL) pStart = m_pRefStart->GetNode();
02585 if (m_pRefEnd != NULL) pEnd = m_pRefEnd ->GetNode();
02586
02587 if (pStart == NULL) pStart = m_pNodeStart;
02588 if (pEnd == NULL) pEnd = m_pNodeEnd;
02589
02590
02591 if (pStart == NULL) pStart = (NodeRenderableInk*)FindPrevious(CC_RUNTIME_CLASS(NodeRenderableInk));
02592 if (pEnd == NULL) pEnd = (NodeRenderableInk*)FindNext(CC_RUNTIME_CLASS(NodeRenderableInk));
02593
02594
02595 ERROR3IF(pStart == NULL,"pStart == NULL");
02596 ERROR3IF(pEnd == NULL,"pEnd == NULL");
02597 ERROR3IF(!pStart->IS_KIND_OF(NodeRenderableInk),"pStart not a NodeRenderableInk");
02598 ERROR3IF(!pEnd ->IS_KIND_OF(NodeRenderableInk),"pEnd not a NodeRenderableInk");
02599 ERROR3IF(pStart->IS_KIND_OF(NodeBlender),"pStart is a NodeBlender");
02600 ERROR3IF(pEnd ->IS_KIND_OF(NodeBlender),"pEnd not a NodeBlender");
02601
02602
02603 BOOL ok = (pStart != NULL) &&
02604 (pEnd != NULL) &&
02605 (pStart->IS_KIND_OF(NodeRenderableInk)) &&
02606 (pEnd ->IS_KIND_OF(NodeRenderableInk)) &&
02607 (!pStart->IS_KIND_OF(NodeBlender)) &&
02608 (!pEnd ->IS_KIND_OF(NodeBlender));
02609
02610 if (ok)
02611 {
02612
02613
02614
02615 DocRect BoundsStart = pStart->GetBoundingRect(DontUseAttrs,HitTest);
02616 DocRect BoundsEnd = pEnd ->GetBoundingRect(DontUseAttrs,HitTest);
02617
02618 DocRect NewBounds;
02619 NewBounds = BoundsStart;
02620 NewBounds = NewBounds.Union(BoundsEnd);
02621
02622 if (GetNodeBlendPath() != NULL)
02623 NewBounds = NewBounds.Union(GetUnionBlendedBounds(BoundsStart,BoundsEnd));
02624
02625
02626
02627 if (DontUseAttrs)
02628 return(NewBounds);
02629
02630
02631 IsBoundingRectValid = TRUE;
02632 BoundingRectangle = NewBounds;
02633 }
02634 }
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651 return BoundingRectangle;
02652 }
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667 DocRect NodeBlender::GetBlobBoundingRect()
02668 {
02669 return (GetBoundingRect());
02670 }
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687 UINT32 NodeBlender::GetNodeSize() const
02688 {
02689 return (sizeof(NodeBlender));
02690 }
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714 BOOL NodeBlender::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods,
02715 Spread* pSpread )
02716 {
02717 if (!Reinit()) return FALSE;
02718
02719
02720 return FALSE;
02721 }
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746 BOOL NodeBlender::CanBecomeA(BecomeA* pBecomeA)
02747 {
02748
02749 if (pBecomeA->BAPath())
02750 {
02751 if (pBecomeA->IsCounting())
02752 {
02753 if (!Reinit()) return FALSE;
02754
02755
02756 if (m_pRefStart == NULL || m_pRefEnd == NULL)
02757 return FALSE;
02758
02759 UINT32 NumBlendSteps = GetNumBlendSteps();
02760
02761
02762
02763 UINT32 NumPathsInStart = m_pRefStart->GetNumBlendPaths();
02764 UINT32 NumPathsInEnd = m_pRefEnd ->GetNumBlendPaths();
02765 UINT32 MaxNumPaths = max(NumPathsInStart,NumPathsInEnd);
02766
02767
02768
02769 pBecomeA->AddCount(NumBlendSteps * MaxNumPaths);
02770 }
02771
02772 return TRUE;
02773 }
02774
02775 return FALSE;
02776 }
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795 BOOL NodeBlender::DoBecomeA(BecomeA* pBecomeA)
02796 {
02797 if (!Reinit()) return TRUE;
02798
02799 if (!m_Initialised) return TRUE;
02800
02801
02802 ERROR2IF(pBecomeA == NULL,FALSE,"pBecomeA is NULL");
02803
02804
02805
02806 BOOL ValidReason = (pBecomeA->GetReason() == BECOMEA_REPLACE || pBecomeA->GetReason() == BECOMEA_PASSBACK);
02807 ERROR2IF_PF(!ValidReason,FALSE,("Unkown BecomeA reason %d",pBecomeA->GetReason()));
02808
02809
02810
02811
02812 HandleBecomeA HBecomeA(this,this,pBecomeA);
02813 CreateBlends(NULL,&HBecomeA);
02814
02815 switch (pBecomeA->GetReason())
02816 {
02817 case BECOMEA_REPLACE :
02818 {
02819
02820
02821
02822
02823
02824 UndoableOperation* pOp = pBecomeA->GetUndoOp();
02825
02826
02827
02828
02829
02830
02831 Node* pNode = m_pNodeStart->FindNext();
02832
02833 while (pNode != NULL && pNode != m_pNodeEnd)
02834 {
02835
02836 if (pNode->IsCompoundClass())
02837 {
02838 if (pOp)
02839 {
02840 if (!pOp->DoFactorOutCommonChildAttributes((NodeCompound*)pNode))
02841 return FALSE;
02842 }
02843 else
02844 {
02845 if (!((NodeCompound*)pNode)->FactorOutCommonChildAttributes())
02846 return(FALSE);
02847 }
02848 }
02849
02850 pNode = pNode->FindNext();
02851 }
02852
02853 NodeHidden* pHiddenNodeBlender = NULL;
02854
02855
02856 if (pOp)
02857 {
02858 if (!pOp->DoHideNode(this, TRUE, &pHiddenNodeBlender))
02859 return FALSE;
02860 }
02861 else
02862 {
02863 CascadeDelete();
02864 delete this;
02865 }
02866 }
02867 break;
02868
02869 case BECOMEA_PASSBACK :
02870
02871 break;
02872 default: break;
02873 }
02874
02875 return TRUE;
02876 }
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896 BOOL NodeBlender::Snap(DocCoord* pDocCoord)
02897 {
02898 return FALSE;
02899 }
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929 BOOL NodeBlender::Snap(DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord)
02930 {
02931 return FALSE;
02932 }
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956 BOOL NodeBlender::IsPointOverBlob(DocCoord* pPointerPos,BlendPath** ppBlendPath,INT32* pIndex,BOOL* pAStart)
02957 {
02958 #if !defined(EXCLUDE_FROM_RALPH)
02959 if (m_pRefStart == NULL || m_pRefEnd == NULL || pPointerPos == NULL) return FALSE;
02960
02961 BOOL Found = FALSE;
02962
02963 if (m_pRefStart->GetNumBlendPaths() == 1 && m_pRefEnd->GetNumBlendPaths() == 1)
02964 {
02965 Trans2DMatrix* pRotateStart= NULL;
02966 Trans2DMatrix* pRotateEnd = NULL;
02967
02968 if (GetNodeBlendPath() != NULL)
02969 {
02970 pRotateStart = GetRotateMatrix(m_pRefStart->GetNode(),m_AngleStart);
02971 pRotateEnd = GetRotateMatrix(m_pRefEnd ->GetNode(),m_AngleEnd );
02972 }
02973
02974 if (m_pRefStart->IsPointOverBlob(pPointerPos,ppBlendPath,pIndex,pRotateStart))
02975 {
02976 Found = TRUE;
02977 *pAStart = TRUE;
02978 }
02979
02980 if (m_pRefEnd->IsPointOverBlob(pPointerPos,ppBlendPath,pIndex,pRotateEnd))
02981 {
02982 Found = TRUE;
02983 *pAStart = FALSE;
02984 }
02985
02986 DELPTR(pRotateStart);
02987 DELPTR(pRotateEnd);
02988 }
02989
02990 return Found;
02991 #else
02992 return FALSE;
02993 #endif
02994 }
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037 BOOL NodeBlender::Initialise( NodeRenderableInk* pThisNodeStart,
03038 NodeRenderableInk* pThisNodeEnd,
03039 INT32 ThisPathIndexStart,
03040 INT32 ThisPathIndexEnd,
03041 UndoableOperation* pUndoOp,
03042 Progress* pProgress,
03043 BOOL IgnoreEscape)
03044 {
03045
03046 m_pNodeStart = pThisNodeStart;
03047 m_pNodeEnd = pThisNodeEnd;
03048
03049
03050 m_PathIndexStart = ThisPathIndexStart;
03051 m_PathIndexEnd = ThisPathIndexEnd;
03052
03053
03054 if (m_pNodeStart == NULL) m_pNodeStart = (NodeRenderableInk*)FindPrevious();
03055 if (m_pNodeEnd == NULL) m_pNodeEnd = (NodeRenderableInk*)FindNext();
03056
03057
03058 ERROR2IF(m_pNodeStart == NULL,FALSE,"m_pNodeStart == NULL");
03059 ERROR2IF(m_pNodeEnd == NULL,FALSE,"m_pNodeEnd == NULL");
03060 ERROR2IF(!m_pNodeStart->IS_KIND_OF(NodeRenderableInk),FALSE,"m_pNodeStart not a NodeRenderableInk");
03061 ERROR2IF(!m_pNodeEnd ->IS_KIND_OF(NodeRenderableInk),FALSE,"m_pNodeEnd not a NodeRenderableInk");
03062 ERROR2IF(m_pNodeStart->IS_KIND_OF(NodeBlender),FALSE,"m_pNodeStart is a NodeBlender");
03063 ERROR2IF(m_pNodeEnd ->IS_KIND_OF(NodeBlender),FALSE,"m_pNodeEnd not a NodeBlender");
03064
03065
03066 DELPTR(m_pRefStart);
03067 DELPTR(m_pRefEnd);
03068
03069
03070 m_pRefStart = NULL;
03071 m_pRefEnd = NULL;
03072 m_ObjIndexStart = -1;
03073 m_ObjIndexEnd = -1;
03074 m_Initialised = FALSE;
03075
03076 Trans2DMatrix* pRotateStart= NULL;
03077 Trans2DMatrix* pRotateEnd = NULL;
03078
03079 if (GetNodeBlendPath() != NULL)
03080 {
03081 pRotateStart = GetRotateMatrix(m_pNodeStart,360.0 - m_AngleStart);
03082 pRotateEnd = GetRotateMatrix(m_pNodeEnd ,360.0 - m_AngleEnd );
03083 }
03084
03085 BOOL ok = TRUE;
03086
03087
03088
03089
03090
03091
03092
03093 if (ok) ok = InitBlendRef(m_pNodeStart,&m_pRefStart,m_PathIndexStart,pUndoOp,pProgress,IgnoreEscape,pRotateStart);
03094 if (ok) ok = InitBlendRef(m_pNodeEnd ,&m_pRefEnd ,m_PathIndexEnd ,pUndoOp,pProgress,IgnoreEscape,pRotateEnd);
03095
03096 if (ok) { m_pRefStart->StripRedundantNodeBlendPaths (m_pRefEnd); }
03097
03098 if (ok) ok = CalcObjIndex(m_pNodeStart,&m_ObjIndexStart);
03099 if (ok) ok = CalcObjIndex(m_pNodeEnd ,&m_ObjIndexEnd);
03100
03101
03102
03103
03104
03105 if (((m_pRefStart->GetNumBlendPaths () > 1) && (m_pRefEnd->GetNumBlendPaths () == 1))
03106 ||
03107 ((m_pRefStart->GetNumBlendPaths () == 1) && (m_pRefEnd->GetNumBlendPaths () > 1)))
03108 {
03109 m_PathIndexStart = -1;
03110 m_PathIndexEnd = -1;
03111 DELPTR(m_pRefStart);
03112 DELPTR(m_pRefEnd);
03113
03114 if (ok) ok = InitBlendRef(m_pNodeStart,&m_pRefStart,m_PathIndexStart,pUndoOp,pProgress,IgnoreEscape,pRotateStart);
03115 if (ok) ok = InitBlendRef(m_pNodeEnd ,&m_pRefEnd ,m_PathIndexEnd ,pUndoOp,pProgress,IgnoreEscape,pRotateEnd);
03116
03117 if (ok) { m_pRefStart->StripRedundantNodeBlendPaths (m_pRefEnd); }
03118 }
03119
03120 if (ok) m_PathIndexStart = m_pRefStart->GetOrigMapping();
03121 if (ok) m_PathIndexEnd = m_pRefEnd ->GetOrigMapping();
03122
03123
03124 if (ok) CheckFullyInitialised();
03125 if (ok) ok = m_Initialised;
03126
03127 DELPTR(pRotateStart);
03128 DELPTR(pRotateEnd);
03129
03130
03131
03132
03133 return (ok);
03134 }
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158 BOOL NodeBlender::InitBlendRef(NodeRenderableInk* pNode,BlendRef** ppRef,INT32 Index,UndoableOperation* pUndoOp,Progress* pProgress,BOOL IgnoreEscape,Trans2DMatrix* pMatrix)
03159 {
03160 ERROR2IF(ppRef == NULL,FALSE,"ppRef == NULL");
03161
03162 ALLOC_WITH_FAIL(*ppRef,new BlendRef,pUndoOp);
03163 BOOL ok = (*ppRef != NULL);
03164
03165 if (ok) ok = (*ppRef)->Initialise(pNode,Index,pUndoOp,pProgress,IgnoreEscape,pMatrix);
03166
03167 return (ok);
03168 }
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188 BOOL NodeBlender::CalcObjIndex(NodeRenderableInk* pInkNode,INT32* pObjIndex)
03189 {
03190 ERROR2IF(pInkNode == NULL,FALSE,"pInkNode is NULL");
03191 ERROR2IF(pObjIndex == NULL,FALSE,"pObjIndex is NULL");
03192
03193 Node* pParent = pInkNode->FindParent();
03194
03195
03196
03197
03198
03199
03200 ERROR2IF(pParent == NULL,FALSE,"pInkNode has no parent");
03201
03202 if (!pParent->IsController ())
03203 {
03204 ERROR2IF(!IS_A(pParent,NodeBlend),FALSE,"pInkNode parent is not a NodeBlend");
03205 ERROR2IF(pParent != this->FindParent(),FALSE,"pInkNode has different parent to this node");
03206 }
03207 else
03208 {
03209
03210 if (IS_A (pParent->FindParent (), NodeShadowController))
03211 {
03212 pParent = pParent->FindParent ()->FindParent ();
03213 }
03214
03215 ERROR2IF(pParent->FindParent () != this->FindParent(),FALSE,"pInkNode has different parent to this node");
03216 }
03217
03218 INT32 Index = 0;
03219 Node* pNode = pParent->FindFirstChild();
03220
03221 while (pNode != NULL && pNode != pInkNode)
03222 {
03223 if (pNode->IS_KIND_OF(NodeRenderableInk))
03224 Index++;
03225 if (pNode->IS_KIND_OF(NodeBlendPath))
03226 Index--;
03227 pNode = pNode->FindNext();
03228 }
03229
03230 if (pNode == pInkNode)
03231 *pObjIndex = Index;
03232 else
03233 *pObjIndex = -1;
03234
03235 return (pNode == pInkNode);
03236 }
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257 NodeRenderableInk* NodeBlender::FindObjIndexedNode(INT32 ObjIndex)
03258 {
03259 ERROR3IF_PF(ObjIndex < 0,("ObjIndex is -ve!! (%ld)",ObjIndex));
03260 if (ObjIndex < 0) return NULL;
03261
03262 Node* pParent = this->FindParent();
03263 Node* pFoundNode = NULL;
03264
03265 ERROR3IF(pParent == NULL,"pInkNode has no parent");
03266 ERROR3IF(!IS_A(pParent,NodeBlend),"parent is not a NodeBlend");
03267
03268 if (pParent != NULL && IS_A(pParent,NodeBlend))
03269 {
03270 Node* pNode = pParent->FindFirstChild();
03271 while (pNode != NULL && ObjIndex >= 0)
03272 {
03273 if (pNode->IS_KIND_OF(NodeRenderableInk))
03274 {
03275
03276
03277 if (!pNode->IS_KIND_OF(NodeBlendPath))
03278 {
03279 if (ObjIndex == 0)
03280 pFoundNode = pNode;
03281 ObjIndex--;
03282 }
03283 }
03284 pNode = pNode->FindNext();
03285 }
03286 }
03287
03288 if (pFoundNode != NULL)
03289 {
03290 if (IS_A(pFoundNode,NodeBlender))
03291 {
03292 ERROR3("Found node is a NodeBlender");
03293 pFoundNode = NULL;
03294 }
03295 else if (!pFoundNode->IS_KIND_OF(NodeRenderableInk))
03296 {
03297 ERROR3("Found node is not a NodeRenderableInk");
03298 pFoundNode = NULL;
03299 }
03300 }
03301 else
03302 ERROR3("Couldn't find ref node");
03303
03304 return ((NodeRenderableInk*)pFoundNode);
03305 }
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327 BOOL NodeBlender::CanSelectAsSimple()
03328 {
03329 return FALSE;
03330 }
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350 void NodeBlender::CheckFullyInitialised()
03351 {
03352 m_Initialised = ((m_pRefStart != NULL) &&
03353 (m_pRefEnd != NULL) &&
03354 (m_ObjIndexStart >= 0) &&
03355 (m_ObjIndexEnd >= 0));
03356 }
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380 BOOL NodeBlender::Reinit(NodeRenderableInk* pInkNodeStart,NodeRenderableInk* pInkNodeEnd,BOOL ProgressBar)
03381 {
03382 if (GetNodeBlend())
03383 {
03384 CProfileBiasGain* pObjProfile = GetNodeBlend()->GetObjectProfile();
03385 if (pObjProfile)
03386 {
03387
03388 GetNodeBlend()->RequestObjectProfileProcessing(TRUE);
03389 }
03390 }
03391
03392 if (m_Initialised) return TRUE;
03393
03394
03395
03396
03397
03398
03399 if (pInkNodeStart == NULL) pInkNodeStart = m_pNodeStart;
03400 if (pInkNodeEnd == NULL) pInkNodeEnd = m_pNodeEnd;
03401
03402
03403 if (pInkNodeStart == NULL && m_ObjIndexStart >= 0) pInkNodeStart = FindObjIndexedNode(m_ObjIndexStart);
03404 if (pInkNodeEnd == NULL && m_ObjIndexEnd >= 0) pInkNodeEnd = FindObjIndexedNode(m_ObjIndexEnd);
03405
03406
03407 if (pInkNodeStart == NULL) pInkNodeStart = (NodeRenderableInk*)FindPrevious(CC_RUNTIME_CLASS(NodeRenderableInk));
03408 if (pInkNodeEnd == NULL) pInkNodeEnd = (NodeRenderableInk*)FindNext(CC_RUNTIME_CLASS(NodeRenderableInk));
03409
03410 while (pInkNodeEnd->IS_KIND_OF(NodeBlendPath))
03411 pInkNodeEnd = (NodeRenderableInk*)pInkNodeEnd->FindNext(CC_RUNTIME_CLASS(NodeRenderableInk));
03412
03413
03414
03415 ERROR3IF(pInkNodeStart == NULL,"pInkNodeStart is NULL");
03416 ERROR3IF(pInkNodeEnd == NULL,"pInkNodeEnd is NULL");
03417
03418 if (pInkNodeStart == NULL || pInkNodeEnd == NULL) return TRUE;
03419
03420 if (ProgressBar)
03421 {
03422 Progress Hourglass(_R(IDS_REINTBLEND));
03423 return (Initialise(pInkNodeStart,pInkNodeEnd,m_PathIndexStart,m_PathIndexEnd,NULL,&Hourglass,TRUE));
03424 }
03425 else
03426 return (Initialise(pInkNodeStart,pInkNodeEnd,m_PathIndexStart,m_PathIndexEnd,NULL,NULL,TRUE));
03427 }
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448 void NodeBlender::Deinit(BOOL bNodesMayBeChanged)
03449 {
03450
03451
03452
03453
03454 Node* node = FindPrevious ();
03455
03456 NodeBlend* node2 = (NodeBlend*) node->FindFirstChild (CC_RUNTIME_CLASS (NodeBlend));
03457
03458 NodeGroup::KillAllBlendBecomeAConsListItem (node2);
03459
03460 if (bNodesMayBeChanged)
03461 {
03462 m_pNodeStart = NULL;
03463 m_pNodeEnd = NULL;
03464 }
03465
03466 if (m_Initialised)
03467 {
03468 DELPTR(m_pRefStart);
03469 DELPTR(m_pRefEnd);
03470
03471 m_Initialised = FALSE;
03472 }
03473
03474
03475 NodeBlendPath* pNodeBlendPath = GetNodeBlendPath();
03476 if (pNodeBlendPath != NULL)
03477 pNodeBlendPath->DestroyCachedInformation();
03478 }
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495 UINT32 NodeBlender::GetNumBlendSteps()
03496 {
03497 UINT32 NumBlendSteps = 5;
03498
03499 NodeBlend* pNode = GetNodeBlend();
03500 if (pNode != NULL)
03501 NumBlendSteps = pNode->GetNumBlendSteps();
03502 else
03503 {
03504 ERROR3("Parent of blender is not there, or is not a NodeBlend!!!");
03505 }
03506
03507 return NumBlendSteps;
03508 }
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524 ColourBlendType NodeBlender::GetColourBlendType()
03525 {
03526 ColourBlendType ColBlendType = COLOURBLEND_FADE;
03527
03528 NodeBlend* pNode = GetNodeBlend();
03529 if (pNode != NULL)
03530 ColBlendType = pNode->GetColourBlendType();
03531 else
03532 {
03533 ERROR3("Parent of blender is not there, or is not a NodeBlend!!!");
03534 }
03535
03536 return ColBlendType;
03537 }
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553 BOOL NodeBlender::IsOneToOne()
03554 {
03555 BOOL OneToOne = FALSE;
03556
03557 NodeBlend* pNode = GetNodeBlend();
03558 if (pNode != NULL)
03559 OneToOne = pNode->IsOneToOne();
03560 else
03561 {
03562 ERROR3("Parent of blender is not there, or is not a NodeBlend!!!");
03563 }
03564
03565 return OneToOne;
03566 }
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582 BOOL NodeBlender::IsNotAntialiased()
03583 {
03584 BOOL NotAntialiased = FALSE;
03585
03586 NodeBlend* pNode = GetNodeBlend();
03587 if (pNode != NULL)
03588 NotAntialiased = pNode->IsNotAntialiased();
03589 else
03590 {
03591 ERROR3("Parent of blender is not there, or is not a NodeBlend!!!");
03592 }
03593
03594 return NotAntialiased;
03595 }
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610 BOOL NodeBlender::IsTangential()
03611 {
03612 NodeBlend* pNode = GetNodeBlend();
03613 if (pNode != NULL)
03614 return pNode->IsTangential();
03615
03616 return FALSE;
03617 }
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634 INT32 NodeBlender::GetNodeBlendPathIndex()
03635 {
03636 return m_NodeBlendPathIndex;
03637 }
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654 void NodeBlender::SetNodeBlendPathIndex(INT32 Index)
03655 {
03656 if (Index < -2)
03657 {
03658 ERROR3("Invalid index value");
03659 return;
03660 }
03661
03662 m_NodeBlendPathIndex = Index;
03663 return;
03664 }
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680 BOOL NodeBlender::ReverseEnds()
03681 {
03682 NodeRenderableInk* pTemp = NULL;
03683 pTemp = m_pNodeStart;
03684 m_pNodeStart = m_pNodeEnd;
03685 m_pNodeEnd = pTemp;
03686
03687 SetReversed(!IsReversed());
03688
03689 INT32 Temp = m_ObjIndexStart;
03690 m_ObjIndexStart = m_ObjIndexEnd;
03691 m_ObjIndexEnd = Temp;
03692
03693 return TRUE;
03694 }
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713 BOOL NodeBlender::PreBlend()
03714 {
03715
03716 PostBlend();
03717 if (m_pRefStart != NULL) m_pRefStart->PreBlend();
03718 if (m_pRefEnd != NULL) m_pRefEnd ->PreBlend();
03719
03720
03721 return (ReallocTempBuffers(1000));
03722 }
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740 void NodeBlender::PostBlend()
03741 {
03742 if (m_pRefStart != NULL) m_pRefStart->PostBlend();
03743 if (m_pRefEnd != NULL) m_pRefEnd ->PostBlend();
03744 DeallocTempBuffers();
03745 }
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762 BOOL NodeBlender::ReallocTempBuffers(UINT32 Size)
03763 {
03764 DeallocTempBuffers();
03765
03766
03767 m_TempArraySize = Size;
03768 m_pTempCoords = (DocCoord*) CCMalloc(Size*sizeof(DocCoord));
03769 m_pTempVerbs = (PathVerb*) CCMalloc(Size*sizeof(PathVerb));
03770 m_pTempFlags = (PathFlags*) CCMalloc(Size*sizeof(PathFlags));
03771
03772
03773 if (m_pTempCoords == NULL || m_pTempVerbs == NULL || m_pTempFlags == NULL)
03774 {
03775 DeallocTempBuffers();
03776 return FALSE;
03777 }
03778
03779
03780 return TRUE;
03781 }
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797 void NodeBlender::DeallocTempBuffers()
03798 {
03799 if (m_pTempCoords != NULL) { CCFree(m_pTempCoords); m_pTempCoords = NULL; }
03800 if (m_pTempVerbs != NULL) { CCFree(m_pTempVerbs); m_pTempVerbs = NULL; }
03801 if (m_pTempFlags != NULL) { CCFree(m_pTempFlags); m_pTempFlags = NULL; }
03802 m_TempArraySize = 0;
03803
03804 if (m_pGBlendBuff != NULL) { CCFree(m_pGBlendBuff); m_pGBlendBuff = NULL; }
03805 m_GBlendBuffSize = 0;
03806 }
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822 DocCoord* NodeBlender::GetCoordArray(UINT32 MinSize)
03823 {
03824 MinSize++;
03825 if (m_TempArraySize >= MinSize) return m_pTempCoords;
03826
03827 if (ReallocTempBuffers(MinSize))
03828 return m_pTempCoords;
03829 else
03830 return NULL;
03831 }
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847 PathVerb* NodeBlender::GetVerbArray(UINT32 MinSize)
03848 {
03849 MinSize++;
03850 if (m_TempArraySize >= MinSize) return m_pTempVerbs;
03851
03852 if (ReallocTempBuffers(MinSize))
03853 return m_pTempVerbs;
03854 else
03855 return NULL;
03856 }
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872 PathFlags* NodeBlender::GetFlagArray(UINT32 MinSize)
03873 {
03874 MinSize++;
03875 if (m_TempArraySize >= MinSize) return m_pTempFlags;
03876
03877 if (ReallocTempBuffers(MinSize))
03878 return m_pTempFlags;
03879 else
03880 return NULL;
03881 }
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897 UINT32* NodeBlender::GetGBlendBuff(UINT32 MinSize)
03898 {
03899 MinSize++;
03900 if (m_GBlendBuffSize >= MinSize) return m_pGBlendBuff;
03901
03902 if (m_pGBlendBuff != NULL) CCFree(m_pGBlendBuff);
03903
03904 m_pGBlendBuff = (UINT32*) CCMalloc(MinSize*sizeof(UINT32));
03905
03906 if (m_pGBlendBuff != NULL)
03907 m_GBlendBuffSize = MinSize;
03908 else
03909 m_GBlendBuffSize = 0;
03910
03911 return m_pGBlendBuff;
03912 }
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932 BOOL NodeBlender::Remap(DocCoord PosStart,DocCoord PosEnd,DocCoord* pInvPosStart,DocCoord* pInvPosEnd)
03933 {
03934 BOOL Mapped = FALSE;
03935
03936 if (m_pRefStart != NULL && m_pRefEnd != NULL)
03937 {
03938 BlendPath* pBlendPathStart = m_pRefStart->GetFirstBlendPath();
03939 BlendPath* pBlendPathEnd = m_pRefEnd ->GetFirstBlendPath();
03940
03941 if (pBlendPathStart != NULL && pBlendPathEnd != NULL)
03942 {
03943 if (GetNodeBlendPath() != NULL)
03944 {
03945 Trans2DMatrix* pRotateStart = GetRotateMatrix(m_pRefStart->GetNode(),360.0 - m_AngleStart);
03946 Trans2DMatrix* pRotateEnd = GetRotateMatrix(m_pRefEnd ->GetNode(),360.0 - m_AngleEnd );
03947 if (pRotateStart) pRotateStart->Transform(&PosStart,1);
03948 if (pRotateEnd) pRotateEnd ->Transform(&PosEnd ,1);
03949 DELPTR(pRotateStart);
03950 DELPTR(pRotateEnd);
03951 }
03952
03953 *pInvPosStart = pBlendPathStart->MapPath(PosStart);
03954 *pInvPosEnd = pBlendPathEnd ->MapPath(PosEnd);
03955 Mapped = TRUE;
03956
03957 if (GetNodeBlendPath() != NULL)
03958 {
03959 Trans2DMatrix* pRotateStart = GetRotateMatrix(m_pRefStart->GetNode(),m_AngleStart);
03960 Trans2DMatrix* pRotateEnd = GetRotateMatrix(m_pRefEnd ->GetNode(),m_AngleEnd );
03961 if (pRotateStart) pRotateStart->Transform(pInvPosStart,1);
03962 if (pRotateEnd) pRotateEnd ->Transform(pInvPosEnd ,1);
03963 DELPTR(pRotateStart);
03964 DELPTR(pRotateEnd);
03965 }
03966 }
03967
03968
03969 m_PathIndexStart = m_pRefStart->GetOrigMapping();
03970 m_PathIndexEnd = m_pRefEnd ->GetOrigMapping();
03971 }
03972
03973 return Mapped;
03974 }
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994 BOOL NodeBlender::ConvertAWPathIndexesToCamelot(INT32 *pPathIndexStart,INT32* pPathIndexEnd)
03995 {
03996 BOOL ok = FindPathEndPoint(FindPrevious(),pPathIndexStart);
03997 if (ok) ok = FindPathEndPoint(FindNext(), pPathIndexEnd);
03998 return ok;
03999 }
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017
04018 BOOL NodeBlender::FindPathEndPoint(Node* pNodePath,INT32* pIndex)
04019 {
04020 ERROR3IF(pIndex == NULL,"pIndex == NULL");
04021 ERROR3IF(pNodePath == NULL,"pNodePath == NULL");
04022 if (pIndex == NULL || pNodePath == NULL)
04023 return FALSE;
04024
04025
04026 if (!pNodePath->IS_KIND_OF(NodePath))
04027 *pIndex = 0;
04028
04029
04030
04031 if (*pIndex < 0)
04032 return TRUE;
04033
04034 Path* pPath = &(((NodePath*)pNodePath)->InkPath);
04035
04036 INT32 Index=0;
04037 for (INT32 n=*pIndex;n>0;n--)
04038 {
04039 if (!pPath->FindNextEndPoint(&Index))
04040 return FALSE;
04041 }
04042
04043 *pIndex = Index;
04044
04045 return TRUE;
04046 }
04047
04048
04049
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066 BlendRef::BlendRef()
04067 {
04068 m_pNode = NULL;
04069 m_NumBlendPaths = 0;
04070 m_pBlendPathAttrMap = NULL;
04071 }
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086 BlendRef::~BlendRef()
04087 {
04088 m_BlendPathList.DeleteAll();
04089 DELPTR(m_pBlendPathAttrMap);
04090 }
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110
04111
04112
04113
04114
04115
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169 BOOL BlendRef::Initialise(NodeRenderableInk* pThisNode,INT32 Index,UndoableOperation* pUndoOp,Progress* pProgress,BOOL IgnoreEscape,
04170 Trans2DMatrix* pMatrix, AttrBrushType* pAttrBrush)
04171 {
04172 ERROR2IF(pThisNode == NULL,FALSE,"pThisNode == NULL");
04173
04174
04175 m_pNode = pThisNode;
04176 m_NumBlendPaths = 0;
04177 m_BlendPathList.DeleteAll();
04178
04179
04180 BlendBecomeA ParamBecomeA( BECOMEA_PASSBACK,
04181 CC_RUNTIME_CLASS(NodePath),
04182 pUndoOp,
04183 this,
04184 Index,
04185 pProgress,
04186 IgnoreEscape,
04187 pMatrix);
04188
04189 ERROR2IF(!pThisNode->CanBecomeA(&ParamBecomeA), FALSE, "pThisNode can't become a NodePath!");
04190
04191 BOOL ok = FALSE;
04192
04193 if (pAttrBrush != NULL)
04194 {
04195
04196 if (pAttrBrush->GetBrushHandle() != BrushHandle_NoBrush)
04197 ok = pAttrBrush->DoBecomeA(&ParamBecomeA, pThisNode);
04198 else
04199 ok = m_pNode->DoBecomeA(&ParamBecomeA);
04200 }
04201 else
04202
04203 ok = m_pNode->DoBecomeA(&ParamBecomeA);
04204
04205 if (!ok)
04206 {
04207
04208 m_pNode = NULL;
04209 m_NumBlendPaths = 0;
04210 m_BlendPathList.DeleteAll();
04211 }
04212
04213 return (ok);
04214 }
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231 BOOL BlendRef::InitialiseForBrush(NodeRenderableInk* pThisNode)
04232 {
04233 ERROR2IF(pThisNode == NULL,FALSE,"pThisNode == NULL");
04234
04235
04236 m_pNode = pThisNode;
04237 m_NumBlendPaths = 0;
04238 m_BlendPathList.DeleteAll();
04239
04240
04241 BrushBecomeA MyBecomeA(BECOMEA_PASSBACK,
04242 CC_RUNTIME_CLASS(NodePath),
04243 NULL,
04244 this);
04245
04246 ERROR2IF(!pThisNode->CanBecomeA(&MyBecomeA), FALSE, "pThisNode can't become a NodePath!");
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259 BOOL ok = m_pNode->DoBecomeA(&MyBecomeA);
04260
04261 if (!ok)
04262 {
04263
04264 m_pNode = NULL;
04265 m_NumBlendPaths = 0;
04266 m_BlendPathList.DeleteAll();
04267 }
04268
04269 return (ok);
04270
04271 }
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290 BOOL BlendRef::AddBlendPath(BlendPath* pBlendPath)
04291 {
04292 m_BlendPathList.AddTail(pBlendPath);
04293 m_NumBlendPaths++;
04294
04295 return TRUE;
04296 }
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306
04307
04308
04309
04310
04311 BlendPath* BlendRef::GetFirstBlendPath()
04312 {
04313 return ((BlendPath*)m_BlendPathList.GetHead());
04314 }
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329 BlendPath* BlendRef::GetNextBlendPath(BlendPath* pCurrentBlendPath)
04330 {
04331 return ((BlendPath*)m_BlendPathList.GetNext(pCurrentBlendPath));
04332 }
04333
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348 BlendPath* BlendRef::GetBlendPath(INT32 Index)
04349 {
04350 if (m_NumBlendPaths <= 0)
04351 return NULL;
04352
04353 if (Index >= INT32(m_NumBlendPaths)) { ERROR3("Index too big"); Index = m_NumBlendPaths-1; }
04354 if (Index < 0) { ERROR3("Index is -ve "); Index = 0; }
04355
04356 BlendPath* pBlendPath = GetFirstBlendPath();
04357 while (pBlendPath != NULL && Index > 0)
04358 {
04359 pBlendPath = GetNextBlendPath(pBlendPath);
04360 Index--;
04361 }
04362 ERROR3IF(pBlendPath==NULL,"pBlendPath == NULL");
04363 return (pBlendPath);
04364 }
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378 void BlendRef::Transform( TransformBase& Trans )
04379 {
04380 BlendPath* pBlendPath = GetFirstBlendPath();
04381
04382 while (pBlendPath != NULL)
04383 {
04384 pBlendPath->Transform(Trans);
04385 pBlendPath = GetNextBlendPath(pBlendPath);
04386 }
04387 }
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403 void BlendRef::RenderBlendBlobs(RenderRegion* pRender,Trans2DMatrix* pMatrix)
04404 {
04405 BlendPath* pBlendPath = GetFirstBlendPath();
04406
04407 while (pBlendPath != NULL)
04408 {
04409 pBlendPath->RenderBlendBlobs(pRender,pMatrix);
04410 pBlendPath = GetNextBlendPath(pBlendPath);
04411 }
04412 }
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435 BOOL BlendRef::IsPointOverBlob(DocCoord* pPointerPos,BlendPath** ppBlendPath,INT32* pIndex,Trans2DMatrix* pMatrix)
04436 {
04437 if (pPointerPos == NULL) return FALSE;
04438 if (GetNumBlendPaths() != 1) return FALSE;
04439
04440 BOOL Found = FALSE;
04441 BlendPath* pBlendPath = GetFirstBlendPath();
04442
04443 if (pBlendPath != NULL)
04444 {
04445 Found = pBlendPath->IsPointOverBlob(pPointerPos,pIndex,pMatrix);
04446 if (Found) *ppBlendPath = pBlendPath;
04447 }
04448
04449 return Found;
04450 }
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469
04470 INT32 BlendRef::GetOrigMapping()
04471 {
04472 INT32 Mapping = -1;
04473
04474 if (GetNumBlendPaths() == 1)
04475 {
04476 BlendPath* pBlendPath = GetFirstBlendPath();
04477
04478 if (pBlendPath != NULL)
04479 Mapping = pBlendPath->GetOrigMapping();
04480 }
04481
04482 return Mapping;
04483 }
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499 void BlendRef::PreBlend()
04500 {
04501
04502 if (m_pBlendPathAttrMap == NULL && m_NumBlendPaths > 0)
04503 PORTNOTE("other","Maps aren't hash bashed, so have no initial size")
04504 m_pBlendPathAttrMap = new CMapPtrToPtr();
04505 }
04506
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521 void BlendRef::PostBlend()
04522 {
04523
04524 BlendPath* pBlendPath = GetFirstBlendPath();
04525 while (pBlendPath != NULL)
04526 {
04527 pBlendPath->FreeAppliedAttributes();
04528 pBlendPath = GetNextBlendPath(pBlendPath);
04529 }
04530
04531
04532 if (m_pBlendPathAttrMap != NULL)
04533 m_pBlendPathAttrMap->clear();
04534 }
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552 CCAttrMap* BlendRef::FindAppliedAttributes(BlendPath* pBlendPath)
04553 {
04554
04555
04556 if (pBlendPath->UniqueAppliedAttrs())
04557 return (pBlendPath->FindAppliedAttributes());
04558
04559
04560 if (m_pBlendPathAttrMap == NULL)
04561 return (pBlendPath->FindAppliedAttributes());
04562
04563
04564 CCAttrMap* pAttrMap = NULL;
04565
04566
04567 NodeRenderableInk* pCreatedByNode = pBlendPath->GetCreatedByNode();
04568
04569 if (pCreatedByNode->IsCompound())
04570 {
04571 pCreatedByNode = ((NodeCompound *)pCreatedByNode)->GetNodeToBlend();
04572 }
04573
04574 if (pCreatedByNode != NULL)
04575 {
04576
04577 CMapPtrToPtr::iterator iter = m_pBlendPathAttrMap->find( pCreatedByNode );
04578 if( m_pBlendPathAttrMap->end() != iter )
04579 pAttrMap = (CCAttrMap *)iter->second;
04580 else
04581 {
04582
04583
04584 pAttrMap = pBlendPath->FindAppliedAttributes();
04585 if (pAttrMap != NULL)
04586 (*m_pBlendPathAttrMap)[pCreatedByNode] = pAttrMap;
04587 }
04588 }
04589
04590 return pAttrMap;
04591 }
04592
04593
04594
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608 DocRect BlendRef::GetBoundingRect()
04609 {
04610 DocRect Rect;
04611
04612 BlendPath *pBlendPath = GetFirstBlendPath();
04613 while (pBlendPath != NULL)
04614 {
04615 DocRect PathRect = pBlendPath->m_pPath->GetBoundingRect();
04616 Rect = Rect.Union(PathRect);
04617
04618 pBlendPath = GetNextBlendPath(pBlendPath);
04619 }
04620 return Rect;
04621 }
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639 void BlendRef::StripRedundantNodeBlendPaths (BlendRef* spouse)
04640 {
04641 INT32 numbBlendPathInited = 0, spouseNumbBlendPathInited = 0;
04642
04643 BlendPath *pBlendPath = GetFirstBlendPath();
04644 while (pBlendPath != NULL)
04645 {
04646 if (pBlendPath->GetCreatedViaNodeBlendPath ())
04647 {
04648 numbBlendPathInited++;
04649 }
04650
04651 pBlendPath = GetNextBlendPath(pBlendPath);
04652 }
04653
04654 pBlendPath = spouse->GetFirstBlendPath();
04655 while (pBlendPath != NULL)
04656 {
04657 if (pBlendPath->GetCreatedViaNodeBlendPath ())
04658 {
04659 spouseNumbBlendPathInited++;
04660 }
04661
04662 pBlendPath = spouse->GetNextBlendPath(pBlendPath);
04663 }
04664
04665
04666 if (numbBlendPathInited != spouseNumbBlendPathInited)
04667 {
04668 if ((numbBlendPathInited == 0) && (spouseNumbBlendPathInited > 0))
04669 {
04670
04671
04672 pBlendPath = spouse->GetFirstBlendPath();
04673 while (pBlendPath != NULL)
04674 {
04675 if (pBlendPath->GetCreatedViaNodeBlendPath ())
04676 {
04677 BlendPath* remover = pBlendPath;
04678 pBlendPath = spouse->GetNextBlendPath(pBlendPath);
04679 delete (spouse->m_BlendPathList.RemoveItem (remover));
04680 spouse->m_NumBlendPaths--;
04681 }
04682 else
04683 {
04684 pBlendPath = spouse->GetNextBlendPath(pBlendPath);
04685 }
04686 }
04687 }
04688 else if ((spouseNumbBlendPathInited == 0) && (numbBlendPathInited > 0))
04689 {
04690
04691
04692 pBlendPath = GetFirstBlendPath();
04693 while (pBlendPath != NULL)
04694 {
04695 if (pBlendPath->GetCreatedViaNodeBlendPath ())
04696 {
04697 BlendPath* remover = pBlendPath;
04698 pBlendPath = GetNextBlendPath(pBlendPath);
04699 delete (m_BlendPathList.RemoveItem (remover));
04700 m_NumBlendPaths--;
04701 }
04702 else
04703 {
04704 pBlendPath = GetNextBlendPath(pBlendPath);
04705 }
04706 }
04707 }
04708
04709 }
04710 }
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728 BOOL BlendRef::RemoveLastBlendPath()
04729 {
04730 if (m_BlendPathList.IsEmpty())
04731 return FALSE;
04732
04733 m_BlendPathList.RemoveTail();
04734 m_NumBlendPaths--;
04735
04736 return TRUE;
04737 }
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757 BlendPath::BlendPath()
04758 {
04759 m_pBlendNode = NULL;
04760 m_pPath = NULL;
04761 m_pCreatedByNode= NULL;
04762 m_pAppliedAttrs = NULL;
04763
04764 m_CloseFigure = 0;
04765 m_OrigMapping = 0;
04766 m_PathType = PATHTYPE_NONE;
04767 m_SubPathID = 0;
04768 m_DirChanged = FALSE;
04769 m_NumElements = -1;
04770 m_UniqueAttrs = FALSE;
04771
04772 m_bDeleteAll = FALSE;
04773 m_bFreeAttrMapOnDestruct = FALSE;
04774
04775 m_AppliedLineWidth = -1;
04776
04777 m_bCreatedViaNodeBlendPath = FALSE;
04778
04779 m_pCopyPath = NULL;
04780 m_pCopyAttrs = NULL;
04781 }
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807 BlendPath::~BlendPath()
04808 {
04809
04810 DeleteCopyPathAndAttributes();
04811
04812
04813
04814
04815
04816 if (m_SubPathNum == 0 || m_bDeleteAll)
04817 {
04818 if ((m_UniqueAttrs || m_bDeleteAll) && m_pAppliedAttrs != NULL)
04819 {
04820 CCRuntimeClass *pType;
04821 void *pVal;
04822
04823 CMapPtrToPtr::iterator Pos = m_pAppliedAttrs->GetStartPosition();
04824 CMapPtrToPtr::iterator End = m_pAppliedAttrs->GetEndPosition();
04825 for(; Pos != End;)
04826 {
04827
04828 m_pAppliedAttrs->GetNextAssoc( Pos, pType, pVal );
04829 if (pVal != NULL)
04830 delete (NodeAttribute*)pVal;
04831 }
04832 }
04833 if (m_pAppliedAttrs != NULL)
04834 {
04835 delete m_pAppliedAttrs;
04836 m_pAppliedAttrs = NULL;
04837 }
04838 }
04839
04840
04841 if (m_bFreeAttrMapOnDestruct)
04842 {
04843 if (m_pAppliedAttrs != NULL)
04844 {
04845 delete m_pAppliedAttrs;
04846 m_pAppliedAttrs = NULL;
04847 }
04848 }
04849
04850 if (m_pBlendNode)
04851 {
04852 m_pBlendNode->CascadeDelete();
04853 delete m_pBlendNode;
04854 }
04855
04856 if (m_bDeleteAll)
04857 {
04858 if (m_pPath != NULL)
04859 delete m_pPath;
04860 }
04861
04862 }
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892
04893
04894 BOOL BlendPath::Initialise( NodeRenderableInk* pThisBlendNode,
04895 INT32 Index,
04896 NodeRenderableInk* pThisCreatedByNode,
04897 UINT32 ThisSubPathID,
04898 UINT32 ThisSubPathNum,
04899 CCAttrMap* pAttrMap,
04900 BOOL CheckDirection)
04901 {
04902 if (pThisBlendNode == NULL || pThisCreatedByNode == NULL) return FALSE;
04903
04904 if (pThisBlendNode->IsNodePath())
04905 ERROR3IF(ThisSubPathID == 0,"Invalid subpath ID");
04906
04907 DELPTR(m_pBlendNode);
04908
04909 m_pBlendNode = pThisBlendNode;
04910
04911 if (m_pBlendNode->IsNodePath())
04912 {
04913 m_pPath = &(((NodePath *)m_pBlendNode)->InkPath);
04914
04915 }
04916 else
04917 {
04918
04919 if (pThisBlendNode->IsCompound())
04920 {
04921 NodeRenderableInk * pInk = ((NodeCompound *)pThisBlendNode)->GetNodeToBlend();
04922
04923 if (pInk)
04924 {
04925 if (pInk->IsNodePath())
04926 {
04927 m_pPath = &(((NodePath *)pInk)->InkPath);
04928 }
04929 else
04930 {
04931 ERROR3("Node to blend isn't a node path");
04932 }
04933 }
04934 else
04935 {
04936 ERROR3("No node to blend");
04937 }
04938 }
04939 }
04940
04941 m_pCreatedByNode= pThisCreatedByNode;
04942 m_SubPathID = ThisSubPathID;
04943 m_SubPathNum = ThisSubPathNum;
04944 m_pAppliedAttrs = pAttrMap;
04945 m_UniqueAttrs = (pAttrMap != NULL);
04946
04947 if (m_pPath)
04948 {
04949 m_NumElements = m_pPath->GetNumElements();
04950 m_PathType = m_pPath->GetPathType();
04951 }
04952 else
04953 {
04954 m_NumElements = 0;
04955 m_PathType = PATHTYPE_SHAPE;
04956 }
04957
04958
04959
04960 if (m_pPath && CheckDirection)
04961 {
04962
04963 if (Index < 0 && m_PathType == PATHTYPE_SHAPE) Index = FindBottomLeft();
04964
04965 ProcessVerbs();
04966 MapPath(Index);
04967 CorrectDirection(Index);
04968
04969 }
04970
04971
04972
04973 DocRect BRect;
04974
04975 if (m_pPath)
04976 {
04977 BRect = m_pPath->GetBoundingRect();
04978 }
04979 else
04980 {
04981 BRect = m_pBlendNode->GetBoundingRect(FALSE, FALSE);
04982 }
04983
04984 m_BrushStartCoord = BRect.Centre();
04985
04986 return TRUE;
04987 }
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000
05001
05002
05003 BOOL BlendPath::Initialise( BlendPath *pBlendPath,
05004 NodeRenderableInk * pNodeToBlend)
05005 {
05006 m_pPath = pBlendPath->GetPath();
05007
05008 pNodeToBlend->NodeCopy((Node **)(&m_pBlendNode));
05009 m_pCreatedByNode = pBlendPath->GetCreatedByNode();
05010 m_OrigMapping = pBlendPath->GetOrigMapping();
05011 m_PathType = pBlendPath->GetPathType();
05012 m_SubPathID = pBlendPath->GetSubPathID();
05013 m_SubPathNum = pBlendPath->GetSubPathNum();
05014 m_NumElements = pBlendPath->GetNumElements();
05015 m_UniqueAttrs = pBlendPath->UniqueAppliedAttrs();
05016 m_DirChanged = pBlendPath->m_DirChanged;
05017 m_BrushStartCoord = pBlendPath->m_BrushStartCoord;
05018 m_BrushCurrentCoord = pBlendPath->m_BrushCurrentCoord;
05019
05020 if (m_pAppliedAttrs)
05021 m_pAppliedAttrs = pBlendPath->m_pAppliedAttrs->Copy();
05022 else
05023 m_pAppliedAttrs = NULL;
05024
05025 return TRUE;
05026 }
05027
05028
05029
05030
05031
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042 void BlendPath::CorrectDirection(INT32 Index)
05043 {
05044 switch (m_PathType)
05045 {
05046 case PATHTYPE_SHAPE:
05047 {
05048
05049 UINT32 l; POINT p;
05050
05051
05052 BOOL Direction = GWinding((PPOINT)m_pPath->GetCoordArray(),m_pPath->GetVerbArray(),m_pPath->GetNumCoords(),FLATNESS,l,p);
05053
05054
05055 if (Direction)
05056 m_pPath->Reverse();
05057
05058 m_DirChanged = Direction;
05059 }
05060 break;
05061
05062 case PATHTYPE_LINE:
05063 {
05064
05065 INT32 NumCoords = m_pPath->GetNumCoords();
05066
05067 if (Index != 0 && Index != (NumCoords-1))
05068 {
05069
05070 DocCoord* pCoords = m_pPath->GetCoordArray();
05071
05072
05073 DocCoord Coord1 = pCoords[0];
05074 DocCoord Coord2 = pCoords[NumCoords-1];
05075
05076
05077 if ((Coord1.x + Coord1.y) > (Coord2.x + Coord2.y))
05078 {
05079 m_pPath->Reverse();
05080 m_OrigMapping = NumCoords-1;
05081 }
05082 }
05083 }
05084 break;
05085
05086 default : ERROR3("Unknown path type"); break;
05087 }
05088 }
05089
05090
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103
05104
05105
05106
05107 INT32 BlendPath::MapPath(INT32 Index)
05108 {
05109 INT32 NumCoords = m_pPath->GetNumCoords();
05110
05111 INT32 InverseMapping = 0;
05112
05113
05114 if (Index > 0 && Index < NumCoords)
05115 {
05116
05117 PathFlags* pFlags = m_pPath->GetFlagArray();
05118 PathVerb* pVerbs = m_pPath->GetVerbArray();
05119 DocCoord* pCoords = m_pPath->GetCoordArray();
05120
05121 ERROR3IF(!pFlags[Index].IsEndPoint,"Index not on end point");
05122 if (!pFlags[Index].IsEndPoint)
05123 {
05124
05125
05126 INT32 OldIndex = Index;
05127 INT32 PrevIndex = 0;
05128 while (PrevIndex < OldIndex)
05129 {
05130 Index = PrevIndex;
05131 if (!m_pPath->FindNextEndPoint(&PrevIndex))
05132 {
05133 Index = 0;
05134 break;
05135 }
05136 }
05137 }
05138
05139 switch (m_PathType)
05140 {
05141 case PATHTYPE_SHAPE:
05142
05143 if (m_DirChanged)
05144 {
05145 DocCoord Pos = pCoords[Index];
05146 m_pPath->Reverse();
05147 m_pPath->FindNearestPoint(Pos,POINTFLAG_ENDPOINTS,&Index);
05148 }
05149
05150
05151 m_pPath->ChangeStartElement(Index);
05152
05153
05154
05155 pVerbs[NumCoords-1] &= ~PT_CLOSEFIGURE;
05156
05157
05158
05159 m_OrigMapping += Index;
05160
05161 if (m_OrigMapping >= (NumCoords-1))
05162 m_OrigMapping = (m_OrigMapping+1) % NumCoords;
05163
05164 InverseMapping = NumCoords-Index-1;
05165
05166 if (m_DirChanged)
05167 {
05168 DocCoord Pos = pCoords[InverseMapping];
05169 m_pPath->Reverse();
05170 m_pPath->FindNearestPoint(Pos,POINTFLAG_ENDPOINTS,&InverseMapping);
05171 }
05172 break;
05173
05174 case PATHTYPE_LINE:
05175
05176
05177 if (Index == (NumCoords-1))
05178 {
05179
05180 m_pPath->Reverse();
05181
05182
05183 if (m_OrigMapping == 0)
05184 m_OrigMapping = NumCoords-1;
05185 else
05186 m_OrigMapping = 0;
05187
05188 InverseMapping = NumCoords-1;
05189 }
05190 break;
05191
05192 default : ERROR3("Unknown path type"); break;
05193 }
05194 }
05195
05196 return InverseMapping;
05197 }
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216
05217 DocCoord BlendPath::MapPath(DocCoord Pos)
05218 {
05219 DocCoord InversePos(0,0);
05220
05221 ERROR2IF(m_pPath == NULL,InversePos,"m_pPath == NULL");
05222 DocCoord* pCoords = m_pPath->GetCoordArray();
05223 ERROR2IF(pCoords == NULL,InversePos,"pCoords == NULL");
05224
05225
05226 InversePos = pCoords[0];
05227
05228 INT32 Index = 0;
05229 INT32 InvIndex = 0;
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242 if (m_pPath->FindNearestPoint(Pos,POINTFLAG_ENDPOINTS,&Index))
05243 InvIndex = MapPath(Index);
05244
05245 InversePos = pCoords[InvIndex];
05246
05247
05248
05249
05250
05251
05252
05253
05254
05255
05256
05257 return InversePos;
05258 }
05259
05260
05261
05262
05263
05264
05265
05266
05267
05268
05269
05270
05271
05272
05273
05274 INT32 BlendPath::FindBottomLeft()
05275 {
05276 DocCoord* pCoords = m_pPath->GetCoordArray();
05277 if (pCoords == NULL) return -1;
05278
05279 INT32 BottomLeftIndex = -1;
05280 INT32 Index;
05281 BOOL ok;
05282
05283 DocCoord VeryMostBottomLeft(0x7fffffff,0x7fffffff);
05284 double SmallestDist = 1.0e100,ThisDist;
05285
05286 for (Index=0,ok=TRUE;ok;)
05287 {
05288 if (pCoords[Index].x < VeryMostBottomLeft.x) VeryMostBottomLeft.x = pCoords[Index].x;
05289 if (pCoords[Index].y < VeryMostBottomLeft.y) VeryMostBottomLeft.y = pCoords[Index].y;
05290 ok = m_pPath->FindNextEndPoint(&Index);
05291 }
05292
05293 for (Index=0,ok=TRUE;ok;)
05294 {
05295 ThisDist = VeryMostBottomLeft.Distance(pCoords[Index]);
05296 if (ThisDist < SmallestDist)
05297 {
05298 BottomLeftIndex = Index;
05299 SmallestDist = ThisDist;
05300 }
05301 ok = m_pPath->FindNextEndPoint(&Index);
05302 }
05303
05304
05305
05306 UINT32 u; POINT p;
05307
05308
05309 GWinding((PPOINT)m_pPath->GetCoordArray(),m_pPath->GetVerbArray(),m_pPath->GetNumCoords(),FLATNESS,u,p);
05310
05311
05312
05313 INT32 GIndex=-1;
05314 DocCoord Coord(p.x,p.y);
05315 SmallestDist = 1.0e100;
05316 for (Index=0,ok=TRUE;ok;)
05317 {
05318 ThisDist = Coord.Distance(pCoords[Index]);
05319 if ((ThisDist-SmallestDist) < 5.0)
05320 {
05321
05322 GIndex = Index;
05323
05324
05325 if (ThisDist < SmallestDist)
05326 SmallestDist = ThisDist;
05327 }
05328
05329 ok = m_pPath->FindNextEndPoint(&Index);
05330 }
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340
05341
05342 return GIndex;
05343
05344 }
05345
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359
05360
05361
05362
05363 void BlendPath::ProcessVerbs()
05364 {
05365 PathVerb* pPathVerb = m_pPath->GetVerbArray();
05366 INT32 n = m_pPath->GetNumCoords()-1;
05367
05368 m_CloseFigure = 0;
05369
05370 for (;n>=0;n--)
05371 {
05372
05373 PathVerb Verb = pPathVerb[n];
05374
05375
05376 if (m_CloseFigure == 0) m_CloseFigure = Verb & PT_CLOSEFIGURE;
05377
05378
05379 pPathVerb[n] = Verb & ~PT_CLOSEFIGURE;
05380 }
05381 }
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392
05393
05394
05395
05396 void BlendPath::Transform( TransformBase& Trans )
05397 {
05398 if (m_pBlendNode != NULL) m_pBlendNode->Transform(Trans);
05399
05400 if (m_UniqueAttrs && m_pAppliedAttrs != NULL)
05401 {
05402 CCRuntimeClass *pType;
05403 void *pVal;
05404
05405
05406 for( CMapPtrToPtr::iterator Pos = m_pAppliedAttrs->GetStartPosition();
05407 Pos != m_pAppliedAttrs->GetEndPosition();)
05408 {
05409
05410 m_pAppliedAttrs->GetNextAssoc(Pos,pType,pVal);
05411
05412
05413 NodeAttribute* pNodeAttr = (NodeAttribute *)pVal;
05414
05415 pNodeAttr->Transform(Trans);
05416 }
05417 }
05418
05419 }
05420
05421
05422
05423
05424
05425
05426
05427
05428
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438
05439 void BlendPath::Transform( Matrix* pTransMatrix, BOOL TransformLines, BOOL Tile )
05440 {
05441 Trans2DMatrix Trans(*pTransMatrix);
05442
05443 if (m_pBlendNode != NULL)
05444 m_pBlendNode->Transform(Trans);
05445 else
05446 {
05447
05448
05449 DocCoord* pCoords = m_pPath->GetCoordArray();
05450 INT32 NumCoords = m_pPath->GetNumCoords();
05451 if (pCoords != NULL && NumCoords > 0)
05452 Trans.Transform(pCoords, NumCoords);
05453 else
05454 ERROR3("No coordinates in BlendPath::Transform");
05455 }
05456
05457 CCAttrMap* pAttrMap = FindAppliedAttributes();
05458 if (pAttrMap != NULL)
05459 {
05460 if (Tile)
05461 pAttrMap->TransformForBrush(Trans);
05462 else
05463 pAttrMap->Transform(Trans);
05464 }
05465 else
05466 {
05467 ERROR3("No applied attributes");
05468 }
05469
05470
05471 return;
05472 }
05473
05474
05475
05476
05477
05478
05479
05480
05481
05482
05483
05484
05485
05486
05487
05488
05489 BOOL BlendPath::TransformBrushAttributesBeforeSave()
05490 {
05491 if (m_pPath == NULL)
05492 {
05493 ERROR2(FALSE, "This blendpath has no path");
05494 return FALSE;
05495 }
05496 DocRect BRect = m_pPath->GetBoundingRect();
05497 m_BrushCurrentCoord = BRect.Centre();
05498
05499 Trans2DMatrix Trans(m_BrushStartCoord.x - m_BrushCurrentCoord.x,
05500 m_BrushStartCoord.y - m_BrushCurrentCoord.y);
05501
05502 CCAttrMap* pAttrMap = FindAppliedAttributes();
05503
05504 if (pAttrMap == NULL)
05505 {
05506 ERROR3("No applied attributes");
05507 return FALSE;
05508 }
05509
05510
05511
05512 AttrFractalFill* pFrac = NULL;
05513 if( pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrFractalFill), (void*&)pFrac ) )
05514 pAttrMap->RemoveKey( CC_RUNTIME_CLASS(AttrFractalFill) );
05515
05516 pAttrMap->Transform(Trans);
05517
05518 return TRUE;
05519 }
05520
05521
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533 BOOL BlendPath::TransformBrushAttributesAfterSave()
05534 {
05535 Trans2DMatrix Trans(m_BrushCurrentCoord.x - m_BrushStartCoord.x,
05536 m_BrushCurrentCoord.y - m_BrushStartCoord.y);
05537
05538 CCAttrMap* pAttrMap = FindAppliedAttributes();
05539
05540 if (pAttrMap == NULL)
05541 {
05542 ERROR3("No applied attributes");
05543 return FALSE;
05544 }
05545
05546 pAttrMap->TransformForBrush(Trans);
05547
05548 return TRUE;
05549 }
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561
05562
05563
05564 BOOL BlendPath::IsFilled()
05565 {
05566 if (m_pPath != NULL)
05567 return (m_pPath->IsFilled);
05568 else
05569 return FALSE;
05570 }
05571
05572
05573
05574
05575
05576
05577
05578
05579
05580
05581
05582
05583
05584
05585 BOOL BlendPath::IsStroked()
05586 {
05587 if (m_pPath != NULL)
05588 return (m_pPath->IsStroked);
05589 else
05590 return FALSE;
05591 }
05592
05593
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607 DocCoord BlendPath::GetPathCoord(INT32 Index)
05608 {
05609 DocCoord Result(0,0);
05610
05611 if (m_pPath != NULL)
05612 {
05613 if (m_DirChanged)
05614 m_pPath->Reverse();
05615
05616 DocCoord* pCoords = m_pPath->GetCoordArray();
05617 INT32 n = m_pPath->GetNumCoords();
05618 if (Index >= n || Index < 0) Index = 0;
05619
05620 if (Index < n && pCoords != NULL)
05621 Result = pCoords[Index];
05622
05623 if (m_DirChanged)
05624 m_pPath->Reverse();
05625 }
05626
05627 return Result;
05628 }
05629
05630
05631
05632
05633
05634
05635
05636
05637
05638
05639
05640
05641
05642
05643
05644 void BlendPath::RenderBlendBlobs(RenderRegion* pRender,Trans2DMatrix* pMatrix)
05645 {
05646 #if !defined(EXCLUDE_FROM_RALPH)
05647 if (m_pPath != NULL)
05648 {
05649
05650 DocCoord* pCoords = m_pPath->GetCoordArray();
05651 INT32 n = m_pPath->GetNumCoords();
05652 INT32 Index = 0;
05653
05654 pRender->SetLineColour(COLOUR_NONE);
05655 pRender->SetFillColour(COLOUR_UNSELECTEDBLOB);
05656
05657 INT32 i=0;
05658 DocCoord* pCoordList = (DocCoord*) malloc(n*sizeof(DocCoord));
05659
05660 if (pCoordList)
05661 {
05662 switch (m_PathType)
05663 {
05664 case PATHTYPE_SHAPE:
05665
05666
05667 while (m_pPath->FindNextEndPoint(&Index))
05668 pCoordList[i++] = pCoords[Index];
05669 break;
05670
05671 case PATHTYPE_LINE:
05672
05673
05674 pCoordList[i++] = pCoords[0];
05675 pCoordList[i++] = pCoords[n-1];
05676 break;
05677
05678 default:
05679 ERROR3("Unknown pathtype");
05680 break;
05681 }
05682
05683 if (pMatrix && i > 0)
05684 pMatrix->Transform(pCoordList,i);
05685
05686 for (;i>0;i--)
05687 pRender->DrawBlob(pCoordList[i-1], BT_UNSELECTED);
05688 }
05689 DELPTR(pCoordList);
05690 }
05691 #endif
05692 }
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714 BOOL BlendPath::IsPointOverBlob(DocCoord* pPointerPos,INT32* pIndex,Trans2DMatrix* pMatrix)
05715 {
05716 #if !defined(EXCLUDE_FROM_RALPH)
05717 BOOL Found = FALSE;
05718
05719 if (m_pPath != NULL && pIndex != NULL)
05720 {
05721 Path* pPath = m_pPath;
05722 if (pMatrix)
05723 {
05724 pPath = new Path;
05725 if (pPath != NULL && pPath->Initialise())
05726 {
05727 pPath->MergeTwoPaths(*m_pPath);
05728 pMatrix->Transform((DocCoord*)(pPath->GetCoordArray()), pPath->GetNumCoords() );
05729 }
05730 }
05731
05732 Found = pPath->FindNearestPoint(*pPointerPos,POINTFLAG_ENDPOINTS,pIndex);
05733
05734 if (Found)
05735 {
05736 if (m_PathType == PATHTYPE_LINE)
05737 Found = ((*pIndex == 0) || (*pIndex == (pPath->GetNumCoords()-1)));
05738 else if (m_DirChanged)
05739 {
05740 pPath->Reverse();
05741 pPath->FindNearestPoint(*pPointerPos,POINTFLAG_ENDPOINTS,pIndex);
05742 pPath->Reverse();
05743 }
05744
05745 if (Found)
05746 {
05747 *pPointerPos = GetPathCoord(*pIndex);
05748 if (pMatrix)
05749 pMatrix->Transform(pPointerPos,1);
05750 }
05751 }
05752
05753 if (pMatrix)
05754 DELPTR(pPath);
05755 }
05756
05757 return Found;
05758 #else
05759 return FALSE;
05760 #endif
05761 }
05762
05763
05764
05765
05766
05767
05768
05769
05770
05771
05772
05773
05774
05775
05776
05777
05778
05779
05780 CCAttrMap* BlendPath::FindAppliedAttributes()
05781 {
05782 if (m_pAppliedAttrs == NULL)
05783 {
05784 m_pAppliedAttrs = new CCAttrMap(30);
05785 if (m_pAppliedAttrs != NULL)
05786 {
05787
05788
05789
05790 if (!m_pCreatedByNode->FindAppliedAttributes(m_pAppliedAttrs,5000,NULL,TRUE))
05791 {
05792 delete m_pAppliedAttrs;
05793 m_pAppliedAttrs = NULL;
05794 }
05795 AttrTranspFillGeometry* pTransp = NULL;
05796 m_pCreatedByNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrTranspFillGeometry), (NodeAttribute**)&pTransp);
05797 }
05798 }
05799
05800 return m_pAppliedAttrs;
05801 }
05802
05803
05804
05805
05806
05807
05808
05809
05810
05811
05812
05813
05814
05815
05816
05817 void BlendPath::FreeAppliedAttributes()
05818 {
05819 if (!m_UniqueAttrs && m_pAppliedAttrs != NULL)
05820 {
05821 delete m_pAppliedAttrs;
05822 m_pAppliedAttrs = NULL;
05823 }
05824 }
05825
05826
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838
05839
05840
05841 CCAttrMap* BlendPath::MakeAttributeMapCopy()
05842 {
05843
05844
05845 CCAttrMap* pAttrMap = FindAppliedAttributes();
05846
05847 if (pAttrMap == NULL)
05848 {
05849 ERROR3("Unable to find attributes in BlendPath::MakeAttributeMap");
05850 return NULL;
05851 }
05852
05853
05854 CCAttrMap* pCopyMap = new CCAttrMap(30);
05855 if (pCopyMap == NULL)
05856 return NULL;
05857
05858
05859 CCRuntimeClass *pType;
05860 void *pVal;
05861 NodeAttribute* pNodeAttr = NULL;
05862 NodeAttribute* pAttrCopy = NULL;
05863
05864
05865 for( CMapPtrToPtr::iterator Pos = pAttrMap->GetStartPosition();
05866 Pos != pAttrMap->GetEndPosition();)
05867 {
05868
05869 pAttrMap->GetNextAssoc(Pos,pType,pVal);
05870
05871
05872 pNodeAttr = (NodeAttribute *)pVal;
05873
05874 pAttrCopy = (NodeAttribute*)pNodeAttr->SimpleCopy();
05875 if (pAttrCopy == NULL)
05876 {
05877 ERROR3("Unable to make attribute copy in BlendPath::MakeAttributeMap");
05878 DeleteAttributeMapAndAttributes(pCopyMap);
05879 return NULL;
05880 }
05881
05882 pCopyMap->SetAt( pAttrCopy->GetAttributeType(), (void *)pAttrCopy );
05883 pAttrCopy = NULL;
05884 }
05885
05886 return pCopyMap;
05887 }
05888
05889
05890
05891
05892
05893
05894
05895
05896
05897
05898
05899
05900
05901
05902
05903
05904
05905 CCAttrMap* BlendPath::UpdateAttributeMapCopy(CCAttrMap* pCopyMap)
05906 {
05907
05908
05909 CCAttrMap* pAttrMap = FindAppliedAttributes();
05910
05911 if (pAttrMap == NULL)
05912 {
05913 ERROR3("Unable to find attributes in BlendPath::UpdateAttributeMapCopy");
05914 return NULL;
05915 }
05916
05917 ERROR2IF(pCopyMap==NULL, NULL, "Unable to find attribute copies in BlendPath::UpdateAttributeMapCopy");
05918
05919
05920 CCRuntimeClass *pType;
05921 void *pVal;
05922 void *pCopyVal;
05923 NodeAttribute *pNodeAttr = NULL;
05924 NodeAttribute *pAttrCopy = NULL;
05925
05926
05927 for( CMapPtrToPtr::iterator Pos = pAttrMap->GetStartPosition();
05928 Pos != pAttrMap->GetEndPosition();)
05929 {
05930
05931 pAttrMap->GetNextAssoc(Pos, pType, pVal);
05932
05933 pNodeAttr = (NodeAttribute*)pVal;
05934
05935 BOOL bFound = pCopyMap->Lookup( pType, pCopyVal );
05936 if (bFound)
05937 {
05938 pAttrCopy = (NodeAttribute*)pCopyVal;
05939 pNodeAttr->PolyCopyNodeContents(pAttrCopy);
05940 }
05941 }
05942
05943 return pCopyMap;
05944 }
05945
05946
05947
05948
05949
05950
05951
05952
05953
05954
05955
05956
05957
05958
05959
05960
05961
05962
05963 void BlendPath::DeleteAttributeMapAndAttributes(CCAttrMap* pMap)
05964 {
05965
05966 if (pMap != NULL)
05967 {
05968 pMap->DeleteAttributes();
05969
05970 delete pMap;
05971 pMap = NULL;
05972 }
05973
05974 }
05975
05976
05977
05978
05979
05980
05981
05982
05983
05984
05985
05986
05987
05988
05989
05990
05991
05992
05993 void BlendPath::SetFreeAttributeFlag(BOOL Value)
05994 {
05995 m_bFreeAttrMapOnDestruct = TRUE;
05996 }
05997
05998
05999
06000
06001
06002
06003
06004
06005
06006
06007
06008
06009
06010
06011
06012
06013
06014 void BlendPath::SetAppliedAttributes(CCAttrMap* pMap)
06015 {
06016 if (pMap == NULL)
06017 return;
06018
06019
06020 FreeAppliedAttributes();
06021 m_pAppliedAttrs = pMap;
06022 }
06023
06024
06025
06026
06027
06028
06029
06030
06031
06032
06033
06034
06035
06036
06037
06038
06039
06040
06041 void BlendPath::SetPath(Path* pPath)
06042 {
06043 if (pPath != NULL)
06044 {
06045 m_pPath = pPath;
06046 m_NumElements = m_pPath->GetNumElements();
06047 m_PathType = m_pPath->GetPathType();
06048 m_SubPathNum = m_pPath->GetNumSubpaths();
06049 }
06050 }
06051
06052
06053
06054
06055
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067
06068
06069
06070 void BlendPath::DeleteAttributesAndPath()
06071 {
06072 m_bDeleteAll = TRUE;
06073 }
06074
06075
06076
06077
06078
06079
06080
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090 AttrBitmapFill* BlendPath::GetAppliedBitmapColourFill()
06091 {
06092
06093 CCAttrMap* pAttrMap = FindAppliedAttributes();
06094 if (pAttrMap == NULL)
06095 return NULL;
06096
06097
06098 CCRuntimeClass *pType;
06099 void *pVal;
06100 NodeAttribute* pNodeAttr = NULL;
06101
06102 for( CMapPtrToPtr::iterator Pos = pAttrMap->GetStartPosition();
06103 Pos != pAttrMap->GetEndPosition();)
06104 {
06105
06106 pAttrMap->GetNextAssoc(Pos,pType,pVal);
06107
06108
06109 pNodeAttr = (NodeAttribute *)pVal;
06110
06111 if (pNodeAttr->IsABitmapFill() &&!pNodeAttr->IsATranspFill())
06112 break;
06113
06114 pNodeAttr = NULL;
06115 }
06116
06117
06118 if (pNodeAttr != NULL)
06119 {
06120 return (AttrBitmapFill*)pNodeAttr;
06121 }
06122
06123 return NULL;
06124
06125 }
06126
06127
06128
06129
06130
06131
06132
06133
06134
06135
06136
06137
06138
06139
06140
06141
06142 AttrBitmapFill* BlendPath::GetAppliedBitmapTranspFill()
06143 {
06144
06145 CCAttrMap* pAttrMap = FindAppliedAttributes();
06146 if (pAttrMap == NULL)
06147 return NULL;
06148
06149
06150 CCRuntimeClass *pType;
06151 void *pVal;
06152 NodeAttribute* pNodeAttr = NULL;
06153
06154 for( CMapPtrToPtr::iterator Pos = pAttrMap->GetStartPosition();
06155 Pos != pAttrMap->GetEndPosition();)
06156 {
06157
06158 pAttrMap->GetNextAssoc(Pos,pType,pVal);
06159
06160
06161 pNodeAttr = (NodeAttribute *)pVal;
06162
06163 if (pNodeAttr->IsABitmapFill() &&pNodeAttr->IsATranspFill())
06164 break;
06165
06166 pNodeAttr = NULL;
06167 }
06168
06169
06170 if (pNodeAttr != NULL)
06171 {
06172 return (AttrBitmapFill*)pNodeAttr;
06173 }
06174
06175 return NULL;
06176
06177 }
06178
06179
06180
06181
06182
06183
06184
06185
06186
06187
06188
06189
06190
06191
06192
06193
06194
06195 MILLIPOINT BlendPath::GetAppliedLineWidth()
06196 {
06197
06198 NodeAttribute* pAttr = NULL;
06199 m_pCreatedByNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrLineWidth), &pAttr);
06200 if (pAttr != NULL)
06201 m_AppliedLineWidth = ((AttrLineWidth*)pAttr)->Value.LineWidth;
06202
06203 return m_AppliedLineWidth;
06204 }
06205
06206
06207
06208
06209
06210
06211
06212
06213
06214
06215
06216
06217
06218
06219
06220
06221
06222
06223
06224
06225
06226
06227
06228 BOOL BlendPath::MakeCopyPathAndAttributes()
06229 {
06230
06231 ERROR2IF(m_pPath == NULL, FALSE, "Path is NULL in BlendPath::MakeCopyPathAndAttributes");
06232
06233
06234 CCAttrMap* pAttrMap = FindAppliedAttributes();
06235
06236 ERROR2IF(pAttrMap == NULL, FALSE, "Unable to find attributes in BlendPath::MakeCopyPathAndAttributes");
06237
06238
06239 if (m_pCopyPath != NULL || m_pCopyAttrs != NULL)
06240 DeleteCopyPathAndAttributes();
06241
06242
06243 m_pCopyPath = new Path;
06244
06245 if (m_pCopyPath == NULL)
06246 return FALSE;
06247
06248 if (!m_pCopyPath->Initialise(m_pPath->GetNumCoords()))
06249 {
06250 delete m_pCopyPath;
06251 m_pCopyPath = NULL;
06252 return FALSE;
06253 }
06254 if (!m_pCopyPath->CopyPathDataFrom(m_pPath))
06255 {
06256 delete m_pCopyPath;
06257 m_pCopyPath = NULL;
06258 return FALSE;
06259 }
06260
06261
06262 m_pCopyAttrs = MakeAttributeMapCopy();
06263
06264 if (m_pCopyAttrs == NULL)
06265 {
06266 delete m_pCopyPath;
06267 m_pCopyPath = NULL;
06268 return FALSE;
06269 }
06270 return TRUE;
06271 }
06272
06273
06274
06275
06276
06277
06278
06279
06280
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293
06294
06295 BOOL BlendPath::UpdateCopyPathAndAttributes()
06296 {
06297
06298 ERROR2IF(m_pPath == NULL, FALSE, "Path is NULL in BlendPath::UpdateCopyPathAndAttributes");
06299 ERROR2IF(m_pCopyPath == NULL, FALSE, "CopyPath is NULL in BlendPath::UpdateCopyPathAndAttributes");
06300
06301
06302 ERROR2IF(m_pAppliedAttrs==NULL, FALSE, "No applied attrs in BlendPath::UpdateCopyPathAndAttributes");
06303
06304 ERROR2IF(m_pPath->GetNumCoords()!=m_pCopyPath->GetNumCoords(), FALSE, "Mismatching paths in BlendPath::UpdateCopyPathAndAttributes");
06305
06306 if (!m_pCopyPath->Initialise(m_pPath->GetNumCoords()))
06307 {
06308 delete m_pCopyPath;
06309 m_pCopyPath = NULL;
06310 return FALSE;
06311 }
06312 if (!m_pCopyPath->CopyPathDataFrom(m_pPath))
06313 {
06314 delete m_pCopyPath;
06315 m_pCopyPath = NULL;
06316 return FALSE;
06317 }
06318
06319
06320 m_pCopyAttrs = UpdateAttributeMapCopy(m_pCopyAttrs);
06321
06322 if (m_pCopyAttrs == NULL)
06323 {
06324 delete m_pCopyPath;
06325 m_pCopyPath = NULL;
06326 return FALSE;
06327 }
06328 return TRUE;
06329 }
06330
06331
06332
06333
06334
06335
06336
06337
06338
06339
06340
06341
06342
06343
06344
06345
06346 void BlendPath::DeleteCopyPathAndAttributes()
06347 {
06348 if (m_pCopyPath != NULL)
06349 {
06350 delete m_pCopyPath;
06351 m_pCopyPath = NULL;
06352 }
06353 if (m_pCopyAttrs != NULL)
06354 {
06355 DeleteAttributeMapAndAttributes(m_pCopyAttrs);
06356 m_pCopyAttrs = NULL;
06357 }
06358 }
06359
06360
06361
06362
06363
06364
06365
06366
06367
06368
06369
06370
06371
06372
06373
06374
06375 Path* BlendPath::GetCopyPath()
06376 {
06377 return m_pCopyPath;
06378 }
06379
06380
06381
06382
06383
06384
06385
06386
06387
06388
06389
06390
06391
06392
06393
06394
06395 CCAttrMap* BlendPath::GetCopyAttributes()
06396 {
06397 return m_pCopyAttrs;
06398 }
06399
06400
06401
06402
06403
06404
06405 BecomeA::BecomeA(BecomeAReason ThisReason,
06406 CCRuntimeClass* pClass,
06407 UndoableOperation* pOp ,
06408 BOOL sel ,
06409 BOOL First
06410 ) : Reason(ThisReason), pClassToBecome(pClass), pUndoOp(pOp)
06411 { Select = sel;
06412 pCallNode = NULL;
06413 AmFirstNode = First;
06414 fSilhouette = FALSE;
06415 fShadowSilhouettes = FALSE;
06416 insertComplexBlendStepsAsPaths = FALSE;
06417 m_Count = 0;
06418 m_bIsCounting = FALSE;
06419 m_bBecomeANodePath = (pClassToBecome==CC_RUNTIME_CLASS(NodePath));
06420 m_bInPlace = FALSE;
06421 m_bSecondary = FALSE;
06422 m_bPathsOnly = FALSE;
06423 }
06424
06425 BOOL BecomeA::BAPath() const {return m_bBecomeANodePath;}
06426
06427
06428
06429 BOOL BecomeA::PassBack(NodeRenderableInk* pNewNode,NodeRenderableInk* pCreatedByNode,CCAttrMap* pAttrMap )
06430 {
06431 if (pAttrMap)
06432 {
06433 pAttrMap->DeleteAttributes();
06434 delete pAttrMap;
06435 }
06436 return FALSE;
06437 }
06438
06439
06440
06441
06442
06443
06444
06445
06446
06447
06448
06449
06450
06451
06452
06453
06454
06455
06456 NodeRenderableInk * BlendBecomeA::CreateWrapNode(NodeRenderableInk * pNode, NodeCompound *pTree,
06457 CCAttrMap * pMap)
06458 {
06459 NodeCompound * pCompound = (NodeCompound *)pTree->FindFirstChild(CC_RUNTIME_CLASS(NodeCompound));
06460
06461 if (pCompound)
06462 {
06463
06464 pNode = CreateWrapNode(pNode, pCompound, pMap);
06465 }
06466
06467
06468 return pTree->CreateTreeFromNodeToBlend(pNode, pMap);
06469 }
06470
06471
06472
06473
06474
06475
06476
06477
06478
06479
06480
06481
06482
06483
06484
06485
06486
06487
06488
06489
06490
06491
06492
06493
06494
06495
06496
06497
06498
06499
06500 BOOL BlendBecomeA::PassBack(NodeRenderableInk* pNewNode,NodeRenderableInk* pCreatedByNode,CCAttrMap* pAttrMap)
06501 {
06502 ERROR2IF(pBlendRef == NULL,FALSE,"pBlendRef == NULL");
06503 ERROR2IF(pNewNode == NULL,FALSE,"pNewNode == NULL");
06504
06505 if (pProgress != NULL)
06506 {
06507 if (!pProgress->Update(pProgress->GetCount(1),TRUE) && !IgnoreEscape)
06508 return FALSE;
06509 }
06510
06511 Path* pInkPath = NULL;
06512
06513 Node * pPathNode = NULL;
06514
06515
06516
06517
06518
06519 if (pNewNode->IsNodePath())
06520 {
06521 pInkPath = &(((NodePath*)pNewNode)->InkPath);
06522 pPathNode = (NodePath *)pNewNode;
06523 }
06524 else if (pNewNode->IsCompound())
06525 {
06526 NodeRenderableInk * pNodeToBlend = ((NodeCompound *)pNewNode)->GetNodeToBlend();
06527
06528 if (pNodeToBlend)
06529 {
06530 if (pNodeToBlend->IsNodePath())
06531 {
06532 pInkPath = &(((NodePath *)pNodeToBlend)->InkPath);
06533 pPathNode = (NodePath *)pNodeToBlend;
06534 }
06535 }
06536 }
06537
06538 INT32 NumCoords = pInkPath->GetNumCoords();
06539 INT32 StartIndex=0,EndIndex=0;
06540 UINT32 NumSubPaths=0;
06541
06542 Path TempPath;
06543 BOOL ok = TempPath.Initialise(NumCoords);
06544
06545
06546 SubPathID++;
06547
06548 NodeRenderableInk * pTreeNode = NULL;
06549
06550
06551 while (ok && StartIndex < NumCoords)
06552 {
06553
06554 EndIndex = StartIndex;
06555 pInkPath->FindEndElOfSubPath(&EndIndex);
06556
06557 ERROR2IF(EndIndex >= NumCoords,FALSE,"EndIndex gone beyond num coords in path");
06558
06559
06560 TempPath.ClearPath(FALSE);
06561 ok = pInkPath->CopySectionTo(&TempPath,StartIndex,(EndIndex-StartIndex)+1);
06562
06563 if (ok)
06564 {
06565
06566 TempPath.IsFilled = pInkPath->IsFilled;
06567 TempPath.IsStroked = pInkPath->IsStroked;
06568
06569 if (m_pMatrix != NULL)
06570 m_pMatrix->Transform((DocCoord*)TempPath.GetCoordArray(), TempPath.GetNumCoords() );
06571
06572
06573 NodePath* pNewNodePath = new NodePath;
06574 ok = (pNewNodePath != NULL);
06575 if (ok)
06576 {
06577
06578 Path* pNewPath = &(pNewNodePath->InkPath);
06579 ok = pNewPath->Initialise(TempPath.GetNumCoords());
06580
06581 if (ok) ok = pNewPath->CopyPathDataFrom(&TempPath);
06582
06583 if (ok)
06584 {
06585
06586 BlendPath* pBlendPath = new BlendPath;
06587 ok = (pBlendPath != NULL);
06588
06589
06590
06591 if (pNewNode->IsCompound())
06592 {
06593 NodeRenderableInk * pWrapNode = CreateWrapNode(pNewNodePath, (NodeCompound *)pNewNode, pAttrMap);
06594
06595 if (!pWrapNode)
06596 return FALSE;
06597
06598
06599 ((NodeCompound *)pWrapNode)->SetBlendCreatedByNode(((NodeCompound *)pNewNode)->GetBlendCreatedByNode());
06600
06601
06602
06603 if (NumSubPaths != 0)
06604 {
06605 pTreeNode = pWrapNode;
06606
06607 while (pTreeNode && pTreeNode->IsCompound())
06608 {
06609 if (((NodeCompound *)pTreeNode)->IsStartBlendGroupNode())
06610 {
06611 ((NodeCompound *)pTreeNode)->SetStartBlendGroupNode(FALSE);
06612 }
06613
06614 pTreeNode = (NodeCompound *)pTreeNode->FindFirstChild(CC_RUNTIME_CLASS(NodeCompound));
06615 }
06616 }
06617
06618
06619 if (EndIndex != NumCoords-1)
06620 {
06621 pTreeNode = pWrapNode;
06622
06623 while (pTreeNode && pTreeNode->IsCompound())
06624 {
06625 if (((NodeCompound *)pTreeNode)->IsEndBlendGroupNode())
06626 {
06627 ((NodeCompound *)pTreeNode)->SetEndBlendGroupNode(FALSE);
06628 }
06629
06630 pTreeNode = (NodeCompound *)pTreeNode->FindFirstChild(CC_RUNTIME_CLASS(NodeCompound));
06631 }
06632 }
06633
06634 if (pWrapNode->IsCompound())
06635 {
06636 if (((NodeCompound *)pWrapNode)->IsStartBlendGroupNode())
06637 {
06638 TRACEUSER( "ChrisS", _T("BlendBecomeA::Start node\n"));
06639 }
06640
06641 if (((NodeCompound *)pWrapNode)->IsEndBlendGroupNode())
06642 {
06643 TRACEUSER( "ChrisS", _T("BlendBecomeA::End node\n"));
06644 }
06645 }
06646
06647 if (ok) ok = pBlendPath->Initialise(pWrapNode,Index,pCreatedByNode,SubPathID,NumSubPaths,NULL);
06648 if (ok) ok = pBlendRef->AddBlendPath(pBlendPath);
06649 }
06650 else
06651 {
06652
06653
06654 if (ok) ok = pBlendPath->Initialise(pNewNodePath,Index,pCreatedByNode,SubPathID,NumSubPaths,pAttrMap);
06655 if (ok) ok = pBlendRef->AddBlendPath(pBlendPath);
06656
06657 if (IS_A (pNewNode, NodeBlendPath))
06658 {
06659 pBlendPath->SetCreatedViaNodeBlendPath (TRUE);
06660 }
06661 }
06662 }
06663 }
06664 }
06665 Index = -1;
06666 StartIndex = EndIndex+1;
06667
06668
06669 NumSubPaths++;
06670 }
06671
06672 if (pNewNode->IsCompound())
06673 {
06674 pAttrMap->DeleteAttributes();
06675 delete pAttrMap;
06676 }
06677
06678 if (ok)
06679 {
06680 pBlendRef->SetAWComplex(NumSubPaths > 1);
06681 pNewNode->CascadeDelete();
06682 delete pNewNode;
06683 pNewNode = NULL;
06684 }
06685
06686 return (ok);
06687
06688 }
06689
06690
06691
06692
06693
06694
06695
06696
06697
06698
06699
06700
06701
06702
06703
06704
06705
06706
06707
06708 BOOL HandleBecomeA::PassBack(Path* pBlendedPath,CCAttrMap* pBlendedAttrMap,UINT32 Step)
06709 {
06710
06711 ERROR3IF(pBecomeA == NULL,"pBecomeA is NULL");
06712 ERROR3IF(pNodeBlender == NULL,"pNodeBlender is NULL");
06713 if (pBecomeA == NULL || pNodeBlender == NULL)
06714 return FALSE;
06715
06716
06717 ERROR3IF(pBlendedPath == NULL,"pBlendedPath is NULL");
06718 ERROR3IF(pBlendedAttrMap == NULL,"pBlendedAttrMap is NULL");
06719 if (pBlendedPath == NULL || pBlendedAttrMap == NULL) return FALSE;
06720
06721
06722
06723 BOOL ValidReason = (pBecomeA->GetReason() == BECOMEA_REPLACE || pBecomeA->GetReason() == BECOMEA_PASSBACK);
06724 ERROR3IF_PF(!ValidReason,("Unkown BecomeA reason %d",pBecomeA->GetReason()));
06725 if (!ValidReason) return FALSE;
06726
06727
06728
06729 BOOL Success = TRUE;
06730 NodePath* pNewNodePath = NULL;
06731
06732 if (pBecomeA->BAPath())
06733 {
06734
06735
06736
06737 ALLOC_WITH_FAIL(pNewNodePath, (new NodePath), pBecomeA->GetUndoOp());
06738 Success = (pNewNodePath != NULL);
06739
06740
06741 if (Success) CALL_WITH_FAIL(pNewNodePath->InkPath.Initialise(pBlendedPath->GetNumCoords(),12), pBecomeA->GetUndoOp(), Success);
06742 if (Success) CALL_WITH_FAIL(pNewNodePath->InkPath.CopyPathDataFrom(pBlendedPath), pBecomeA->GetUndoOp(), Success);
06743
06744
06745
06746 if (Success)
06747 {
06748 switch (pBecomeA->GetReason())
06749 {
06750 case BECOMEA_REPLACE :
06751 {
06752
06753
06754
06755
06756
06757
06758 ERROR2IF(pContextNode == NULL,FALSE,"pContextNode is NULL");
06759
06760
06761 Node* pAttachNode = pContextNode;
06762 AttachNodeDirection AttachDir = PREV;
06763
06764
06765 BOOL HideNode = TRUE;
06766 Node* pNodeToHide = pNewNodePath;
06767
06768
06769 if (MakeGroupPerStep())
06770 {
06771
06772 if (Step != LastStep)
06773 {
06774
06775
06776 LastStep = Step;
06777
06778
06779 pNodeGroup = new NodeGroup;
06780 Success = (pNodeGroup != NULL);
06781 if (Success)
06782 {
06783
06784 pNodeGroup->AttachNode(pContextNode,PREV);
06785
06786
06787 HideNode = TRUE;
06788 pNodeToHide = pNodeGroup;
06789 }
06790 }
06791 else
06792 HideNode = FALSE;
06793
06794
06795
06796 if (Success)
06797 {
06798 pAttachNode = pNodeGroup;
06799 AttachDir = LASTCHILD;
06800 }
06801 }
06802
06803 if (Success)
06804 {
06805 ERROR2IF(pAttachNode == NULL,FALSE,"The attach node is NULL!!!");
06806
06807
06808 pNewNodePath->AttachNode(pAttachNode,AttachDir);
06809
06810
06811 pNewNodePath->ApplyAttributes(pBlendedAttrMap,TRUE);
06812
06813
06814 pNewNodePath->ValidateBoundingRect();
06815 pNewNodePath->InvalidateBoundingRect();
06816
06817
06818 if (HideNode)
06819 {
06820 ERROR2IF(pNodeToHide == NULL,FALSE,"pNodeToHide is NULL");
06821
06822 if (pBecomeA->GetUndoOp())
06823 {
06824 HideNodeAction* UndoHideNodeAction;
06825 Success = (HideNodeAction::Init(pBecomeA->GetUndoOp(),
06826 pBecomeA->GetUndoOp()->GetUndoActionList(),
06827 pNodeToHide,
06828 TRUE,
06829 ( Action**)(&UndoHideNodeAction))
06830 != AC_FAIL);
06831 }
06832 }
06833
06834 CCAttrMap* pNewAttrMap = pBlendedAttrMap->Copy();
06835 if (pNewAttrMap != NULL)
06836 pBecomeA->PassBack(pNewNodePath, pNodeBlender, pNewAttrMap);
06837 }
06838 }
06839 break;
06840
06841 case BECOMEA_PASSBACK :
06842 {
06843
06844
06845
06846 CCAttrMap* pNewAttrMap = pBlendedAttrMap->Copy();
06847 if (pNewAttrMap != NULL)
06848 Success = pBecomeA->PassBack(pNewNodePath,pNodeBlender,pNewAttrMap);
06849 else
06850 Success = FALSE;
06851 break;
06852 }
06853
06854 default:
06855 break;
06856 }
06857 }
06858 }
06859
06860 if (!Success)
06861 {
06862 if (pNodeGroup != NULL)
06863 {
06864
06865
06866 pNodeGroup->CascadeDelete();
06867 delete pNodeGroup;
06868 pNodeGroup = NULL;
06869 }
06870 else if (pNewNodePath != NULL)
06871 {
06872
06873
06874 pNewNodePath->CascadeDelete();
06875 delete pNewNodePath;
06876 pNewNodePath = NULL;
06877 }
06878 }
06879
06880 return Success;
06881 }
06882
06883
06884
06885
06886
06887
06888
06889
06890
06891
06892
06893
06894
06895
06896
06897
06898
06899
06900
06901
06902
06903
06904
06905
06906 void NodeBlender::PreExportRender(RenderRegion* pRegion)
06907 {
06908 #ifdef DO_EXPORT
06909
06910 if (!Reinit())
06911 return;
06912
06913 if (pRegion->IS_KIND_OF(ArtWorksEPSRenderRegion))
06914 {
06915 EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC();
06916
06917 if (IS_A(pRegion, CamelotEPSRenderRegion))
06918 {
06919
06920 return;
06921 }
06922 else if (pRegion->IS_KIND_OF(NativeRenderRegion))
06923 {
06924
06925 pDC->OutputValue(INT32(0));
06926 pDC->OutputValue(INT32(0));
06927 pDC->OutputValue(INT32(0));
06928 pDC->OutputValue(INT32(0));
06929 pDC->OutputValue(m_ObjIndexStart);
06930 pDC->OutputValue(m_ObjIndexEnd);
06931 pDC->OutputValue(m_PathIndexStart);
06932 pDC->OutputValue(m_PathIndexEnd);
06933 pDC->OutputToken(_T("csbr"));
06934 pDC->OutputNewLine();
06935
06936 }
06937 else
06938 {
06939 NodeBlend* pNodeBlend = GetNodeBlend();
06940
06941 if (pNodeBlend != NULL)
06942 {
06943 if (pNodeBlend->IsArtWorksEPSCompatible())
06944 {
06945
06946 pDC->OutputValue(INT32(0));
06947 pDC->OutputValue(INT32(IsComplex()));
06948 pDC->OutputValue(INT32(IsOneToOne()));
06949 pDC->OutputValue(INT32(GetNumBlendSteps()+1));
06950 pDC->OutputValue(GetAWStartPathIndex());
06951 pDC->OutputValue(GetAWEndPathIndex());
06952 pDC->OutputToken(_T("asbr"));
06953 pDC->OutputNewLine();
06954
06955
06956 return;
06957 }
06958 else
06959 {
06960
06961 Render(pRegion);
06962 }
06963 }
06964 else
06965 { ERROR3("Parent is not a NodeBlend"); }
06966 }
06967 }
06968
06969
06970
06971
06972 #endif
06973 }
06974
06975
06976
06977
06978
06979
06980
06981
06982
06983
06984
06985
06986
06987
06988
06989
06990
06991 BOOL NodeBlender::ExportRender(RenderRegion* pRegion)
06992 {
06993 #ifdef DO_EXPORT
06994
06995 if (!Reinit())
06996 return FALSE;
06997
06998 if (pRegion->IS_KIND_OF(ArtWorksEPSRenderRegion))
06999 {
07000 EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC();
07001
07002 if (IS_A(pRegion, CamelotEPSRenderRegion))
07003 {
07004
07005 return FALSE;
07006 }
07007 else if (pRegion->IS_KIND_OF(NativeRenderRegion))
07008 {
07009 pDC->OutputToken(_T("cebr"));
07010 pDC->OutputNewLine();
07011 }
07012 else
07013 {
07014 NodeBlend* pNodeBlend = GetNodeBlend();
07015
07016 if (pNodeBlend != NULL)
07017 {
07018 if (pNodeBlend->IsArtWorksEPSCompatible())
07019 {
07020 pDC->OutputToken(_T("aebr"));
07021 pDC->OutputNewLine();
07022 }
07023 }
07024 }
07025
07026 return TRUE;
07027 }
07028 #endif
07029
07030 return FALSE;
07031 }
07032
07033
07034
07035
07036
07037
07038
07039
07040
07041
07042
07043
07044
07045
07046
07047
07048
07049
07050
07051
07052 BOOL NodeBlender::IsArtWorksEPSCompatible()
07053 {
07054 ERROR2IF(m_pRefStart == NULL,FALSE,"m_pRefStart == NULL");
07055 ERROR2IF(m_pRefEnd == NULL,FALSE,"m_pRefEnd == NULL");
07056
07057 Node* pPrevNode = FindPrevious();
07058 Node* pNextNode = FindNext();
07059
07060 return (pPrevNode == m_pNodeStart &&
07061 pNextNode == m_pNodeEnd &&
07062 pPrevNode != NULL &&
07063 pNextNode != NULL &&
07064 IS_A(pPrevNode,NodePath) &&
07065 IS_A(pNextNode,NodePath) &&
07066 m_pRefStart->GetNumBlendPaths() == m_pRefEnd->GetNumBlendPaths());
07067 }
07068
07069
07070
07071
07072
07073
07074
07075
07076
07077
07078
07079
07080
07081
07082
07083
07084 BOOL NodeBlender::IsComplex()
07085 {
07086 ERROR2IF(m_pRefStart == NULL,FALSE,"m_pRefStart == NULL");
07087 ERROR2IF(m_pRefEnd == NULL,FALSE,"m_pRefEnd == NULL");
07088
07089 return (m_pRefStart->GetAWComplex() || m_pRefEnd->GetAWComplex());
07090 }
07091
07092
07093
07094
07095
07096
07097
07098
07099
07100
07101
07102
07103
07104
07105
07106 INT32 NodeBlender::GetAWStartPathIndex()
07107 {
07108 ERROR2IF(m_pRefStart == NULL,-1,"m_pRefStart == NULL");
07109 return (GetAWPathIndex(m_pRefStart,m_PathIndexStart));
07110 }
07111
07112
07113
07114
07115
07116
07117
07118
07119
07120
07121
07122
07123
07124
07125
07126 INT32 NodeBlender::GetAWEndPathIndex()
07127 {
07128 ERROR2IF(m_pRefEnd == NULL,-1,"m_pRefEnd == NULL");
07129 return (GetAWPathIndex(m_pRefEnd,m_PathIndexEnd));
07130 }
07131
07132
07133
07134
07135
07136
07137
07138
07139
07140
07141
07142
07143
07144
07145
07146
07147 INT32 NodeBlender::GetAWPathIndex(BlendRef *pRef,INT32 PathIndex)
07148 {
07149 BlendPath* pBlendPath = pRef->GetFirstBlendPath();
07150 if (pBlendPath == NULL || pBlendPath->GetPath() == NULL)
07151 return -1;
07152
07153 Path* pPath = pBlendPath->GetPath();
07154 INT32 AWPathIndex=0,Index=0;
07155 while (Index < PathIndex)
07156 {
07157 pPath->FindNextEndPoint(&Index);
07158 AWPathIndex++;
07159 }
07160
07161 return AWPathIndex;
07162 }
07163
07164
07165
07166
07167
07168
07169
07170
07171
07172
07173
07174
07175
07176
07177
07178
07179
07180
07181 BOOL NodeBlender::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
07182 {
07183 #ifdef DO_EXPORT
07184 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
07185
07186 BOOL ok = TRUE;
07187
07188 CXaraFileRecord Rec(TAG_BLENDER,TAG_BLENDER_SIZE);
07189
07190 if (ok) ok = Rec.Init();
07191 if (ok) ok = Rec.WriteINT32(m_PathIndexStart);
07192 if (ok) ok = Rec.WriteINT32(m_PathIndexEnd);
07193 if (ok) ok = pFilter->Write(&Rec);
07194
07195
07196 CXaraFileRecord Additional(TAG_BLENDERADDITIONAL, TAG_BLENDERADDITIONAL_SIZE);
07197 if (ok) ok = Additional.Init();
07198 if (ok) ok = Additional.WriteINT32(m_BlendedOnCurve);
07199
07200 if (ok)
07201 {
07202 if (m_NodeBlendPathIndex == -2)
07203 ok = Additional.WriteINT32(-1);
07204 else
07205 ok = Additional.WriteINT32(m_NodeBlendPathIndex);
07206 }
07207 if (ok) ok = Additional.WriteINT32(m_ObjIndexStart);
07208 if (ok) ok = Additional.WriteINT32(m_ObjIndexEnd);
07209
07210
07211
07212
07213 if (ok)
07214 {
07215 BYTE BitField = IsReversed() ? 1 : 0;
07216 ok = Additional.WriteBYTE(BitField);
07217 }
07218
07219 if (ok) ok = pFilter->Write(&Additional);
07220
07221 return ok;
07222 #else
07223 return FALSE;
07224 #endif
07225 }
07226
07227
07228
07229
07230 BOOL NodeBlender::WritePreChildrenNative(BaseCamelotFilter* pFilter)
07231 {
07232 #ifdef DO_EXPORT
07233 return WritePreChildrenWeb(pFilter);
07234 #else
07235 return FALSE;
07236 #endif
07237 }
07238
07239
07240
07241
07242
07243
07244
07245
07246
07247
07248
07249
07250
07251
07252
07253
07254
07255
07256 BOOL NodeBlender::WriteBeginChildRecordsNative(BaseCamelotFilter* pFilter)
07257 {
07258 #ifdef DO_EXPORT
07259 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
07260
07261 if (GetNodeBlendPath() == NULL)
07262 return NodeRenderableInk::WriteBeginChildRecordsNative(pFilter);
07263
07264
07265 BOOL ok = (pFilter->WriteZeroSizedRecord(TAG_DOWN));
07266
07267
07268 {
07269 CamelotFileRecord PropRec(pFilter,TAG_BLENDER_CURVEPROP,TAG_BLENDER_CURVEPROP_SIZE);
07270 if (ok) ok = PropRec.Init();
07271 if (ok) ok = PropRec.WriteDOUBLE(m_ProportionOfPathDistStart);
07272 if (ok) ok = PropRec.WriteDOUBLE(m_ProportionOfPathDistEnd);
07273 if (ok) ok = pFilter->Write(&PropRec);
07274 }
07275
07276
07277 if (m_AngleStart != 0.0 || m_AngleEnd != 0.0)
07278 {
07279 CamelotFileRecord AngleRec(pFilter,TAG_BLENDER_CURVEANGLES,TAG_BLENDER_CURVEANGLES_SIZE);
07280 if (ok) ok = AngleRec.Init();
07281 if (ok) ok = AngleRec.WriteDOUBLE(m_AngleStart);
07282 if (ok) ok = AngleRec.WriteDOUBLE(m_AngleEnd);
07283 if (ok) ok = pFilter->Write(&AngleRec);
07284 }
07285
07286 return ok;
07287 #else
07288 return TRUE;
07289 #endif //DO_EXPORT
07290 }
07291
07292
07293
07294
07295
07296
07297
07298
07299
07300
07301
07302
07303
07304
07305
07306
07307
07308
07309 BOOL NodeBlender::WriteEndChildRecordsNative(BaseCamelotFilter* pFilter)
07310 {
07311 #ifdef DO_EXPORT
07312 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
07313
07314 if (GetNodeBlendPath() == NULL)
07315 return NodeRenderableInk::WriteEndChildRecordsNative(pFilter);
07316
07317 return pFilter->WriteZeroSizedRecord(TAG_UP);
07318 #else
07319 return FALSE;
07320 #endif
07321 }
07322
07323
07324
07325
07326
07327
07328
07329
07330
07331
07332
07333
07334
07335
07336
07337
07338 BOOL NodeBlender::WriteBeginChildRecordsWeb(BaseCamelotFilter* pFilter)
07339 {
07340 return WriteBeginChildRecordsNative(pFilter);
07341 }
07342
07343
07344
07345
07346
07347
07348
07349
07350
07351
07352
07353
07354
07355
07356
07357
07358 BOOL NodeBlender::WriteEndChildRecordsWeb(BaseCamelotFilter* pFilter)
07359 {
07360 return WriteEndChildRecordsNative(pFilter);
07361 }
07362
07363
07364
07365
07366
07367
07368
07369
07370
07371
07372
07373
07374
07375
07376
07377
07378
07379
07380 NodeBlend* NodeBlender::GetNodeBlend()
07381 {
07382 Node* pNode = FindParent();
07383 if (pNode != NULL && IS_A(pNode,NodeBlend))
07384 return (NodeBlend*)pNode;
07385
07386 return NULL;
07387 }
07388
07389
07390
07391
07392
07393
07394
07395
07396
07397
07398
07399
07400
07401
07402 NodeBlendPath* NodeBlender::GetNodeBlendPath()
07403 {
07404 if (m_NodeBlendPathIndex > -1)
07405 {
07406 NodeBlend* pNode = GetNodeBlend();
07407 if (pNode != NULL)
07408 return pNode->GetNodeBlendPath(m_NodeBlendPathIndex);
07409 }
07410 return NULL;
07411 }
07412
07413
07414
07415
07416
07417
07418
07419
07420
07421
07422
07423
07424
07425
07426
07427
07428
07429
07430 BOOL NodeBlender::GetPointOnNodeBlendPath(double BlendRatio,DocCoord* pPoint,double* pAngle)
07431 {
07432 ERROR2IF(pPoint == NULL,FALSE,"NULL coord ptr");
07433
07434 BOOL ok = FALSE;
07435
07436 NodeBlendPath* pNodeBlendPath = GetNodeBlendPath();
07437
07438 if (pNodeBlendPath)
07439 {
07440 double PropStart = GetProportionOfPathDistStart();
07441 double PropEnd = GetProportionOfPathDistEnd();
07442
07443 double PathLen = pNodeBlendPath->GetPathLength();
07444 double PropLen = PropEnd-PropStart;
07445 double PathLenOffset = PathLen*PropStart;
07446
07447 double Tangent = 0.0;
07448 MILLIPOINT Dist = MILLIPOINT(((PathLen*PropLen) * BlendRatio)+PathLenOffset);
07449 ok = pNodeBlendPath->GetPointAtDistance(Dist,pPoint,&Tangent);
07450
07451 if (ok && pAngle)
07452 {
07453 if (IsTangential())
07454 *pAngle = Tangent/PI*180;
07455 else
07456 *pAngle = 0.0;
07457 }
07458 }
07459
07460 return ok;
07461 }
07462
07463
07464
07465
07466
07467
07468
07469
07470
07471
07472
07473
07474
07475
07476
07477
07478
07479
07480
07481 BOOL NodeBlender::GetPointFromDistance(double Distance, DocCoord* pPoint, double* pAngle)
07482 {
07483 ERROR2IF(pPoint == NULL,FALSE,"NULL coord ptr");
07484
07485 BOOL ok = FALSE;
07486
07487 NodeBlendPath* pNodeBlendPath = GetNodeBlendPath();
07488
07489 if (pNodeBlendPath)
07490 {
07491 double Tangent = 0.0;
07492 ok = pNodeBlendPath->GetPointAtDistance((INT32)Distance,pPoint,&Tangent);
07493
07494 if (ok && pAngle)
07495 {
07496 if (IsTangential())
07497 *pAngle = Tangent/PI*180;
07498 else
07499 *pAngle = 0.0;
07500 }
07501 }
07502
07503 return ok;
07504 }
07505
07506
07507
07508
07509 double NodeBlender::GetProportionOfPathDistStart()
07510 {
07511 if (m_ProportionOfPathDistStart < 0.0) return 0.0;
07512 return m_ProportionOfPathDistStart;
07513 }
07514
07515 double NodeBlender::GetProportionOfPathDistEnd()
07516 {
07517 if (m_ProportionOfPathDistEnd < 0.0) return 1.0;
07518 return m_ProportionOfPathDistEnd;
07519 }
07520
07521 void NodeBlender::SetProportionOfPathDistStart(double p)
07522 {
07523 if (p < 0.0) p = 0.0;
07524 if (p > 1.0) p = 1.0;
07525 if (p > GetProportionOfPathDistEnd()) p = GetProportionOfPathDistEnd();
07526 m_ProportionOfPathDistStart = p;
07527 }
07528
07529 void NodeBlender::SetProportionOfPathDistEnd(double p)
07530 {
07531 if (p < 0.0) p = 0.0;
07532 if (p > 1.0) p = 1.0;
07533 if (p < GetProportionOfPathDistStart()) p = GetProportionOfPathDistStart();
07534 m_ProportionOfPathDistEnd = p;
07535 }
07536
07537
07538 double NodeBlender::GetAngleStart()
07539 {
07540 return m_AngleStart;
07541 }
07542
07543 double NodeBlender::GetAngleEnd()
07544 {
07545 return m_AngleEnd;
07546 }
07547
07548 void NodeBlender::SetAngleStart(double Angle)
07549 {
07550 m_AngleStart = fmod(Angle,360.0);
07551 }
07552
07553 void NodeBlender::SetAngleEnd(double Angle)
07554 {
07555 m_AngleEnd = fmod(Angle,360.0);
07556 }
07557
07558
07559
07560
07561
07562
07563
07564
07565
07566
07567
07568
07569
07570
07571
07572
07573
07574
07575 double NodeBlender::GetLinearDistance()
07576 {
07577 DocCoord StartCentre;
07578 DocCoord EndCentre;
07579
07580 BOOL Valid = GetBlendObjectCentres(&StartCentre, &EndCentre);
07581 if (!Valid)
07582 return FALSE;
07583
07584 Coord pStart = (Coord)StartCentre;
07585 Coord pEnd = (Coord)EndCentre;
07586
07587 double Distance = pStart.Distance(pEnd);
07588
07589 return Distance;
07590
07591 }
07592
07593
07594
07595
07596
07597
07598
07599
07600
07601
07602
07603
07604
07605
07606
07607 BOOL NodeBlender::GetBlendDirection(double* Gradient)
07608 {
07609 if (IsBlendedOnCurve())
07610 {
07611 ERROR3("Trying to get linear direction of blend on a curve");
07612 return FALSE;
07613 }
07614
07615 DocCoord StartCentre;
07616 DocCoord EndCentre;
07617
07618 BOOL Valid = GetBlendObjectCentres(&StartCentre, &EndCentre);
07619 if (!Valid)
07620 return FALSE;
07621
07622 double XDiff = EndCentre.x - StartCentre.x;
07623 double YDiff = EndCentre.y - StartCentre.y;
07624
07625 *Gradient = YDiff/XDiff;
07626
07627 return TRUE;
07628 }
07629
07630
07631
07632
07633
07634
07635
07636
07637
07638
07639
07640
07641
07642
07643
07644 BOOL NodeBlender::GetBlendObjectCentres(DocCoord* pFirstCentre, DocCoord* pEndCentre)
07645 {
07646
07647 NodeRenderableInk* pBlendStart = GetNodeStart();
07648 NodeRenderableInk* pBlendEnd = GetNodeEnd();
07649
07650 if (pBlendStart ==NULL || pBlendEnd == NULL)
07651 {
07652 ERROR3IF(pBlendStart ==NULL, "Blender has no start nodes");
07653 ERROR3IF(pBlendEnd ==NULL, "Blender has no end nodes");
07654 return FALSE;
07655 }
07656
07657 DocRect StartRect = pBlendStart->GetBoundingRect();
07658 DocRect EndRect = pBlendEnd->GetBoundingRect();
07659
07660 DocCoord StartCentre = StartRect.Centre();
07661 DocCoord EndCentre = EndRect.Centre();
07662
07663 *pFirstCentre = StartCentre;
07664 *pEndCentre = EndCentre;
07665
07666 return TRUE;
07667 }