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 #include "camtypes.h"
00103
00104
00105 #include "nodeliveeffect.h"
00106
00107
00108
00109 #include "cxftags.h"
00110
00111 #include "blobs.h"
00112
00113 #include "bmpcomp.h"
00114 #include "oilbitmap.h"
00115 #include "bshadow.h"
00116
00117
00118 #include "nodepath.h"
00119 #include "lineattr.h"
00120 #include "blndtool.h"
00121 #include "nodebmp.h"
00122 #include "attrmap.h"
00123
00124
00125
00126
00127
00128
00129 #include "transop.h"
00130
00131
00132 #include "pmaskrgn.h"
00133 #include "scanrr.h"
00134
00135 #include "ophist.h"
00136
00137 DECLARE_SOURCE( "$Revision: 1688 $" );
00138
00139 CC_IMPLEMENT_DYNCREATE(NodeBitmapEffect, NodeEffect)
00140 CC_IMPLEMENT_DYNCREATE(NodeLiveEffect, NodeBitmapEffect)
00141 CC_IMPLEMENT_DYNCREATE(NodeLockedEffect, NodeBitmapEffect)
00142 #ifdef FEATHER_EFFECT
00143 CC_IMPLEMENT_DYNCREATE(NodeFeatherEffect, NodeLiveEffect)
00144 #endif
00145 CC_IMPLEMENT_DYNAMIC(LiveEffectRecordHandler, CamelotRecordHandler)
00146
00147
00148 #define new CAM_DEBUG_NEW
00149
00150
00151 #ifdef DEBUG
00152 #define DEBUGATTACH(STATE, LABEL) {STATE.AttachToDoc(LABEL);}
00153 #else
00154 #define DEBUGATTACH(STATE, LABEL) {}
00155 #endif
00156
00157
00158 #define CAPTURE_BORDER 1
00159
00160
00161
00162 #ifdef DEBUG
00163
00164 #endif
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 UINT32 NodeBitmapEffect::DefaultLivePixelsPerInch = 96;
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 UINT32 NodeBitmapEffect::DefaultLockedPixelsPerInch = 150;
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 UINT32 NodeBitmapEffect::GroupPixelsPerInch = 0;
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 UINT32 NodeBitmapEffect::ShadowPixelsPerInch = 0;
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 BOOL NodeBitmapEffect::DefaultLocked = FALSE;
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 BOOL NodeBitmapEffect::Init()
00250 {
00251 if (Camelot.DeclareSection( _T("Effects"), 10))
00252 {
00253 Camelot.DeclarePref(NULL, _T("DefaultLivePixelsPerInch"), (INT32*)&DefaultLivePixelsPerInch, 0, 72000);
00254 Camelot.DeclarePref(NULL, _T("DefaultLockedPixelsPerInch"), (INT32*)&DefaultLockedPixelsPerInch, 1, 72000);
00255 Camelot.DeclarePref(NULL, _T("DefaultLocked"), (INT32*)&DefaultLocked, FALSE, TRUE);
00256 Camelot.DeclarePref(NULL, _T("GroupPixelsPerInch"), (INT32*)&GroupPixelsPerInch, 0, 72000);
00257 Camelot.DeclarePref(NULL, _T("ShadowPixelsPerInch"), (INT32*)&ShadowPixelsPerInch, 0, 72000);
00258 }
00259
00260 return TRUE;
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
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 NodeBitmapEffect::NodeBitmapEffect(Node* ContextNode,
00308 AttachNodeDirection Direction,
00309 BOOL Locked,
00310 BOOL Mangled,
00311 BOOL Marked,
00312 BOOL Selected
00313 ) : NodeEffect(ContextNode, Direction, Locked, Mangled, Marked, Selected )
00314 {
00315 m_pEditsDoc = NULL;
00316 m_bHasChangedRecently = FALSE;
00317 m_strPostProID = String(_T(""));
00318 m_strDisplayName = String(_T(""));
00319 m_rectDirectBitmap = DocRect(0,0,0,0);
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 NodeBitmapEffect::NodeBitmapEffect() : NodeEffect()
00337 {
00338 m_pEditsDoc = NULL;
00339 m_bHasChangedRecently = FALSE;
00340 m_strPostProID = String( _T("") );
00341 m_strDisplayName = String( _T("") );
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 NodeBitmapEffect::~NodeBitmapEffect()
00359 {
00360 m_pEditsDoc = NULL;
00361
00362
00363
00364
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 double NodeBitmapEffect::GetPixelsPerInch()
00386 {
00387 double dPPI = 0.0;
00388
00389 if (m_dPixelsPerInch==0)
00390 {
00391
00392
00393
00394
00395
00396
00397 BOOL bDirectResolution = GetChildDirectBitmap(NULL, NULL, NULL, NULL, NULL, &dPPI);
00398 if (bDirectResolution && dPPI!=0)
00399 return dPPI;
00400
00401 Node* pParent = this->FindParent();
00402
00403 while (pParent && !pParent->IsLayer())
00404 {
00405 if (pParent->IsBitmapEffect())
00406 {
00407 dPPI = ((NodeBitmapEffect*)pParent)->GetPixelsPerInchValue();
00408 if (dPPI!=0)
00409 break;
00410 }
00411
00412 pParent = pParent->FindParent();
00413 }
00414
00415 if (dPPI==0)
00416 {
00417
00418 View* pView = View::GetCurrent();
00419 if (pView) dPPI = 72000.0 / pView->GetPixelWidth().MakeDouble();
00420 }
00421 }
00422
00423 if (dPPI==0)
00424 dPPI = m_dPixelsPerInch;
00425
00426 if (dPPI==0)
00427 {
00428
00429 ERROR3("GetPixelsPerInch can't get sensible PPI so defaulting to 96");
00430 dPPI = 96.0;
00431 }
00432
00433 return dPPI;
00434 };
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 void NodeBitmapEffect::SetPixelsPerInch(double dPixelsPerInch)
00455 {
00456 m_dPixelsPerInch = dPixelsPerInch;
00457 };
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 BOOL NodeBitmapEffect::GetOriginalBitmap(LPBITMAPINFO* plpInfo, LPBYTE* plpBits, DocRect* pRect)
00496 {
00497
00498
00499
00500
00501
00502 LPBITMAPINFO lpLocalInfo = NULL;
00503 LPBYTE lpLocalBits = NULL;
00504 DocRect rectLocal;
00505 BOOL bFound = GetChildDirectBitmap(NULL, &lpLocalInfo, &lpLocalBits, &rectLocal);
00506 if (bFound)
00507 {
00508 if (plpInfo) *plpInfo = lpLocalInfo;
00509 if (plpBits) *plpBits = lpLocalBits;
00510 if (pRect) *pRect = rectLocal;
00511 return (lpLocalInfo!=NULL && lpLocalBits!=NULL);
00512 }
00513
00514
00515 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
00516 if (pBitmapCache)
00517 {
00518
00519 CBitmapCacheKey inky(this, GetPixelWidth());
00520 CCachedBitmap cbmp;
00521 BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
00522 if (bFound)
00523 {
00524 if (plpInfo) *plpInfo = cbmp.pbmpInfo;
00525 if (plpBits) *plpBits = cbmp.pbmpBits;
00526 if (pRect) *pRect = cbmp.GetCachedRect();
00527 return TRUE;
00528 }
00529 }
00530
00531 if (plpInfo) *plpInfo = NULL;
00532 if (plpBits) *plpBits = NULL;
00533
00534 return FALSE;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 void NodeBitmapEffect::SetOriginalBitmap(LPBITMAPINFO lpInfo, LPBYTE lpBits, DocRect rect)
00554 {
00555 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
00556 if (pBitmapCache==NULL)
00557 return;
00558
00559 if (rect.IsEmpty())
00560 {
00561 rect = GetChildBoundingRect();
00562 rect.Inflate(CAPTURE_BORDER*(INT32)GetPixelWidth());
00563 }
00564
00565 CBitmapCacheKey inky(this, GetPixelWidth());
00566
00567
00568 CCachedBitmap cbmp;
00569 BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
00570 if (bFound)
00571 {
00572 pBitmapCache->RemoveBitmap(inky);
00573 cbmp.Release();
00574 }
00575
00576 if (lpInfo && lpBits)
00577 {
00578 cbmp.pbmpInfo = lpInfo;
00579 cbmp.pbmpBits = lpBits;
00580 cbmp.SetCachedRect(rect);
00581 cbmp.nPriority = CACHEPRIORITY_TEMPBITMAP_HIGH;
00582
00583 pBitmapCache->StoreBitmap(inky, cbmp);
00584 }
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 BOOL NodeBitmapEffect::GetChildDirectBitmap(RenderRegion* pRender,
00607 LPBITMAPINFO* plpInfo,
00608 LPBYTE* plpBits,
00609 DocRect* pRect,
00610 Matrix* pMat,
00611 double* pdRes
00612 )
00613 {
00614 NodeRenderableInk* pInkNode = GetInkNodeFromController();
00615 if (pInkNode==NULL)
00616 return FALSE;
00617
00618
00619
00620
00621
00622
00623 if (!EnableDirectCapture())
00624 return FALSE;
00625
00626 return pInkNode->GetDirectBitmap(pRender, plpInfo, plpBits, pRect, pMat, pdRes);
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 BOOL NodeBitmapEffect::GetDirectBitmap(RenderRegion* pRender, LPBITMAPINFO* plpInfo, LPBYTE* plpBits, DocRect* pRect, Matrix* pMat, double* pdRes)
00651 {
00652 DocRect rectDirect;
00653 Matrix matLocalTransform;
00654 double dResolution = 0;
00655
00656
00657
00658 BOOL bChildDirect = GetChildDirectBitmap(pRender, NULL, NULL, NULL, &matLocalTransform, &dResolution);
00659 if (pMat) *pMat = matLocalTransform;
00660 if (pdRes) *pdRes = dResolution;
00661
00662
00663
00664 GetProcessedBitmap(bChildDirect && !matLocalTransform.IsIdentity(), plpInfo, plpBits, &rectDirect);
00665 if (pRect) *pRect = rectDirect;
00666
00667
00668
00669
00670 if (!bChildDirect && pdRes)
00671 *pdRes = GetPixelsPerInch();
00672
00673
00674 if (plpInfo && plpBits && HasEffectAttrs())
00675 {
00676 AttrFillGeometry* pTranspAttr = NULL;
00677 double dPixelWidth = GetPixelWidth();
00678
00679
00680 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
00681 if (pBitmapCache==NULL)
00682 return FALSE;
00683
00684 CBitmapCacheKey inky2(this, dPixelWidth, 2);
00685 CCachedBitmap cbmp2;
00686 BOOL bFound = pBitmapCache->Lookup(inky2, cbmp2);
00687 if (bFound)
00688 {
00689 if (plpInfo) *plpInfo = cbmp2.pbmpInfo;
00690 if (plpBits) *plpBits = cbmp2.pbmpBits;
00691 return TRUE;
00692 }
00693
00694
00695 ERROR2IF(IsFeatherEffect(), FALSE, "TODO! Give NodeFeatherEffect its own implementation of GetDirectBitmap!");
00696
00697
00698
00699
00700
00701
00702 if (pRender == NULL)
00703 {
00704 if (plpInfo) *plpInfo = NULL;
00705 if (plpBits) *plpBits = NULL;
00706 return TRUE;
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 ERROR3IF(*plpInfo==NULL || *plpBits==NULL, "How come we got here with no processed bitmap?");
00723 DocRect CaptureRect = rectDirect;
00724
00725 CaptureFlags caFlags = CaptureFlags(cfLOCKEDTRANSPARENT | cfFULLCOVERAGE);
00726 pRender->StartCapture(this, CaptureRect, CAPTUREINFO(ctNESTABLE, caFlags), TRUE, FALSE, dResolution);
00727 pRender->SaveContext();
00728
00729 {
00730
00731 DocCoord coords[3];
00732 coords[0] = CaptureRect.lo;
00733 coords[1] = DocCoord(CaptureRect.hi.x, CaptureRect.lo.y);
00734 coords[2] = DocCoord(CaptureRect.lo.x, CaptureRect.hi.y);
00735
00736
00737
00738
00739
00740 NodeAttribute* pAttr;
00741 if (FindAppliedAttribute(CC_RUNTIME_CLASS(AttrTranspFillGeometry), &pAttr))
00742 {
00743 if (pAttr &&
00744 !pAttr->IsADefaultAttr() &&
00745 !pAttr->HasEquivalentDefaultValue(TRUE) &&
00746 pAttr->IsEffectAttribute())
00747 {
00748 pTranspAttr = (AttrFillGeometry*) ((AttrFillGeometry*)pAttr)->SimpleCopy();
00749 DocCoord tcoords[4];
00750 DocCoord* pCoord = NULL;
00751 pCoord = pTranspAttr->GetStartPoint();
00752 tcoords[0] = pCoord ? *pCoord : DocCoord(0,0);
00753 pCoord = pTranspAttr->GetEndPoint();
00754 tcoords[1] = pCoord ? *pCoord : DocCoord(0,0);
00755 pCoord = pTranspAttr->GetEndPoint2();
00756 tcoords[2] = pCoord ? *pCoord : DocCoord(0,0);
00757 pCoord = pTranspAttr->GetEndPoint3();
00758 tcoords[3] = pCoord ? *pCoord : DocCoord(0,0);
00759
00760 Matrix matInverse = matLocalTransform.Inverse();
00761 matInverse.transform(tcoords, 4);
00762
00763 pTranspAttr->SetStartPoint(&tcoords[0]);
00764 pTranspAttr->SetEndPoint(&tcoords[1]);
00765 pTranspAttr->SetEndPoint2(&tcoords[2]);
00766 pTranspAttr->SetEndPoint3(&tcoords[3]);
00767
00768 pTranspAttr->Render(pRender);
00769 }
00770 }
00771
00772 pRender->RenderBits(*plpInfo, *plpBits, coords, 3, FALSE, NULL);
00773 }
00774
00775 pRender->RestoreContext();
00776 if (pTranspAttr)
00777 {
00778 delete pTranspAttr;
00779 pTranspAttr = NULL;
00780 }
00781
00782 LPBITMAPINFO lpInfo = NULL;
00783 LPBYTE lpBits = NULL;
00784 pRender->StopCapture(this, FALSE, FALSE, &lpInfo, &lpBits, &CaptureRect);
00785
00786
00787
00788 if (lpInfo && lpBits)
00789 {
00790 *plpInfo = lpInfo;
00791 *plpBits = lpBits;
00792
00793
00794 cbmp2.pbmpBits = lpBits;
00795 cbmp2.pbmpInfo = lpInfo;
00796 cbmp2.SetCachedRect(CaptureRect);
00797 cbmp2.nPriority = CACHEPRIORITY_TEMPBITMAP_HIGH;
00798 if (cbmp2.IsValid())
00799 pBitmapCache->StoreBitmap(inky2, cbmp2);
00800 }
00801 }
00802
00803 return TRUE;
00804 }
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 BOOL NodeBitmapEffect::CanGetChildDirectBitmap()
00824 {
00825 NodeRenderableInk* pInkNode = GetInkNodeFromController();
00826 if (pInkNode==NULL)
00827 return FALSE;
00828
00829 BOOL bOK = EnableDirectCapture() && pInkNode->CanSupplyDirectBitmap();
00830
00831 return bOK;
00832 }
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 BOOL NodeBitmapEffect::RenderDirectBitmapState(RenderRegion* pRender)
00852 {
00853 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
00854 if (pBitmapCache!=NULL && pRender->RRQuality.GetFillQuality() > Quality::Solid)
00855 {
00856 RenderCachedEffect(pBitmapCache, pRender, TRUE);
00857 }
00858
00859 return TRUE;
00860 }
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878 BOOL NodeBitmapEffect::HasCachedDirectBitmap()
00879 {
00880 Matrix matTrans;
00881 BOOL bDirect = GetChildDirectBitmap(NULL, NULL, NULL, NULL, &matTrans, NULL);
00882 return (bDirect && !matTrans.IsIdentity());
00883 }
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 BOOL NodeBitmapEffect::EnableDirectCapture()
00905 {
00906 NodeRenderableInk* pInkNode = GetInkNodeFromController();
00907 if (pInkNode==NULL)
00908 return FALSE;
00909
00910 PORTNOTE("effects", "EnableDirectCapture returns FALSE until effects work. Forces base objects to render themselves.");
00911 #if !defined(EXCLUDE_FROM_XARALX)
00912 double dChildPPI = 0;
00913 BOOL bDirectResolution = pInkNode->GetDirectBitmap(NULL, NULL, NULL, NULL, NULL, &dChildPPI);
00914 if (!bDirectResolution || dChildPPI==0)
00915 return FALSE;
00916
00917
00918 if (m_dPixelsPerInch==0 || dChildPPI==m_dPixelsPerInch)
00919 return TRUE;
00920 #endif
00921
00922 return FALSE;
00923 }
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 DocRect NodeBitmapEffect::AdjustPixelOffsets(DocRect inRect, INT32 width, INT32 height, double xOffset, double yOffset, double dPixelWidth)
00945 {
00946 if (dPixelWidth==0)
00947 dPixelWidth = GetPixelWidth();
00948
00949 DocRect outRect(inRect.lo.x, inRect.hi.y, inRect.lo.x, inRect.hi.y);
00950
00951 outRect.lo.x += INT32( xOffset * dPixelWidth );
00952 outRect.hi.y -= INT32( yOffset * dPixelWidth );
00953
00954 if (width==0)
00955 outRect.hi.x = outRect.lo.x + inRect.Width();
00956 else
00957 outRect.hi.x = outRect.lo.x + INT32( width * dPixelWidth );
00958
00959 if (height==0)
00960 outRect.lo.y = outRect.hi.y - inRect.Height();
00961 else
00962 outRect.lo.y = outRect.hi.y - INT32( height * dPixelWidth );
00963
00964 return outRect;
00965 }
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 IXMLDOMDocumentPtr NodeBitmapEffect::GetEditList()
00983 {
00984 return m_pEditsDoc;
00985 }
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 void NodeBitmapEffect::SetEditList(IXMLDOMDocumentPtr pNewEditsDoc)
01003 {
01004 m_pEditsDoc = pNewEditsDoc;
01005 }
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 BOOL NodeBitmapEffect::SetDefaultEditList()
01023 {
01024 PORTNOTETRACE("other","NodeBitmapEffect::SetDefaultEditList - do nothing");
01025 #ifndef EXCLUDE_FROM_XARALX
01026
01027 if (m_pEditsDoc==NULL)
01028 {
01029 m_pEditsDoc = CXMLUtils::NewDocument();
01030 ERROR3IF(m_pEditsDoc==NULL, "Can't make default edit document");
01031 return (m_pEditsDoc!=NULL);
01032 }
01033 #endif
01034 return TRUE;
01035 }
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 void NodeBitmapEffect::RenderAfterSubtree(RenderRegion* pRender)
01052 {
01053 Matrix matTrans;
01054 double dResolution = 0;
01055
01056 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
01057 if (pBitmapCache==NULL)
01058 {
01059 return;
01060 }
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071 Capture* pCapture = pRender->GetTopCapture();
01072 if (pCapture==NULL)
01073 return;
01074
01075
01076
01077 if (pCapture->GetOwner()==this)
01078 {
01079
01080
01081
01082 BOOL bCached = FALSE;
01083 BOOL bCaptureIsDirect = pCapture->IsDirect();
01084 LPBITMAPINFO lpInfo = NULL;
01085 LPBYTE lpBits = NULL;
01086 DocRect CaptureRect = GetChildBoundingRect();
01087 CaptureRect.Inflate(CAPTURE_BORDER*(INT32)GetPixelWidth());
01088 pRender->StopCapture(this, FALSE, FALSE, &lpInfo, &lpBits, &CaptureRect, &matTrans, &dResolution);
01089
01090
01091
01092 if (bCaptureIsDirect)
01093 {
01094 ERROR3IF(dResolution==0, "Direct Capture returned 0 pixels per inch\n");
01095
01096
01097
01098
01099
01100
01101
01102 if (lpInfo && lpBits && CaptureRect.IsValid())
01103 {
01104
01105 LPBITMAPINFO lpProcessedInfo = NULL;
01106 LPBYTE lpProcessedBits = NULL;
01107 double xOffset = 0;
01108 double yOffset = 0;
01109 ProcessBitmap(pRender, pBitmapCache, lpInfo, lpBits, CaptureRect, lpProcessedInfo, lpProcessedBits, &xOffset, &yOffset);
01110
01111 if (lpProcessedInfo && lpProcessedBits)
01112 {
01113
01114
01115
01116
01117
01118 SetProcessedBitmap(lpProcessedInfo, lpProcessedBits, CaptureRect, lpProcessedInfo->bmiHeader.biWidth, lpProcessedInfo->bmiHeader.biHeight, xOffset, yOffset, 72000.0/dResolution, &matTrans);
01119
01120
01121
01122 RenderCachedEffect(pBitmapCache, pRender);
01123 }
01124 }
01125 }
01126 else
01127 {
01128
01129 if (lpInfo && lpBits && CaptureRect.IsValid())
01130 {
01131
01132
01133 double PixelWidth = GetPixelWidth();
01134 CBitmapCacheKey inky(this, PixelWidth, 0);
01135
01136 CCachedBitmap cbmp;
01137
01138 cbmp.pbmpBits = lpBits;
01139 cbmp.pbmpInfo = lpInfo;
01140 cbmp.SetCachedRect(CaptureRect);
01141 cbmp.nPriority = CACHEPRIORITY_TEMPBITMAP_HIGH;
01142
01143 if (cbmp.IsValid())
01144 {
01145 pBitmapCache->StoreBitmap(inky, cbmp);
01146 bCached = TRUE;
01147 }
01148
01149
01150 LPBITMAPINFO lpProcessedInfo = NULL;
01151 LPBYTE lpProcessedBits = NULL;
01152 double xOffset = 0;
01153 double yOffset = 0;
01154
01155
01156 ProcessBitmap(pRender, pBitmapCache, lpInfo, lpBits, CaptureRect, lpProcessedInfo, lpProcessedBits, &xOffset, &yOffset);
01157
01158
01159 if (lpProcessedInfo && lpProcessedBits)
01160 {
01161
01162 CaptureRect = SetProcessedBitmap(lpProcessedInfo, lpProcessedBits, CaptureRect, lpProcessedInfo->bmiHeader.biWidth, lpProcessedInfo->bmiHeader.biHeight, xOffset, yOffset);
01163
01164
01165 RenderCachedEffect(pBitmapCache, pRender);
01166
01167
01168
01169
01170
01171 if (pRender->IsKindOf(CC_RUNTIME_CLASS(PrintingMaskedRenderRegion)))
01172 {
01173 double PixelWidth = GetPixelWidth();
01174 CBitmapCacheKey inky(this, PixelWidth, 0);
01175 pBitmapCache->RemoveBitmap(inky);
01176
01177 CBitmapCacheKey inky2(this, PixelWidth, 1);
01178 pBitmapCache->RemoveBitmap(inky2);
01179
01180 bCached = FALSE;
01181 }
01182
01183
01184 if (lpProcessedInfo!=NULL && lpProcessedBits!=NULL && !bCached)
01185 {
01186 FreeDIB(lpProcessedInfo, lpProcessedBits, NULL, FALSE);
01187 }
01188 }
01189 else
01190 {
01191
01192
01193
01194 pRender->RenderBits(lpInfo, lpBits, CaptureRect);
01195 }
01196 }
01197
01198
01199 if (lpInfo!=NULL && lpBits!=NULL && !bCached)
01200 {
01201 FreeDIB(lpInfo, lpBits, NULL, FALSE);
01202 }
01203 }
01204 }
01205 }
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221 void NodeBitmapEffect::Render(RenderRegion* pRender)
01222 {
01223 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
01224 if (pBitmapCache!=NULL && pRender->IsHitDetect() && pRender->RRQuality.GetFillQuality() > Quality::Solid)
01225 {
01226 RenderCachedEffect(pBitmapCache, pRender, TRUE);
01227 }
01228 }
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 BOOL NodeBitmapEffect::FindCachedEffect(CBitmapCache* pBitmapCache)
01246 {
01247
01248
01249 CBitmapCacheKey inky(this, GetPixelWidth(), 1);
01250 CCachedBitmap cbmp;
01251 BOOL bFoundCached = pBitmapCache->Lookup(inky, cbmp);
01252
01253 return bFoundCached;
01254 }
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273 BOOL NodeBitmapEffect::RenderCachedEffect(CBitmapCache* pBitmapCache, RenderRegion* pRender, BOOL bIgnoreCapture)
01274 {
01275 BOOL bRendered = FALSE;
01276
01277 CBitmapCacheKey inky(this, GetPixelWidth(), 1);
01278 CCachedBitmap cbmp;
01279 BOOL bFoundCached = pBitmapCache->Lookup(inky, cbmp);
01280
01281 if (bFoundCached)
01282 {
01283
01284 Capture* pCapture = pRender->GetTopCapture();
01285 if (!bIgnoreCapture && pCapture && pCapture->ConsumeDirectBitmap(this))
01286 {
01287
01288 bRendered = TRUE;
01289 }
01290 else
01291 {
01292
01293
01294
01295 bRendered = pRender->RenderBits(cbmp.pbmpInfo, cbmp.pbmpBits, &cbmp.coord0, 3, TRUE, this);
01296 }
01297 }
01298
01299 return bRendered;
01300 }
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324 BOOL NodeBitmapEffect::ProcessBitmap(RenderRegion* pRender,
01325 CBitmapCache* pBitmapCache,
01326 LPBITMAPINFO pBMPInfo,
01327 LPBYTE pBMPBits,
01328 DocRect BMPRect,
01329 LPBITMAPINFO& pOutputInfo,
01330 LPBYTE& pOutputBits,
01331 double* pXOffset,
01332 double* pYOffset)
01333 {
01334 BOOL bOK = TRUE;
01335
01336 PORTNOTETRACE("other","NodeBitmapEffect::ProcessBitmap - do nothing, CXMLUtils, XPEEditOp");
01337 #ifndef EXCLUDE_FROM_XARALX
01338
01339 BOOL bValidEditList = TRUE;
01340 if (m_pEditsDoc==NULL)
01341 {
01342 HRESULT hr = E_FAIL;
01343 m_pEditsDoc = CXMLUtils::NewDocument();
01344 bValidEditList = FALSE;
01345 ERROR3IF(m_pEditsDoc==NULL, "Can't make default edit document");
01346 }
01347
01348 if (bValidEditList)
01349 {
01350
01351 INT32 iXOffset = (INT32)*pXOffset;
01352 INT32 iYOffset = (INT32)*pYOffset;
01353 bOK = XPEEditOp::ProcessBitmap(pBMPInfo, pBMPBits, pOutputInfo, pOutputBits, m_pEditsDoc, &iXOffset, &iYOffset);
01354 *pXOffset = iXOffset;
01355 *pYOffset = iYOffset;
01356
01357 }
01358 #endif
01359 return bOK;
01360 }
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375 DocRect NodeBitmapEffect::GetBlobBoundingRect()
01376 {
01377 DocRect NewRect = DocRect(0,0,0,0);
01378
01379 #if !defined(EXCLUDE_FROM_RALPH)
01380
01381 BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
01382 if (pBlobMgr!= NULL)
01383 {
01384
01385
01386
01387 DocRect BoundingRect = GetBoundingRect();
01388
01389
01390
01391 DocRect BlobSize;
01392
01393
01394 DocCoord Low = BoundingRect.LowCorner();
01395 DocCoord High = BoundingRect.HighCorner();
01396
01397
01398 pBlobMgr->GetBlobRect(Low, &BlobSize);
01399 NewRect = NewRect.Union(BlobSize);
01400 pBlobMgr->GetBlobRect(High, &BlobSize);
01401 NewRect = NewRect.Union(BlobSize);
01402 pBlobMgr->GetBlobRect(DocCoord(Low.x, High.y), &BlobSize);
01403 NewRect = NewRect.Union(BlobSize);
01404 pBlobMgr->GetBlobRect(DocCoord(High.x, Low.y), &BlobSize);
01405 NewRect = NewRect.Union(BlobSize);
01406
01407 }
01408
01409 Node* pNode=FindFirstChild();
01410 while (pNode!=NULL)
01411 {
01412 if (pNode->IsBounded())
01413 NewRect = NewRect.Union(((NodeRenderableBounded*)pNode)->GetBlobBoundingRect());
01414 pNode = pNode->FindNext();
01415 }
01416
01417 IncludeChildrensBoundingRects(&NewRect);
01418 #endif
01419 return NewRect;
01420 }
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437 BOOL NodeBitmapEffect::CompareState(NodeEffect* pPPNode)
01438 {
01439 if (!pPPNode->IsBitmapEffect())
01440 return FALSE;
01441
01442 PORTNOTETRACE("other","NodeBitmapEffect::CompareState - do nothing, XML and BSTR");
01443 #ifndef EXCLUDE_FROM_XARALX
01444 BSTR temp;
01445 HRESULT hr;
01446
01447 _bstr_t bstrThisEditDoc;
01448 IXMLDOMDocumentPtr pThisEditDoc = GetEditList();
01449 hr = pThisEditDoc->get_xml(&temp);
01450 bstrThisEditDoc = temp;
01451
01452 _bstr_t bstrTestEditDoc;
01453 IXMLDOMDocumentPtr pTestEditDoc = ((NodeBitmapEffect*)pPPNode)->GetEditList();
01454 hr = pTestEditDoc->get_xml(&temp);
01455 bstrTestEditDoc = temp;
01456
01457 return (bstrTestEditDoc == bstrThisEditDoc); */
01458 #else
01459 return false;
01460 #endif
01461 }
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480 BOOL NodeBitmapEffect::DoBecomeA(BecomeA* pBecomeA)
01481 {
01482
01483 ERROR2IF(pBecomeA == NULL, FALSE, "pBecomeA is NULL");
01484
01485 if (!pBecomeA->BAPath())
01486 return FALSE;
01487
01488
01489
01490 BOOL ValidReason = (pBecomeA->GetReason() == BECOMEA_REPLACE || pBecomeA->GetReason() == BECOMEA_PASSBACK);
01491 ERROR2IF_PF(!ValidReason,FALSE,("Unkown BecomeA reason %d",pBecomeA->GetReason()));
01492
01493 BOOL bOK = FALSE;
01494 NodePath* pNewNodePath = NULL;
01495 NodeAttribute* pAttr = NULL;
01496 NodeHidden* pHiddenNode = NULL;
01497
01498 UndoableOperation* pOp = pBecomeA->GetUndoOp();
01499
01500
01501
01502
01503
01504
01505 if (!IsLockedEffect())
01506 {
01507 if (pBecomeA->IsBlendBecomeA() || pBecomeA->DoSilhouette() || pBecomeA->OnlyNeedPaths() || pBecomeA->ResultsStayInPlace())
01508 return NodeEffect::DoBecomeA(pBecomeA);
01509 }
01510 else
01511 {
01512 if (pBecomeA->OnlyNeedPaths() || (pBecomeA->IsBlendBecomeA() && pBecomeA->GetReason() == BECOMEA_PASSBACK))
01513 return NodeEffect::DoBecomeA(pBecomeA);
01514 }
01515
01516
01517 if (!IsLockedEffect() && FindParent() && FindParent()->IsEffect())
01518 return TRUE;
01519
01520
01521 DocCoord coords[3];
01522 KernelBitmap* kBitmap = GetKernelBitmap(coords, TRUE);
01523
01524
01525
01526 ALLOC_WITH_FAIL(pNewNodePath, new NodePath, pOp);
01527 if (pNewNodePath)
01528 {
01529 Path InkPath;
01530 InkPath.Initialise();
01531 InkPath.AddMoveTo(coords[0]);
01532 InkPath.AddLineTo(coords[1]);
01533 InkPath.AddLineTo(DocCoord(coords[2].x+coords[1].x-coords[0].x, coords[2].y+coords[1].y-coords[0].y));
01534 InkPath.AddLineTo(coords[2]);
01535 InkPath.AddLineTo(coords[0]);
01536 InkPath.CloseSubPath();
01537
01538 pNewNodePath->InkPath.Initialise();
01539 pNewNodePath->InkPath.CloneFrom(InkPath);
01540 pNewNodePath->InkPath.IsFilled = TRUE;
01541 pNewNodePath->InkPath.TryToClose();
01542 pNewNodePath->InkPath.InitialiseFlags();
01543
01544 switch (pBecomeA->GetReason())
01545 {
01546 case BECOMEA_REPLACE:
01547 {
01548
01549
01550
01551
01552
01553
01554 BitmapFillAttribute* pBitmapAttr = NULL;
01555 ALLOC_WITH_FAIL(pBitmapAttr, new BitmapFillAttribute, pOp);
01556 if (pBitmapAttr!=NULL && kBitmap)
01557 {
01558 pBitmapAttr->GetBitmapRef()->SetBitmap(kBitmap);
01559 pBitmapAttr->StartPoint = coords[0];
01560 pBitmapAttr->EndPoint = coords[1];
01561 pBitmapAttr->EndPoint2 = coords[2];
01562
01563
01564 pAttr = pBitmapAttr->MakeNode();
01565 pAttr->AttachNode(pNewNodePath, FIRSTCHILD);
01566 delete pBitmapAttr;
01567 pBitmapAttr = NULL;
01568 }
01569
01570 AttrStrokeColour* pStrokeColour = NULL;
01571 ALLOC_WITH_FAIL(pStrokeColour, new AttrStrokeColour, pOp);
01572 if (pStrokeColour!=NULL)
01573 {
01574
01575 DocColour colNone(COLOUR_NONE);
01576 pStrokeColour->SetStartColour(&colNone);
01577 pStrokeColour->AttachNode(pNewNodePath, FIRSTCHILD);
01578 }
01579
01580 bOK = TRUE;
01581
01582
01583
01584
01585 NodeAttribute* pEffectAttr = NodeAttribute::FindFirstAppliedAttr(this);
01586 while (bOK && pEffectAttr && pEffectAttr->IsEffectAttribute())
01587 {
01588 CALL_WITH_FAIL(pEffectAttr->CopyNode(pNewNodePath, FIRSTCHILD), pOp, bOK);
01589
01590 pEffectAttr = NodeAttribute::FindPrevAppliedAttr(pEffectAttr);
01591 }
01592
01593
01594 if (bOK)
01595 {
01596 if (pOp)
01597 {
01598 bOK = pOp->DoInsertNewNode(pNewNodePath, this, NEXT, TRUE, FALSE, this->IsSelected() || this->IsParentOfSelected(), TRUE);
01599 }
01600 else
01601 {
01602 pNewNodePath->AttachNode(this, NEXT);
01603 pNewNodePath->Select(this->IsSelected() || this->IsParentOfSelected());
01604 }
01605 }
01606
01607
01608 if (bOK)
01609 {
01610 CCAttrMap ThisMap;
01611 CCAttrMap* pThisMap = NULL;
01612 if (pNewNodePath->FindAppliedAttributes(&ThisMap))
01613 pThisMap = ThisMap.Copy();
01614 pBecomeA->PassBack(pNewNodePath, this, pThisMap);
01615 }
01616
01617
01618 if (bOK)
01619 {
01620 if (pOp)
01621 {
01622 bOK = pOp->DoHideNode(this, TRUE, &pHiddenNode, FALSE);
01623 }
01624 else
01625 {
01626 CascadeDelete();
01627 delete this;
01628 }
01629 }
01630 }
01631 break;
01632
01633 case BECOMEA_PASSBACK:
01634 {
01635
01636 CCAttrMap ThisMap;
01637 if (FindAppliedAttributes(&ThisMap))
01638 {
01639
01640 CCAttrMap* pNewAttrMap = ThisMap.Copy();
01641 AttrStrokeColour* pStrokeColour = NULL;
01642
01643 if( pNewAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStrokeColour), (void*&)(pStrokeColour) ) )
01644 {
01645 if (pStrokeColour && pStrokeColour->GetStartColour())
01646 {
01647 DocColour colNone(COLOUR_NONE);
01648 pStrokeColour->SetStartColour(&colNone);
01649 }
01650 }
01651
01652
01653
01654 AttrFillGeometry* pBitmapFill = new AttrBitmapColourFill();
01655 if (pBitmapFill && kBitmap)
01656 {
01657
01658
01659 pBitmapFill->AttachBitmap(kBitmap);
01660
01661
01662
01663
01664
01665
01666 pBitmapFill->SetStartPoint(&coords[0]);
01667 pBitmapFill->SetEndPoint(&coords[1]);
01668 pBitmapFill->SetEndPoint2(&coords[2]);
01669
01670 void* pOldFill;
01671 if (pNewAttrMap->Lookup(CC_RUNTIME_CLASS(AttrFillGeometry), pOldFill))
01672 {
01673
01674 pNewAttrMap->RemoveKey(CC_RUNTIME_CLASS(AttrFillGeometry));
01675 delete (AttrFillGeometry*)pOldFill;
01676 }
01677
01678
01679 pNewAttrMap->SetAt(CC_RUNTIME_CLASS(AttrFillGeometry),(void*)pBitmapFill);
01680 }
01681
01682
01683 pBecomeA->PassBack(pNewNodePath, this, pNewAttrMap);
01684 bOK = TRUE;
01685 }
01686 }
01687 break;
01688
01689 case BECOMEA_TEST:
01690 ERROR3("Unhandled BECOMEA type\n");
01691 break;
01692 }
01693 }
01694
01695 if (!bOK)
01696 {
01697 if (pNewNodePath != NULL)
01698 {
01699
01700
01701 pNewNodePath->CascadeDelete();
01702 delete pNewNodePath;
01703 pNewNodePath = NULL;
01704 }
01705 }
01706
01707 return bOK;
01708 }
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725 BOOL NodeBitmapEffect::CanBecomeA(BecomeA* pBecomeA)
01726 {
01727
01728
01729
01730
01731
01732 if (!IsLockedEffect())
01733 {
01734 if (pBecomeA->IsBlendBecomeA() || pBecomeA->ResultsStayInPlace())
01735 {
01736 return NodeEffect::CanBecomeA(pBecomeA);
01737 }
01738 }
01739
01740
01741 if (!IsLockedEffect() && FindParent() && FindParent()->IsEffect())
01742 return FALSE;
01743
01744 if (pBecomeA->BAPath())
01745 {
01746 pBecomeA->AddCount(1);
01747
01748 return TRUE;
01749 }
01750
01751 return FALSE;
01752 }
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768 BOOL NodeBitmapEffect::CanGenerateBitmap()
01769 {
01770 double PixelWidth = GetPixelWidth();
01771 DocRect CaptureRect = GetChildBoundingRect();
01772 return (CaptureRect.Width()>=PixelWidth && CaptureRect.Height()>=PixelWidth);
01773 }
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794 BOOL NodeBitmapEffect::WriteBoundsRecord(BaseCamelotFilter* pFilter)
01795 {
01796 BOOL ok = TRUE;
01797
01798
01799 pFilter->AddTagDescription(TAG_COMPOUNDRENDER, _R(IDS_TAG_COMPOUNDRENDER));
01800
01801
01802 DocRect Rect = GetChildBoundingRect();
01803
01804 CamelotFileRecord Rec(pFilter, TAG_COMPOUNDRENDER, TAG_COMPOUNDRENDER_SIZE);
01805 ok = Rec.Init();
01806 if (ok) ok = Rec.WriteUINT32(0);
01807 if (ok) ok = Rec.WriteCoord(Rect.lo);
01808 if (ok) ok = Rec.WriteCoord(Rect.hi);
01809 if (ok) ok = pFilter->Write(&Rec);
01810
01811 return ok;
01812 }
01813
01814
01815
01816
01817
01818
01819
01820
01821
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
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864 NodeLiveEffect::NodeLiveEffect(Node* ContextNode,
01865 AttachNodeDirection Direction,
01866 BOOL Locked,
01867 BOOL Mangled,
01868 BOOL Marked,
01869 BOOL Selected
01870 ) : NodeBitmapEffect(ContextNode, Direction, Locked, Mangled, Marked, Selected )
01871 {
01872 m_rectEstimatedBounds = DocRect(0,0,0,0);
01873 m_lMaxBorder = 0;
01874 m_dPixelsPerInch = (double)NodeBitmapEffect::DefaultLivePixelsPerInch;
01875 }
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891 NodeLiveEffect::NodeLiveEffect() : NodeBitmapEffect()
01892 {
01893 m_rectEstimatedBounds = DocRect(0,0,0,0);
01894 m_lMaxBorder = 0;
01895 m_dPixelsPerInch = (double)NodeBitmapEffect::DefaultLivePixelsPerInch;
01896 }
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912 NodeLiveEffect::~NodeLiveEffect()
01913 {
01914 m_pEditsDoc = NULL;
01915
01916 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
01917 if (pBitmapCache!=NULL)
01918 {
01919 CBitmapCacheKey inky(this, 42);
01920 pBitmapCache->RemoveAllOwnedBitmaps(inky, FALSE, CACHEPRIORITY_PERMANENT);
01921 }
01922 }
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940 DocRect NodeLiveEffect::GetBoundingRect(BOOL DontUseAttrs, BOOL HitTest)
01941 {
01942
01943 BOOL bIncludeAttrs = !DontUseAttrs;
01944
01945
01946 if (IsBoundingRectValid && bIncludeAttrs)
01947 return BoundingRectangle;
01948
01949
01950
01951 if (bIncludeAttrs)
01952 {
01953
01954 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
01955 if (pBitmapCache!=NULL)
01956 {
01957
01958 CBitmapCacheKey inky(this, GetPixelWidth(), 1);
01959 CCachedBitmap cbmp;
01960 BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
01961 if (bFound)
01962 {
01963 BoundingRectangle = cbmp.GetCachedRect();
01964 IsBoundingRectValid = TRUE;
01965 return BoundingRectangle;
01966 }
01967 }
01968 }
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978 DocRect brect = GetChildBoundingRect(bIncludeAttrs);
01979
01980 if (bIncludeAttrs)
01981 {
01982 brect.Inflate(CAPTURE_BORDER*(INT32)GetPixelWidth());
01983
01984
01985 brect.Inflate((INT32)m_lMaxBorder);
01986
01987
01988
01989
01990
01991
01992
01993 brect.Inflate((INT32)GetPixelWidth()*50);
01994
01995
01996 if (!m_rectEstimatedBounds.IsEmpty())
01997 brect = brect.Union(m_rectEstimatedBounds);
01998 }
01999
02000 return brect;
02001 }
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020 SubtreeRenderState NodeLiveEffect::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip)
02021 {
02022 BOOL bRendered = FALSE;
02023
02024 if (pRender == NULL)
02025 return SUBTREE_ROOTANDCHILDREN;
02026
02027
02028
02029 if (pRender->RRQuality.GetFillQuality() <= Quality::Solid)
02030 return SUBTREE_ROOTANDCHILDREN;
02031
02032
02033 if (pRender->IsKindOf(CC_RUNTIME_CLASS(ScanningRenderRegion)))
02034 {
02035 ScanningRenderRegion* pScanner = (ScanningRenderRegion*)pRender;
02036 pScanner->ComplexShapeFoundWrapper();
02037 return SUBTREE_NORENDER;
02038 }
02039
02040 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02041 if (pBitmapCache==NULL)
02042 return SUBTREE_NORENDER;
02043
02044
02045 BOOL bFoundCached = FindCachedEffect(pBitmapCache);
02046
02047
02048
02049
02050 DocRect BoundingRect = GetBoundingRect();
02051 if (!BoundingRect.IsValid())
02052 return SUBTREE_ROOTANDCHILDREN;
02053
02054 if (!bFoundCached)
02055 BoundingRect.Inflate((INT32)(GetPixelWidth()*150));
02056 DocRect ClipRect = pRender->GetClipRect();
02057
02058 if (bClip && !ClipRect.IsIntersectedWith(BoundingRect))
02059 return SUBTREE_NORENDER;
02060
02061
02062
02063
02064
02065 bRendered = RenderCachedEffect(pBitmapCache, pRender);
02066
02067 if (bRendered)
02068 return SUBTREE_NORENDER;
02069
02070
02071
02072 if (!pRender->GetImmediateRender())
02073 {
02074
02075 if (GetQuickRender())
02076 return SUBTREE_ROOTANDCHILDREN;
02077
02078
02079 PORTNOTE("xpe", "NodeLiveEffect::RenderSubtree - removed use of XPE")
02080 #if !defined(EXCLUDE_FROM_XARALX)
02081 if (!XPEHost::EnableLERendering(this))
02082 return SUBTREE_ROOTANDCHILDREN;
02083 #endif
02084 }
02085
02086
02087
02088 if (CanGenerateBitmap())
02089 {
02090 DocRect CaptureRect = GetChildBoundingRect();
02091 CaptureRect.Inflate(CAPTURE_BORDER*(INT32)GetPixelWidth());
02092
02093
02094
02095
02096
02097
02098 CaptureFlags caFlags = CaptureFlags(cfLOCKEDTRANSPARENT | cfFULLCOVERAGE | cfUNCLIP | (EnableDirectCapture() ? cfALLOWDIRECT : cfNONE));
02099 double dResolution = GetPixelsPerInch();
02100
02101 pRender->StartCapture(this, CaptureRect, CAPTUREINFO(ctNESTABLE, caFlags), TRUE, FALSE, dResolution, GetInkNodeFromController());
02102
02103
02104 }
02105
02106 return SUBTREE_ROOTANDCHILDREN;
02107 }
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124 BOOL NodeLiveEffect::GetProcessedBitmap(BOOL bDirect, LPBITMAPINFO* plpInfo, LPBYTE* plpBits, DocRect* pRect)
02125 {
02126 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02127 if (pBitmapCache==NULL)
02128 return FALSE;
02129
02130 CBitmapCacheKey inky(this, GetPixelWidth(), 1);
02131
02132
02133 CCachedBitmap cbmp;
02134 BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
02135 if (bFound)
02136 {
02137 if (plpInfo)
02138 *plpInfo = cbmp.pbmpInfo;
02139 if (plpBits)
02140 *plpBits = cbmp.pbmpBits;
02141 if (pRect)
02142 {
02143 if (bDirect)
02144 *pRect = m_rectDirectBitmap;
02145 else
02146 *pRect = cbmp.GetCachedRect();
02147 }
02148 return TRUE;
02149 }
02150
02151 if (plpInfo)
02152 *plpInfo = NULL;
02153 if (plpBits)
02154 *plpBits = NULL;
02155
02156 return FALSE;
02157 }
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175 DocRect NodeLiveEffect::SetProcessedBitmap(LPBITMAPINFO lpInfo, LPBYTE lpBits, DocRect rect, INT32 width, INT32 height, double xOffset, double yOffset, double dPixelWidth, Matrix* pmatTransform)
02176 {
02177 BOOL bWasInvalidBounds = !IsBoundingRectValid;
02178 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02179 if (pBitmapCache==NULL)
02180 return rect;
02181
02182 if (dPixelWidth==0)
02183 dPixelWidth = GetPixelWidth();
02184
02185 if (rect.IsEmpty())
02186 {
02187 rect = GetChildBoundingRect();
02188 rect.Inflate(CAPTURE_BORDER*(INT32)dPixelWidth);
02189 }
02190
02191 CBitmapCacheKey inky(this, dPixelWidth, 1);
02192 DocRect crect = AdjustPixelOffsets(rect, width, height, xOffset, yOffset, dPixelWidth);
02193 DocRect uprect = crect;
02194
02195
02196 DocCoord coords[3];
02197 coords[0] = crect.lo;
02198 coords[1] = DocCoord(crect.hi.x, crect.lo.y);
02199 coords[2] = DocCoord(crect.lo.x, crect.hi.y);
02200 if (pmatTransform)
02201 pmatTransform->transform(coords, 3);
02202
02203
02204 CCachedBitmap cbmp;
02205 BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
02206 if (bFound)
02207 {
02208 pBitmapCache->RemoveBitmap(inky);
02209 cbmp.Release();
02210 m_rectDirectBitmap = DocRect(0,0,0,0);
02211 }
02212
02213 if (lpInfo!=NULL && lpBits!=NULL)
02214 {
02215 cbmp.pbmpInfo = lpInfo;
02216 cbmp.pbmpBits = lpBits;
02217
02218 cbmp.SetCachedParallelogram(coords, 3);
02219 cbmp.nPriority = CACHEPRIORITY_PERMANENT;
02220
02221 pBitmapCache->StoreBitmap(inky, cbmp);
02222
02223 m_rectDirectBitmap = crect;
02224
02225 uprect = cbmp.GetCachedRect();
02226
02227 IsBoundingRectValid = TRUE;
02228 InvalidateBoundingRect();
02229 BoundingRectangle = uprect;
02230 IsBoundingRectValid = TRUE;
02231
02232
02233 m_rectEstimatedBounds = uprect;
02234
02235
02236
02237
02238
02239
02240
02241 DocCoord OrigCoords[4];
02242 OrigCoords[0] = rect.lo;
02243 OrigCoords[1] = DocCoord(rect.lo.x, rect.hi.y);
02244 OrigCoords[2] = DocCoord(rect.hi.x, rect.lo.y);
02245 OrigCoords[3] = rect.hi;
02246 if (pmatTransform)
02247 pmatTransform->transform(OrigCoords, 4);
02248
02249 DocRect OrigRect(OrigCoords[0], OrigCoords[0]);
02250 OrigRect.IncludePoint(OrigCoords[1]);
02251 OrigRect.IncludePoint(OrigCoords[2]);
02252 OrigRect.IncludePoint(OrigCoords[3]);
02253
02254 m_lMaxBorder = max(OrigRect.lo.x-uprect.lo.x, OrigRect.lo.y-uprect.lo.y);
02255 m_lMaxBorder = max(uprect.hi.x-OrigRect.hi.x, m_lMaxBorder);
02256 m_lMaxBorder = max(uprect.hi.y-OrigRect.hi.y, m_lMaxBorder);
02257
02258 if ( !Error::IsUserName("Gavin") )
02259 ERROR3IF(m_lMaxBorder<0, "m_lMaxBorder has become negative!");
02260 m_lMaxBorder = 0;
02261
02262
02263
02264 if (rect!=crect || bWasInvalidBounds)
02265 {
02266 DocView* pView = DocView::GetCurrent();
02267 if (pView)
02268 pView->NotifyBoundsChanged();
02269 }
02270 }
02271
02272
02273 return uprect;
02274 }
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299 String NodeLiveEffect::Describe(BOOL Plural, BOOL Verbose)
02300 {
02301 if (Plural)
02302 return(String(_R(IDS_LIVEEFFECT_DESCRP)));
02303 else
02304 return(String(_R(IDS_LIVEEFFECT_DESCRS)));
02305 };
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327 Node* NodeLiveEffect::SimpleCopy()
02328 {
02329 NodeLiveEffect* NodeCopy;
02330 NodeCopy = new NodeLiveEffect();
02331 ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL);
02332 CopyNodeContents(NodeCopy);
02333 return (NodeCopy);
02334 }
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355 void NodeLiveEffect::CopyNodeContents(NodeLiveEffect* pCopyOfNode)
02356 {
02357 NodeBitmapEffect::CopyNodeContents(pCopyOfNode);
02358
02359
02360 if (m_pEditsDoc)
02361 {
02362 PORTNOTETRACE("other","NodeLiveEffect::CopyNodeContents - not copying XML data");
02363 #ifndef EXCLUDE_FROM_XARALX
02364 pCopyOfNode->m_pEditsDoc = CXMLUtils::NewDocument(m_pEditsDoc);
02365 #endif
02366 }
02367 else
02368 pCopyOfNode->m_pEditsDoc = NULL;
02369 pCopyOfNode->m_dPixelsPerInch = m_dPixelsPerInch;
02370 pCopyOfNode->m_strDisplayName = m_strDisplayName;
02371 pCopyOfNode->m_rectEstimatedBounds = m_rectEstimatedBounds;
02372 pCopyOfNode->m_lMaxBorder = m_lMaxBorder;
02373 pCopyOfNode->m_rectDirectBitmap = m_rectDirectBitmap;
02374
02375
02376
02377 CopyCached(pCopyOfNode, GetPixelWidth(), 1);
02378 }
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395 void NodeLiveEffect::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
02396 {
02397 ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
02398 ENSURE(IS_A(pNodeCopy, NodeLiveEffect), "PolyCopyNodeContents given wrong dest node type");
02399
02400 if (IS_A(pNodeCopy, NodeLiveEffect))
02401 CopyNodeContents((NodeLiveEffect*)pNodeCopy);
02402 }
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422 UINT32 NodeLiveEffect::GetNodeSize() const
02423 {
02424 return sizeof(NodeLiveEffect);
02425 }
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442 void NodeLiveEffect::Transform( TransformBase& Trans )
02443 {
02444 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02445 ERROR3IF(pBitmapCache==NULL, "Can't find BitmapCache");
02446
02447
02448 CCachedBitmap cbmp;
02449 CBitmapCacheKey inky(this, GetPixelWidth(), 0);
02450 BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
02451 if (bFound)
02452 {
02453 cbmp.Transform(Trans);
02454 pBitmapCache->StoreBitmap(inky, cbmp);
02455 }
02456
02457 CBitmapCacheKey inky1(this, GetPixelWidth(), 1);
02458 bFound = pBitmapCache->Lookup(inky1, cbmp);
02459 if (bFound)
02460 {
02461 cbmp.Transform(Trans);
02462 pBitmapCache->StoreBitmap(inky1, cbmp);
02463 }
02464 else
02465 {
02466 Trans.bHaveTransformedCached = FALSE;
02467 Trans.bTransformYourChildren = TRUE;
02468 }
02469
02470
02471
02472
02473
02474
02475 DocCoord t[3];
02476 t[0] = m_rectEstimatedBounds.lo;
02477 t[1] = DocCoord(m_rectEstimatedBounds.hi.x, m_rectEstimatedBounds.lo.y);
02478 t[2] = DocCoord(m_rectEstimatedBounds.lo.x, m_rectEstimatedBounds.hi.y);
02479
02480 Trans.Transform(t, 3);
02481
02482 m_rectEstimatedBounds = DocRect(t[0], t[0]);
02483 m_rectEstimatedBounds.IncludePoint(t[1]);
02484 m_rectEstimatedBounds.IncludePoint(t[2]);
02485 m_rectEstimatedBounds.IncludePoint(DocCoord(t[2].x+t[1].x-t[0].x, t[2].y+t[1].y-t[0].y));
02486
02487
02488
02489
02490
02491 InvalidateBoundingRect();
02492
02493
02494 BOOL bTransCache = Trans.bHaveTransformedCached;
02495
02496
02497
02498
02499 if (Trans.bTransformYourChildren)
02500 TransformChildren(Trans);
02501 else
02502 {
02503 TransformEffectAttrs(Trans);
02504 Trans.bHaveTransformedChildren = FALSE;
02505 }
02506
02507
02508
02509
02510 Trans.bHaveTransformedCached = bTransCache;
02511
02512
02513
02514
02515 }
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537 BOOL NodeLiveEffect::ReleaseCached(BOOL bAndParents, BOOL bAndChildren, BOOL bSelf, BOOL bAndDerived)
02538 {
02539
02540
02541 if (!IsDragged())
02542 {
02543 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02544 if (pBitmapCache!=NULL && bSelf)
02545 {
02546 CBitmapCacheKey inky(this, 42);
02547 pBitmapCache->RemoveAllOwnedBitmaps(inky, FALSE, CACHEPRIORITY_PERMANENT);
02548 m_rectDirectBitmap = DocRect(0,0,0,0);
02549 }
02550 }
02551
02552
02553 if (bAndChildren)
02554 {
02555 Node* pChild = FindFirstChild();
02556 while (pChild)
02557 {
02558 if (pChild->IsBounded())
02559 ((NodeRenderableBounded*)pChild)->ReleaseCached(FALSE, TRUE, TRUE, TRUE);
02560
02561 pChild = pChild->FindNext();
02562 }
02563 }
02564
02565
02566 if (bAndParents && FindParent() && FindParent()->IsBounded())
02567 ((NodeRenderableBounded*)FindParent())->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
02568
02569 return TRUE;
02570 }
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588 BOOL NodeLiveEffect::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
02589 {
02590 #ifdef DO_EXPORT
02591
02592 BOOL ok = TRUE;
02593
02594 ok = WriteLiveEffect(pFilter);
02595
02596 return ok;
02597
02598 #else
02599 return FALSE;
02600 #endif
02601 }
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616 BOOL NodeLiveEffect::WritePreChildrenNative(BaseCamelotFilter* pFilter)
02617 {
02618 #ifdef DO_EXPORT
02619
02620 BOOL ok = TRUE;
02621
02622 ok = WriteLiveEffect(pFilter);
02623
02624 return ok;
02625
02626 #else
02627 return FALSE;
02628 #endif
02629 }
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647 BOOL NodeLiveEffect::WriteLiveEffect(BaseCamelotFilter* pFilter)
02648 {
02649 #ifdef DO_EXPORT
02650 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
02651
02652 BOOL ok = TRUE;
02653 BYTE Flags = 0;
02654
02655 UINT32 Tag = TAG_LIVE_EFFECT;
02656
02657 CXaraFileRecord Rec(Tag);
02658
02659 PORTNOTETRACE("other","NodeLiveEffect::WriteLiveEffect - removed use of XML");
02660 #ifndef EXCLUDE_FROM_XARALX
02661 BSTR bstrValue;
02662 HRESULT hr;
02663 hr = m_pEditsDoc->get_xml(&bstrValue);
02664 ok = (SUCCEEDED(hr));
02665 #endif
02666 if (ok) ok = Rec.Init();
02667 if (ok) ok = Rec.WriteBYTE(Flags);
02668 if (ok) ok = Rec.WriteDOUBLE(m_dPixelsPerInch);
02669 if (ok) ok = Rec.WriteUnicode(m_strPostProID);
02670 if (ok) ok = Rec.WriteUnicode(m_strDisplayName);
02671 if (ok) ok = Rec.WriteUTF16STR(m_vstrEdits);
02672
02673
02674 if (ok) ok = pFilter->Write(&Rec);
02675
02676 return ok;
02677 #else
02678 return FALSE;
02679 #endif
02680 }
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700 NodeRenderableInk* NodeLiveEffect::FindNodeAtPointHelper(const Spread* pSpread, const DocCoord dcPoint)
02701 {
02702
02703
02704
02705
02706
02707 NodeRenderableInk* pNode = this;
02708 while (pNode!=NULL && pNode->IsCompoundClass() && !(pNode->CanSelectAsCompoundParent() && pNode->PromoteHitTestOnChildrenToMe()))
02709 {
02710 pNode = ((NodeCompound*)pNode)->GetInkNodeFromController();
02711 }
02712
02713 return pNode;
02714 }
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733 KernelBitmap* NodeLiveEffect::GetKernelBitmap(DocCoord* pCoords, BOOL bRetainCached)
02734 {
02735
02736 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02737 CBitmapCacheKey inky(this, GetPixelWidth(), 1);
02738 CCachedBitmap cbmp;
02739 BOOL bFoundCached = pBitmapCache->Lookup(inky, cbmp);
02740 if (!bFoundCached)
02741 return NULL;
02742
02743 CWxBitmap *wBitmap = new CWxBitmap(cbmp.pbmpInfo, cbmp.pbmpBits);
02744 if (wBitmap==NULL)
02745 return NULL;
02746
02747 wBitmap->SetHidden(TRUE);
02748 KernelBitmap* kBitmap = new KernelBitmap(wBitmap);
02749 if (kBitmap==NULL)
02750 {
02751 delete wBitmap;
02752 return NULL;
02753 }
02754 Document* pDoc = Document::GetCurrent();
02755 BitmapList* pBmpList = pDoc->GetBitmapList();
02756 kBitmap->Attach(pBmpList);
02757 PORTNOTE("xpe", "NodeLiveEffect::GetKernelBitmap - removed use of XPE")
02758 #if !defined(EXCLUDE_FROM_XARALX)
02759 XPEHost::GetEffectDetails(m_strPostProID, &m_strDisplayName);
02760 #endif
02761 String_256 name(m_strDisplayName);
02762 kBitmap->SetName(name);
02763
02764 if (pCoords)
02765 {
02766 pCoords[0] = cbmp.coord0;
02767 pCoords[1] = cbmp.coord1;
02768 pCoords[2] = cbmp.coord2;
02769 }
02770
02771 if (!bRetainCached)
02772 pBitmapCache->RemoveBitmap(inky);
02773
02774 return kBitmap;
02775 }
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794 void NodeLiveEffect::RemoveBitmapFromCache()
02795 {
02796 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02797 CBitmapCacheKey inky(this, GetPixelWidth(), 1);
02798 pBitmapCache->RemoveBitmap(inky);
02799 }
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850 NodeLockedEffect::NodeLockedEffect(Node* ContextNode,
02851 AttachNodeDirection Direction,
02852 BOOL Locked,
02853 BOOL Mangled,
02854 BOOL Marked,
02855 BOOL Selected
02856 ) : NodeBitmapEffect(ContextNode, Direction, Locked, Mangled, Marked, Selected )
02857 {
02858 m_PGram[0] = DocCoord(0,0);
02859 m_PGram[1] = DocCoord(0,0);
02860 m_PGram[2] = DocCoord(0,0);
02861
02862 m_dPixelsPerInch = (double)NodeBitmapEffect::DefaultLockedPixelsPerInch;
02863 m_bIsDestructive = TRUE;
02864 }
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880 NodeLockedEffect::NodeLockedEffect() : NodeBitmapEffect()
02881 {
02882 m_PGram[0] = DocCoord(0,0);
02883 m_PGram[1] = DocCoord(0,0);
02884 m_PGram[2] = DocCoord(0,0);
02885
02886 m_dPixelsPerInch = (double)NodeBitmapEffect::DefaultLockedPixelsPerInch;
02887 m_bIsDestructive = TRUE;
02888 }
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904 NodeLockedEffect::~NodeLockedEffect()
02905 {
02906 m_BitmapRef.Detach();
02907 m_pEditsDoc = NULL;
02908
02909
02910
02911 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02912 if (pBitmapCache!=NULL)
02913 {
02914 CBitmapCacheKey inky(this, 42);
02915 pBitmapCache->RemoveAllOwnedBitmaps(inky, FALSE, CACHEPRIORITY_PERMANENT);
02916 }
02917 }
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936 void NodeLockedEffect::UnlinkNodeFromTree(BaseDocument* pOwnerDoc)
02937 {
02938 KernelBitmap* pOldBitmap = m_BitmapRef.GetBitmap();
02939 if (pOldBitmap && pOwnerDoc)
02940 {
02941 m_BitmapRef.Detach();
02942
02943 BitmapList* pBmpList = pOldBitmap->GetParentBitmapList();
02944 if (pBmpList)
02945 {
02946 if (pOwnerDoc && pOwnerDoc->IsKindOf(CC_RUNTIME_CLASS(Document)))
02947 {
02948 Document* pBitmapDoc = (Document*)pOwnerDoc;
02949 if (pBitmapDoc && !pOldBitmap->IsUsedInDocument(pBitmapDoc, TRUE))
02950 {
02951 pOldBitmap->Detach();
02952 BROADCAST_TO_ALL(BitmapListChangedMsg(pBmpList, pOldBitmap));
02953 delete pOldBitmap;
02954
02955
02956
02957 Camelot.GetGlobalBitmapList()->DeleteAllUnusedBitmaps();
02958 }
02959 }
02960 }
02961 }
02962
02963
02964 NodeBitmapEffect::UnlinkNodeFromTree(pOwnerDoc);
02965 }
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995 KernelBitmap* NodeLockedEffect::EnumerateBitmaps(UINT32 Count)
02996 {
02997 if (Count == 0) return m_BitmapRef.GetBitmap();
02998
02999 return NULL;
03000 }
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017 DocRect NodeLockedEffect::GetBoundingRect(BOOL DontUseAttrs, BOOL HitTest)
03018 {
03019
03020 BOOL bIncludeAttrs = !DontUseAttrs;
03021
03022
03023 if (IsBoundingRectValid && bIncludeAttrs)
03024 return BoundingRectangle;
03025
03026
03027
03028 if (bIncludeAttrs)
03029 {
03030
03031 if (m_BitmapRef.GetBitmap()!=NULL)
03032 {
03033 DocRect r(m_PGram[0], m_PGram[0]);
03034 r.IncludePoint(m_PGram[1]);
03035 r.IncludePoint(m_PGram[2]);
03036 r.IncludePoint(DocCoord(m_PGram[2].x+m_PGram[1].x-m_PGram[0].x, m_PGram[2].y+m_PGram[1].y-m_PGram[0].y));
03037 IsBoundingRectValid = TRUE;
03038 BoundingRectangle = r;
03039 return r;
03040 }
03041 }
03042
03043 DocRect brect = GetChildBoundingRect(bIncludeAttrs);
03044
03045
03046 if (bIncludeAttrs)
03047 brect.Inflate((INT32)(GetPixelWidth()*50+0.5));
03048
03049 return brect;
03050 }
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069 SubtreeRenderState NodeLockedEffect::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip)
03070 {
03071
03072
03073 if (pRender == NULL)
03074 return SUBTREE_ROOTANDCHILDREN;
03075
03076 DocRect BoundingRect = GetBoundingRect();
03077 if (!BoundingRect.IsValid())
03078 return SUBTREE_ROOTANDCHILDREN;
03079
03080 DocRect ClipRect = pRender->GetClipRect();
03081 if (m_BitmapRef.GetBitmap()!=NULL)
03082 {
03083
03084
03085
03086
03087 if (bClip && !ClipRect.IsIntersectedWith(BoundingRect))
03088 return SUBTREE_NORENDER;
03089
03090 KernelBitmap* pkBitmap = m_BitmapRef.GetBitmap();
03091 if (pkBitmap==NULL || pkBitmap->HasBeenDeleted())
03092 return SUBTREE_ROOTANDCHILDREN;
03093
03094 #ifdef _DEBUG
03095 BOOL bRendered = RenderCachedEffect(NULL, pRender);
03096 ERROR3IF(!bRendered, "How can something so simple fail to render?");
03097 #else
03098 RenderCachedEffect(NULL, pRender);
03099 #endif
03100
03101 return SUBTREE_NORENDER;
03102 }
03103
03104 BoundingRect.Inflate((INT32)(GetPixelWidth()*150));
03105 if (bClip && !ClipRect.IsIntersectedWith(BoundingRect))
03106 return SUBTREE_NORENDER;
03107
03108
03109
03110
03111
03112
03113 DocRect viewrect = ClipRect;
03114 DocRect CaptureRect = GetChildBoundingRect();
03115
03116
03117 if (CanGenerateBitmap())
03118 {
03119
03120
03121
03122
03123
03124
03125
03126 DocRect CaptureRect = GetChildBoundingRect();
03127 CaptureRect.Inflate(CAPTURE_BORDER*(INT32)GetPixelWidth());
03128 CaptureFlags caFlags = CaptureFlags(cfLOCKEDTRANSPARENT | cfFULLCOVERAGE | cfUNCLIP | (EnableDirectCapture() ? cfALLOWDIRECT : cfNONE));
03129 double dResolution = GetPixelsPerInch();
03130
03131 pRender->StartCapture(this, CaptureRect, CAPTUREINFO(ctNESTABLE, caFlags), TRUE, FALSE, dResolution, GetInkNodeFromController());
03132
03133
03134 }
03135
03136 return SUBTREE_ROOTANDCHILDREN;
03137 }
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153 void NodeLockedEffect::Render(RenderRegion* pRender)
03154 {
03155 if (m_BitmapRef.GetBitmap()!=NULL && pRender->IsHitDetect())
03156 {
03157 CWxBitmap* pWBitmap = (CWxBitmap*)m_BitmapRef.GetBitmap()->GetActualBitmap();
03158 if (pWBitmap==NULL || pWBitmap->HasBeenDeleted())
03159 return;
03160
03161 LPBITMAPINFO lpInfo = pWBitmap->BMInfo;
03162 LPBYTE lpBits = pWBitmap->BMBytes;
03163 #ifdef _DEBUG
03164 BOOL bRendered = pRender->RenderBits(lpInfo, lpBits, m_PGram, 3, TRUE, this);
03165 ERROR3IF(!bRendered, "How can something so simple fail to render?");
03166 #else
03167 pRender->RenderBits(lpInfo, lpBits, m_PGram, 3, TRUE, this);
03168 #endif
03169 }
03170 }
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187 BOOL NodeLockedEffect::GetProcessedBitmap(BOOL bDirect, LPBITMAPINFO* plpInfo, LPBYTE* plpBits, DocRect* pRect)
03188 {
03189 if (plpInfo) *plpInfo = NULL;
03190 if (plpBits) *plpBits = NULL;
03191
03192 if (m_BitmapRef.GetBitmap()!=NULL)
03193 {
03194 CWxBitmap* pWBitmap = (CWxBitmap*)m_BitmapRef.GetBitmap()->GetActualBitmap();
03195 if (pWBitmap!=NULL && !pWBitmap->HasBeenDeleted())
03196 {
03197 if (plpInfo) *plpInfo = pWBitmap->BMInfo;
03198 if (plpBits) *plpBits = pWBitmap->BMBytes;
03199 if (pRect)
03200 {
03201 if (bDirect)
03202 *pRect = m_rectDirectBitmap;
03203 else
03204 {
03205 DocRect uprect = DocRect(m_PGram[0], m_PGram[0]);
03206 uprect.IncludePoint(m_PGram[1]);
03207 uprect.IncludePoint(m_PGram[2]);
03208 uprect.IncludePoint(DocCoord(m_PGram[2].x+m_PGram[1].x-m_PGram[0].x, m_PGram[2].y+m_PGram[1].y-m_PGram[0].y));
03209 *pRect = uprect;
03210 }
03211 }
03212
03213 return TRUE;
03214 }
03215 }
03216
03217 return FALSE;
03218 }
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233 DocRect NodeLockedEffect::SetProcessedBitmap(LPBITMAPINFO lpInfo, LPBYTE lpBits, DocRect rect, INT32 width, INT32 height, double xOffset, double yOffset, double dPixelWidth, Matrix* pmatTransform)
03234 {
03235 BOOL bWasInvalidBounds = !IsBoundingRectValid;
03236
03237 if (dPixelWidth==0)
03238 dPixelWidth = GetPixelWidth();
03239
03240 if (rect.IsEmpty())
03241 {
03242 rect = GetChildBoundingRect();
03243 rect.Inflate(CAPTURE_BORDER*(INT32)dPixelWidth);
03244 }
03245
03246 DocRect crect = AdjustPixelOffsets(rect, width, height, xOffset, yOffset, dPixelWidth);
03247 DocRect uprect = crect;
03248
03249
03250 DocCoord coords[3];
03251 coords[0] = crect.lo;
03252 coords[1] = DocCoord(crect.hi.x, crect.lo.y);
03253 coords[2] = DocCoord(crect.lo.x, crect.hi.y);
03254
03255 if (pmatTransform)
03256 {
03257 pmatTransform->transform(coords, 3);
03258
03259
03260 uprect = DocRect(coords[0], coords[0]);
03261 uprect.IncludePoint(coords[1]);
03262 uprect.IncludePoint(coords[2]);
03263 uprect.IncludePoint(DocCoord(coords[2].x+coords[1].x-coords[0].x, coords[2].y+coords[1].y-coords[0].y));
03264 }
03265
03266
03267
03268 m_BitmapRef.Detach();
03269 m_rectDirectBitmap = DocRect(0,0,0,0);
03270
03271 if (lpInfo && lpBits)
03272 {
03273
03274 CWxBitmap* wBitmap = new CWxBitmap(lpInfo, lpBits);
03275 if (wBitmap==NULL)
03276 return uprect;
03277 wBitmap->SetHidden(TRUE);
03278 KernelBitmap* kBitmap = new KernelBitmap(wBitmap);
03279 if (kBitmap==NULL)
03280 {
03281 delete wBitmap;
03282 return uprect;
03283 }
03284
03285 m_rectDirectBitmap = crect;
03286
03287 Document* pDoc = Document::GetCurrent();
03288 BitmapList* pBmpList = pDoc->GetBitmapList();
03289 kBitmap->Attach(pBmpList);
03290 PORTNOTE("xpe", "NodeLockedEffect::SetProcessedBitmap - removed use of XPE")
03291 #if !defined(EXCLUDE_FROM_XARALX)
03292 XPEHost::GetEffectDetails(m_strPostProID, &m_strDisplayName);
03293 #endif
03294 String_256 strName(m_strDisplayName);
03295 kBitmap->SetName(strName);
03296 m_BitmapRef.Attach(kBitmap);
03297
03298 IsBoundingRectValid = TRUE;
03299 InvalidateBoundingRect();
03300 BoundingRectangle = uprect;
03301 m_PGram[0] = coords[0];
03302 m_PGram[1] = coords[1];
03303 m_PGram[2] = coords[2];
03304 IsBoundingRectValid = TRUE;
03305
03306
03307 if (rect!=uprect || bWasInvalidBounds)
03308 {
03309 DocView* pView = DocView::GetCurrent();
03310 if (pView)
03311 pView->NotifyBoundsChanged();
03312 }
03313 }
03314
03315
03316 return uprect;
03317 }
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336 BOOL NodeLockedEffect::RenderCachedEffect(CBitmapCache* pBitmapCache, RenderRegion* pRender, BOOL bIgnoreCapture)
03337 {
03338 BOOL bRendered = FALSE;
03339
03340
03341 Capture* pCapture = pRender->GetTopCapture();
03342 if (!bIgnoreCapture && pCapture && pCapture->ConsumeDirectBitmap(this))
03343 {
03344
03345 bRendered = TRUE;
03346 }
03347 else
03348 {
03349 CWxBitmap* pWBitmap = (CWxBitmap*)m_BitmapRef.GetBitmap()->GetActualBitmap();
03350 if (pWBitmap==NULL || pWBitmap->HasBeenDeleted())
03351 return FALSE;
03352
03353 LPBITMAPINFO lpInfo = pWBitmap->BMInfo;
03354 LPBYTE lpBits = pWBitmap->BMBytes;
03355 bRendered = pRender->RenderBits(lpInfo, lpBits, m_PGram, 3, TRUE, this);
03356 ENSURE(bRendered, "How can something so simple fail to render?");
03357 }
03358
03359 return bRendered;
03360 }
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385 String NodeLockedEffect::Describe(BOOL Plural, BOOL Verbose)
03386 {
03387 if (Plural)
03388 return(String(_R(IDS_DLIVEEFFECT_DESCRP)));
03389 else
03390 return(String(_R(IDS_DLIVEEFFECT_DESCRS)));
03391 };
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413 Node* NodeLockedEffect::SimpleCopy()
03414 {
03415 NodeLockedEffect* NodeCopy;
03416 NodeCopy = new NodeLockedEffect();
03417 ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL);
03418 CopyNodeContents(NodeCopy);
03419 return (NodeCopy);
03420 }
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441 void NodeLockedEffect::CopyNodeContents(NodeLockedEffect* pCopyOfNode)
03442 {
03443 NodeBitmapEffect::CopyNodeContents(pCopyOfNode);
03444
03445
03446 PORTNOTE("other","NodeLockedEffect::CopyNodeContents - Removed CXMLUtils usage")
03447 #ifndef EXCLUDE_FROM_XARALX
03448 pCopyOfNode->m_pEditsDoc = CXMLUtils::NewDocument(m_pEditsDoc);
03449 #endif
03450 pCopyOfNode->m_dPixelsPerInch = m_dPixelsPerInch;
03451 pCopyOfNode->m_strDisplayName = m_strDisplayName;
03452 pCopyOfNode->m_rectDirectBitmap = m_rectDirectBitmap;
03453
03454 pCopyOfNode->m_BitmapRef = m_BitmapRef;
03455 pCopyOfNode->m_PGram[0] = m_PGram[0];
03456 pCopyOfNode->m_PGram[1] = m_PGram[1];
03457 pCopyOfNode->m_PGram[2] = m_PGram[2];
03458 pCopyOfNode->m_bIsDestructive = m_bIsDestructive;
03459 }
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476 void NodeLockedEffect::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
03477 {
03478 ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
03479 ENSURE(IS_A(pNodeCopy, NodeLockedEffect), "PolyCopyNodeContents given wrong dest node type");
03480
03481 if (IS_A(pNodeCopy, NodeLockedEffect))
03482 CopyNodeContents((NodeLockedEffect*)pNodeCopy);
03483 }
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503 UINT32 NodeLockedEffect::GetNodeSize() const
03504 {
03505 UINT32 Size = sizeof(NodeLockedEffect);
03506
03507
03508 KernelBitmap* pBitmap = ((NodeLockedEffect*)this)->m_BitmapRef.GetBitmap();
03509 if (pBitmap && pBitmap->ActualBitmap)
03510 {
03511 Size += pBitmap->ActualBitmap->GetBitmapSize();
03512 }
03513
03514 return Size;
03515 }
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532 void NodeLockedEffect::Transform( TransformBase& Trans )
03533 {
03534
03535 Trans.Transform(m_PGram, 3);
03536
03537 InvalidateBoundingRect();
03538
03539
03540 if (Trans.bTransformYourChildren)
03541 TransformChildren(Trans);
03542 else
03543 TransformEffectAttrs(Trans);
03544 }
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562 BOOL NodeLockedEffect::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
03563 {
03564 #ifdef DO_EXPORT
03565
03566 BOOL ok = TRUE;
03567
03568 ok = WriteLockedEffect(pFilter);
03569
03570 return ok;
03571
03572 #else
03573 return FALSE;
03574 #endif
03575 }
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590 BOOL NodeLockedEffect::WritePreChildrenNative(BaseCamelotFilter* pFilter)
03591 {
03592 #ifdef DO_EXPORT
03593
03594 BOOL ok = TRUE;
03595
03596 ok = WriteLockedEffect(pFilter);
03597
03598 return ok;
03599
03600 #else
03601 return FALSE;
03602 #endif
03603 }
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621 BOOL NodeLockedEffect::WriteLockedEffect(BaseCamelotFilter* pFilter)
03622 {
03623 #ifdef DO_EXPORT
03624 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
03625
03626 BOOL ok = TRUE;
03627 BYTE Flags = 0;
03628 if (!m_bIsDestructive) Flags |= 0x02;
03629
03630
03631 KernelBitmap* pBmp = m_BitmapRef.GetBitmap();
03632 ERROR2IF(pBmp == NULL, FALSE, "NULL kernel bitmap in WriteLockedEffect");
03633
03634
03635 INT32 BitmapRecordRef = pFilter->WriteRecord(pBmp);
03636 ERROR2IF(BitmapRecordRef == 0, FALSE, "Bitmap ref is zero in WriteLockedEffect");
03637
03638
03639 if (ok) ok = (BitmapRecordRef != 0);
03640
03641 UINT32 Tag = TAG_LOCKED_EFFECT;
03642
03643 CXaraFileRecord Rec(Tag);
03644
03645 PORTNOTETRACE("other","NodeLockedEffect::WriteLockedEffect - removed use of XML");
03646 #ifndef EXCLUDE_FROM_XARALX
03647 BSTR bstrValue;
03648 HRESULT hr;
03649 hr = m_pEditsDoc->get_xml(&bstrValue);
03650 ok = (SUCCEEDED(hr));
03651 #endif
03652 if (ok) ok = Rec.Init();
03653 if (ok) ok = Rec.WriteBYTE(Flags);
03654 if (ok) ok = Rec.WriteDOUBLE(m_dPixelsPerInch);
03655 if (ok) ok = Rec.WriteReference(BitmapRecordRef);
03656 if (ok) ok = Rec.WriteCoordTrans(m_PGram[0], 0, 0);
03657 if (ok) ok = Rec.WriteCoordTrans(m_PGram[1], 0, 0);
03658 if (ok) ok = Rec.WriteCoordTrans(m_PGram[2], 0, 0);
03659 if (ok) ok = Rec.WriteUnicode(m_strPostProID);
03660 if (ok) ok = Rec.WriteUnicode(m_strDisplayName);
03661 if (ok) ok = Rec.WriteUTF16STR(m_vstrEdits);
03662
03663
03664 if (ok) ok = pFilter->Write(&Rec);
03665
03666 return ok;
03667 #else
03668 return FALSE;
03669 #endif
03670 }
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689 KernelBitmap* NodeLockedEffect::GetKernelBitmap(DocCoord* pCoords, BOOL bRetainCached)
03690 {
03691 KernelBitmap* kBitmap = m_BitmapRef.GetBitmap();
03692
03693 if (pCoords)
03694 {
03695 pCoords[0] = m_PGram[0];
03696 pCoords[1] = m_PGram[1];
03697 pCoords[2] = m_PGram[2];
03698 }
03699
03700 return kBitmap;
03701 }
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718 void NodeLockedEffect::RenderObjectBlobs(RenderRegion* pRender)
03719 {
03720 #if !defined(EXCLUDE_FROM_RALPH)
03721 ERROR3IF(!IsSelected(), "Who's asking us to render blobs when we're not selected?");
03722
03723 DocRect r = GetBoundingRect();
03724 pRender->SetLineColour(COLOUR_NONE);
03725 pRender->SetFillColour(COLOUR_UNSELECTEDBLOB);
03726
03727 pRender->DrawBlob(r.lo, BT_UNSELECTED);
03728 pRender->DrawBlob(DocCoord(r.hi.x, r.lo.y), BT_UNSELECTED);
03729 pRender->DrawBlob(r.hi, BT_UNSELECTED);
03730 pRender->DrawBlob(DocCoord(r.lo.x, r.hi.y), BT_UNSELECTED);
03731 #endif
03732 }
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748 void NodeLockedEffect::RenderTinyBlobs(RenderRegion* pRender)
03749 {
03750 #if !defined(EXCLUDE_FROM_RALPH)
03751
03752
03753 DocRect r = GetBoundingRect();
03754 pRender->SetLineColour(COLOUR_NONE);
03755 pRender->SetFillColour(COLOUR_UNSELECTEDBLOB);
03756
03757 pRender->DrawBlob(r.hi, BT_UNSELECTED);
03758 #endif
03759 }
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779 NodeRenderableInk* NodeLockedEffect::GetInkNodeFromController() const
03780 {
03781 NodeRenderableInk* pNode = FindFirstChildInk();
03782 if (pNode == FindLastChildInk())
03783 return pNode;
03784
03785 return NULL;
03786 }
03787
03788
03789
03790
03791
03792
03793
03794
03795 #ifdef FEATHER_EFFECT
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842 NodeFeatherEffect::NodeFeatherEffect(Node* ContextNode,
03843 AttachNodeDirection Direction,
03844 BOOL Locked,
03845 BOOL Mangled,
03846 BOOL Marked,
03847 BOOL Selected
03848 ) : NodeLiveEffect(ContextNode, Direction, Locked, Mangled, Marked, Selected )
03849 {
03850
03851 m_FeatherSize = 0;
03852
03853
03854
03855
03856 }
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872 NodeFeatherEffect::NodeFeatherEffect() : NodeLiveEffect()
03873 {
03874
03875 m_FeatherSize = 0;
03876
03877
03878
03879
03880 }
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896 NodeFeatherEffect::~NodeFeatherEffect()
03897 {
03898 CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
03899 if (pBitmapCache!=NULL)
03900 {
03901 CBitmapCacheKey inky(this, 42);
03902 pBitmapCache->RemoveAllOwnedBitmaps(inky, FALSE, CACHEPRIORITY_PERMANENT);
03903 }
03904 }
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929 String NodeFeatherEffect::Describe(BOOL Plural, BOOL Verbose)
03930 {
03931 if (Plural)
03932 return(String(_R(IDS_FEATHEREFFECT_DESCRP)));
03933 else
03934 return(String(_R(IDS_FEATHEREFFECT_DESCRS)));
03935 };
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957 Node* NodeFeatherEffect::SimpleCopy()
03958 {
03959 NodeFeatherEffect* NodeCopy;
03960 NodeCopy = new NodeFeatherEffect();
03961 ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL);
03962 CopyNodeContents(NodeCopy);
03963 return (NodeCopy);
03964 }
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985 void NodeFeatherEffect::CopyNodeContents(NodeFeatherEffect* pCopyOfNode)
03986 {
03987 NodeLiveEffect::CopyNodeContents(pCopyOfNode);
03988
03989
03990 pCopyOfNode->m_FeatherSize = m_FeatherSize;
03991 pCopyOfNode->m_Profile = m_Profile;
03992 }
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009 void NodeFeatherEffect::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
04010 {
04011 ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
04012 ENSURE(IS_A(pNodeCopy, NodeFeatherEffect), "PolyCopyNodeContents given wrong dest node type");
04013
04014 if (IS_A(pNodeCopy, NodeFeatherEffect))
04015 CopyNodeContents((NodeFeatherEffect*)pNodeCopy);
04016 }
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035
04036 UINT32 NodeFeatherEffect::GetNodeSize() const
04037 {
04038 return sizeof(NodeFeatherEffect);
04039 }
04040
04041
04042
04043
04044
04045
04046
04047
04048
04049
04050
04051
04052
04053
04054
04055
04056
04057 BOOL NodeFeatherEffect::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
04058 {
04059 #ifdef DO_EXPORT
04060
04061 BOOL ok = TRUE;
04062
04063 ok = WriteFeatherEffect(pFilter);
04064
04065 return ok;
04066
04067 #else
04068 return FALSE;
04069 #endif
04070 }
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085 BOOL NodeFeatherEffect::WritePreChildrenNative(BaseCamelotFilter* pFilter)
04086 {
04087 #ifdef DO_EXPORT
04088
04089 BOOL ok = TRUE;
04090
04091 ok = WriteFeatherEffect(pFilter);
04092
04093 return ok;
04094
04095 #else
04096 return FALSE;
04097 #endif
04098 }
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110
04111
04112
04113
04114
04115
04116 BOOL NodeFeatherEffect::WriteFeatherEffect(BaseCamelotFilter* pFilter)
04117 {
04118 #ifdef DO_EXPORT
04119 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
04120
04121 BOOL ok = TRUE;
04122 BYTE Flags = 0;
04123
04124 UINT32 Tag = TAG_FEATHER_EFFECT;
04125
04126 CXaraFileRecord Rec(Tag);
04127
04128 if (ok) ok = Rec.Init();
04129 if (ok) ok = Rec.WriteBYTE(Flags);
04130 if (ok) ok = Rec.WriteDOUBLE(m_dPixelsPerInch);
04131 if (ok) ok = Rec.WriteUnicode(m_strPostProID);
04132 if (ok) ok = Rec.WriteUnicode(m_strDisplayName);
04133 if (ok) ok = Rec.WriteINT32(m_FeatherSize);
04134 if (ok) ok = Rec.WriteDOUBLE((double)m_Profile.GetBias());
04135 if (ok) ok = Rec.WriteDOUBLE((double)m_Profile.GetGain());
04136
04137
04138 if (ok) ok = pFilter->Write(&Rec);
04139
04140 return ok;
04141 #else
04142 return FALSE;
04143 #endif
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 BOOL NodeFeatherEffect::ProcessBitmap(RenderRegion* pRender,
04169 CBitmapCache* pBitmapCache,
04170 LPBITMAPINFO pBMPInfo,
04171 LPBYTE pBMPBits,
04172 DocRect BMPRect,
04173 LPBITMAPINFO& pOutputInfo,
04174 LPBYTE& pOutputBits,
04175 double* pXOffset,
04176 double* pYOffset)
04177 {
04178 pOutputInfo = NULL;
04179 pOutputBits = NULL;
04180 *pXOffset = 0;
04181 *pYOffset = 0;
04182
04184
04186
04187
04188
04189
04190
04191 double dPixBlurDiameter = (double)m_FeatherSize/GetPixelWidth();
04192 double dRemainingContour = dPixBlurDiameter/2;
04193 double dContourStep = 20;
04194
04195 if (dPixBlurDiameter<1)
04196 return TRUE;
04197
04198
04199 ProcessBitmapState bmpstate(pBMPInfo, pBMPBits, 0, 0, FALSE);
04200
04201
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211 bmpstate = bmpstate.Create8BPPMask();
04212
04213
04214
04215 while (dRemainingContour>0)
04216 {
04217 if (dContourStep>dRemainingContour) dContourStep = dRemainingContour;
04218 bmpstate = bmpstate.Contour8BPP(-dContourStep);
04219
04220 dRemainingContour -= dContourStep;
04221 }
04222
04223 UINT32 uBlurDiameter = UINT32(dPixBlurDiameter+0.5)-1 ;
04224 bmpstate = bmpstate.Expand8BPP(uBlurDiameter, 0xFF);
04225
04226 bmpstate = bmpstate.Blur8BPP(dPixBlurDiameter);
04227
04228
04229
04230
04231 if (bmpstate.IsOK())
04232 {
04233 bmpstate.GetPixelOffsets(pXOffset, pYOffset);
04234 bmpstate.GetBitmap(pOutputInfo, pOutputBits);
04235 }
04236 else
04237 bmpstate.DeInit();
04238
04239 return bmpstate.IsOK();
04240 }
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259 BOOL NodeFeatherEffect::FindCachedEffect(CBitmapCache* pBitmapCache)
04260 {
04261 BOOL bFoundCached = FALSE;
04262 CCachedBitmap cbmp;
04263
04264
04265 CBitmapCacheKey inky(this, GetPixelWidth(), 0);
04266 bFoundCached = pBitmapCache->Lookup(inky, cbmp);
04267
04268
04269 CBitmapCacheKey inky2(this, GetPixelWidth(), 1);
04270 bFoundCached = bFoundCached & pBitmapCache->Lookup(inky2, cbmp);
04271
04272 return bFoundCached;
04273 }
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291 BOOL NodeFeatherEffect::RenderCachedEffect(CBitmapCache* pBitmapCache, RenderRegion* pRender, BOOL bIgnoreCapture)
04292 {
04293 BOOL bRendered = FALSE;
04294 BOOL bFoundCached = FALSE;
04295
04296
04297 CBitmapCacheKey inky(this, GetPixelWidth(), 0);
04298 CCachedBitmap cbmp;
04299 bFoundCached = pBitmapCache->Lookup(inky, cbmp);
04300
04301
04302
04303
04304 CBitmapCacheKey inky2(this, GetPixelWidth(), 1);
04305 CCachedBitmap cbmpFeather;
04306 bFoundCached = bFoundCached & pBitmapCache->Lookup(inky2, cbmpFeather);
04307
04308 if (bFoundCached)
04309 {
04310
04311 Capture* pCapture = pRender->GetTopCapture();
04312 if (!bIgnoreCapture && pCapture && pCapture->ConsumeDirectBitmap(this))
04313 {
04314
04315 bRendered = TRUE;
04316 }
04317 else
04318 {
04319 pRender->SaveContext();
04320
04321
04322
04323
04324
04325 CWxBitmap* wFeatherBitmap = new CWxBitmap(cbmpFeather.pbmpInfo, cbmpFeather.pbmpBits);
04326 KernelBitmap* kFeatherBitmap = new KernelBitmap(wFeatherBitmap,TRUE);
04327 if (kFeatherBitmap->GetBPP()==8)
04328 {
04329 LPRGBQUAD pPalette = kFeatherBitmap->GetPaletteForBitmap();
04330 for ( INT32 i=0 ; i<0x100 ; i++ )
04331 (UINT32&)pPalette[i] = i*0x010101 ;
04332
04333 kFeatherBitmap->SetAsGreyscale();
04334 }
04335
04336 BitmapTranspFillAttribute* pBmpTranspFill = new BitmapTranspFillAttribute;
04337 TranspFillMappingLinearAttribute* pNoRepeatAttr = new TranspFillMappingLinearAttribute;
04338 if (kFeatherBitmap != NULL)
04339 {
04340 pNoRepeatAttr->Repeat = 0;
04341 pRender->SetTranspFillMapping(pNoRepeatAttr, TRUE);
04342
04343 CreateBitmapTranspFill(kFeatherBitmap, &cbmpFeather.coord0, pBmpTranspFill);
04344 pRender->SetTranspFillGeometry(pBmpTranspFill, TRUE);
04345 }
04346
04347
04348
04349
04350 if (!this->HasEffectAttrs())
04351
04352 bRendered = pRender->RenderBits(cbmp.pbmpInfo, cbmp.pbmpBits, &cbmp.coord0, 3, FALSE, NULL);
04353 else
04354 {
04355
04356 pRender->SaveContext();
04357
04358 LPBITMAPINFO lpCapturedInfo = NULL;
04359 LPBYTE lpCapturedBits = NULL;
04360 CaptureFlags caFlags = CaptureFlags(cfLOCKEDTRANSPARENT | cfUNCLIP | cfPIXWIDTHSCALE);
04361 DocRect CaptureRect = GetBoundingRect();
04362 pRender->StartCapture(this, CaptureRect, CAPTUREINFO(ctNESTABLE, caFlags), TRUE, FALSE, 0);
04363 bRendered = pRender->RenderBits(cbmp.pbmpInfo, cbmp.pbmpBits, &cbmp.coord0, 3, FALSE, NULL);
04364 pRender->StopCapture(this, FALSE, FALSE, &lpCapturedInfo, &lpCapturedBits, &CaptureRect);
04365
04366 pRender->RestoreContext();
04367
04368 if (bRendered && lpCapturedInfo && lpCapturedBits)
04369 {
04370
04371 bRendered = pRender->RenderBits(lpCapturedInfo, lpCapturedBits, CaptureRect, FALSE, this);
04372 FreeDIB(lpCapturedInfo, lpCapturedBits);
04373 }
04374 }
04375
04376 if (wFeatherBitmap)
04377 wFeatherBitmap->BMBytes = ((CWxBitmap*)OILBitmap::Default)->BMBytes;
04378 if (kFeatherBitmap)
04379 delete kFeatherBitmap;
04380
04381 pRender->RestoreContext();
04382 }
04383 }
04384
04385 return bRendered;
04386 }
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403 BOOL NodeFeatherEffect::CreateBitmapTranspFill(KernelBitmap* pFeather, DocCoord* pCoords, BitmapTranspFillAttribute* BmpTranspFill)
04404 {
04405
04406 BmpTranspFill->StartPoint = pCoords[0];
04407 BmpTranspFill->EndPoint = pCoords[1];
04408 BmpTranspFill->EndPoint2 = pCoords[2];
04409 BmpTranspFill->EndPoint3 = DocCoord(pCoords[1].x, pCoords[2].y);
04410 BmpTranspFill->GetBitmapRef()->SetBitmap(pFeather);
04411 BmpTranspFill->Transp = 0;
04412 BmpTranspFill->EndTransp = 255;
04413 m_Profile.SetIsAFeatherProfile(TRUE);
04414 BmpTranspFill->SetProfile(m_Profile);
04415
04416 return TRUE;
04417 }
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436 BOOL NodeFeatherEffect::ProcessBitmap(LPBITMAPINFO pBMPInfo,
04437 LPBYTE pBMPBits,
04438 double dPixBlurDiameter,
04439 CProfileBiasGain profileFeather)
04440 {
04441 LPBITMAPINFO pOutputInfo = NULL;
04442 LPBYTE pOutputBits = NULL;
04443
04444
04445
04447
04449
04450
04451
04452
04453
04454 dPixBlurDiameter = floor(dPixBlurDiameter+0.5);
04455 double dRemainingContour = dPixBlurDiameter/2;
04456 double dContourStep = 20;
04457
04458 if (dPixBlurDiameter<1)
04459 return TRUE;
04460
04461
04462 ProcessBitmapState bmpstate(pBMPInfo, pBMPBits, 0, 0, FALSE);
04463
04464
04465
04466
04467
04468
04469
04470
04471
04472
04473
04474 bmpstate = bmpstate.Create8BPPMask();
04475
04476
04477
04478 while (dRemainingContour>0)
04479 {
04480 if (dContourStep>dRemainingContour) dContourStep = dRemainingContour;
04481 bmpstate = bmpstate.Contour8BPP(-dContourStep);
04482
04483 dRemainingContour -= dContourStep;
04484 }
04485
04486 UINT32 uBlurDiameter = UINT32(dPixBlurDiameter+0.5)-1 ;
04487 bmpstate = bmpstate.Expand8BPP(uBlurDiameter, 0xFF);
04488
04489 bmpstate = bmpstate.Blur8BPP(dPixBlurDiameter);
04490
04491 bmpstate = bmpstate.AddMaskTo(pBMPInfo, pBMPBits);
04492
04493
04494
04495
04496 if (bmpstate.IsOK())
04497 {
04498
04499 bmpstate.GetBitmap(pOutputInfo, pOutputBits);
04500 }
04501 else
04502 bmpstate.DeInit();
04503
04504 return bmpstate.IsOK();
04505 }
04506
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665
04666
04667
04668
04669
04670 BOOL NodeFeatherEffect::CompareState(NodeEffect* pPPNode)
04671 {
04672 if (!pPPNode->IsFeatherEffect())
04673 return FALSE;
04674
04675 NodeFeatherEffect* pTest = (NodeFeatherEffect*)pPPNode;
04676
04677 BOOL bSame = m_FeatherSize == pTest->m_FeatherSize;
04678 bSame = bSame && m_Profile == pTest->m_Profile;
04679
04680 return bSame;
04681 }
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696 BOOL NodeFeatherEffect::GetQuickRender()
04697 {
04698 if (Operation::GetQuickRender(this)==FALSE)
04699 return FALSE;
04700
04701
04702
04703
04704 PORTNOTE("effects", "NodeFeatherEffect::GetQuickRender - removed OpChangeFeatherSize usage.");
04705 #if defined(EXCLUDE_FROM_XARALX)
04706 return FALSE;
04707 #else
04708 Operation* pOp = Operation::GetCurrentDragOp();
04709 return (pOp!=NULL && !pOp->IsKindOf(CC_RUNTIME_CLASS(OpChangeFeatherSize)));
04710 #endif
04711 }
04712 #endif
04713
04714
04715
04716
04717
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736 UINT32* LiveEffectRecordHandler::GetTagList()
04737 {
04738 static UINT32 TagList[] = { TAG_LIVE_EFFECT,
04739 TAG_LOCKED_EFFECT,
04740 TAG_FEATHER_EFFECT,
04741
04742 CXFRH_TAG_LIST_END};
04743
04744 return (UINT32*)&TagList;
04745 }
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762
04763 BOOL LiveEffectRecordHandler::IsStreamed(UINT32 Tag)
04764 {
04765
04766 BOOL Streamed = FALSE;
04767 switch (Tag)
04768 {
04769 case TAG_LIVE_EFFECT:
04770 case TAG_LOCKED_EFFECT:
04771 case TAG_FEATHER_EFFECT:
04772 Streamed = FALSE;
04773
04774 break;
04775 default:
04776 Streamed = FALSE;
04777 ERROR3_PF(("LiveEffectRecordHandler::IsStreamed I don't handle records with the tag (%d)\n", Tag));
04778 break;
04779 }
04780
04781 return Streamed;
04782 }
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797
04798 BOOL LiveEffectRecordHandler::HandleRecord(CXaraFileRecord* pCXaraFileRecord)
04799 {
04800 ERROR2IF(pCXaraFileRecord == NULL,FALSE,"LiveEffectRecordHandler::HandleRecord pCXaraFileRecord is NULL");
04801
04802 BOOL ok = TRUE;
04803 INT32 tag = pCXaraFileRecord->GetTag();
04804 switch (tag)
04805 {
04806 case TAG_LIVE_EFFECT:
04807 {
04808
04809
04810 BYTE Flags;
04811 if (ok) ok = pCXaraFileRecord->ReadBYTE(&Flags);
04812
04813
04814 double dPixelsPerInch;
04815 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dPixelsPerInch);
04816
04817
04818 String_256 strPostProID;
04819 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strPostProID);
04820
04821
04822 String_256 strDisplayName;
04823 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strDisplayName);
04824
04825
04826
04827
04828 StringVar strXML;
04829 if (ok) ok = pCXaraFileRecord->ReadUTF16STR(&strXML, pCXaraFileRecord->GetSize());
04830
04831
04832 if (ok)
04833 {
04834 NodeLiveEffect* pLE = new NodeLiveEffect();
04835
04836 pLE->m_dPixelsPerInch = dPixelsPerInch;
04837
04838 pLE->m_strPostProID = strPostProID;
04839
04840 pLE->m_strDisplayName = strDisplayName;
04841
04842 PORTNOTETRACE("other","LiveEffectRecordHandler::HandleRecord - removed use of XML");
04843 #ifndef EXCLUDE_FROM_XARALX
04844 VARIANT_BOOL varResult;
04845 IXMLDOMDocumentPtr pxmlDoc = CXMLUtils::NewDocument();
04846 HRESULT hr = pxmlDoc->loadXML(bstrXML, &varResult);
04847 ok = (SUCCEEDED(hr) && VARIANT_TRUE == varResult);
04848 if (ok) pLE->m_pEditsDoc = pxmlDoc;
04849 #else
04850 pLE->m_pEditsDoc = NULL;
04851 pLE->m_vstrEdits = strXML;
04852 #endif
04853
04854 if (ok) ok = InsertNode(pLE);
04855 }
04856 return ok;
04857 }
04858 break;
04859
04860 case TAG_LOCKED_EFFECT:
04861 {
04862
04863
04864 BYTE Flags;
04865 if (ok) ok = pCXaraFileRecord->ReadBYTE(&Flags);
04866
04867
04868 double dPixelsPerInch;
04869 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dPixelsPerInch);
04870
04871
04872 INT32 BitmapRef;
04873 if (ok) ok = pCXaraFileRecord->ReadINT32(&BitmapRef);
04874
04875
04876 DocCoord tc[3];
04877 if (ok) ok = pCXaraFileRecord->ReadCoordTrans(&tc[0], 0, 0);
04878 if (ok) ok = pCXaraFileRecord->ReadCoordTrans(&tc[1], 0, 0);
04879 if (ok) ok = pCXaraFileRecord->ReadCoordTrans(&tc[2], 0, 0);
04880
04881
04882 String_256 strPostProID;
04883 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strPostProID);
04884
04885
04886 String_256 strDisplayName;
04887 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strDisplayName);
04888
04889
04890
04891
04892 StringVar strXML;
04893 if (ok) ok = pCXaraFileRecord->ReadUTF16STR(&strXML, pCXaraFileRecord->GetSize());
04894
04895
04896 if (ok)
04897 {
04898 NodeLockedEffect* pLE = new NodeLockedEffect();
04899
04900 pLE->m_bIsDestructive = !((Flags & 0x02) == 0x02);
04901
04902 pLE->m_dPixelsPerInch = dPixelsPerInch;
04903 pLE->m_strPostProID = strPostProID;
04904 pLE->m_strDisplayName = strDisplayName;
04905 pLE->m_PGram[0] = tc[0];
04906 pLE->m_PGram[1] = tc[1];
04907 pLE->m_PGram[2] = tc[2];
04908
04909 PORTNOTETRACE("other","LiveEffectRecordHandler::HandleRecord - removed use of XML");
04910 #ifndef EXCLUDE_FROM_XARALX
04911 VARIANT_BOOL varResult;
04912 IXMLDOMDocumentPtr pxmlDoc = CXMLUtils::NewDocument();
04913 HRESULT hr = pxmlDoc->loadXML(bstrXML, &varResult);
04914 ok = (SUCCEEDED(hr) && VARIANT_TRUE == varResult);
04915 if (ok) pLE->m_pEditsDoc = pxmlDoc;
04916 #else
04917 pLE->m_pEditsDoc = NULL;
04918 pLE->m_vstrEdits = strXML;
04919 #endif
04920
04921
04922 if (ok)
04923 {
04924 KernelBitmap* pBitmap = NULL;
04925 pBitmap = GetReadBitmapReference(BitmapRef);
04926 pBitmap->GetActualBitmap()->SetHidden(TRUE);
04927 ok = (pBitmap != NULL);
04928 if (ok) pLE->m_BitmapRef.Attach(pBitmap);
04929 }
04930
04931 if (ok) ok = InsertNode(pLE);
04932 }
04933
04934 return ok;
04935 }
04936 break;
04937
04938 #ifdef FEATHER_EFFECT
04939 case TAG_FEATHER_EFFECT:
04940 {
04941
04942
04943 BYTE Flags;
04944 if (ok) ok = pCXaraFileRecord->ReadBYTE(&Flags);
04945
04946
04947 double dPixelsPerInch;
04948 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dPixelsPerInch);
04949
04950
04951 String_256 strPostProID;
04952 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strPostProID);
04953
04954
04955 String_256 strDisplayName;
04956 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strDisplayName);
04957
04958
04959 MILLIPOINT mpFeatherSize = 0;
04960 double dBias = 0;
04961 double dGain = 0;
04962 if (ok) ok = pCXaraFileRecord->ReadINT32(&mpFeatherSize);
04963 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dBias);
04964 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dGain);
04965
04966
04967 if (ok)
04968 {
04969 NodeFeatherEffect* pFE = new NodeFeatherEffect();
04970
04971 pFE->m_dPixelsPerInch = dPixelsPerInch;
04972
04973 pFE->m_strPostProID = strPostProID;
04974
04975 pFE->m_strDisplayName = strDisplayName;
04976
04977 pFE->SetFeatherSize(mpFeatherSize);
04978
04979 CProfileBiasGain Profile((AFp)dBias, (AFp)dGain);
04980 pFE->SetProfile(Profile);
04981
04982 if (ok) ok = InsertNode(pFE);
04983 }
04984
04985 return ok;
04986 }
04987 break;
04988 #endif
04989
04990 default:
04991 ERROR3_PF(("I don't handle records with the tag (%d)\n", pCXaraFileRecord->GetTag()));
04992 break;
04993 }
04994
04995 return FALSE;
04996 }
04997
04998
04999
05000
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020 BOOL LiveEffectRecordHandler::HandleStreamedRecord(CXaraFile * pCXFile, UINT32 Tag,UINT32 Size,UINT32 RecordNumber)
05021 {
05022 ERROR2IF(pCXFile == NULL,FALSE,"BitmapRecordHandler::HandleStreamedRecord pCXFile is NULL");
05023
05024 ERROR3_PF(("Unimplemented!", Tag));
05025
05026 return TRUE;
05027 }
05028
05029
05030
05031
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042
05043
05044
05045
05046
05047 #ifdef XAR_TREE_DIALOG
05048 void LiveEffectRecordHandler::GetRecordDescriptionText(CXaraFileRecord* pCXaraFileRecord, StringBase* pStr)
05049 {
05050 if (pStr == NULL || pCXaraFileRecord == NULL)
05051 return;
05052
05053 TCHAR s[256];
05054 BOOL ok = TRUE;
05055
05056
05057 CamelotRecordHandler::GetRecordDescriptionText(pCXaraFileRecord, pStr);
05058
05059 switch (pCXaraFileRecord->GetTag())
05060 {
05061 case TAG_LIVE_EFFECT:
05062 {
05063
05064
05065 BYTE Flags;
05066 if (ok) ok = pCXaraFileRecord->ReadBYTE(&Flags);
05067
05068
05069 double dPixelsPerInch;
05070 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dPixelsPerInch);
05071
05072
05073 String_256 strPostProID;
05074 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strPostProID);
05075
05076
05077 String_256 strDisplayName;
05078 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strDisplayName);
05079
05080
05081
05082
05083 StringVar strXML;
05084 if (ok) ok = pCXaraFileRecord->ReadUTF16STR(&strXML, pCXaraFileRecord->GetSize());
05085
05086
05087 camSprintf(s,_T("Flags\t\t= %d\r\n"), (INT32)Flags);
05088 (*pStr) += s;
05089 }
05090 break;
05091
05092 case TAG_LOCKED_EFFECT:
05093 {
05094
05095
05096 BYTE Flags;
05097 if (ok) ok = pCXaraFileRecord->ReadBYTE(&Flags);
05098
05099
05100 double dPixelsPerInch;
05101 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dPixelsPerInch);
05102
05103
05104 INT32 BitmapRef;
05105 if (ok) ok = pCXaraFileRecord->ReadINT32(&BitmapRef);
05106
05107
05108 DocCoord tc[3];
05109 if (ok) ok = pCXaraFileRecord->ReadCoordTrans(&tc[0], 0, 0);
05110 if (ok) ok = pCXaraFileRecord->ReadCoordTrans(&tc[1], 0, 0);
05111 if (ok) ok = pCXaraFileRecord->ReadCoordTrans(&tc[2], 0, 0);
05112
05113
05114 String_256 strPostProID;
05115 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strPostProID);
05116
05117
05118 String_256 strDisplayName;
05119 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strDisplayName);
05120
05121
05122
05123
05124 StringVar strXML;
05125 if (ok) ok = pCXaraFileRecord->ReadUTF16STR(&strXML, pCXaraFileRecord->GetSize());
05126
05127
05128 camSprintf(s,_T("Flags\t\t= %d\r\n"), (INT32)Flags);
05129 (*pStr) += s;
05130 }
05131 break;
05132
05133 #ifdef FEATHER_EFFECT
05134 case TAG_FEATHER_EFFECT:
05135 {
05136
05137
05138 BYTE Flags;
05139 if (ok) ok = pCXaraFileRecord->ReadBYTE(&Flags);
05140
05141
05142 double dPixelsPerInch;
05143 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dPixelsPerInch);
05144
05145
05146 String_256 strPostProID;
05147 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strPostProID);
05148
05149
05150 String_256 strDisplayName;
05151 if (ok) ok = pCXaraFileRecord->ReadUnicode(&strDisplayName);
05152
05153
05154 MILLIPOINT mpFeatherSize = 0;
05155 double dBias = 0;
05156 double dGain = 0;
05157 if (ok) ok = pCXaraFileRecord->ReadINT32(&mpFeatherSize);
05158 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dBias);
05159 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&dGain);
05160
05161
05162 camSprintf(s,_T("Flags\t\t= %d\r\n"), (INT32)Flags);
05163 (*pStr) += s;
05164 }
05165 break;
05166 #endif
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184 }
05185 }
05186 #endif
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213 #ifdef FEATHER_EFFECT
05214 ProcessBitmapState::ProcessBitmapState(LPBITMAPINFO lpInitialInfo,
05215 LPBYTE lpInitialBits,
05216 double InitialXOffset,
05217 double InitialYOffset,
05218 BOOL bInitialTempState)
05219 {
05220 m_lpInfo = lpInitialInfo;
05221 m_lpBits = lpInitialBits;
05222 m_XOffset = InitialXOffset;
05223 m_YOffset = InitialYOffset;
05224 m_XPelsPerMeter = 0;
05225 m_YPelsPerMeter = 0;
05226 m_bTemp = bInitialTempState;
05227 m_bOK = TRUE;
05228 }
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244
05245
05246 ProcessBitmapState::ProcessBitmapState(const ProcessBitmapState& copystate)
05247 {
05248 m_lpInfo = copystate.m_lpInfo;
05249 m_lpBits = copystate.m_lpBits;
05250 m_XOffset = copystate.m_XOffset;
05251 m_YOffset = copystate.m_YOffset;
05252 m_XPelsPerMeter = copystate.m_XPelsPerMeter;
05253 m_YPelsPerMeter = copystate.m_YPelsPerMeter;
05254 m_bTemp = copystate.m_bTemp;
05255 m_bOK = copystate.m_bOK;
05256 }
05257
05258
05259
05260
05261
05262
05263
05264
05265
05266
05267
05268
05269
05270
05271
05272
05273
05274
05275 void ProcessBitmapState::InitPipelineSettings(ProcessBitmapState* const prevstate)
05276 {
05277 m_XOffset = prevstate->m_XOffset;
05278 m_YOffset = prevstate->m_YOffset;
05279
05280 if (m_lpInfo)
05281 {
05282 m_lpInfo->bmiHeader.biXPelsPerMeter = prevstate->GetXPelsPerMeter();
05283 m_lpInfo->bmiHeader.biYPelsPerMeter = prevstate->GetYPelsPerMeter();
05284 }
05285 else
05286 {
05287 m_XPelsPerMeter = prevstate->GetXPelsPerMeter();
05288 m_YPelsPerMeter = prevstate->GetYPelsPerMeter();
05289 }
05290 }
05291
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309 void ProcessBitmapState::DeInit()
05310 {
05311 if (m_lpInfo && m_lpBits && m_bTemp)
05312 {
05313 ::FreeDIB(m_lpInfo, m_lpBits);
05314 m_lpInfo = NULL;
05315 m_lpBits = NULL;
05316 }
05317 }
05318
05319
05320
05321
05322
05323
05324
05325
05326
05327
05328
05329
05330
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340 ProcessBitmapState& ProcessBitmapState::operator=(const ProcessBitmapState& rhsstate)
05341 {
05342 if (m_lpInfo && m_lpBits && m_bTemp && m_lpInfo!=rhsstate.m_lpInfo && m_lpBits!=rhsstate.m_lpBits)
05343 {
05344 ::FreeDIB(m_lpInfo, m_lpBits);
05345 m_lpInfo = NULL;
05346 m_lpBits = NULL;
05347 }
05348
05349 m_lpInfo = rhsstate.m_lpInfo;
05350 m_lpBits = rhsstate.m_lpBits;
05351 m_XOffset = rhsstate.m_XOffset;
05352 m_YOffset = rhsstate.m_YOffset;
05353 m_bTemp = rhsstate.m_bTemp;
05354 m_bOK = rhsstate.m_bOK;
05355
05356 if (m_lpInfo)
05357 {
05358 m_lpInfo->bmiHeader.biXPelsPerMeter = rhsstate.GetXPelsPerMeter();
05359 m_lpInfo->bmiHeader.biYPelsPerMeter = rhsstate.GetYPelsPerMeter();
05360 m_XPelsPerMeter = 0;
05361 m_YPelsPerMeter = 0;
05362 }
05363 else
05364 {
05365 m_XPelsPerMeter = rhsstate.GetXPelsPerMeter();
05366 m_YPelsPerMeter = rhsstate.GetYPelsPerMeter();
05367 }
05368
05369 return *this;
05370 }
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392 void ProcessBitmapState::GetBitmap(LPBITMAPINFO& pOutputInfo, LPBYTE& pOutputBits, BOOL bTemp)
05393 {
05394 if (m_lpInfo && m_XPelsPerMeter!=0 && m_YPelsPerMeter!=0)
05395 {
05396 m_lpInfo->bmiHeader.biXPelsPerMeter = m_XPelsPerMeter;
05397 m_lpInfo->bmiHeader.biYPelsPerMeter = m_YPelsPerMeter;
05398 m_XPelsPerMeter = 0;
05399 m_YPelsPerMeter = 0;
05400 }
05401
05402 pOutputInfo = m_lpInfo;
05403 pOutputBits = m_lpBits;
05404 m_bTemp = bTemp;
05405 }
05406
05407
05408
05409
05410
05411
05412
05413
05414
05415
05416
05417
05418
05419
05420
05421
05422
05423
05424
05425
05426
05427 BOOL ProcessBitmapState::AllocDIB(UINT32 Width, UINT32 Height, UINT32 Depth)
05428 {
05429 m_bOK = FALSE;
05430 m_lpInfo = ::AllocDIB(Width, Height, Depth, &m_lpBits);
05431 if (m_lpInfo)
05432 {
05433 m_bOK = TRUE;
05434 if (m_XPelsPerMeter!=0 && m_YPelsPerMeter!=0)
05435 {
05436 m_lpInfo->bmiHeader.biXPelsPerMeter = m_XPelsPerMeter;
05437 m_lpInfo->bmiHeader.biYPelsPerMeter = m_YPelsPerMeter;
05438 m_XPelsPerMeter = 0;
05439 m_YPelsPerMeter = 0;
05440 }
05441 }
05442
05443 return m_bOK;
05444 }
05445
05446
05447
05448
05449
05450
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464 ProcessBitmapState ProcessBitmapState::Create8BPPMask()
05465 {
05466
05467 ProcessBitmapState mask;
05468 mask.InitPipelineSettings(this);
05469
05470
05471 if (!m_bOK)
05472 return mask;
05473
05474
05475
05476
05477
05478 mask.AllocDIB(GetWidth(), GetHeight(), 8);
05479 if (!mask.IsOK())
05480 return mask;
05481
05482 if (GetDepth()==32)
05483 {
05484 UINT32 uWidth = mask.GetWidth();
05485 UINT32 uHeight = mask.GetHeight();
05486 UINT32 uByteWidth8 = DIBUtil::ScanlineSize(uWidth, 8);
05487 UINT32 uByteWidth32 = DIBUtil::ScanlineSize(GetWidth(), GetDepth())/sizeof(UINT32);
05488
05489 LPBYTE pDst = mask.m_lpBits;
05490 UINT32* pSrc = (UINT32*)m_lpBits;
05491 UINT32 i;
05492 UINT32 j;
05493 for ( j=0 ; j<uHeight ; j++ )
05494 {
05495 for ( i=0 ; i<uWidth ; i++ )
05496 {
05497
05498
05499
05500
05501
05502 pDst[i] = (pSrc[i]&0xFF000000) >> 24;
05503 }
05504 pDst += uByteWidth8;
05505 pSrc += uByteWidth32;
05506 }
05507 }
05508 else
05509 {
05510
05511
05512
05513 UINT32 uWidth = mask.GetWidth();
05514 UINT32 uHeight = mask.GetHeight();
05515 UINT32 uByteWidth8 = DIBUtil::ScanlineSize(uWidth, 8);
05516
05517 LPBYTE pDst = mask.m_lpBits;
05518 UINT32 i;
05519 UINT32 j;
05520 for ( j=0 ; j<uHeight ; j++ )
05521 {
05522 for ( i=0 ; i<uWidth ; i++ )
05523 {
05524 pDst[i] = 0;
05525 }
05526 pDst += uByteWidth8;
05527 }
05528 }
05529
05530 return mask;
05531 }
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548
05549
05550
05551 ProcessBitmapState ProcessBitmapState::AddMaskTo(LPBITMAPINFO lpDeepInfo, LPBYTE lpDeepBits)
05552 {
05553
05554 ProcessBitmapState deep;
05555 deep.InitPipelineSettings(this);
05556
05557
05558 if (!m_bOK)
05559 return deep;
05560
05561 ERROR3IF(GetDepth()!=8, "Error");
05562 ERROR3IF(lpDeepInfo->bmiHeader.biBitCount != 32, "Error");
05563 ERROR3IF(lpDeepInfo->bmiHeader.biWidth != (INT32)GetWidth(), "Error");
05564 ERROR3IF(lpDeepInfo->bmiHeader.biHeight != (INT32)GetHeight(), "Error");
05565 if (GetDepth()!=8) return deep;
05566 if (lpDeepInfo->bmiHeader.biBitCount != 32) return deep;
05567 if (lpDeepInfo->bmiHeader.biWidth != (INT32)GetWidth()) return deep;
05568 if (lpDeepInfo->bmiHeader.biHeight != (INT32)GetHeight()) return deep;
05569
05570 deep.m_lpInfo = lpDeepInfo;
05571 deep.m_lpBits = lpDeepBits;
05572 if (!deep.IsOK())
05573 return deep;
05574
05575 UINT32 uWidth = GetWidth();
05576 UINT32 uHeight = GetHeight();
05577 UINT32 uByteWidth8 = DIBUtil::ScanlineSize(uWidth, 8);
05578 UINT32 uByteWidth32 = DIBUtil::ScanlineSize(deep.GetWidth(), deep.GetDepth())/sizeof(UINT32);
05579
05580 UINT32* pDst = (UINT32*)lpDeepBits;
05581 LPBYTE pSrc = m_lpBits;
05582 UINT32 i;
05583 UINT32 j;
05584 for ( j=0 ; j<uHeight ; j++ )
05585 {
05586 for ( i=0 ; i<uWidth ; i++ )
05587 {
05588 pDst[i] = (pDst[i]&0xFF000000) | pSrc[i] << 24;
05589 }
05590 pDst += uByteWidth32;
05591 pSrc += uByteWidth8;
05592 }
05593
05594 return deep;
05595 }
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607
05608
05609
05610
05611
05612
05613
05614
05615 ProcessBitmapState ProcessBitmapState::Contour8BPP(double dContourWidth)
05616 {
05617
05618 double OffsetX = 0;
05619 double OffsetY = 0;
05620 ProcessBitmapState contour;
05621 contour.InitPipelineSettings(this);
05622
05623
05624 if (!m_bOK)
05625 return contour;
05626
05627 ERROR3IF(GetDepth()!=8, "Contour8BPP only copes with 8BPP inputs at the moment");
05628 ERROR3IF(dContourWidth>=0, "Contour8BPP only copes with inner contours at the moment");
05629
05630
05631 contour.m_bOK = CBitmapShadow::ContourBitmap(m_lpInfo,
05632 m_lpBits,
05633 fabs(dContourWidth),
05634 (dContourWidth<0),
05635 0xFE,
05636 &contour.m_lpInfo,
05637 &contour.m_lpBits,
05638 &OffsetX,
05639 &OffsetY
05640 );
05641 ERROR3IF(!contour.IsOK(), "ContourBitmap failed in RenderShadowedNodeOffscreen");
05642 if (!contour.IsOK())
05643 return contour;
05644
05645
05646
05647 if (contour.m_lpInfo==NULL)
05648 return *this;
05649
05650 contour.m_XOffset += OffsetX;
05651 contour.m_YOffset += OffsetY;
05652
05653 return contour;
05654 }
05655
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674 ProcessBitmapState ProcessBitmapState::Blur8BPP(double dBlurWidth)
05675 {
05676
05677 ProcessBitmapState blur;
05678 blur.InitPipelineSettings(this);
05679
05680
05681 if (!m_bOK)
05682 return blur;
05683
05684 ERROR3IF(GetDepth()!=8, "Blur8BPP only copes with 8BPP inputs at the moment");
05685
05686
05687 UINT32 DWordWidth = DIBUtil::ScanlineSize(GetWidth(), GetDepth());
05688
05689 UINT32 uBlurDiameter = UINT32(dBlurWidth+0.5)-1 ;
05690 blur.AllocDIB(GetWidth()-uBlurDiameter, GetHeight()-uBlurDiameter, 8);
05691 if (!blur.IsOK())
05692 return blur;
05693
05694 CBitmapShadow::Blur8BppBitmap(&m_lpInfo->bmiHeader, m_lpBits, &blur.m_lpInfo->bmiHeader, blur.m_lpBits, DWordWidth, dBlurWidth/2);
05695
05696
05697
05698 blur.m_XOffset += dBlurWidth/2;
05699 blur.m_YOffset += dBlurWidth/2;
05700
05701 return blur;
05702 }
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716
05717
05718
05719
05720
05721
05722 ProcessBitmapState ProcessBitmapState::Expand8BPP(INT32 nPixels, BYTE fill)
05723 {
05724 ProcessBitmapState expand;
05725 expand.InitPipelineSettings(this);
05726
05727
05728 if (!m_bOK)
05729 return expand;
05730
05731 ERROR3IF(GetDepth()!=8, "Expand8BPP only copes with 8BPP inputs at the moment");
05732
05733 expand.AllocDIB(GetWidth()+nPixels*2, GetHeight()+nPixels*2, 8);
05734 if (!expand.IsOK())
05735 return expand;
05736
05737 UINT32 uSrcWidth8 = GetWidth();
05738 UINT32 uSrcHeight8 = GetHeight();
05739 UINT32 uSrcByteWidth8 = DIBUtil::ScanlineSize(uSrcWidth8, 8);
05740
05741 UINT32 uExWidth8 = expand.GetWidth();
05742 UINT32 uExHeight8 = expand.GetHeight();
05743 UINT32 uExByteWidth8 = DIBUtil::ScanlineSize(uExWidth8, 8);
05744
05745 LPBYTE pSrc = m_lpBits;
05746 LPBYTE pDst = expand.m_lpBits + uExByteWidth8*nPixels + nPixels;
05747 UINT32 i,j;
05748
05749 memset(expand.m_lpBits, fill, uExByteWidth8*uExHeight8);
05750
05751 for ( j=0 ; j<uSrcHeight8 ; j++ )
05752 {
05753 for ( i=0 ; i<uSrcWidth8 ; i++ )
05754 pDst[i] = pSrc[i];
05755
05756 pSrc += uSrcByteWidth8;
05757 pDst += uExByteWidth8;
05758 }
05759
05760
05761 expand.m_XOffset -= (double)nPixels;
05762 expand.m_YOffset -= (double)nPixels;
05763
05764 return expand;
05765 }
05766
05767
05768
05769
05770
05771
05772
05773
05774
05775
05776
05777
05778
05779
05780
05781
05782
05783
05784
05785 #ifdef DEBUG
05786 void ProcessBitmapState::AttachToDoc(String_256 strName)
05787 {
05788 if (m_lpInfo != NULL && m_lpBits != NULL)
05789 {
05790 CWxBitmap* wbmp = new CWxBitmap(m_lpInfo, m_lpBits);
05791 KernelBitmap* kbmp = new KernelBitmap(wbmp, TRUE);
05792 if (kbmp->GetBPP()==8)
05793 {
05794 LPRGBQUAD pPalette = kbmp->GetPaletteForBitmap();
05795 for ( INT32 i=0 ; i<0x100 ; i++ )
05796 (UINT32&)pPalette[i] = i*0x010101 ;
05797
05798 kbmp->SetAsGreyscale();
05799 }
05800 kbmp->AttachDebugCopyToCurrentDocument(strName);
05801 wbmp->BMBytes = ((CWxBitmap*)OILBitmap::Default)->BMBytes;
05802 delete kbmp;
05803 }
05804 }
05805 #endif
05806
05807 #endif