00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include "camtypes.h"
00104 #include "ppbrush.h"
00105 #include "brshcomp.h"
00106 #include "pathproc.h"
00107
00108
00109 #include "attrmap.h"
00110 #include "brushref.h"
00111 #include "ndbldpth.h"
00112
00113
00114
00115
00116 #include "qualattr.h"
00117
00118
00119
00120
00121 #include "cxftags.h"
00122
00123
00124 #include "progress.h"
00125 #include "mtrand.h"
00126 #include "pen.h"
00127 #include "brshbeca.h"
00128 #include "lineattr.h"
00129
00130 #include "cnamecol.h"
00131
00132 #include "samplist.h"
00133 #include "scanrr.h"
00134 #include "valfunc.h"
00135 #include "strkattr.h"
00136
00137
00138
00139 #include "ophist.h"
00140 #include "vectrndr.h"
00141
00142 DECLARE_SOURCE("$Revision: 1328 $");
00143
00144 CC_IMPLEMENT_DYNAMIC(PathProcessorBrush, PathProcessor);
00145 PORTNOTE("other","Removed BrushSubRenderContext - derived from SubRenderContext")
00146 #ifndef EXCLUDE_FROM_XARALX
00147 CC_IMPLEMENT_DYNCREATE(BrushSubRenderContext, SubRenderContext);
00148 #endif
00149
00150
00151 #define new CAM_DEBUG_NEW
00152
00153 const double MAX_RANDOM_FACTOR = 2.0;
00154 const double MIN_RANDOM_FACTOR = 1.0;
00155 const double MIN_ROTATION_RANDOM_FACTOR = 1.0;
00156 const double MAX_ROTATION_RANDOM_FACTOR = 1.0;
00157 const UINT32 MAX_RANDOM_AMOUNT = 100;
00158 const UINT32 MIN_RANDOM_AMOUNT = 0;
00159
00160
00161
00162 #define NEW_RENDERBRUSHATPOINT
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 PathProcessorBrush::PathProcessorBrush()
00176 {
00177 m_AltValue = 0;
00178 m_BrushSpacing = 10000;
00179 m_bScaleToLineWidth = TRUE;
00180 m_LineWidth = -1;
00181 m_pParentAttr = NULL;
00182
00183 m_BrushScaling = 1.0;
00184 m_BrushScalingIncr = 1.0;
00185 m_BrushScalingIncrConst = 0.0;
00186 m_BrushScalingMaxRand = 0;
00187 m_BrushScalingRandSeed = 0;
00188 m_ScalingMaxPressure = 0;
00189
00190 m_BrushSpacingIncrProp = 1.0;
00191 m_BrushSpacingIncrConst = 0;
00192 m_BrushSpacingMaxRand = 0;
00193 m_BrushSpacingRandSeed = 5;
00194 m_SpacingMaxPressure = 0;
00195
00196 m_RotationMaxRand = 0;
00197 m_RotationRandSeed = 0;
00198 #ifdef USE_MTRNG
00199 m_pSpacingRNG = NULL;
00200 m_pScalingRNG = NULL;
00201 m_pOffsetTypeRNG = NULL;
00202 m_pOffsetValueRNG = NULL;
00203 m_pRotationRNG = NULL;
00204 m_pSaturationRNG = NULL;
00205 m_pHueRNG = NULL;
00206 m_pSequenceRNG = NULL;
00207 #endif
00208 m_PathOffsetIncrProp = 1.0;
00209 m_PathOffsetIncrConst = 0;
00210
00211 m_SequenceType = SEQ_FORWARD;
00212 m_SequenceRandSeed = 0;
00213
00214 m_OffsetTypeRandSeed = 0;
00215 m_bUseLocalFillColour = FALSE;
00216 m_bUseLocalTransp = FALSE;
00217 m_bUseNamedColours = TRUE;
00218 m_CurrentPressure.m_Pressure = MAXPRESSURE / 2;
00219 m_bCalculateRect = FALSE;
00220
00221 m_RotateAngle = 0.0;
00222 m_RotAngleIncrProp = 1.0;
00223 m_RotAngleIncrConst = 0;
00224
00225 m_BrushSatMaxRand = 0;
00226 m_BrushSatRandSeed = 0;
00227 m_BrushHueMaxRand = 0;
00228 m_BrushHueRandSeed = 0;
00229 m_BrushHueIncrement = 1.0;
00230 m_BrushSatIncrement = 1.0;
00231
00232 m_LastOffset = 0;
00233 m_LastScaling = 10000;
00234 m_LastObject = 0;
00235
00236 m_pObjectRendered = NULL;
00237 m_pLastScalingRendered = NULL;
00238 m_pLastTangent = NULL;
00239 m_pLastRotation = NULL;
00240
00241 m_BrushTransparency = 100;
00242 m_TranspMaxPressure = 0;
00243
00244
00245
00246 m_pDefaultTransp = NULL;
00247
00248 m_pDefaultTransp = new AttrFlatTranspFill;
00249 if (m_pDefaultTransp != NULL)
00250 {
00251 TranspFillAttribute* pVal = (TranspFillAttribute*)m_pDefaultTransp->GetAttributeValue();
00252 if (pVal != NULL)
00253 pVal->Transp = 0;
00254 }
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 PathProcessorBrush::~PathProcessorBrush()
00271 {
00272
00273 #ifdef USE_MTRNG
00274 if (m_pSpacingRNG != NULL)
00275 delete m_pSpacingRNG;
00276 if (m_pScalingRNG != NULL)
00277 delete m_pScalingRNG;
00278 if (m_pOffsetTypeRNG != NULL)
00279 delete m_pOffsetTypeRNG;
00280 if (m_pOffsetValueRNG != NULL)
00281 delete m_pOffsetValueRNG;
00282 if (m_pRotationRNG != NULL)
00283 delete m_pRotationRNG;
00284 if (m_pSaturationRNG != NULL)
00285 delete m_pSaturationRNG;
00286 if (m_pHueRNG != NULL)
00287 delete m_pHueRNG;
00288 if (m_pSequenceRNG != NULL)
00289 delete m_pSequenceRNG;
00290 #endif
00291
00292 if (m_pDefaultTransp != NULL)
00293 delete m_pDefaultTransp;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 BOOL PathProcessorBrush::WillChangeFillAndBrushSeparately(void)
00319 {
00320 return(TRUE);
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 BOOL PathProcessorBrush::IsAPathProcessorBrush()
00337 {
00338 return TRUE;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 void PathProcessorBrush::ProcessPath(Path *pPath, RenderRegion *pRender,
00366 PathShape ShapePath)
00367 {
00368 ERROR3IF(pPath == NULL || pRender == NULL, "Illegal NULL Params");
00369
00370
00371 if (pRender->DrawingMode != DM_COPYPEN)
00372 {
00373 pRender->DrawPath(pPath, this);
00374 return;
00375 }
00376
00377
00378
00379
00380
00381 {
00382 QualityAttribute *pQuality = (QualityAttribute *) pRender->GetCurrentAttribute(ATTR_QUALITY);
00383 if (pQuality != NULL && pQuality->QualityValue.GetBlendQuality() != Quality::FullBlend)
00384 {
00385 pRender->DrawPath(pPath, this, ShapePath);
00386 return;
00387 }
00388 }
00389
00390
00391 #ifdef NEWFASTBRUSHES
00392 GRenderRegionWrapper* pRendWrap = NULL;
00393 RenderRegion *pOrig = NULL;
00394 NodePath* pParentPath = NULL;
00395
00396 if (pLinkedAttr)
00397 {
00398 TRACEUSER( "Phil", _T("PathProcessorBrush::ProcessPath: entered with pNewAttr"));
00399 if (pLinkedAttr->GetCachedBitmap ())
00400 {
00401
00402 pLinkedAttr->GetCachedBitmap ()->Render(pRender);
00403 TRACEUSER( "Phil", _T("PathProcessorBrush::ProcessPath: rendered with bitmap\n"));
00404 return;
00405 }
00406 else
00407 {
00408
00409 pParentPath = (NodePath*) pLinkedAttr->GetBoundsParent ();
00410
00411 if (pParentPath)
00412 {
00413
00414 pRendWrap = GRenderRegionWrapper::GetAppropriateRenderWrapper ((GRenderRegion*)pRender, 1.0, pParentPath->GetBoundingRect (), 32, TRUE);
00415 TRACEUSER( "Phil", _T("PathProcessorBrush::ProcessPath: rendered with path\n"));
00416 }
00417 else
00418 {
00419
00420
00421
00422
00423 pRendWrap = GRenderRegionWrapper::GetAppropriateRenderWrapper ((GRenderRegion*)pRender, 1.0, pRender->GetClipRect (), 32, TRUE);
00424 TRACEUSER( "Phil", _T("PathProcessorBrush::ProcessPath: rendered with path\n"));
00425 }
00426
00427 }
00428 }
00429
00430 if (pRendWrap)
00431 {
00432 pOrig = pRender;
00433 pRender = (RenderRegion*) pRendWrap->GetRenderRegion();
00434 }
00435 #endif
00436
00437
00438 BrushDefinition* pBrushDef = GetOurBrushDefinition();
00439 if (pBrushDef == NULL)
00440 {
00441 pRender->DrawPath(pPath, this);
00442 return;
00443 }
00444
00445 Reset();
00446
00447
00448
00449
00450 StrokeColourAttribute* pStroke = (StrokeColourAttribute*)pRender->GetCurrentAttribute(ATTR_STROKECOLOUR);
00451 BOOL NoStroke = FALSE;
00452
00453 if (pStroke != NULL)
00454 {
00455 m_CurrentStrokeCol = pStroke->Colour;
00456 NoStroke = pStroke->Colour.IsTransparent();
00457 }
00458 else
00459 {
00460 NoStroke = TRUE;
00461 }
00462
00463
00464 LineWidthAttribute* pLine = (LineWidthAttribute*)pRender->GetCurrentAttribute(ATTR_LINEWIDTH);
00465
00466
00467
00468
00469
00470 pRender->SaveContext();
00471
00472 pRender->SetLineColour(COLOUR_TRANS);
00473
00474 pRender->DrawPath(pPath, this);
00475
00476 if (NoStroke)
00477 {
00478 pRender->RestoreContext();
00479 return;
00480 }
00481
00482
00483 UINT32 LineWidth = pLine->LineWidth;
00484
00485
00486 if (!pBrushDef->StartRender())
00487 {
00488 TRACEUSER( "Diccon", _T("Unable to render brush%d\n"));
00489 pRender->DrawPath(pPath, this);
00490 pRender->RestoreContext();
00491 return;
00492 }
00493
00494 UINT32 NumBrushObjects = pBrushDef->GetNumBrushObjects();
00495
00496
00497 if (!PrepareForRenderingLoop(NumBrushObjects))
00498 {
00499 pRender->RestoreContext();
00500 return;
00501 }
00502
00503
00504 double dPathLength = pPath->GetPathLength(750/2);
00505 double dOrigPathLength = dPathLength;
00506 MILLIPOINT PathLength = (MILLIPOINT)dPathLength;
00507 double PathProportion = 0.0;
00508
00509
00510 MILLIPOINT DistanceToPoint = 10;
00511
00512
00513 MILLIPOINT Spacing = m_BrushSpacing;
00514
00515 CPathPointInfo PathPoint;
00516 double Angle;
00517 DocCoord Point;
00518 BOOL ok = FALSE;
00519 BOOL Found = TRUE;
00520 UINT32 Count = 0;
00521
00522
00523
00524 UINT32 BrushObjectToRender = m_LastObject;
00525
00526
00527
00528
00529
00530 DocRect RenderRect = pRender->GetClipRect();
00531 DocRect InkRect = pBrushDef->GetLargestBoundingBox();
00532
00533 MILLIPOINT InkWidth = InkRect.Width() / 2;
00534 MILLIPOINT InkHeight = InkRect.Height() / 2;
00535
00536
00537
00538
00539
00540 ValueFunction* pValFunc = NULL;
00541 CDistanceSampler* pPressure = GetPressureCacheAndInitialise(pRender, &pValFunc);
00542 CSampleItem TheItem;
00543
00544
00545 if (LineWidth < 500)
00546 LineWidth = 500;
00547
00548 ScaleToValue(LineWidth, !m_bValidPressure);
00549
00550
00551 VariableWidthAttrValue* pVarWidth = new VariableWidthAttrValue(NULL);
00552 if (pVarWidth)
00553 pRender->SetVariableWidth(pVarWidth, TRUE);
00554
00555
00556
00557 DistanceToPoint = 10;
00558
00559 m_bRenderAllAttributes = TRUE;
00560
00561 DocCoord TestPoint;
00562
00563 if (pPath->IsClosed())
00564 {
00565
00566
00567
00568 double ActualSpacing = m_BrushScaling * (double)m_BrushSpacing;
00569
00570 PathLength -= (MILLIPOINT)(ActualSpacing * 0.2);
00571 dPathLength = (double)PathLength;
00572
00573 AdjustSpacingForClosedPath(pPath, dOrigPathLength);
00574 }
00575
00576
00577 m_LastScalingRendered = m_BrushScaling;
00578 m_CurrentScaling = GetNextScaling(Count);
00579
00580
00581
00582
00583
00584
00585 Spacing = GetNextSpacing();
00586 double TestAngle = 0;
00587 m_LastScalingRendered = m_CurrentScaling;
00588
00589
00590 BOOL bScan = pRender->IsKindOf(CC_RUNTIME_CLASS(ScanningRenderRegion))
00591 || pRender->IsKindOf(CC_RUNTIME_CLASS(VectorFileRenderRegion));
00592
00593 BOOL bContinue = TRUE;
00594
00595
00596
00597 while ((DistanceToPoint < PathLength) && bContinue)
00598 {
00599
00600
00601 ok = GetPointAtDistance(pPath, DistanceToPoint, &Point, &Angle);
00602
00603
00604 m_LastOffsetType = GetNextOffsetType();
00605
00606 if (ok)
00607 {
00608
00609
00610 TestPoint = AdjustPositionForOffset(Point, Angle, m_BrushScaling, GetNextOffset(), m_LastOffsetType);
00611 GetNextAngle();
00612 GetNextHueMultiplier();
00613 GetNextSaturationMultiplier();
00614
00615
00616 TestAngle = m_LastAngle;
00617 if (m_bRotate)
00618 TestAngle += (Angle / PI * 180);
00619
00620
00621
00622 if (bScan || ObjectIsWithinRect(RenderRect, TestPoint, InkWidth, InkHeight, m_LastScaling, TestAngle))
00623 {
00624
00625 if (m_CurrentScaling > 0)
00626 RenderBrushAtPoint(Point, Angle, BrushObjectToRender, Count, pRender);
00627
00628
00629 if (NumBrushObjects == 1)
00630 m_bRenderAllAttributes = FALSE;
00631
00632 }
00633
00634
00635
00636 Count++;
00637
00638 if (NumBrushObjects > 1)
00639 {
00640 BrushObjectToRender = GetNextInkObject(BrushObjectToRender, NumBrushObjects);
00641 }
00642
00643
00644
00645 DecideWhetherToUseActualScaling(BrushObjectToRender);
00646
00647 }
00648
00649
00650
00651 #ifdef SCALESPACING
00652 DistanceToPoint += (MILLIPOINT)(Spacing * m_LastScaling);
00653
00654 if (pPressure)
00655 pPressure->SetSampleRateFromSpacing((INT32)(Spacing * m_CurrentScaling));
00656 #else
00657 DistanceToPoint += (MILLIPOINT)(Spacing * m_BrushScaling);
00658 #endif
00659
00660 Spacing = GetNextSpacing();
00661
00662 if (pValFunc != NULL)
00663 {
00664 PathProportion = (double)DistanceToPoint / dPathLength;
00665 m_CurrentPressure.m_Pressure = GetNextSampleItem(NULL, pValFunc, PathProportion).m_Pressure;
00666
00667
00668 if (m_CurrentPressure.m_Pressure > MAXPRESSURE)
00669 m_CurrentPressure.m_Pressure = MAXPRESSURE;
00670 }
00671
00672 if (pPressure != NULL)
00673 {
00674 double pLength = dOrigPathLength;
00675 double pDataLength = pPressure->GetDistanceRep (), count = pPressure->GetCount ();
00676 double dataRatio = 1.0;
00677
00678 if (pDataLength < pLength)
00679 {
00680 dataRatio = pDataLength / pLength;
00681 }
00682 else
00683 {
00684 dataRatio = pLength / pDataLength;
00685 }
00686
00687 double offset = 1.0;
00688
00689 if (DistanceToPoint < pLength)
00690 {
00691 offset = (DistanceToPoint / pLength) * dataRatio * count;
00692 }
00693 else
00694 {
00695 offset = (pLength / DistanceToPoint) * dataRatio * count;
00696 }
00697
00698 if (pPressure->GetAtPos (offset, &TheItem))
00699 {
00700 if (TheItem.m_Pressure < MAXPRESSURE)
00701 m_CurrentPressure.m_Pressure = TheItem.m_Pressure;
00702 else
00703 m_CurrentPressure.m_Pressure = MAXPRESSURE;
00704
00705 }
00706 }
00707
00708
00709
00710 m_LastScalingRendered = m_pLastScalingRendered[BrushObjectToRender];
00711 m_CurrentScaling = GetNextScaling(Count);
00712
00713
00714
00715
00716 if (m_AltValue == 0)
00717 m_AltValue = 1;
00718 else
00719 m_AltValue = 0;
00720 if (Found == FALSE)
00721 TRACEUSER( "Diccon", _T("Failed to find point at %d\n"), DistanceToPoint);
00722
00723
00724 bContinue = TRUE;
00725 }
00726
00727
00728
00729 CleanUpAfterRender();
00730
00731 TRACEUSER( "Diccon", _T("Finished Process Path, rendered %d objects\n"), Count);
00732
00733 pRender->RestoreContext();
00734
00735 pBrushDef->StopRender();
00736
00737 #ifdef NEWFASTBRUSHES
00738 if (pRendWrap)
00739 {
00740 pRender = pOrig;
00741
00742 KernelBitmap* kBmp = pRendWrap->GetKernelBitmap();
00743 pRendWrap->RestorePreviousRendererState();
00744
00745 NodePath* pParentPath = (NodePath*) pLinkedAttr->GetBoundsParent ();
00746
00747 NodeBitmap* DummyBmp = new NodeBitmap();
00748
00749 if (DummyBmp)
00750 {
00751 DummyBmp->SetUpPath();
00752
00753 if (pParentPath)
00754 {
00755 DummyBmp->CreateShape(pParentPath->GetBoundingRect ());
00756 }
00757 else
00758 {
00759
00760
00761
00762
00763
00764 DummyBmp->CreateShape(pRender->GetClipRect ());
00765 }
00766
00767 DummyBmp->GetBitmapRef()->SetBitmap(kBmp);
00768 pLinkedAttr->SetCachedBitmap (DummyBmp);
00769 DummyBmp->Render (pRender);
00770 }
00771 }
00772 #endif
00773 }
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825 #ifdef NEW_RENDERBRUSHATPOINT
00826 void PathProcessorBrush::RenderBrushAtPoint(DocCoord Point,
00827 double Tangent,
00828 UINT32 BrushIndex,
00829 UINT32 Counter,
00830 RenderRegion* pRender,
00831 HandleBrushBecomeA* pBecomeA,
00832 BOOL RealtimeBrush,
00833 BrushDefinition* pBrushDefinition)
00834 {
00835 BrushDefinition* pOurBrushDef = NULL;
00836 if (!pBrushDefinition)
00837 {
00838 pOurBrushDef = GetOurBrushDefinition();
00839 }
00840 else
00841 {
00842 pOurBrushDef = pBrushDefinition;
00843 }
00844
00845 if (pOurBrushDef == NULL)
00846 return;
00847
00848
00849 Trans2DMatrix Trans;
00850 BrushRef* pBrushRef;
00851 CCAttrMap* pAttrMap = NULL;
00852 Path* pRenderPath = NULL;
00853 BlendPath* pBlendPath = NULL;
00854 DocCoord* pRenderCoords = NULL;
00855 INT32 NumRenderCoords = 0;
00856 DocCoord RenderPoint;
00857 MILLIPOINT OffsetVal = 0;
00858 DocCoord TransformCentre;
00859
00860 BrushRef::iterator ListPosition;
00861 BlendPathOffset* pOffset = NULL;
00862
00863
00864
00865 if (BrushIndex >= pOurBrushDef->GetNumBrushObjects())
00866 BrushIndex = 0;
00867
00868
00869
00870 double Scaling = 1.0;
00871 double ExtraAngle = 0;
00872 if (!RealtimeBrush)
00873 {
00874 Scaling = m_CurrentScaling;
00875 ExtraAngle = m_LastAngle;
00876
00877 OffsetVal = m_LastOffset;
00878 }
00879 else
00880 {
00881 ExtraAngle = GetNextAngle();
00882 Scaling = GetNextScaling(Counter);
00883 if (Scaling <= 0)
00884 return;
00885
00886 GetNextHueMultiplier();
00887 GetNextSaturationMultiplier();
00888
00889 OffsetVal = GetNextOffset();
00890 }
00891
00892 double TranspAdjust = GetNextTransparencyAdjust();
00893 double PressureTranspAdjust = GetNextPressureTranspAdjust();
00894
00895 pBrushRef = pOurBrushDef->GetBrushRef(BrushIndex);
00896
00897 if (pBrushRef == NULL)
00898 {
00899 ERROR3("No brushref in RenderBrushAtPoint");
00900 return;
00901 }
00902
00903 UINT32 NumBlendPaths = pBrushRef->GetNumBlendPaths();
00904
00905
00906
00907
00908
00909
00910
00911 if (NumBlendPaths > 1)
00912 {
00913 m_bRenderAllAttributes = TRUE;
00914 }
00915
00916 if (pBrushRef != NULL)
00917 {
00918 pOffset = pBrushRef->GetFirstOffset(&ListPosition);
00919 pBlendPath = pBrushRef->GetFirstBlendPath();
00920 pRenderPath = pBrushRef->GetFirstCopyPath();
00921
00922 DocRect ChangedRect = DocRect(0,0,0,0);
00923
00924
00925 if (pBecomeA != NULL)
00926 pBecomeA->SetNumBlendPaths(NumBlendPaths);
00927
00928 UINT32 ObjectCounter = 0;
00929 while (pRenderPath != NULL)
00930 {
00931 DocRect BRect;
00932 Matrix transform;
00933
00934
00935 pRenderCoords = pRenderPath->GetCoordArray();
00936 NumRenderCoords = pRenderPath->GetNumCoords();
00937
00938
00939 pAttrMap = pBlendPath->GetCopyAttributes();
00940 if (pAttrMap == NULL)
00941 {
00942 ERROR3("No applied attributes");
00943 return;
00944 }
00945
00946 ObjectCounter++;
00947
00948
00949
00950 RenderPoint = AdjustPositionForOffset(Point, Tangent, m_BrushScaling, OffsetVal, m_LastOffsetType);
00951
00952
00953 BRect = pRenderPath->GetBoundingRect();
00954 DocCoord CurrentPoint = BRect.Centre();
00955
00956
00957 if (pOffset != NULL)
00958 CurrentPoint = AdjustPositionForBlendPathOffset(CurrentPoint, pOffset, -1.0, Tangent);
00959
00960
00961
00962 transform.translate(-CurrentPoint.x, -CurrentPoint.y );
00963
00964
00965
00966 if (Scaling != 1.0)
00967 {
00968
00969 FIXED16 NewScale(Scaling);
00970 transform *= Matrix(NewScale, NewScale);
00971
00972 Trans.SetTransform(transform);
00973 Trans.TransLines = TRUE;
00974
00975
00976 if (pAttrMap->WillScaleLineWidthToZero(Trans))
00977 {
00978 AttrStrokeColour* pOldStrokeCol = NULL;
00979 pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStrokeColour), (void*&)pOldStrokeCol );
00980 if (pOldStrokeCol)
00981 {
00982
00983 pOldStrokeCol->Value.Colour = DocColour(COLOUR_TRANS);
00984 }
00985 else
00986 {
00987 AttrStrokeColour* pNewStrokeCol = new AttrStrokeColour;
00988 pNewStrokeCol->Value.Colour = DocColour(COLOUR_TRANS);
00989 }
00990 }
00991 }
00992
00993
00994
00995 if (m_bRotate)
00996 {
00997
00998
00999 double Tang = Tangent / PI * 180;
01000 transform *= Matrix(Tang);
01001 }
01002
01003
01004
01005 if (m_LastAngle != 0 || m_RotationMaxRand != 0)
01006 {
01007 double RotAngle = 0;
01008 RotAngle += m_LastAngle;
01009 transform *= Matrix(RotAngle);
01010 }
01011
01012
01013
01014 transform.translate(RenderPoint.x, RenderPoint.y);
01015
01016
01017
01018
01019
01020 Trans.SetTransform(transform);
01021 if (Scaling != 1.0)
01022 Trans.TransLines = TRUE;
01023
01024 Trans.Transform(pRenderCoords, NumRenderCoords);
01025
01026 if (m_bTile)
01027 pAttrMap->TransformForBrush(Trans);
01028 else
01029 pAttrMap->Transform(Trans);
01030
01031
01032 transform.TransformBounds(&BRect);
01033
01034
01035
01036
01037
01038
01039 CHSVChanger ColChanger;
01040 ColChanger.SetHueMultiplier(m_LastHueMultiplier);
01041 ColChanger.SetSaturationMultiplier(m_LastSatMultiplier);
01042
01043
01044 CTransparencyReplacer TranspRep;
01045 TranspRep.SetAdjustmentValue(TranspAdjust);
01046 TranspRep.SetInvertedAdjuster(PressureTranspAdjust);
01047
01048
01049
01050 if (pRender != NULL)
01051 {
01052 RenderAttributes(pRender, pAttrMap, &ColChanger, &TranspRep);
01053 pRender->DrawPath(pRenderPath, this);
01054 }
01055
01056
01057
01058 if (pBecomeA != NULL)
01059 {
01060 AdjustFillAttributes(pAttrMap, &ColChanger, &TranspRep);
01061 pBecomeA->Passback(pRenderPath, pAttrMap, ObjectCounter);
01062 }
01063
01064
01065 if (ColChanger.IsInitialised())
01066 ColChanger.RestoreColours();
01067 if (TranspRep.IsInitialised())
01068 TranspRep.RestoreTransparency();
01069
01070
01071 AttrLineWidth* pLineWidth = NULL;
01072 pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrLineWidth), (void*&)pLineWidth );
01073 INT32 LineWidth = 1500;
01074 if (pLineWidth != NULL)
01075 {
01076 LineWidth = pLineWidth->Value.LineWidth;
01077 if (LineWidth <= 500)
01078 LineWidth = 1500;
01079 }
01080
01081 pRenderPath->GetTrueBoundingRect(&BRect, LineWidth, NULL);
01082
01083
01084
01085 if (ListPosition!=pBrushRef->GetEndPosition())
01086 pOffset = pBrushRef->GetNextOffset(&ListPosition);
01087
01088
01089
01090 if (ChangedRect.IsEmpty())
01091 ChangedRect = BRect;
01092 else
01093 ChangedRect = ChangedRect.Union(BRect);
01094
01095
01096 if (m_bCalculateRect)
01097 {
01098 if (m_CachedRect.IsEmpty())
01099 m_CachedRect = ChangedRect;
01100 else
01101 m_CachedRect = m_CachedRect.Union(ChangedRect);
01102 }
01103
01104
01105
01106
01107
01108
01109
01110 pBlendPath->UpdateCopyPathAndAttributes();
01111
01112
01113
01114 pRenderPath = pBrushRef->GetNextCopyPath();
01115 pBlendPath = pBrushRef->GetNextBlendPath(pBlendPath);
01116
01117 }
01118
01119
01120 if (RealtimeBrush == TRUE)
01121 {
01122
01123
01124
01125
01126 PORTNOTE("other","Removed GRenderBrush usage")
01127
01128 #ifndef EXCLUDE_FROM_XARALX
01129 ((GRenderBrush*)pRender)->SetChangedBBox(ChangedRect);
01130 #endif
01131 }
01132
01133 }
01134
01135 m_pObjectRendered[BrushIndex] = TRUE;
01136 m_pLastScalingRendered[BrushIndex] = m_LastScaling;
01137 }
01138 #endif
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185 #ifndef NEW_RENDERBRUSHATPOINT
01186
01187 void PathProcessorBrush::RenderBrushAtPoint(DocCoord Point, double Tangent, UINT32 BrushIndex, UINT32 Counter,
01188 RenderRegion* pRender, HandleBrushBecomeA* pBecomeA,
01189 BOOL RealtimeBrush, BrushDefinition* pBrushDefinition)
01190 {
01191 BrushDefinition* pOurBrushDef = NULL;
01192 if (!pBrushDefinition)
01193 {
01194 pOurBrushDef = GetOurBrushDefinition();
01195 }
01196 else
01197 {
01198 pOurBrushDef = pBrushDefinition;
01199 }
01200
01201 if (pOurBrushDef == NULL)
01202 return;
01203
01204
01205
01206
01207 Trans2DMatrix Trans;
01208 Trans2DMatrix Rotate;
01209 Trans2DMatrix RevRotate;
01210 Trans2DMatrix TangMat;
01211 Trans2DMatrix RevTangent;
01212 Trans2DMatrix Scale;
01213
01214
01215
01216 BrushRef* pBrushRef;
01217 CCAttrMap* pAttrMap = NULL;
01218 Path* pRenderPath = NULL;
01219 DocCoord* pRenderCoords = NULL;
01220 INT32 NumRenderCoords = 0;
01221 DocCoord RenderPoint;
01222
01223 POSITION ListPosition;
01224 BlendPathOffset* pOffset = NULL;
01225
01226
01227
01228 if (BrushIndex >= pOurBrushDef->GetNumBrushObjects())
01229 BrushIndex = 0;
01230
01231
01232
01233 double Scaling = 1.0;
01234 double ExtraAngle = 0;
01235 if (!RealtimeBrush)
01236 {
01237 Scaling = m_CurrentScaling;
01238 ExtraAngle = m_LastAngle;
01239 }
01240 else
01241 {
01242 ExtraAngle = GetNextAngle();
01243 Scaling = GetNextScaling(Counter);
01244 if (Scaling <= 0)
01245 return;
01246
01247 GetNextHueMultiplier();
01248 GetNextSaturationMultiplier();
01249
01250 }
01251
01252
01253 MILLIPOINT OffsetVal = 0;
01254 if (RealtimeBrush)
01255 OffsetVal = GetNextOffset();
01256 else
01257 OffsetVal = m_LastOffset;
01258
01259 double TranspAdjust = GetNextTransparencyAdjust();
01260 double PressureTranspAdjust = GetNextPressureTranspAdjust();
01261
01262 pBrushRef = pOurBrushDef->GetBrushRef(BrushIndex);
01263
01264 if (pBrushRef == NULL)
01265 {
01266 ERROR3("No brushref in RenderBrushAtPoint");
01267 return;
01268 }
01269 DocCoord RotateCoord;
01270 UINT32 NumBlendPaths = pBrushRef->GetNumBlendPaths();
01271
01272
01273
01274
01275
01276 BOOL SpecifyRotateCoord = FALSE;
01277
01278 if (NumBlendPaths > 1)
01279 {
01280 m_bRenderAllAttributes = TRUE;
01281 SpecifyRotateCoord = TRUE;
01282 }
01283
01284 if (pBrushRef!= NULL)
01285 {
01286 pOffset = pBrushRef->GetFirstOffset(&ListPosition);
01287
01288 pRenderPath = pBrushRef->GetFirstCopyPath();
01289
01290 DocRect ChangedRect = DocRect(0,0,0,0);
01291 DocRect BRect;
01292
01293
01294 if (pBecomeA != NULL)
01295 pBecomeA->SetNumBlendPaths(NumBlendPaths);
01296 UINT32 ObjectCounter = 0;
01297 while (pRenderPath != NULL)
01298 {
01299
01300 pRenderCoords = pRenderPath->GetCoordArray();
01301 NumRenderCoords = pRenderPath->GetNumCoords();
01302
01303 ObjectCounter++;
01304
01305 RenderPoint = AdjustPositionForOffset(Point, Tangent, m_BrushScaling, OffsetVal, m_LastOffsetType);
01306
01307
01308
01309 if (SpecifyRotateCoord)
01310 RotateCoord = RenderPoint;
01311
01312 if (pOffset != NULL)
01313 RenderPoint = AdjustPositionForBlendPathOffset(RenderPoint, pOffset, m_LastScaling, Tangent);
01314
01315
01316
01317 BRect = pRenderPath->GetBoundingRect();
01318 DocCoord CurrentPoint = BRect.Centre();
01319
01320 Trans.SetTransform(RenderPoint.x - CurrentPoint.x, RenderPoint.y - CurrentPoint.y );
01321 BRect.Translate(RenderPoint.x - CurrentPoint.x, RenderPoint.y - CurrentPoint.y );
01322
01323
01324
01325
01326
01327 pAttrMap = pBrushRef->GetCurrentAttributeCopy();
01328 if (pAttrMap == NULL)
01329 {
01330 ERROR3("No applied attributes");
01331 return;
01332 }
01333
01334
01335 Trans.Transform(pRenderCoords, NumRenderCoords);
01336
01337 if (m_bTile)
01338 pAttrMap->TransformForBrush(Trans);
01339 else
01340 pAttrMap->Transform(Trans);
01341
01342
01343
01344 Matrix ScaleMat;
01345 Matrix RevScaleMat;
01346
01347
01348 if (Scaling != 1.0)
01349 {
01350
01351 FIXED16 NewScale(Scaling);
01352 FIXED16 OldScale = 1 / NewScale;
01353
01354
01355 ScaleMat*=Matrix(-BRect.Centre().x, -BRect.Centre().y);
01356 ScaleMat*=Matrix(NewScale, NewScale);
01357 ScaleMat*=Matrix(BRect.Centre().x, BRect.Centre().y);
01358
01359
01360 Scale.SetTransform(ScaleMat);
01361 Scale.TransLines = TRUE;
01362
01363
01364 if (pAttrMap->WillScaleLineWidthToZero(Scale))
01365 {
01366 AttrStrokeColour* pOldStrokeCol = NULL;
01367 pAttrMap->Lookup((void*)CC_RUNTIME_CLASS(AttrStrokeColour), (void*&)pOldStrokeCol);
01368 if (pOldStrokeCol)
01369 {
01370
01371 pOldStrokeCol->Value.Colour = DocColour(COLOUR_TRANS);
01372 }
01373 else
01374 {
01375 AttrStrokeColour* pNewStrokeCol = new AttrStrokeColour;
01376 pNewStrokeCol->Value.Colour = DocColour(COLOUR_TRANS);
01377 }
01378
01379 }
01380
01381
01382
01383 Scale.Transform(pRenderCoords, NumRenderCoords);
01384
01385
01386 if (m_UseActualScaling)
01387 {
01388 if (m_BrushScaling != 0)
01389 {
01390 FIXED16 FillScale(m_BrushScaling);
01391 Trans2DMatrix ScaleFills;
01392 Matrix FillScaleMat;
01393 FillScaleMat*=Matrix(-BRect.Centre().x, -BRect.Centre().y);
01394 FillScaleMat*=Matrix(FillScale, FillScale);
01395 FillScaleMat*=Matrix(BRect.Centre().x, BRect.Centre().y);
01396 ScaleFills.SetTransform(FillScaleMat);
01397
01398 pAttrMap->TransformBrushFills(ScaleFills);
01399 }
01400
01401 }
01402
01403
01404 if (m_bTile)
01405 pAttrMap->TransformForBrush(Scale);
01406 else
01407 pAttrMap->Transform(Scale);
01408
01409
01410 ScaleMat.TransformBounds(&BRect);
01411 }
01412
01413
01414 if (m_bRotate)
01415 {
01416
01417
01418 double Tang = Tangent / PI * 180;
01419 if (SpecifyRotateCoord)
01420 {
01421 TangMat.SetTransform(RotateCoord, Tang);
01422 RevTangent.SetTransform(RotateCoord, -Tang);
01423
01424 }
01425 else
01426 {
01427 TangMat.SetTransform(RenderPoint, Tang);
01428 RevTangent.SetTransform(RenderPoint, -Tang);
01429
01430
01431 }
01432 BrushAttrValue::RotateBounds(Tang, &BRect);
01433
01434
01435 TangMat.Transform(pRenderCoords, NumRenderCoords);
01436 if (m_bTile)
01437 pAttrMap->TransformForBrush(TangMat);
01438 else
01439 pAttrMap->Transform(TangMat);
01440 }
01441
01442
01443
01444
01445 if (m_LastAngle != 0 || m_RotationMaxRand != 0)
01446 {
01447 double RotAngle = 0;
01448 RotAngle += m_LastAngle;
01449 if (SpecifyRotateCoord)
01450 Rotate.SetTransform(RotateCoord, RotAngle);
01451 else
01452 Rotate.SetTransform(RenderPoint, RotAngle);
01453
01454
01455 Rotate.Transform(pRenderCoords, NumRenderCoords);
01456
01457 if (m_bTile)
01458 pAttrMap->TransformForBrush(Rotate);
01459 else
01460 pAttrMap->Transform(Rotate);
01461
01462
01463 RevRotate.SetTransform(RenderPoint, -RotAngle);
01464
01465 BrushAttrValue::RotateBounds(RotAngle, &BRect);
01466 }
01467
01468
01469 CHSVChanger ColChanger;
01470 ColChanger.SetHueMultiplier(m_LastHueMultiplier);
01471 ColChanger.SetSaturationMultiplier(m_LastSatMultiplier);
01472
01473
01474 CTransparencyReplacer TranspRep;
01475
01476 TranspRep.SetAdjustmentValue(TranspAdjust);
01477 TranspRep.SetInvertedAdjuster(PressureTranspAdjust);
01478
01479
01480 if (pRender != NULL)
01481 {
01482 RenderAttributes(pRender, pAttrMap, &ColChanger, &TranspRep);
01483
01484 pRender->DrawPath(pRenderPath, this);
01485
01486 }
01487
01488 if (pBecomeA != NULL)
01489 {
01490 AdjustFillAttributes(pAttrMap, &ColChanger, &TranspRep);
01491 pBecomeA->Passback(pRenderPath, pAttrMap, ObjectCounter);
01492 }
01493
01494
01495 if (ColChanger.IsInitialised())
01496 ColChanger.RestoreColours();
01497 if (TranspRep.IsInitialised())
01498 TranspRep.RestoreTransparency();
01499
01500
01501 AttrLineWidth* pLineWidth = NULL;
01502 pAttrMap->Lookup((void*)CC_RUNTIME_CLASS(AttrLineWidth), (void*&)pLineWidth);
01503 INT32 LineWidth = 1500;
01504 if (pLineWidth != NULL)
01505 {
01506 LineWidth = pLineWidth->Value.LineWidth;
01507 if (LineWidth <= 500)
01508 LineWidth = 1500;
01509 }
01510
01511
01512 pRenderPath->GetTrueBoundingRect(&BRect, LineWidth, NULL);
01513
01514
01515 if (m_LastAngle != 0 )
01516 {
01517
01518 RevRotate.Transform(pRenderCoords, NumRenderCoords);
01519 if (m_bTile)
01520 pAttrMap->TransformForBrush(RevRotate);
01521 else
01522 pAttrMap->Transform(RevRotate);
01523 DocRect NewRect = BRect;
01524 BrushAttrValue::RotateBounds(m_LastAngle, &NewRect);
01525 BRect = BRect.Union(NewRect);
01526 }
01527
01528 if (m_bRotate )
01529 {
01530
01531 RevTangent.Transform(pRenderCoords, NumRenderCoords);
01532 if (m_bTile)
01533 pAttrMap->TransformForBrush(RevTangent);
01534 else
01535 pAttrMap->Transform(RevTangent);
01536
01537 DocRect NewRect = BRect;
01538 BrushAttrValue::RotateBounds(Tangent, &NewRect);
01539 BRect = BRect.Union(NewRect);
01540 }
01541
01542
01543
01544 if (ListPosition != NULL)
01545 pOffset = pBrushRef->GetNextOffset(&ListPosition);
01546
01547 pRenderPath = pBrushRef->GetNextCopyPath();
01548
01549
01550
01551
01552 if (ChangedRect.IsEmpty())
01553 ChangedRect = BRect;
01554 else
01555 ChangedRect = ChangedRect.Union(BRect);
01556
01557
01558 if (m_bCalculateRect)
01559 {
01560 if (m_CachedRect.IsEmpty())
01561 m_CachedRect = ChangedRect;
01562 else
01563 m_CachedRect = m_CachedRect.Union(ChangedRect);
01564 }
01565
01566 }
01567
01568
01569 if (RealtimeBrush == TRUE)
01570 {
01571
01572 INT32 Height = ChangedRect.Height();
01573 INT32 Width = ChangedRect.Width();
01574
01575
01576
01577 ((GRenderBrush*)pRender)->SetChangedBBox(ChangedRect);
01578 }
01579
01580 }
01581
01582 m_pObjectRendered[BrushIndex] = TRUE;
01583 m_pLastScalingRendered[BrushIndex] = m_LastScaling;
01584
01585 }
01586 #endif
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620 void PathProcessorBrush::RenderAttributes(RenderRegion* pRender, CCAttrMap* pAttrMap,
01621 CHSVChanger* pColChange, CTransparencyReplacer* pTranspRep)
01622 {
01623
01624 BOOL ok = (pRender != NULL && pAttrMap != NULL);
01625 ERROR3IF(!ok,"One or more NULL entry params");
01626 if (!ok) return;
01627
01628 BOOL bRenderedTransp = FALSE;
01629 BOOL bRenderedColourFill = FALSE;
01630
01631 CCRuntimeClass *pType;
01632 void *pVal;
01633 NodeAttribute *pNodeAttr;
01634
01635 m_bRenderAllAttributes = TRUE;
01636
01637 pRender->SetFillColour(COLOUR_NONE);
01638
01639
01640 for( CCAttrMap::iterator Pos = pAttrMap->GetStartPosition(); Pos != pAttrMap->GetEndPosition(); )
01641 {
01642
01643 pAttrMap->GetNextAssoc( Pos, pType, pVal );
01644
01645
01646 pNodeAttr = (NodeAttribute *)pVal;
01647
01648
01649 if (pNodeAttr->IsAColourFill() && !pNodeAttr->IsATranspFill() && !pNodeAttr->IsABitmapFill())
01650 {
01651
01652
01653
01654
01655
01656
01657
01658 bRenderedColourFill = TRUE;
01659 if (!m_bUseLocalFillColour)
01660 {
01661
01662
01663 ColourFillAttribute* pVal = (ColourFillAttribute*)pNodeAttr->GetAttributeValue();
01664 if (pVal->ContainsNamedColour())
01665 {
01666 if (!m_bUseNamedColours)
01667 {
01668
01669
01670
01671
01672 DocColour Col = m_CurrentStrokeCol;
01673 pColChange->Initialise(pVal, &Col);
01674 pColChange->ReplaceColours();
01675
01676
01677
01678 }
01679 }
01680
01681
01682 if (pColChange->ShouldChangeHSV())
01683 {
01684 pColChange->SetColourFill(pVal);
01685 pColChange->ChangeHSVValues();
01686 }
01687
01688
01689 if (m_bRenderAllAttributes || pNodeAttr->NeedsToRenderAtEachBrushStroke())
01690 {
01691 pNodeAttr->Render(pRender);
01692 }
01693
01694 }
01695 else
01696 {
01697
01698 if (m_pParentAttr != NULL)
01699 {
01700 DocColour LocalColour = m_CurrentStrokeCol;
01701 if (pColChange != NULL)
01702 {
01703 pColChange->ChangeColour(&LocalColour);
01704 }
01705 pRender->SetFillColour(LocalColour);
01706 }
01707 }
01708 }
01709 else if (pNodeAttr->IsATranspFill())
01710 {
01711 AdjustAndRenderTransparency(pRender, (AttrFillGeometry*)pNodeAttr, pTranspRep);
01712 bRenderedTransp = TRUE;
01713 }
01714 else
01715 {
01716
01717 if (m_bRenderAllAttributes || pNodeAttr->NeedsToRenderAtEachBrushStroke())
01718 {
01719 pNodeAttr->Render(pRender);
01720 }
01721 }
01722
01723 }
01724
01725
01726 if (m_bRenderAllAttributes)
01727 {
01728
01729
01730 if (m_pDefaultTransp != NULL && !bRenderedTransp)
01731 {
01732 AdjustAndRenderTransparency(pRender, m_pDefaultTransp, pTranspRep);
01733 m_pDefaultTransp->Render(pRender);
01734 }
01735 }
01736
01737 if (bRenderedColourFill == FALSE)
01738 pRender->SetFillColour(COLOUR_NONE);
01739
01740
01741 if (m_bTile)
01742 {
01743 FillMappingAttribute* pVal = (FillMappingAttribute*)pRender->GetCurrentAttribute(ATTR_FILLMAPPING);
01744 if (pVal)
01745 {
01746 if (pVal->Repeat == RT_Simple)
01747 {
01748
01749
01750
01751
01752
01753
01754 FillMappingAttribute* pNewVal = (FillMappingAttribute*)(pVal->GetRuntimeClass()->CreateObject());
01755 if (pNewVal)
01756 {
01757 pNewVal->SimpleCopy(pVal);
01758 pNewVal->Repeat = RT_Repeating;
01759 pRender->SetFillMapping(pNewVal, TRUE);
01760 }
01761 }
01762 }
01763 }
01764 }
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786 void PathProcessorBrush::AdjustAndRenderTransparency(RenderRegion* pRender, AttrFillGeometry* pAttrTransp,
01787 CTransparencyReplacer* pRep)
01788 {
01789 if (pRender == NULL || pAttrTransp == NULL || pRep == NULL)
01790 return;
01791
01792 if (!pAttrTransp->IsATranspFill())
01793 {
01794 ERROR3("Attribute is not transparent in PathProcessorBrush::AdjustAndRenderTransparency");
01795 return;
01796 }
01797
01798 TranspFillAttribute* pTranspVal = (TranspFillAttribute*)pAttrTransp->GetAttributeValue();
01799 if (pTranspVal != NULL)
01800 {
01801
01802 if (m_pParentAttr != NULL)
01803 {
01804 UINT32 ReplaceVal = m_pParentAttr->GetLocalTranspValue();
01805 if (ReplaceVal > 0)
01806 pRep->SetReplacementValue((INT32)ReplaceVal);
01807 UINT32 Type = m_pParentAttr->GetLocalTranspType();
01808 pTranspVal->SetTranspType(Type);
01809 }
01810 pRep->SetTransparencyAttr(pTranspVal);
01811 pRep->ReplaceTransparency();
01812 }
01813
01814 pAttrTransp->Render(pRender);
01815 }
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837 void PathProcessorBrush::AdjustFillAttributes(CCAttrMap* pAttrMap, CHSVChanger* pColChange,
01838 CTransparencyReplacer* pTranspRep)
01839 {
01840 if (pAttrMap == NULL || pColChange == NULL || pTranspRep == NULL)
01841 {
01842 ERROR3("Invalid inputs to PathProcessorBrush::AdjustFillAttributes");
01843 return;
01844 }
01845
01846
01847
01848 CCRuntimeClass *pType;
01849 void *pVal;
01850 NodeAttribute *pNodeAttr;
01851
01852 BOOL FoundTransp = FALSE;
01853
01854
01855 for( CCAttrMap::iterator Pos = pAttrMap->GetStartPosition(); Pos != pAttrMap->GetEndPosition(); )
01856 {
01857
01858 pAttrMap->GetNextAssoc(Pos,pType,pVal);
01859
01860
01861 pNodeAttr = (NodeAttribute *)pVal;
01862
01863 if (pNodeAttr->IsAColourFill())
01864 {
01865 if (!m_bUseLocalFillColour)
01866 {
01867
01868
01869 ColourFillAttribute* pVal = (ColourFillAttribute*)pNodeAttr->GetAttributeValue();
01870 if (pVal->ContainsNamedColour())
01871 {
01872 if (!m_bUseNamedColours)
01873 {
01874
01875
01876 if (m_pParentAttr != NULL && pColChange != NULL)
01877 {
01878 DocColour Col = m_CurrentStrokeCol;
01879 pColChange->Initialise(pVal, &Col);
01880 pColChange->ReplaceColours();
01881
01882 }
01883
01884
01885 }
01886 }
01887
01888
01889 if (pColChange->ShouldChangeHSV())
01890 {
01891 pColChange->SetColourFill(pVal);
01892 pColChange->ChangeHSVValues();
01893 }
01894
01895 }
01896
01897 }
01898 if (pNodeAttr->IsATranspFill())
01899 {
01900 TranspFillAttribute* pTranspVal = (TranspFillAttribute*)pNodeAttr->GetAttributeValue();
01901 if (pTranspVal != NULL)
01902 {
01903
01904 if (m_pParentAttr != NULL)
01905 {
01906 UINT32 ReplaceVal = m_pParentAttr->GetLocalTranspValue();
01907 if (ReplaceVal > 0)
01908 {
01909 pTranspRep->SetReplacementValue((INT32)ReplaceVal);
01910 UINT32 Type = m_pParentAttr->GetLocalTranspType();
01911 pTranspVal->SetTranspType(Type);
01912 }
01913
01914 }
01915
01916 pTranspRep->SetTransparencyAttr(pTranspVal);
01917 pTranspRep->ReplaceTransparency();
01918 FoundTransp = TRUE;
01919 }
01920 }
01921
01922 }
01923
01924
01925 if (FoundTransp == FALSE)
01926 {
01927 AttrFlatTranspFill* pTransp = new AttrFlatTranspFill;
01928 if (m_pParentAttr != NULL && pTransp != NULL)
01929 {
01930
01931 UINT32 TranspVal = m_pParentAttr->GetLocalTranspValue();
01932 TranspFillAttribute* pTranspVal = (TranspFillAttribute*)pTransp->GetAttributeValue();
01933 pTranspVal->Transp = TranspVal;
01934
01935 UINT32 Type = m_pParentAttr->GetLocalTranspType();
01936 pTranspVal->SetTranspType(Type);
01937
01938
01939 pAttrMap->SetAt( CC_RUNTIME_CLASS(AttrFlatTranspFill), (void*)pTransp );
01940
01941
01942 pTranspRep->SetTransparencyAttr(pTranspVal);
01943 pTranspRep->ReplaceTransparency();
01944
01945 }
01946
01947 }
01948 }
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978 DocCoord PathProcessorBrush::AdjustPositionForOffset(DocCoord OriginalPoint, double Angle, double Scaling,
01979 MILLIPOINT OffsetValue, UINT32 OffsetType)
01980
01981 {
01982
01983 if (OffsetValue <= 0)
01984 return OriginalPoint;
01985
01986
01987 OffsetValue = (MILLIPOINT)((double) OffsetValue * Scaling);
01988
01989 double theta;
01990 double NewX;
01991 double NewY;
01992
01993
01994 switch (m_PathOffsetType)
01995 {
01996 case OFFSET_NONE:
01997 break;
01998 case OFFSET_ALTERNATE:
01999 if (m_AltValue == 0)
02000 {
02001 theta = Angle - (PI / 2);
02002 }
02003 else
02004 {
02005 theta = Angle + (PI / 2);
02006 }
02007
02008 NewX = OffsetValue * cos (theta);
02009 NewY = OffsetValue * sin (theta);
02010
02011 OriginalPoint.translate((INT32)NewX, (INT32)NewY);
02012 break;
02013 case OFFSET_RIGHT:
02014 theta = Angle - (PI / 2);
02015 NewX = OffsetValue * cos (theta);
02016 NewY = OffsetValue * sin (theta);
02017 OriginalPoint.translate((INT32)NewX, (INT32)NewY);
02018 break;
02019 case OFFSET_LEFT:
02020 theta = Angle + (PI / 2);
02021 NewX = OffsetValue * cos (theta);
02022 NewY = OffsetValue * sin (theta);
02023 OriginalPoint.translate((INT32)NewX, (INT32)NewY);
02024 break;
02025 case OFFSET_RANDOM:
02026 {
02027
02028 switch (OffsetType)
02029 {
02030 case OFFSETTYPE_LEFT:
02031 theta = Angle + (PI / 2);
02032 NewX = OffsetValue * cos (theta);
02033 NewY = OffsetValue * sin (theta);
02034 OriginalPoint.translate((INT32)NewX, (INT32)NewY);
02035 break;
02036 case OFFSETTYPE_RIGHT:
02037 theta = Angle - (PI / 2);
02038 NewX = OffsetValue * cos (theta);
02039 NewY = OffsetValue * sin (theta);
02040 OriginalPoint.translate((INT32)NewX, (INT32)NewY);
02041 break;
02042 case OFFSETTYPE_CENTRE:
02043 break;
02044 default:
02045 ERROR3("Invalid offset type returned");
02046 break;
02047 }
02048 break;
02049 }
02050
02051 default:
02052 ERROR3("Unknown offset type");
02053 break;
02054 }
02055
02056 return OriginalPoint;
02057 }
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078 DocCoord PathProcessorBrush::AdjustPositionForBlendPathOffset(DocCoord OriginalPoint, BlendPathOffset* pOffset,
02079 double Scaling, double Angle)
02080 {
02081 if (pOffset->m_XOffset == 0 && pOffset->m_YOffset == 0)
02082 return OriginalPoint;
02083
02084 MILLIPOINT XOffset;
02085 MILLIPOINT YOffset;
02086
02087 DocCoord RotateCentre = OriginalPoint;
02088
02089 XOffset = (MILLIPOINT)(pOffset->m_XOffset *Scaling);
02090 YOffset = (MILLIPOINT)(pOffset->m_YOffset *Scaling);
02091
02092
02093 OriginalPoint.translate(XOffset, YOffset);
02094
02095 return OriginalPoint;
02096 }
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114 void PathProcessorBrush::RenderTimeStampPoints(RenderRegion* pRender)
02115 {
02116 if (m_pParentAttr == NULL)
02117 {
02118
02119 return;
02120 }
02121
02122 BrushDefinition* pBrushDef = GetOurBrushDefinition();
02123 if (pBrushDef == NULL)
02124 {
02125 ERROR3("No brush definition");
02126 return;
02127 }
02128
02129 UINT32 NumBrushObjects = pBrushDef->GetNumBrushObjects();
02130
02131 Reset();
02132
02133
02134
02135
02136 UINT32 Count = 0;
02137 UINT32 BrushObjectToRender = 0;
02138
02139 DocRect InkRect = pBrushDef->GetLargestBoundingBox();
02140 DocRect RenderRect = pRender->GetClipRect();
02141
02142
02143
02144 if ((m_bRotate) || (m_RotateAngle != 0.0) || m_RotationMaxRand != 0)
02145 m_pParentAttr->RotateBounds(90, &InkRect);
02146
02147 MILLIPOINT InkWidth = InkRect.Width() / 2;
02148 MILLIPOINT InkHeight = InkRect.Height() / 2;
02149
02150
02151 TimeStampList* pTimeStampList = m_pParentAttr->GetTimeStampList();
02152 if( pTimeStampList == NULL || pTimeStampList->empty() )
02153 {
02154 ERROR3("No Timestamp list");
02155 return;
02156 }
02157 TimeStampList::iterator ListPos = pTimeStampList->begin();
02158 TimeStampBrushPoint TSBP;
02159
02160
02161
02162
02163 m_bRenderAllAttributes = TRUE;
02164 DocCoord TestPoint;
02165 m_bRenderAllAttributes = TRUE;
02166 while( ListPos != pTimeStampList->end() )
02167 {
02168 TSBP = *ListPos++;
02169
02170 m_CurrentScaling = GetNextScaling(Count);
02171
02172
02173
02174
02175
02176
02177 SetNextOffsetType();
02178 GetNextAngle();
02179 TestPoint = AdjustPositionForOffset(TSBP.m_Point, TSBP.m_Tangent, m_CurrentScaling, GetNextOffset(), m_LastOffsetType);
02180
02181 if (ObjectIsWithinRect(RenderRect, TestPoint, InkWidth, InkHeight, m_CurrentScaling))
02182 {
02183
02184 RenderBrushAtPoint(TSBP.m_Point, TSBP.m_Tangent,
02185 BrushObjectToRender, Count, pRender);
02186
02187 }
02188 if (NumBrushObjects > 1)
02189 BrushObjectToRender = GetNextInkObject(BrushObjectToRender, NumBrushObjects);
02190 Count++;
02191 GetNextAngle();
02192
02193
02194 if (m_AltValue == 0)
02195 m_AltValue = 1;
02196 else
02197 m_AltValue = 0;
02198
02199 }
02200 pRender->RestoreContext();
02201
02202 }
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226 BOOL PathProcessorBrush::ObjectIsWithinRect(DocRect Rect, DocCoord Centre, MILLIPOINT HalfWidth,
02227 MILLIPOINT HalfHeight, double Scaling, double Angle)
02228 {
02229 if (Rect.IsEmpty())
02230 return FALSE;
02231
02232
02233 if (Scaling != 1.0)
02234 {
02235 if (Scaling <=0)
02236 return FALSE;
02237 HalfHeight = (MILLIPOINT)((double)HalfHeight * Scaling);
02238 HalfWidth = (MILLIPOINT)((double)HalfWidth * Scaling);
02239 }
02240
02241
02242 DocRect TestRect;
02243 TestRect.hi.x = Centre.x + HalfWidth;
02244 TestRect.lo.x = Centre.x - HalfWidth;
02245 TestRect.hi.y = Centre.y + HalfHeight;
02246 TestRect.lo.y = Centre.y - HalfHeight;
02247
02248 BrushAttrValue::RotateBounds(Angle, &TestRect, &Centre);
02249
02250
02251 if (Rect.IsIntersectedWith(TestRect))
02252 {
02253
02254 return TRUE;
02255 }
02256
02257 return FALSE;
02258 }
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278 BOOL PathProcessorBrush::GetPointAtDistance(Path* pPath, MILLIPOINT Distance, DocCoord* pPoint,
02279 double* pTangent)
02280 {
02281 ERROR2IF(pPoint == NULL,FALSE,"NULL pPoint param");
02282 ERROR2IF(pPath == NULL, FALSE, "Path is NULL");
02283
02284 BOOL Found = FALSE;
02285 BrushPointInfo PointInfo;
02286
02287
02288 #ifdef BRUSHPOINTSCACHE
02289
02290 PointsMap* pCache = NULL;
02291 if (m_pParentAttr != NULL && m_pParentAttr->CanUsePointsCache())
02292 {
02293 pCache = m_pParentAttr->GetCache();
02294 if (pCache != NULL)
02295 {
02296
02297 PointsMap::iterator iter = pCache->find( Distance );
02298 Found = ( pCache->end() != iter );
02299 if( Found )
02300 {
02301 PointInfo = iter->second;
02302 }
02303
02304
02305
02306 }
02307 }
02308
02309 #endif
02310 if (!Found)
02311 {
02312
02313 if (pPath->GetPointAtDistance(Distance,&PointInfo.m_Point,&PointInfo.m_Tangent, &PointInfo.m_Pressure))
02314 {
02315 #ifdef BRUSHPOINTSCACHE
02316
02317 if (pCache != NULL)
02318 (*pCache)[Distance] = PointInfo;
02319 #endif
02320
02321 Found = TRUE;
02322 }
02323
02324 }
02325
02326 if (Found)
02327 {
02328 *pPoint = PointInfo.m_Point;
02329 if (pTangent)
02330 *pTangent = PointInfo.m_Tangent;
02331
02332 }
02333
02334
02335 if (Found == FALSE)
02336 TRACEUSER( "Diccon", _T("Not found at distance %d\n"), Distance);
02337 return Found;
02338 }
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357 void PathProcessorBrush::Reset()
02358 {
02359
02360 m_LastScaling = m_BrushScaling;
02361 m_LastScalingRendered = m_BrushScaling;
02362 m_LastSpacing = m_BrushSpacing;
02363 m_LastOffset = m_PathOffsetValue;
02364 m_LastAngle = m_RotateAngle;
02365 m_AltValue = 0;
02366 m_LastObject = 0;
02367 m_LastHueMultiplier = m_BrushHueIncrement;
02368 m_LastSatMultiplier = m_BrushSatIncrement;
02369
02370 m_LastSpacingNoRandom = m_BrushSpacing;
02371 if (m_PathOffsetType != OFFSET_RANDOM)
02372 m_LastOffsetNoRandom = m_PathOffsetValue;
02373 else
02374 m_LastOffsetNoRandom = 0;
02375
02376 m_LastScalingNoRandom = m_BrushScaling;
02377 m_LastRotationNoRandom = m_RotateAngle;
02378
02379 m_CurrentStrokeCol = DocColour(COLOUR_BLACK);
02380
02381
02382 ResetRandomNumberGenerators();
02383
02384
02385
02386
02387
02388 UINT32 NumObjects = 1;
02389 BrushDefinition* pDef = GetOurBrushDefinition();
02390 ERROR3IF(pDef == NULL, "No brush definition in PathProcessorBrush::Reset");
02391
02392 if (pDef)
02393 {
02394 NumObjects = pDef->GetNumBrushObjects();
02395
02396 switch (m_SequenceType)
02397 {
02398 case SEQ_FORWARD:
02399 case SEQ_MIRROR:
02400 m_LastObject = 0;
02401 m_MirrorSeqAscend = TRUE;
02402 break;
02403 case SEQ_BACKWARD:
02404 m_LastObject = NumObjects -1;
02405 break;
02406 case SEQ_RANDOM:
02407 if (NumObjects > 1)
02408 m_LastObject = GetNextInkObject(m_LastObject, NumObjects);
02409 break;
02410 default:
02411 ERROR3("Invalid sequence type in PathProcessorBrush::Reset");
02412 }
02413 }
02414 }
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431 DocRect PathProcessorBrush::CalculateBoundingBox(Path* pPath, NodeRenderableInk* pParent)
02432 {
02433 DocRect ReturnRect(0,0,0,0);
02434
02435 ERROR2IF(pPath == NULL, ReturnRect, "Path is null in PathProcessorBrush::CalculateBoundingBox");
02436 ERROR2IF(pParent == NULL, ReturnRect, "Parent is null in PathProcessorBrush::CalculateBoundingBox");
02437
02438
02439 if (m_pParentAttr != NULL)
02440 {
02441 if (m_pParentAttr->IsTimeStamping())
02442 {
02443 return TimeStampBoundingBox();
02444 }
02445 }
02446 BrushDefinition* pBrushDef = GetOurBrushDefinition();
02447 if (pBrushDef == NULL)
02448 {
02449 return ReturnRect;
02450 }
02451
02452
02453 if (!pBrushDef->StartRender())
02454 {
02455 TRACEUSER( "Diccon", _T("Unable to start render brush for bounding box\n"));
02456 return ReturnRect;
02457 }
02458
02459 Reset();
02460
02461 if (m_BrushScaling <= 0)
02462 return ReturnRect;
02463
02464 UINT32 NumBrushObjects = pBrushDef->GetNumBrushObjects();
02465
02466 if (!PrepareForRenderingLoop(NumBrushObjects))
02467 return ReturnRect;
02468
02469
02470 double dPathLength = pPath->GetPathLength(750/2);
02471
02472 MILLIPOINT PathLength = (MILLIPOINT)dPathLength;
02473 double PathProportion = 0.0;
02474
02475
02476 MILLIPOINT DistanceToPoint = 10;
02477
02478
02479 MILLIPOINT Spacing = m_BrushSpacing;
02480 CPathPointInfo PathPoint;
02481 double Angle;
02482 DocCoord Point;
02483 BOOL ok = FALSE;
02484
02485 UINT32 Count = 0;
02486 UINT32 BrushObjectToRender = m_LastObject;
02487
02488
02489
02490
02491
02492
02493 ValueFunction* pValFunc = NULL;
02494 CDistanceSampler* pPressure = GetPressureCacheAndInitialise(pParent, &pValFunc);
02495 CSampleItem TheItem;
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506 m_bRenderAllAttributes = TRUE;
02507
02508 m_CachedRect = DocRect(0,0,0,0);
02509 m_bCalculateRect = TRUE;
02510
02511 TRACEUSER( "Diccon", _T("About to calculate bounding box\n"));
02512
02513
02514 m_UseActualScaling = TRUE;
02515 m_CurrentScaling = GetNextScaling(Count);
02516 m_LastScalingRendered = m_CurrentScaling;
02517
02518 Spacing = GetNextSpacing();
02519
02520
02521 while (DistanceToPoint < PathLength)
02522 {
02523
02524
02525 ok = GetPointAtDistance(pPath, DistanceToPoint, &Point, &Angle);
02526
02527 if (ok)
02528 {
02529 GetNextAngle();
02530 SetNextOffsetType();
02531 GetNextOffset();
02532
02533 if (m_CurrentScaling > 0)
02534 RenderBrushAtPoint(Point, Angle,
02535 BrushObjectToRender, Count, NULL);
02536 Count++;
02537
02538
02539 if (NumBrushObjects > 1)
02540 BrushObjectToRender = GetNextInkObject(BrushObjectToRender, NumBrushObjects);
02541
02542 DecideWhetherToUseActualScaling(BrushObjectToRender);
02543 }
02544
02545 if (pPressure != NULL)
02546 {
02547 if (pPressure->GetNext(&TheItem))
02548 {
02549 if (TheItem.m_Pressure < 0 || TheItem.m_Pressure > MAXPRESSURE)
02550 {
02551
02552
02553 }
02554 else
02555 {
02556 m_CurrentPressure.m_Pressure = TheItem.m_Pressure;
02557
02558 }
02559 }
02560
02561
02562 }
02563 #ifdef SCALESPACING
02564 DistanceToPoint += (MILLIPOINT)(Spacing * m_LastScaling);
02565
02566 if (pPressure)
02567 pPressure->SetSampleRateFromSpacing((INT32)(Spacing * m_CurrentScaling));
02568 #else
02569 DistanceToPoint += (MILLIPOINT)(Spacing * m_BrushScaling);
02570
02571 if (pPressure)
02572 pPressure->SetSampleRateFromSpacing((INT32)(Spacing * m_CurrentScaling));
02573 #endif
02574
02575
02576 Spacing = GetNextSpacing();
02577 m_LastScalingRendered = m_pLastScalingRendered[BrushObjectToRender];
02578
02579 if (pValFunc != NULL)
02580 {
02581 PathProportion = (double)DistanceToPoint / dPathLength;
02582 m_CurrentPressure.m_Pressure = GetNextSampleItem(NULL, pValFunc, PathProportion).m_Pressure;
02583 if (m_CurrentPressure.m_Pressure > MAXPRESSURE)
02584 m_CurrentPressure.m_Pressure = MAXPRESSURE;
02585 }
02586
02587 m_CurrentScaling = GetNextScaling(Count);
02588
02589
02590 if (m_CurrentScaling <= 0)
02591 break;
02592
02593
02594
02595 if (m_AltValue == 0)
02596 m_AltValue = 1;
02597 else
02598 m_AltValue = 0;
02599
02600 }
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611 m_bCalculateRect = FALSE;
02612 TRACEUSER( "Diccon", _T("Finished bounding box\n"));
02613 CleanUpAfterRender();
02614 pBrushDef->StopRender();
02615
02616 return m_CachedRect;
02617 }
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634 DocRect PathProcessorBrush::TimeStampBoundingBox()
02635 {
02636 if (m_pParentAttr == NULL)
02637 {
02638
02639 return DocRect(0,0,0,0);
02640 }
02641
02642 BrushDefinition* pBrushDef = GetOurBrushDefinition();
02643 if (pBrushDef == NULL)
02644 {
02645 ERROR3("No brush definition");
02646 return DocRect(0,0,0,0);
02647 }
02648
02649 UINT32 NumBrushObjects = pBrushDef->GetNumBrushObjects();
02650
02651
02652 if (m_SequenceType == SEQ_RANDOM)
02653 srand(m_SequenceRandSeed);
02654
02655
02656 ResetRandomNumberGenerators();
02657
02658
02659
02660
02661 UINT32 Count = 0;
02662 UINT32 BrushObjectToRender = 0;
02663
02664
02665
02666 TimeStampList* pTimeStampList = m_pParentAttr->GetTimeStampList();
02667 if (pTimeStampList == NULL || pTimeStampList->empty())
02668 {
02669 ERROR3("No Timestamp list");
02670 return DocRect(0,0,0,0);
02671 }
02672 TimeStampList::iterator ListPos = pTimeStampList->begin();
02673 TimeStampBrushPoint TSBP;
02674
02675
02676
02677
02678
02679 m_bCalculateRect = TRUE;
02680 m_CachedRect = DocRect(0,0,0,0);
02681 while (ListPos != pTimeStampList->end())
02682 {
02683 TSBP = *ListPos++;
02684
02685 m_CurrentScaling = GetNextScaling(Count);
02686
02687
02688
02689
02690
02691
02692
02693 RenderBrushAtPoint(TSBP.m_Point, TSBP.m_Tangent,
02694 BrushObjectToRender, Count, NULL);
02695
02696
02697 if (NumBrushObjects > 1)
02698 BrushObjectToRender = GetNextInkObject(BrushObjectToRender, NumBrushObjects);
02699 Count++;
02700
02701
02702
02703 if (m_AltValue == 0)
02704 m_AltValue = 1;
02705 else
02706 m_AltValue = 0;
02707 }
02708
02709 return m_CachedRect;
02710
02711 }
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727 void PathProcessorBrush::SetCalculateBoundingBox(BOOL Set)
02728 {
02729 m_bCalculateRect = Set;
02730 }
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744 DocRect PathProcessorBrush::GetCachedRect()
02745 {
02746 return m_CachedRect;
02747 }
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766 BOOL PathProcessorBrush::DoBecomeA(BecomeA* pBecomeA, Path* pPath, Node* pParent)
02767 {
02768 ERROR2IF(pBecomeA == NULL, FALSE, "BecomeA pointer is NULL in PathProcessorBrush::DoBecomeA");
02769 ERROR2IF(pParent == NULL, FALSE, "Parent is NULL in PathProcessorBrush::DoBecomeA");
02770 ERROR2IF(pPath == NULL, FALSE, "Path is NULL in PathProcessorBrush::DoBecomeA");
02771
02772 BeginSlowJob();
02773
02774 TRACEUSER( "Diccon", _T("ABOUT TO BECOME A\n"));
02775
02776 BrushDefinition* pBrushDef = GetOurBrushDefinition();
02777 if (pBrushDef == NULL)
02778 {
02779 return FALSE;
02780 }
02781 if (!pBrushDef->StartRender())
02782 return FALSE;
02783
02784 UINT32 NumBrushObjects = pBrushDef->GetNumBrushObjects();
02785 if (!PrepareForRenderingLoop(NumBrushObjects))
02786 return FALSE;
02787 Reset();
02788
02789 if (m_BrushScaling <= 0)
02790 return TRUE;
02791
02792
02793 double dPathLength = pPath->GetPathLength(750/2);
02794 double dOrigPathLength = dPathLength;
02795 MILLIPOINT PathLength = (MILLIPOINT)dPathLength;
02796 double PathProportion = 0.0;
02797
02798
02799 MILLIPOINT DistanceToPoint = 0;
02800
02801
02802 MILLIPOINT Spacing = m_BrushSpacing;
02803 CPathPointInfo PathPoint;
02804 double Angle;
02805 DocCoord Point;
02806 BOOL ok = FALSE;
02807
02808 UINT32 Count = 0;
02809 UINT32 BrushObjectToRender = m_LastObject;
02810
02811 m_bRenderAllAttributes = TRUE;
02812
02813 if (pPath->IsClosed())
02814 {
02815
02816
02817
02818 double ActualSpacing = m_BrushScaling * (double)m_BrushSpacing;
02819
02820 PathLength -= (MILLIPOINT)(ActualSpacing * 0.2);
02821 dPathLength = (double)PathLength;
02822 AdjustSpacingForClosedPath(pPath, dOrigPathLength);
02823
02824 if (pParent->IsARegularShape())
02825 pPath->Reverse();
02826
02827 }
02828
02829
02830 ValueFunction* pValFunc = NULL;
02831 CDistanceSampler* pPressure = GetPressureCacheAndInitialise((NodeRenderableInk*)pParent, &pValFunc);
02832 CSampleItem TheItem;
02833
02834
02835 HandleBrushBecomeA HandleBecomeA;
02836 HandleBecomeA.SetSecondary(pBecomeA->IsSecondary());
02837
02838
02839 UndoableOperation* pUndoOp = pBecomeA->GetUndoOp();
02840 NodeRenderableInk* pContext = (NodeRenderableInk*)pParent;
02841 NodeGroup* pNodeGroup = NULL;
02842
02843
02844 if (pBecomeA->GetReason() == BECOMEA_REPLACE || pBecomeA->IsBrushBecomeAGroup())
02845 {
02846 ALLOC_WITH_FAIL(pNodeGroup, (new NodeGroup), pUndoOp);
02847 if (pNodeGroup == NULL)
02848 return FALSE;
02849
02850 pContext = pNodeGroup;
02851 }
02852
02853
02854 if (pBecomeA->GetReason() == BECOMEA_REPLACE)
02855 {
02856
02857 if (pUndoOp)
02858 {
02859 BOOL ok = TRUE;
02860
02861 if (pBecomeA->IsSecondary())
02862 ok = pUndoOp->DoInsertNewNode(pContext,pParent,NEXT,FALSE,FALSE,FALSE,FALSE);
02863 else
02864 ok = pUndoOp->DoInsertNewNode(pContext,pParent,PREV,FALSE,FALSE,FALSE,FALSE);
02865
02866 if (!ok)
02867 {
02868 delete pNodeGroup;
02869 return FALSE;
02870 }
02871 }
02872 else
02873 {
02874 pContext->AttachNode(pParent, PREV);
02875 }
02876
02877 HandleBecomeA.Initialise(pBecomeA, pNodeGroup, pParent);
02878 }
02879 else
02880 HandleBecomeA.Initialise(pBecomeA, pContext, pParent);
02881
02882
02883 NodeAttribute* pStrokeColour = NULL;
02884
02885
02886 ((NodeRenderableInk*)pParent)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), &pStrokeColour);
02887
02888 if (pStrokeColour != NULL)
02889 {
02890
02891
02892 StrokeColourAttribute* pVal = (StrokeColourAttribute*)pStrokeColour->GetAttributeValue();
02893 if (pVal != NULL)
02894 m_CurrentStrokeCol = pVal->Colour;
02895 }
02896
02897
02898 m_UseActualScaling = TRUE;
02899 m_CurrentScaling = GetNextScaling(Count);
02900 m_LastScalingRendered = m_CurrentScaling;
02901
02902 Spacing = GetNextSpacing();
02903 while (DistanceToPoint < PathLength)
02904 {
02905
02906
02907 ok = GetPointAtDistance(pPath, DistanceToPoint, &Point, &Angle);
02908 GetNextAngle();
02909 GetNextOffset();
02910 GetNextHueMultiplier();
02911 GetNextSaturationMultiplier();
02912 if (ok)
02913 {
02914 SetNextOffsetType();
02915
02916 if (m_CurrentScaling > 0)
02917 RenderBrushAtPoint(Point, Angle,
02918 BrushObjectToRender, Count, NULL, &HandleBecomeA);
02919
02920
02921 if (pPressure != NULL)
02922 {
02923 double pLength = dOrigPathLength;
02924 double pDataLength = pPressure->GetDistanceRep (), count = pPressure->GetCount ();
02925 double dataRatio = 1.0;
02926
02927 if (pDataLength < pLength)
02928 {
02929 dataRatio = pDataLength / pLength;
02930 }
02931 else
02932 {
02933 dataRatio = pLength / pDataLength;
02934 }
02935
02936 double offset = 1.0;
02937
02938 if (DistanceToPoint < pLength)
02939 {
02940 offset = (DistanceToPoint / pLength) * dataRatio * count;
02941 }
02942 else
02943 {
02944 offset = (pLength / DistanceToPoint) * dataRatio * count;
02945 }
02946
02947 if (pPressure->GetAtPos (offset, &TheItem))
02948 {
02949 if (TheItem.m_Pressure < MAXPRESSURE)
02950 m_CurrentPressure.m_Pressure = TheItem.m_Pressure;
02951 else
02952 m_CurrentPressure.m_Pressure = MAXPRESSURE;
02953
02954 }
02955 }
02956
02957 Count++;
02958
02959
02960 if (NumBrushObjects > 1)
02961 BrushObjectToRender = GetNextInkObject(BrushObjectToRender, NumBrushObjects);
02962
02963 DecideWhetherToUseActualScaling(BrushObjectToRender);
02964 }
02965 #ifdef SCALESPACING
02966 DistanceToPoint += (MILLIPOINT)(Spacing * m_LastScaling);
02967
02968 if (pPressure)
02969 pPressure->SetSampleRateFromSpacing((INT32)(Spacing * m_CurrentScaling));
02970 #else
02971 DistanceToPoint += (MILLIPOINT)(Spacing * m_BrushScaling);
02972
02973 if (pPressure)
02974 pPressure->SetSampleRateFromSpacing(Spacing);
02975 #endif
02976
02977 if (pValFunc != NULL)
02978 {
02979 PathProportion = (double)DistanceToPoint / dPathLength;
02980 m_CurrentPressure.m_Pressure = GetNextSampleItem(NULL, pValFunc, PathProportion).m_Pressure;
02981 if (m_CurrentPressure.m_Pressure > MAXPRESSURE)
02982 m_CurrentPressure.m_Pressure = MAXPRESSURE;
02983 }
02984
02985
02986 Spacing = GetNextSpacing();
02987 m_LastScalingRendered = m_pLastScalingRendered[BrushObjectToRender];
02988 m_CurrentScaling = GetNextScaling(Count);
02989
02990
02991
02992 if (m_AltValue == 0)
02993 m_AltValue = 1;
02994 else
02995 m_AltValue = 0;
02996
02997 }
02998
02999 pBrushDef->StopRender();
03000
03001 CleanUpAfterRender();
03002 TRACEUSER( "Diccon", _T("FINISHED BRUSH DOBECOMEA\n"));
03003
03004 if (pBecomeA->GetReason() == BECOMEA_REPLACE)
03005 {
03006 HandleBecomeA.FinishPassback();
03007
03008 return HandleBecomeA.HideCreatedByNode();
03009 }
03010 else
03011 return HandleBecomeA.FinishPassback();
03012
03013 return FALSE;
03014 }
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034 BOOL PathProcessorBrush::DoesActuallyDoAnything(RenderRegion* pRender)
03035 {
03036 if (pRender == NULL)
03037 {
03038 ERROR3("No render region supplied to PathProcessorBrush::DoesActuallyDoAnything");
03039 return FALSE;
03040 }
03041
03042
03043 LineWidthAttribute* pLine = (LineWidthAttribute*)pRender->GetCurrentAttribute(ATTR_LINEWIDTH);
03044
03045 if (pLine && pLine->LineWidth < 500)
03046 return FALSE;
03047
03048
03049 StrokeColourAttribute* pStroke = (StrokeColourAttribute*)pRender->GetCurrentAttribute(ATTR_STROKECOLOUR);
03050
03051 if (pStroke && pStroke != NULL)
03052 {
03053 if (pStroke->Colour.IsTransparent())
03054 return FALSE;
03055 }
03056 return TRUE;
03057 }
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070 BrushDefinition* PathProcessorBrush::GetOurBrushDefinition()
03071 {
03072
03073 if (m_BrushHandle == BrushHandle_NoBrush)
03074 {
03075
03076 return NULL;
03077 }
03078
03079 return BrushComponent::FindBrushDefinition(m_BrushHandle);
03080
03081 }
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103 BOOL PathProcessorBrush::IsDifferent(PathProcessorBrush *pOther)
03104 {
03105 ERROR3IF(pOther == NULL, "Illegal NULL param");
03106
03107 if (GetRuntimeClass() != pOther->GetRuntimeClass())
03108 return(TRUE);
03109
03110
03111 if (
03112 (m_BrushHandle != pOther->GetBrushDefinitionHandle())
03113 || (m_BrushSpacing != pOther->GetSpacing())
03114 || (m_BrushSpacingIncrConst != pOther->GetSpacingIncrConst())
03115 || (m_BrushSpacingIncrProp != pOther->GetSpacingIncrProp())
03116 || (m_BrushSpacingMaxRand != pOther->GetSpacingMaxRand())
03117 || (m_BrushSpacingRandSeed != pOther->GetSpacingRandSeed())
03118 || (m_BrushScaling != pOther->GetBrushScaling())
03119 || (m_BrushScalingIncr != pOther->GetBrushScalingIncr())
03120 || (m_BrushScalingIncrConst != pOther->GetBrushScalingIncrConst())
03121 || (m_BrushScalingMaxRand != pOther->GetScalingMaxRand())
03122 || (m_BrushScalingRandSeed != pOther->GetScalingRandSeed())
03123 || (m_RotateAngle != pOther->GetRotationAngle())
03124 || (m_RotAngleIncrConst != pOther->GetRotationIncrConst())
03125 || (m_RotationMaxRand != pOther->GetRotationMaxRand())
03126 || (m_RotationRandSeed != pOther->GetRotationRandSeed())
03127 || (m_bTile != pOther->IsTiled())
03128 || (m_bRotate != pOther->IsRotated())
03129 || (m_PathOffsetType != pOther->GetPathOffsetType())
03130 || (m_PathOffsetValue != pOther->GetPathOffsetValue())
03131 || (m_PathOffsetIncrConst != pOther->GetPathOffsetIncrConst())
03132 || (m_PathOffsetIncrProp != pOther->GetPathOffsetIncrProp())
03133 || (m_OffsetValueMaxRand != pOther->GetOffsetValueMaxRand())
03134 || (m_OffsetValueRandSeed != pOther->GetOffsetValueRandSeed())
03135 || (m_OffsetTypeRandSeed != pOther->GetOffsetTypeRandSeed())
03136 || (m_SequenceType != pOther->GetSequenceType())
03137 || (m_SequenceRandSeed != pOther->GetSequenceSeed())
03138 || (m_bUseLocalFillColour != pOther->GetUseLocalFillColour())
03139 || (m_bUseLocalTransp != pOther->GetUseLocalTransp())
03140 || (m_bUseNamedColours != pOther->GetUseNamedColours())
03141 )
03142 return TRUE;
03143
03144
03145 return(FALSE);
03146 }
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164 PathProcessorBrush *PathProcessorBrush::Clone(void)
03165 {
03166
03167
03168 PathProcessorBrush *pClone = new PathProcessorBrush;
03169
03170 if (pClone == NULL)
03171 return NULL;
03172
03173
03174 pClone->SetBrushDefinition(m_BrushHandle);
03175 pClone->SetPathOffsetType(m_PathOffsetType);
03176 pClone->SetPathOffsetValue(m_PathOffsetValue);
03177 pClone->SetRotated(m_bRotate);
03178 pClone->SetRotationAngle(m_RotateAngle);
03179 pClone->SetRotationIncrConst(m_RotAngleIncrConst);
03180 pClone->SetRotationIncrProp(m_RotAngleIncrProp);
03181 pClone->SetRotationMaxPressure(m_RotationMaxPressure);
03182
03183 pClone->SetSpacing(m_BrushSpacing);
03184 pClone->SetTiling(m_bTile);
03185 pClone->SetBrushScaling(m_BrushScaling);
03186 pClone->SetBrushScalingIncr(m_BrushScalingIncr);
03187 pClone->SetBrushScalingIncrConst(m_BrushScalingIncrConst);
03188 pClone->SetMaxScaling(m_MaxScaling);
03189 pClone->SetScalingMaxPressure(m_ScalingMaxPressure);
03190 pClone->SetSpacingIncrProp(m_BrushSpacingIncrProp);
03191 pClone->SetSpacingIncrConst(m_BrushSpacingIncrConst);
03192 pClone->SetSpacingMaxPressure(m_SpacingMaxPressure);
03193 pClone->SetPathOffsetIncrConst(m_PathOffsetIncrConst);
03194 pClone->SetPathOffsetIncrProp(m_PathOffsetIncrProp);
03195 pClone->SetSpacingMaxRand(m_BrushSpacingMaxRand);
03196 pClone->SetSpacingRandSeed(m_BrushSpacingRandSeed);
03197 pClone->SetScalingMaxRand(m_BrushScalingMaxRand);
03198 pClone->SetScalingRandSeed(m_BrushScalingRandSeed);
03199 pClone->SetSequenceType(m_SequenceType);
03200 pClone->SetSequenceSeed(m_SequenceRandSeed);
03201 pClone->SetOffsetValueMaxRand(m_OffsetValueMaxRand);
03202 pClone->SetOffsetValueRandSeed(m_OffsetValueRandSeed);
03203 pClone->SetOffsetTypeRandSeed(m_OffsetTypeRandSeed);
03204
03205 pClone->SetRotationMaxRand(m_RotationMaxRand);
03206 pClone->SetRotationRandSeed(m_RotationRandSeed);
03207
03208 pClone->SetUseLocalFillColour(m_bUseLocalFillColour);
03209 pClone->SetUseLocalTransp(m_bUseLocalTransp);
03210 pClone->SetUseNamedColours(m_bUseNamedColours);
03211
03212 pClone->SetHueIncrement(m_BrushHueIncrement);
03213 pClone->SetHueMaxRand(m_BrushHueMaxRand);
03214 pClone->SetHueRandSeed(m_BrushHueRandSeed);
03215 pClone->SetSatIncrement(m_BrushSatIncrement);
03216 pClone->SetSatMaxRand(m_BrushSatMaxRand);
03217 pClone->SetSatRandSeed(m_BrushSatRandSeed);
03218
03219 pClone->SetBrushTransparency(m_BrushTransparency);
03220 pClone->SetTransparencyPressure(m_TranspMaxPressure);
03221
03222 pClone->SetParentAttribute(m_pParentAttr);
03223
03224 return(pClone);
03225 }
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244 void PathProcessorBrush::SetBrushDefinition(BrushHandle Handle)
03245 {
03246 m_BrushHandle = Handle;
03247 }
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263 BrushHandle PathProcessorBrush::GetBrushDefinitionHandle()
03264 {
03265 return m_BrushHandle;
03266 }
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284 void PathProcessorBrush::SwitchAlternateValue()
03285 {
03286 if (m_AltValue == 0)
03287 m_AltValue = 1;
03288 else
03289 m_AltValue = 0;
03290 }
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305 INT32 PathProcessorBrush::GetObjectCountToDistance(MILLIPOINT Distance)
03306 {
03307 if (Distance < 0)
03308 return -1;
03309 Reset();
03310 MILLIPOINT DistanceSoFar = 0;
03311 INT32 Count = 0;
03312 while (DistanceSoFar < Distance)
03313 {
03314 DistanceSoFar += GetNextSpacing();
03315 Count++;
03316 }
03317 return Count;
03318 }
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333 MILLIPOINT PathProcessorBrush::GetDistanceToObject(UINT32 ObjectNum)
03334 {
03335 MILLIPOINT Distance = 0;
03336 UINT32 ObjectCounter = 0;
03337
03338 Reset();
03339
03340 while (ObjectCounter < ObjectNum)
03341 {
03342 Distance += GetNextSpacing();
03343 ObjectCounter++;
03344 }
03345 return Distance;
03346 }
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361 MILLIPOINT PathProcessorBrush::GetSpacingAtDistance(MILLIPOINT Distance)
03362 {
03363 if (Distance < 0)
03364 return -1;
03365
03366 Reset();
03367
03368 MILLIPOINT DistanceSoFar = 0;
03369
03370 while (DistanceSoFar <= Distance)
03371 {
03372 DistanceSoFar+= GetNextSpacing();
03373 }
03374
03375 MILLIPOINT SpacingGap = DistanceSoFar - Distance;
03376 TRACEUSER( "Diccon", _T("Spacing at distance = %d\n"), SpacingGap);
03377 return SpacingGap;
03378 }
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405 BOOL PathProcessorBrush::GetSpacingAndScalingAtDistance(MILLIPOINT Distance, MILLIPOINT* pSpacing,
03406 double* pScaling, UINT32* pPressure)
03407
03408 {
03409
03410 ERROR2IF(pSpacing == NULL, FALSE, "Invalid input to PathProcessorBrush::GetSpacingAndScalingAtDistance");
03411 ERROR2IF(pScaling == NULL, FALSE, "Invalid input to PathProcessorBrush::GetSpacingAndScalingAtDistance");
03412 ERROR2IF(Distance < 0, FALSE, "Invalid input to PathProcessorBrush::GetSpacingAndScalingAtDistance");
03413
03414
03415 Reset();
03416
03417
03418 CDistanceSampler* pSampler = GetPressureCacheAndInitialise();
03419 CSampleItem TheItem;
03420
03421 UINT32 Count = 0;
03422 m_CurrentScaling = GetNextScaling(Count);
03423 MILLIPOINT Spacing = GetNextSpacing();
03424 MILLIPOINT DistanceSoFar = 0;
03425
03426 while (DistanceSoFar <= Distance)
03427 {
03428
03429 #ifdef SCALESPACING
03430 DistanceSoFar += (MILLIPOINT)(Spacing * m_LastScaling);
03431 #else
03432 DistanceSoFar += (MILLIPOINT)Spacing;
03433 #endif
03434
03435
03436 if (pSampler != NULL)
03437 {
03438 if (pSampler->GetNext(&TheItem))
03439 {
03440 if (TheItem.m_Pressure < MAXPRESSURE)
03441 m_CurrentPressure.m_Pressure = TheItem.m_Pressure;
03442 }
03443 }
03444 #ifdef SCALESPACING
03445 if (pPressure)
03446 pSampler->SetSampleRateFromSpacing((INT32)(Spacing * m_LastScaling));
03447 #else
03448 if (pPressure)
03449 pSampler->SetSampleRateFromSpacing(Spacing);
03450 #endif
03451
03452
03453 Spacing = GetNextSpacing();
03454 m_CurrentScaling = GetNextScaling(Count);
03455 }
03456
03457
03458 MILLIPOINT DistanceGap = DistanceSoFar - Distance;
03459 if (Spacing < DistanceGap)
03460 DistanceGap = Spacing;
03461
03462
03463 if (DistanceGap == 0)
03464 DistanceGap = Spacing;
03465
03466
03467 *pSpacing = DistanceGap;
03468 *pScaling = m_CurrentScaling;
03469 if (pPressure != NULL)
03470 *pPressure = m_CurrentPressure.m_Pressure;
03471
03472 return TRUE;
03473 }
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490 BOOL PathProcessorBrush::AdvanceBrushToDistance(MILLIPOINT Distance)
03491 {
03492 ERROR2IF(Distance < 0, FALSE, "Invalid input to PathProcessorBrush::GetSpacingAndScalingAtDistance");
03493 BrushDefinition* pDef = BrushComponent::FindBrushDefinition(m_BrushHandle);
03494 ERROR2IF(pDef == NULL, FALSE,"No brush definition in PathProcessorBrush::AdvanceBrushToDistance");
03495
03496
03497 Reset();
03498
03499
03500 CDistanceSampler* pSampler = GetPressureCacheAndInitialise();
03501 CSampleItem TheItem;
03502
03503 UINT32 Count = 0;
03504
03505 UINT32 NumBrushObjects = pDef->GetNumBrushObjects();
03506 UINT32 BrushObject = m_LastObject;
03507 if (NumBrushObjects > 1 && m_SequenceType == SEQ_RANDOM)
03508 BrushObject = GetNextInkObject(m_LastObject, NumBrushObjects);
03509
03510 m_CurrentScaling = GetNextScaling(Count++);
03511 MILLIPOINT Spacing = GetNextSpacing();
03512 MILLIPOINT DistanceSoFar = 0;
03513
03514 while (DistanceSoFar <= Distance)
03515 {
03516
03517 #ifdef SCALESPACING
03518 DistanceSoFar += (MILLIPOINT)(Spacing * m_CurrentScaling);
03519 #else
03520 DistanceSoFar += (MILLIPOINT)Spacing;
03521 #endif
03522 GetNextOffsetType();
03523 GetNextOffset();
03524 GetNextAngle();
03525 GetNextHueMultiplier();
03526 GetNextSaturationMultiplier();
03527
03528 if (pSampler != NULL)
03529 {
03530 if (pSampler->GetNext(&TheItem))
03531 {
03532 if (TheItem.m_Pressure < MAXPRESSURE)
03533 m_CurrentPressure.m_Pressure = TheItem.m_Pressure;
03534 }
03535 #ifdef SCALESPACING
03536 pSampler->SetSampleRateFromSpacing((INT32)(Spacing * m_CurrentScaling));
03537 #else
03538 pSampler->SetSampleRateFromSpacing(Spacing);
03539 #endif
03540 }
03541
03542
03543
03544 Spacing = GetNextSpacing();
03545 m_CurrentScaling = GetNextScaling(Count++);
03546
03547 if (m_AltValue == 0)
03548 m_AltValue = 1;
03549 else
03550 m_AltValue = 0;
03551
03552 if (NumBrushObjects > 1)
03553 BrushObject = GetNextInkObject(BrushObject, NumBrushObjects);
03554 }
03555 m_LastObject = BrushObject;
03556 return TRUE;
03557 }
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573 UINT32 PathProcessorBrush::GetLastObject()
03574 {
03575 return m_LastObject;
03576 }
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597 void PathProcessorBrush::AdjustSpacingForClosedPath(NodeRenderableInk* pInk)
03598 {
03599 if (pInk == NULL)
03600 {
03601 ERROR3("Ink node is NULL in PathProcessorBrush::AdjustSpacingForClosedPath");
03602 return;
03603 }
03604 if (pInk->IsCompound())
03605 return;
03606
03607
03608 SimpleBecomeA BecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), NULL);
03609
03610 if (pInk->DoBecomeA(&BecomeA))
03611 {
03612 NodePath* pNodePath = BecomeA.GetNodePath();
03613 if (pNodePath)
03614 {
03615 if (pNodePath->InkPath.IsClosed())
03616 {
03617 AdjustSpacingForClosedPath(&(pNodePath->InkPath), pNodePath->InkPath.GetPathLength(750/2));
03618 }
03619
03620
03621 delete pNodePath;
03622 }
03623 }
03624
03625 }
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645 void PathProcessorBrush::AdjustSpacingForClosedPath(Path* pPath, double dPathLength)
03646 {
03647 if (pPath == NULL || !pPath->IsClosed())
03648 return;
03649
03651
03652
03653
03654
03655
03656 double ActualSpacing = m_BrushScaling * (double)m_BrushSpacing;
03657 INT32 NumObjects = (INT32)(dPathLength / ActualSpacing);
03658
03659
03660
03661 if ( NumObjects == 0 )
03662 {
03663 NumObjects = 1;
03664 }
03665
03666
03667 double NewActualSpacing = dPathLength / (double)NumObjects;
03668
03669 double NewSpacing = NewActualSpacing / m_BrushScaling;
03670
03671
03672 SetSpacing((MILLIPOINT)NewSpacing);
03673 }
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689 CDistanceSampler* PathProcessorBrush::GetPressureCacheAndInitialise()
03690 {
03691
03692 CDistanceSampler* pPressure = NULL;
03693
03694
03695 if (m_pParentAttr != NULL)
03696 pPressure = m_pParentAttr->GetPressureCache();
03697
03698
03699
03700 CSampleItem TheItem;
03701
03702
03703 MILLIPOINT FirstDistance = 10;
03704
03705
03706 m_CurrentPressure.m_Pressure = MAXPRESSURE / 2;
03707 if (pPressure == NULL)
03708 m_bValidPressure = FALSE;
03709 else
03710 {
03711 if (pPressure->GetAt(0, &TheItem))
03712 {
03713 if (TheItem.m_Pressure < 0 || TheItem.m_Pressure > MAXPRESSURE)
03714 {
03715 ERROR3("Invalid pressure here ");
03716 }
03717 else
03718 {
03719 m_CurrentPressure.m_Pressure = TheItem.m_Pressure;
03720 pPressure->SetSampleRateFromSpacing(FirstDistance);
03721 }
03722 }
03723 else
03724 ERROR3("Unable to retrieve first pressure value in PathProcessorBrush::ProcessPath");
03725
03726 m_bValidPressure = TRUE;
03727 }
03728 return pPressure;
03729 }
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757 CDistanceSampler* PathProcessorBrush::GetPressureCacheAndInitialise(RenderRegion* pRegion, ValueFunction** ppValFunc)
03758 {
03759 ERROR2IF(pRegion == NULL, NULL, "Render region is NULL in PathProcessorBrush::GetPressureCacheAndInitialise");
03760
03761 ValueFunction* pValFunc = NULL;
03762
03763
03764 VariableWidthAttrValue *pVarWidthAttr = (VariableWidthAttrValue *) pRegion->GetCurrentAttribute(ATTR_VARWIDTH);
03765 if (pVarWidthAttr != NULL)
03766 pValFunc = pVarWidthAttr->GetWidthFunction();
03767
03768
03769
03770 if (pValFunc == NULL || IS_A(pValFunc, ValueFunctionConstant))
03771 return GetPressureCacheAndInitialise();
03772 else
03773 {
03774
03775
03776
03777 m_CurrentPressure.m_Pressure = MAXPRESSURE / 2;
03778
03779
03780 double Val = pValFunc->GetValue(0);
03781
03782 m_CurrentPressure.m_Pressure = (UINT32)((double)MAXPRESSURE * Val);
03783
03784
03785 *ppValFunc = pValFunc;
03786
03787 m_bValidPressure = TRUE;
03788 }
03789 return NULL;
03790 }
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818 CDistanceSampler* PathProcessorBrush::GetPressureCacheAndInitialise(NodeRenderableInk* pInkNode,
03819 ValueFunction** ppValFunc)
03820 {
03821 ERROR2IF(pInkNode == NULL, NULL, "Ink node is NULL in PathProcessorBrush::GetPressureCacheAndInitialise");
03822
03823 ValueFunction* pValFunc = NULL;
03824 AttrVariableWidth* pVarWidth = NULL;
03825
03826 if (pInkNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrVariableWidth), (NodeAttribute**)&pVarWidth))
03827 {
03828 VariableWidthAttrValue* pVal = (VariableWidthAttrValue*)pVarWidth->GetAttributeValue();
03829 pValFunc = pVal->GetWidthFunction();
03830 }
03831
03832
03833 if (pValFunc == NULL || IS_A(pValFunc, ValueFunctionConstant))
03834 return GetPressureCacheAndInitialise();
03835 else
03836 {
03837
03838
03839
03840 m_CurrentPressure.m_Pressure = MAXPRESSURE / 2;
03841
03842
03843 double Val = pValFunc->GetValue(0);
03844
03845 m_CurrentPressure.m_Pressure = (UINT32)((double)MAXPRESSURE * Val);
03846
03847
03848 *ppValFunc = pValFunc;
03849
03850 m_bValidPressure = TRUE;
03851 }
03852
03853
03854 return NULL;
03855 }
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876 CSampleItem PathProcessorBrush::GetNextSampleItem(CDistanceSampler* pSampler, ValueFunction* pValFunc,
03877 double PathProportion)
03878 {
03879 if (PathProportion > 1.0)
03880 PathProportion = 0.98;
03881 if (PathProportion < 0.0)
03882 PathProportion = 0.0;
03883
03884
03885 CSampleItem TheItem;
03886 TheItem.m_Pressure = MAXPRESSURE / 2;
03887
03888
03889 if (pValFunc != NULL)
03890 {
03891 double Val = pValFunc->GetValue(PathProportion);
03892 TheItem.m_Pressure = (UINT32)((double)MAXPRESSURE * Val);
03893
03894 }
03895 else if (pSampler != NULL)
03896 {
03897 pSampler->GetNext(&TheItem);
03898 }
03899
03900 return TheItem;
03901 }
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922 BOOL PathProcessorBrush::SetSpacing(MILLIPOINT Spacing)
03923 {
03924 if (Spacing < MIN_BRUSH_SPACING || Spacing > MAX_BRUSH_SPACING)
03925 return FALSE;
03926
03927 m_BrushSpacing = Spacing;
03928 m_LastSpacing = Spacing;
03929 m_LastSpacingNoRandom = Spacing;
03930
03931
03932 return TRUE;
03933
03934 }
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949 MILLIPOINT PathProcessorBrush::GetSpacing()
03950 {
03951 return m_BrushSpacing;
03952 }
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968 BOOL PathProcessorBrush::SetSpacingIncrProp(double Incr)
03969 {
03970 if (Incr <= 0)
03971 return FALSE;
03972
03973 m_BrushSpacingIncrProp = Incr;
03974 return TRUE;
03975 }
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990 double PathProcessorBrush::GetSpacingIncrProp()
03991 {
03992 return m_BrushSpacingIncrProp;
03993 }
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009 BOOL PathProcessorBrush::SetSpacingIncrConst(MILLIPOINT Incr)
04010 {
04011
04012 m_BrushSpacingIncrConst = Incr;
04013 return TRUE;
04014 }
04015
04016
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028 MILLIPOINT PathProcessorBrush::GetSpacingIncrConst()
04029 {
04030 return m_BrushSpacingIncrConst;
04031 }
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045 UINT32 PathProcessorBrush::GetSpacingMaxRand()
04046 {
04047 return m_BrushSpacingMaxRand;
04048 }
04049
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063 BOOL PathProcessorBrush::SetSpacingMaxRand(UINT32 Value)
04064 {
04065 if (Value < MIN_BRUSH_RAND || Value > MAX_BRUSH_RAND)
04066 return FALSE;
04067
04068 m_BrushSpacingMaxRand = Value;
04069 return TRUE;
04070 }
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084 UINT32 PathProcessorBrush::GetSpacingRandSeed()
04085 {
04086 return m_BrushSpacingRandSeed;
04087 }
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102 BOOL PathProcessorBrush::SetSpacingRandSeed(UINT32 Value)
04103 {
04104 #ifdef USE_MTRNG
04105 if(m_pSpacingRNG == NULL)
04106 {
04107 m_pSpacingRNG = new MTRand((UINT32)Value);
04108 if (m_pSpacingRNG == NULL)
04109 return FALSE;
04110 }
04111 else
04112 m_pSpacingRNG->seed((UINT32)Value);
04113 #endif
04114 m_BrushSpacingRandSeed = Value;
04115 return TRUE;
04116 }
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127
04128
04129
04130
04131 BOOL PathProcessorBrush::SetSpacingMaxPressure(UINT32 Max)
04132 {
04133 if (Max < MIN_PRESSURE_EFFECT || Max > MAX_PRESSURE_EFFECT)
04134 return FALSE;
04135
04136 m_SpacingMaxPressure = Max;
04137 return TRUE;
04138 }
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153 UINT32 PathProcessorBrush::GetSpacingMaxPressure()
04154 {
04155 return m_SpacingMaxPressure;
04156 }
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172 MILLIPOINT PathProcessorBrush::GetLastSpacing()
04173 {
04174 return m_LastSpacing;
04175 }
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188
04189
04190 PathOffset PathProcessorBrush::GetPathOffsetType()
04191 {
04192 return m_PathOffsetType;
04193 }
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208 void PathProcessorBrush::SetPathOffsetType(PathOffset Offset)
04209 {
04210 #ifdef USE_MTRNG
04211 if (m_pOffsetTypeRNG == NULL)
04212 {
04213 m_pOffsetTypeRNG = new MTRand;
04214 if (m_pOffsetTypeRNG == NULL)
04215 return;
04216 }
04217 m_pOffsetTypeRNG->seed((UINT32)m_OffsetTypeRandSeed);
04218 #endif
04219
04220 m_PathOffsetType = Offset;
04221 }
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238 MILLIPOINT PathProcessorBrush::GetPathOffsetValue()
04239 {
04240 return m_PathOffsetValue;
04241 }
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255 void PathProcessorBrush::SetPathOffsetValue(MILLIPOINT Value)
04256 {
04257 if (Value < 0 || Value > MAX_BRUSH_SPACING)
04258 {
04259
04260 return;
04261 }
04262
04263 m_PathOffsetValue = Value;
04264 m_LastOffset = Value;
04265 m_LastOffsetNoRandom = m_PathOffsetValue;
04266 }
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282 MILLIPOINT PathProcessorBrush::GetPathOffsetIncrConst()
04283 {
04284 return m_PathOffsetIncrConst;
04285 }
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299 BOOL PathProcessorBrush::SetPathOffsetIncrConst(MILLIPOINT Value)
04300 {
04301 m_PathOffsetIncrConst = Value;
04302 return TRUE;
04303 }
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319 double PathProcessorBrush::GetPathOffsetIncrProp()
04320 {
04321 return m_PathOffsetIncrProp;
04322 }
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332
04333
04334
04335
04336 BOOL PathProcessorBrush::SetPathOffsetIncrProp(double Incr)
04337 {
04338 if (Incr <= 0 )
04339 return FALSE;
04340
04341
04342
04343
04344
04345
04346 m_PathOffsetIncrProp = Incr;
04347 return TRUE;
04348 }
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362 UINT32 PathProcessorBrush::GetOffsetValueMaxRand()
04363 {
04364 return m_OffsetValueMaxRand;
04365 }
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380 BOOL PathProcessorBrush::SetOffsetValueMaxRand(UINT32 Value)
04381 {
04382 if (Value < MIN_BRUSH_RAND || Value > MAX_BRUSH_RAND)
04383 return FALSE;
04384
04385 m_OffsetValueMaxRand = Value;
04386 return TRUE;
04387 }
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401 UINT32 PathProcessorBrush::GetOffsetValueRandSeed()
04402 {
04403 return m_OffsetValueRandSeed;
04404 }
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419 BOOL PathProcessorBrush::SetOffsetValueRandSeed(UINT32 Value)
04420 {
04421 #ifdef USE_MTRNG
04422 if(m_pOffsetValueRNG == NULL)
04423 {
04424 m_pOffsetValueRNG = new MTRand((UINT32)Value);
04425 if (m_pOffsetValueRNG == NULL)
04426 return FALSE;
04427 }
04428 else
04429 m_pOffsetValueRNG->seed((UINT32)Value);
04430 #endif
04431 m_OffsetValueRandSeed = Value;
04432 return TRUE;
04433
04434 }
04435
04436
04437
04438
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451 UINT32 PathProcessorBrush::GetOffsetTypeRandSeed()
04452 {
04453 return m_OffsetTypeRandSeed;
04454 }
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468 BOOL PathProcessorBrush::SetOffsetTypeRandSeed(UINT32 Value)
04469 {
04470 #ifdef USE_MTRNG
04471 if(m_pOffsetTypeRNG == NULL)
04472 {
04473 m_pOffsetTypeRNG = new MTRand((UINT32)Value);
04474 if (m_pOffsetTypeRNG == NULL)
04475 return FALSE;
04476 }
04477 else
04478 m_pOffsetTypeRNG->seed((UINT32)Value);
04479 #endif
04480
04481 m_OffsetTypeRandSeed = Value;
04482 return TRUE;
04483
04484 }
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501
04502
04503 void PathProcessorBrush::SetTiling(BOOL Value)
04504 {
04505 m_bTile = Value;
04506 }
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523 BOOL PathProcessorBrush::IsTiled()
04524 {
04525 return m_bTile;
04526 }
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543 BOOL PathProcessorBrush::SetRotationAngle(double Angle)
04544 {
04545
04546
04547
04548
04549
04550
04551 m_RotateAngle = Angle;
04552 m_LastAngle = m_RotateAngle;
04553 m_LastRotationNoRandom = m_RotateAngle;
04554 return TRUE;
04555 }
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570 double PathProcessorBrush::GetRotationAngle()
04571 {
04572 return m_RotateAngle;
04573 }
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589 BOOL PathProcessorBrush::SetRotationIncrConst(double Angle)
04590 {
04591 m_RotAngleIncrConst = Angle;
04592
04593 return TRUE;
04594 }
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609 double PathProcessorBrush::GetRotationIncrConst()
04610 {
04611 return m_RotAngleIncrConst;
04612 }
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628 BOOL PathProcessorBrush::SetRotationIncrProp(double Value)
04629 {
04630 m_RotAngleIncrProp = Value;
04631
04632 return TRUE;
04633 }
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648 double PathProcessorBrush::GetRotationIncrProp()
04649 {
04650 return m_RotAngleIncrProp;
04651 }
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665
04666 UINT32 PathProcessorBrush::GetRotationMaxRand()
04667 {
04668 return m_RotationMaxRand;
04669 }
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685 BOOL PathProcessorBrush::SetRotationMaxRand(UINT32 Value)
04686 {
04687 m_RotationMaxRand = Value;
04688 return TRUE;
04689 }
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699
04700
04701
04702
04703
04704
04705 UINT32 PathProcessorBrush::GetRotationRandSeed()
04706 {
04707 return m_RotationRandSeed;
04708 }
04709
04710
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720
04721
04722
04723
04724
04725 void PathProcessorBrush::SetRotationRandSeed(UINT32 Seed)
04726 {
04727 #ifdef USE_MTRNG
04728 if (m_pRotationRNG == NULL)
04729 {
04730 m_pRotationRNG = new MTRand;
04731 if (m_pRotationRNG == NULL)
04732 return;
04733 }
04734 m_pRotationRNG->seed((UINT32)Seed);
04735 #endif
04736 m_RotationRandSeed = Seed;
04737 }
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754 UINT32 PathProcessorBrush::GetRotationMaxPressure()
04755 {
04756 return m_RotationMaxPressure;
04757 }
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773
04774 BOOL PathProcessorBrush::SetRotationMaxPressure(UINT32 Value)
04775 {
04776 if (Value < MIN_PRESSURE_EFFECT || Value > MAX_PRESSURE_EFFECT)
04777 return FALSE;
04778 m_RotationMaxPressure = Value;
04779 return TRUE;
04780 }
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795 BOOL PathProcessorBrush::IsRotated()
04796 {
04797 return m_bRotate;
04798 }
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809
04810
04811
04812
04813
04814 void PathProcessorBrush::SetRotated(BOOL Value)
04815 {
04816 m_bRotate = Value;
04817 }
04818
04819
04820
04821
04822
04823
04824
04825
04826
04827
04828
04829
04830
04831
04832
04833 double PathProcessorBrush::GetBrushScaling()
04834 {
04835 return m_BrushScaling;
04836 }
04837
04838
04839
04840
04841
04842
04843
04844
04845
04846
04847
04848
04849
04850
04851
04852
04853
04854 BOOL PathProcessorBrush::SetBrushScaling(double Scale)
04855 {
04856
04857
04858
04859
04860
04861
04862 if (Scale >= MAX_BRUSH_SCALE)
04863 {
04864
04865 m_BrushScaling = MAX_BRUSH_SCALE;
04866 return TRUE;
04867 }
04868
04869 m_BrushScaling = Scale;
04870 m_CurrentScaling = Scale;
04871 m_LastScaling = Scale;
04872 m_LastScalingNoRandom = Scale;
04873 return TRUE;
04874 }
04875
04876
04877
04878
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890 double PathProcessorBrush::GetBrushScalingIncr()
04891 {
04892 return m_BrushScalingIncr;
04893 }
04894
04895
04896
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908
04909
04910
04911
04912 BOOL PathProcessorBrush::SetBrushScalingIncr(double Incr)
04913 {
04914 if (Incr <= 0)
04915 {
04916
04917 return FALSE;
04918 }
04919
04920 m_BrushScalingIncr = Incr;
04921 return TRUE;
04922 }
04923
04924
04925
04926
04927
04928
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938 double PathProcessorBrush::GetBrushScalingIncrConst()
04939 {
04940 return m_BrushScalingIncrConst;
04941 }
04942
04943
04944
04945
04946
04947
04948
04949
04950
04951
04952
04953
04954
04955
04956
04957
04958 BOOL PathProcessorBrush::SetBrushScalingIncrConst(double Incr)
04959 {
04960 if (Abs(Incr) >= 100)
04961 {
04962 return FALSE;
04963 }
04964 m_BrushScalingIncrConst = Incr;
04965 return TRUE;
04966 }
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979 UINT32 PathProcessorBrush::GetScalingMaxRand()
04980 {
04981 return m_BrushScalingMaxRand;
04982 }
04983
04984
04985
04986
04987
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997 BOOL PathProcessorBrush::SetScalingMaxRand(UINT32 Value)
04998 {
04999 if (Value < MIN_BRUSH_RAND || Value > MAX_BRUSH_RAND)
05000 return FALSE;
05001
05002 m_BrushScalingMaxRand = Value;
05003 return TRUE;
05004 }
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018 UINT32 PathProcessorBrush::GetScalingRandSeed()
05019 {
05020 return m_BrushScalingRandSeed;
05021 }
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032
05033
05034
05035
05036 BOOL PathProcessorBrush::SetScalingRandSeed(UINT32 Value)
05037 {
05038 #ifdef USE_MTRNG
05039 if(m_pScalingRNG == NULL)
05040 {
05041 m_pScalingRNG = new MTRand((UINT32)Value);
05042 if (m_pScalingRNG == NULL)
05043 return FALSE;
05044 }
05045 else
05046 m_pScalingRNG->seed((UINT32)Value);
05047 #endif
05048 m_BrushScalingRandSeed = Value;
05049 return TRUE;
05050 }
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061
05062
05063
05064 UINT32 PathProcessorBrush::GetScalingMaxPressure()
05065 {
05066 return m_ScalingMaxPressure;
05067 }
05068
05069
05070
05071
05072
05073
05074
05075
05076
05077
05078
05079
05080
05081 double PathProcessorBrush::GetLastScaling()
05082 {
05083 return m_LastScaling;
05084 }
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095
05096
05097
05098 BOOL PathProcessorBrush::SetScalingMaxPressure(UINT32 Max)
05099 {
05100 if (Max < MIN_PRESSURE_EFFECT || Max > MAX_PRESSURE_EFFECT)
05101 return FALSE;
05102 m_ScalingMaxPressure = Max;
05103 return TRUE;
05104 }
05105
05106
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118
05119
05120 double PathProcessorBrush::GetHueIncrement()
05121 {
05122 return m_BrushHueIncrement;
05123 }
05124
05125
05126
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138
05139 BOOL PathProcessorBrush::SetHueIncrement(double Incr)
05140 {
05141 m_BrushHueIncrement = Incr;
05142 return TRUE;
05143 }
05144
05145
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159 UINT32 PathProcessorBrush::GetHueMaxRand()
05160 {
05161 return m_BrushHueMaxRand;
05162 }
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179 BOOL PathProcessorBrush::SetHueMaxRand(UINT32 Rand)
05180 {
05181 m_BrushHueMaxRand = Rand;
05182 return TRUE;
05183 }
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199 UINT32 PathProcessorBrush::GetHueRandSeed()
05200 {
05201 return m_BrushHueRandSeed;
05202 }
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216
05217
05218
05219 BOOL PathProcessorBrush::SetHueRandSeed(UINT32 Rand)
05220 {
05221 m_BrushHueRandSeed = Rand;
05222
05223 #ifdef USE_MTRNG
05224 if(m_pHueRNG == NULL)
05225 {
05226 m_pHueRNG = new MTRand((UINT32)Rand);
05227 if (m_pHueRNG == NULL)
05228 return FALSE;
05229 }
05230 else
05231 m_pHueRNG->seed((UINT32)Rand);
05232 #endif
05233 return TRUE;
05234 }
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244
05245
05246
05247
05248
05249
05250 double PathProcessorBrush::GetSatIncrement()
05251 {
05252 return m_BrushSatIncrement;
05253 }
05254
05255
05256
05257
05258
05259
05260
05261
05262
05263
05264
05265
05266
05267
05268
05269 BOOL PathProcessorBrush::SetSatIncrement(double Incr)
05270 {
05271 m_BrushSatIncrement = Incr;
05272 return TRUE;
05273 }
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289 UINT32 PathProcessorBrush::GetSatMaxRand()
05290 {
05291 return m_BrushSatMaxRand;
05292 }
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309 BOOL PathProcessorBrush::SetSatMaxRand(UINT32 Rand)
05310 {
05311 m_BrushSatMaxRand = Rand;
05312 return TRUE;
05313 }
05314
05315
05316
05317
05318
05319
05320
05321
05322
05323
05324
05325
05326
05327
05328
05329 UINT32 PathProcessorBrush::GetSatRandSeed()
05330 {
05331 return m_BrushSatRandSeed;
05332 }
05333
05334
05335
05336
05337
05338
05339
05340
05341
05342
05343
05344
05345
05346
05347
05348
05349 BOOL PathProcessorBrush::SetSatRandSeed(UINT32 Rand)
05350 {
05351 m_BrushSatRandSeed = Rand;
05352
05353 #ifdef USE_MTRNG
05354 if(m_pSaturationRNG == NULL)
05355 {
05356 m_pSaturationRNG = new MTRand((UINT32)Rand);
05357 if (m_pSaturationRNG == NULL)
05358 return FALSE;
05359 }
05360 else
05361 m_pSaturationRNG->seed((UINT32)Rand);
05362 #endif
05363 return TRUE;
05364 }
05365
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379 SequenceType PathProcessorBrush::GetSequenceType()
05380 {
05381 return m_SequenceType;
05382 }
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398 void PathProcessorBrush::SetSequenceType(SequenceType Type)
05399 {
05400 m_SequenceType = Type;
05401 if (Type == SEQ_MIRROR)
05402 m_MirrorSeqAscend = TRUE;
05403
05404
05405 if (m_SequenceType == SEQ_RANDOM)
05406 SetSequenceSeed(m_SequenceRandSeed);
05407 }
05408
05409
05410
05411
05412
05413
05414
05415
05416
05417
05418
05419
05420
05421
05422
05423 void PathProcessorBrush::SetSequenceSeed(UINT32 Seed)
05424 {
05425 m_SequenceRandSeed = Seed;
05426 if (m_SequenceType == SEQ_RANDOM)
05427 {
05428 #ifdef USE_MTRNG
05429 if (m_pSequenceRNG == NULL)
05430 {
05431 m_pSequenceRNG = new MTRand;
05432 if (m_pSequenceRNG == NULL)
05433 return;
05434 }
05435 m_pSequenceRNG->seed((UINT32)Seed);
05436 }
05437 #endif
05438
05439
05440 }
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450
05451
05452
05453
05454
05455
05456 UINT32 PathProcessorBrush::GetSequenceSeed()
05457 {
05458 return m_SequenceRandSeed;
05459 }
05460
05461
05462
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476
05477 UINT32 PathProcessorBrush::GetNumBrushObjects()
05478 {
05479 BrushDefinition* pBrushDef = GetOurBrushDefinition();
05480 if (pBrushDef == NULL)
05481 return 0;
05482 return pBrushDef->GetNumBrushObjects();
05483 }
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497
05498
05499 BOOL PathProcessorBrush::GetUseLocalFillColour()
05500 {
05501 return m_bUseLocalFillColour;
05502 }
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514
05515
05516
05517
05518
05519
05520 void PathProcessorBrush::SetUseLocalFillColour(BOOL UseLocal)
05521 {
05522 m_bUseLocalFillColour = UseLocal;
05523
05524
05525
05526 if (UseLocal)
05527 m_bUseNamedColours = TRUE;
05528 }
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544 INT32 PathProcessorBrush::GetBrushTransparency()
05545 {
05546 return m_BrushTransparency;
05547 }
05548
05549
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561
05562
05563 BOOL PathProcessorBrush::SetBrushTransparency(INT32 Value)
05564 {
05565 if (Value > MAX_TRANSP_VALUE)
05566 return FALSE;
05567
05568 m_BrushTransparency = Value;
05569 return TRUE;
05570 }
05571
05572
05573
05574
05575
05576
05577
05578
05579
05580
05581
05582
05583
05584
05585
05586 BOOL PathProcessorBrush::SetTransparencyPressure(UINT32 Value)
05587 {
05588 m_TranspMaxPressure = Value;
05589 return TRUE;
05590 }
05591
05592
05593
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606 UINT32 PathProcessorBrush::GetTransparencyPressure()
05607 {
05608 return m_TranspMaxPressure;
05609 }
05610
05611
05612
05613
05614
05615
05616
05617
05618
05619
05620
05621
05622
05623
05624 BOOL PathProcessorBrush::GetUseLocalTransp()
05625 {
05626 return m_bUseLocalTransp;
05627 }
05628
05629
05630
05631
05632
05633
05634
05635
05636
05637
05638
05639
05640
05641
05642
05643
05644 void PathProcessorBrush::SetUseLocalTransp(BOOL UseLocal)
05645 {
05646 m_bUseLocalTransp = UseLocal;
05647 }
05648
05649
05650
05651
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
05662
05663 BOOL PathProcessorBrush::GetUseNamedColours()
05664 {
05665 return m_bUseNamedColours;
05666 }
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680
05681
05682
05683 void PathProcessorBrush::SetUseNamedColours(BOOL Value)
05684 {
05685 m_bUseNamedColours = Value;
05686 if (!Value)
05687 m_bUseLocalFillColour = FALSE;
05688 }
05689
05690
05691
05692
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704 void PathProcessorBrush::CopyBrushData(BrushData* pData)
05705 {
05706 if (pData == NULL)
05707 {
05708 ERROR3("NULL brush data object");
05709 return;
05710 }
05711
05712 pData->m_BrushHandle = m_BrushHandle;
05713
05714 pData->m_BrushScaling = m_BrushScaling;
05715 pData->m_BrushScalingIncr = m_BrushScalingIncr;
05716 pData->m_BrushScalingIncrConst = m_BrushScalingIncrConst;
05717 pData->m_BrushScalingMaxRand = m_BrushScalingMaxRand;
05718 pData->m_BrushScalingRandSeed = m_BrushScalingRandSeed;
05719 pData->m_ScalingMaxPressure = m_ScalingMaxPressure;
05720
05721 pData->m_bRotate = m_bRotate;
05722 pData->m_RotateAngle = m_RotateAngle;
05723 pData->m_RotAngleIncrConst = m_RotAngleIncrConst;
05724 pData->m_RotAngleIncrProp = m_RotAngleIncrProp;
05725 pData->m_RotationMaxRand = m_RotationMaxRand;
05726 pData->m_RotationRandSeed = m_RotationRandSeed;
05727 pData->m_RotationMaxPressure = m_RotationMaxPressure;
05728
05729 pData->m_BrushSpacing = m_BrushSpacing;
05730 pData->m_BrushSpacingIncrConst = m_BrushSpacingIncrConst;
05731 pData->m_BrushSpacingIncrProp = m_BrushSpacingIncrProp;
05732 pData->m_BrushSpacingMaxRand = m_BrushSpacingMaxRand;
05733 pData->m_BrushSpacingRandSeed = m_BrushSpacingRandSeed;
05734
05735 pData->m_PathOffsetType = m_PathOffsetType;
05736 pData->m_PathOffsetValue = m_PathOffsetValue;
05737 pData->m_PathOffsetIncrConst = m_PathOffsetIncrConst;
05738 pData->m_PathOffsetIncrProp = m_PathOffsetIncrProp;
05739 pData->m_OffsetValueMaxRand = m_OffsetValueMaxRand;
05740 pData->m_OffsetValueRandSeed = m_OffsetValueRandSeed;
05741 pData->m_OffsetTypeRandSeed = m_OffsetTypeRandSeed;
05742
05743 pData->m_bTile = m_bTile;
05744
05745 pData->m_SequenceType = m_SequenceType;
05746 pData->m_SequenceRandSeed = m_SequenceRandSeed;
05747
05748 pData->m_bUseLocalFillColour = m_bUseLocalFillColour;
05749 pData->m_bUseLocalTransp = m_bUseLocalTransp;
05750 pData->m_bUseNamedColour = m_bUseNamedColours;
05751
05752 if (m_pParentAttr != NULL)
05753 pData->m_bTimeStampBrushes = m_pParentAttr->IsTimeStamping();
05754 else
05755 pData->m_bTimeStampBrushes = FALSE;
05756
05757 pData->m_TimeStampPeriod = (UINT32)-1;
05758
05759
05760 pData->m_BrushHueIncrement = m_BrushHueIncrement;
05761 pData->m_BrushHueMaxRand = m_BrushHueMaxRand;
05762 pData->m_BrushHueRandSeed = m_BrushHueRandSeed;
05763 pData->m_BrushSatIncrement = m_BrushSatIncrement;
05764 pData->m_BrushSatMaxRand = m_BrushSatMaxRand;
05765 pData->m_BrushSatRandSeed = m_BrushSatRandSeed;
05766
05767 pData->m_BrushTransparency = m_BrushTransparency;
05768 pData->m_TranspMaxPressure = m_TranspMaxPressure;
05769
05770
05771 BrushDefinition* pDef = GetOurBrushDefinition();
05772
05773 if (pDef)
05774 pData->m_Name = *pDef->GetLineName();
05775 }
05776
05777
05778
05779
05780
05781
05782
05783
05784
05785
05786
05787
05788
05789
05790
05791 void PathProcessorBrush::CopyDataFromObject(BrushData* pData)
05792 {
05793 if (pData == NULL)
05794 {
05795 ERROR3("NULL brush data object");
05796 return;
05797 }
05798 m_BrushHandle = pData->m_BrushHandle;
05799
05800
05801 SetBrushScaling(pData->m_BrushScaling);
05802 m_BrushScalingIncr = pData->m_BrushScalingIncr;
05803 m_BrushScalingIncrConst = pData->m_BrushScalingIncrConst;
05804 m_BrushScalingMaxRand = pData->m_BrushScalingMaxRand;
05805 m_BrushScalingRandSeed = pData->m_BrushScalingRandSeed;
05806 m_ScalingMaxPressure = pData->m_ScalingMaxPressure;
05807
05808
05809 m_bRotate = pData->m_bRotate;
05810 SetRotationAngle(pData->m_RotateAngle);
05811 m_RotAngleIncrConst = pData->m_RotAngleIncrConst;
05812 m_RotAngleIncrProp = pData->m_RotAngleIncrProp;
05813 m_RotationMaxRand = pData->m_RotationMaxRand;
05814 m_RotationRandSeed = pData->m_RotationRandSeed;
05815
05816
05817 SetSpacing(pData->m_BrushSpacing);
05818 m_BrushSpacingIncrConst = pData->m_BrushSpacingIncrConst;
05819 m_BrushSpacingIncrProp = pData->m_BrushSpacingIncrProp;
05820 m_BrushSpacingMaxRand = pData->m_BrushSpacingMaxRand;
05821 m_BrushSpacingRandSeed = pData->m_BrushSpacingRandSeed;
05822
05823
05824 m_PathOffsetType = pData->m_PathOffsetType;
05825 SetPathOffsetValue(pData->m_PathOffsetValue);
05826 m_PathOffsetIncrConst = pData->m_PathOffsetIncrConst;
05827 m_PathOffsetIncrProp = pData->m_PathOffsetIncrProp;
05828 m_OffsetValueMaxRand = pData->m_OffsetValueMaxRand;
05829 m_OffsetValueRandSeed = pData->m_OffsetValueRandSeed;
05830 m_OffsetTypeRandSeed = pData->m_OffsetTypeRandSeed;
05831
05832
05833 m_BrushHueMaxRand = pData->m_BrushHueMaxRand;
05834 m_BrushHueRandSeed = pData->m_BrushHueRandSeed;
05835 m_BrushSatMaxRand = pData->m_BrushSatMaxRand;
05836 m_BrushSatRandSeed = pData->m_BrushSatRandSeed;
05837
05838
05839 m_BrushTransparency = pData->m_BrushTransparency;
05840 m_TranspMaxPressure = pData->m_TranspMaxPressure;
05841
05842
05843 m_bTile = pData->m_bTile;
05844
05845 m_SequenceType = pData->m_SequenceType;
05846 m_SequenceRandSeed = pData->m_SequenceRandSeed;
05847
05848 m_bUseLocalFillColour = pData->m_bUseLocalFillColour;
05849 m_bUseLocalTransp = pData->m_bUseLocalTransp;
05850 m_bUseNamedColours = pData->m_bUseNamedColour;
05851
05852
05853 }
05854
05855
05856
05857
05858
05859
05860
05861
05862
05863
05864
05865
05866
05867
05868
05869 void PathProcessorBrush::SetParentAttribute(AttrBrushType* pAttr)
05870 {
05871 m_pParentAttr = pAttr;
05872 }
05873
05874
05875
05876
05877
05878
05879
05880
05881
05882
05883
05884
05885
05886
05887
05888 AttrBrushType* PathProcessorBrush::GetParentAttribute()
05889 {
05890 return m_pParentAttr;
05891 }
05892
05893
05894
05895
05896
05897
05898
05899
05900
05901
05902
05903
05904
05905
05906
05907
05908 void PathProcessorBrush::SetMaxScaling(double Value)
05909 {
05910 m_MaxScaling = Value;
05911 }
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922
05923
05924
05925
05926
05927 void PathProcessorBrush::SetScaleToLineWidth(BOOL Value)
05928 {
05929 m_bScaleToLineWidth = Value;
05930 }
05931
05932
05933
05934
05935
05936
05937
05938
05939
05940
05941
05942
05943
05944
05945
05946
05947
05948 void PathProcessorBrush::ScaleToValue(MILLIPOINT ScaleValue, BOOL IgnorePressure)
05949 {
05950
05951
05952
05953
05954
05955
05956 MILLIPOINT Height = GetBrushSize(IgnorePressure);
05957 double ScaleFactor = double((double)ScaleValue / (double)Height);
05958
05959
05960
05961 if (ScaleFactor <= 0.0)
05962 {
05963
05964 ScaleFactor = 1.0;
05965 }
05966
05967 SetBrushScaling(ScaleFactor);
05968 m_LineWidth = ScaleValue;
05969 }
05970
05971
05972
05973
05974
05975
05976
05977
05978
05979
05980
05981
05982
05983
05984
05985
05986 double PathProcessorBrush::GetScaleValue(MILLIPOINT Value)
05987 {
05988 MILLIPOINT Height = GetBrushSize();
05989 double ScaleFactor = double((double)Value / (double)Height);
05990
05991 return ScaleFactor;
05992 }
05993
05994
05995
05996
05997
05998
05999
06000
06001
06002
06003
06004
06005
06006
06007 MILLIPOINT PathProcessorBrush::GetBrushSize(BOOL IgnorePressure)
06008 {
06009 BrushDefinition* pBrushDef = GetOurBrushDefinition();
06010 if (pBrushDef == NULL)
06011 return -1;
06012 DocRect BRect = pBrushDef->GetLargestBoundingBox();
06013 if (BRect.IsEmpty())
06014 return -1;
06015
06016 MILLIPOINT Height = BRect.Height();
06017 MILLIPOINT Width = BRect.Width();
06018
06019
06020
06021 double ScaleFactor = 1.0;
06022
06023
06024 if (m_RotationMaxRand > 0 || m_RotateAngle != 0.0 || !m_bRotate)
06025 {
06026 if (Width > Height)
06027 Height = Width;
06028 }
06029
06030 if (m_BrushScalingMaxRand > 0)
06031 {
06032
06033 UINT32 Lower = 0;
06034 UINT32 Upper = 0;
06035 GetRandomLimits(100, m_BrushScalingMaxRand, &Lower, &Upper);
06036
06037
06038 ScaleFactor *= ((double)Upper * 0.01);
06039 }
06040
06041
06042
06043
06044
06045
06046
06047 MILLIPOINT NewHeight = (MILLIPOINT)((double)Height * ScaleFactor);
06048
06049
06050 if (m_OffsetValueMaxRand > 0)
06051 {
06052
06053 double RandMultiplier = (double)m_OffsetValueMaxRand * 0.01;
06054 double OffsetAmount = (double)Height * RandMultiplier;
06055
06056
06057 MILLIPOINT mpAmount = (MILLIPOINT)(2*OffsetAmount);
06058 NewHeight += mpAmount;
06059 }
06060
06061 switch (m_PathOffsetType)
06062 {
06063 case OFFSET_NONE:
06064 break;
06065 case OFFSET_LEFT:
06066 case OFFSET_RIGHT:
06067 case OFFSET_ALTERNATE:
06068 {
06069 MILLIPOINT OffsetIncr = 2 * m_PathOffsetValue;
06070 NewHeight += OffsetIncr;
06071 }
06072 break;
06073 case OFFSET_RANDOM:
06074 break;
06075 default:
06076 ERROR3("Invalid offset type");
06077 }
06078
06079 return NewHeight;
06080 }
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104
06105
06106
06107 double PathProcessorBrush::GetNextAngle()
06108 {
06109 double NewAngle = m_LastRotationNoRandom;
06110
06111 NewAngle += m_RotAngleIncrConst;
06112 m_LastRotationNoRandom = NewAngle;
06113 double Rand = 0;
06114 double PressureAngle = 1.0;
06115 #ifdef USE_MTRNG
06116 if (m_RotationMaxRand != 0)
06117 {
06118 if (m_pRotationRNG != NULL)
06119 {
06120
06121
06122
06123
06124
06125
06126 Rand = (double)m_pRotationRNG->GetNextRandomNumberScaled(m_RotationMaxRand, 0);
06127
06128
06129
06130 }
06131 else
06132 ERROR3("Rotation RNG is NULL");
06133 }
06134
06135 #endif
06136 if (m_RotationMaxPressure > 0 && m_bValidPressure)
06137 {
06138 UINT32 PressureVal = GetCurrentPressureEffect(m_RotationMaxPressure);
06139
06140 PressureAngle = (double)PressureVal / 100;
06141
06142 }
06143 m_LastAngle = (NewAngle * PressureAngle) + Rand;
06144
06145 while (m_LastAngle > 360)
06146 m_LastAngle -= 360;
06147
06148 return m_LastAngle;
06149 }
06150
06151
06152
06153
06154
06155
06156
06157
06158
06159
06160
06161
06162
06163
06164
06165
06166
06167
06168
06169
06170 double PathProcessorBrush::GetNextScaling(UINT32 Index)
06171 {
06172 ERROR2IF(m_LastScaling < 0, 1.0, "Invalid scaling value");
06173 ERROR2IF(m_BrushScalingIncr <= 0, 1.0, "Invalid scaling value");
06174
06175 double NewScaling = m_BrushScaling;
06176 if (Index > 0)
06177 NewScaling = m_LastScalingNoRandom;
06178 double RandomScale = 1.0;
06179 double PressureScale = 1.0;
06180
06181
06182 m_LastScalingNoRandom = NewScaling;
06183 if (m_BrushScalingMaxRand != 0)
06184 {
06185 #ifdef USE_MTRNG
06186 if (m_pScalingRNG != NULL)
06187 {
06188
06189 UINT32 UpperLimit = 0;
06190 UINT32 LowerLimit = 0;
06191
06192 GetRandomLimits(100, m_BrushScalingMaxRand, &LowerLimit, &UpperLimit);
06193
06194 UINT32 Random = m_pScalingRNG->GetNextRandomNumberScaled(UpperLimit, LowerLimit, 100);
06195
06196
06197 RandomScale = (double)Random / 100;
06198
06199 }
06200 #endif
06201 }
06202 if (m_ScalingMaxPressure > 0 && m_bValidPressure)
06203 {
06204 UINT32 PressureVal = GetCurrentPressureEffect(m_ScalingMaxPressure, TRUE);
06205
06206 PressureScale = (double)PressureVal / 100;
06207
06208 }
06209
06210 NewScaling = NewScaling * RandomScale * PressureScale;
06211
06212
06213
06214
06215
06216
06217
06218 {
06219 if (NewScaling >= m_MaxScaling)
06220 NewScaling = m_MaxScaling;
06221 }
06222
06223
06224
06225 double NextScaling = NewScaling;
06226
06227 if (!m_UseActualScaling)
06228 NextScaling = NewScaling / m_LastScalingRendered;
06229
06230 m_LastScaling = NewScaling;
06231
06232
06233
06234 return NextScaling;
06235 }
06236
06237
06238
06239
06240
06241
06242
06243
06244
06245
06246
06247
06248
06249
06250
06251
06252
06253 MILLIPOINT PathProcessorBrush::GetNextSpacing()
06254 {
06255 ERROR2IF(m_LastSpacing <= 0, 10000, "Invalid last spacing");
06256 ERROR2IF(m_BrushSpacing <= 0, 10000, "Invalid spacing value");
06257
06258
06259
06260
06261 MILLIPOINT NewSpacing = m_LastSpacingNoRandom;
06262
06263
06264 if (m_BrushSpacingIncrProp != 1.0)
06265 NewSpacing = (MILLIPOINT)(m_BrushSpacingIncrProp * m_LastSpacing);
06266
06267
06268 if (m_BrushSpacingIncrConst != 0)
06269 NewSpacing += m_BrushSpacingIncrConst;
06270
06271
06272 m_LastSpacingNoRandom = NewSpacing;
06273
06274 if (m_BrushSpacingMaxRand != 0)
06275 {
06276 #ifdef USE_MTRNG
06277 if (m_pSpacingRNG != NULL)
06278 {
06279
06280 UINT32 UpperLimit = 0;
06281 UINT32 LowerLimit = 0;
06282
06283 GetRandomLimits(100, m_BrushSpacingMaxRand, &LowerLimit, &UpperLimit);
06284
06285
06286
06287
06288
06289 UINT32 Random = m_pSpacingRNG->GetNextRandomNumberScaled(UpperLimit, LowerLimit/2, 100);
06290
06291
06292 double Mult = (double)Random / 100;
06293
06294 NewSpacing = (MILLIPOINT)(((double)NewSpacing) * Mult);
06295
06296 }
06297 #endif
06298 }
06299 if (m_SpacingMaxPressure > 0 && m_bValidPressure)
06300 {
06301 UINT32 PressureVal = GetCurrentPressureEffect(m_SpacingMaxPressure);
06302
06303 double PressureScale = (double)PressureVal / 100;
06304 NewSpacing = (MILLIPOINT)((double)NewSpacing * PressureScale);
06305 }
06306
06307
06308
06309 if (NewSpacing < MIN_BRUSH_SPACING)
06310 NewSpacing = MIN_BRUSH_SPACING;
06311 else
06312 {
06313 if (NewSpacing > MAX_BRUSH_SPACING)
06314 NewSpacing = MAX_BRUSH_SPACING;
06315 }
06316
06317 m_LastSpacing = NewSpacing;
06319 return m_LastSpacing;
06320 }
06321
06322
06323
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335
06336
06337
06338 UINT32 PathProcessorBrush::GetNextInkObject(UINT32 LastObject, UINT32 NumObjects)
06339 {
06340 if (LastObject > NumObjects)
06341 {
06342 ERROR3("Duh, last object can't be greater than maximum");
06343 return 0;
06344 }
06345 UINT32 RetVal = 0;
06346 switch (m_SequenceType)
06347 {
06348 case SEQ_FORWARD:
06349 if (LastObject < NumObjects -1)
06350 RetVal= ++LastObject;
06351 else
06352 RetVal = 0;
06353 break;
06354 case SEQ_BACKWARD:
06355 if (LastObject > 0)
06356 RetVal = --LastObject;
06357 else
06358 RetVal = NumObjects -1;
06359 break;
06360 case SEQ_MIRROR:
06361
06362 if (m_MirrorSeqAscend)
06363 {
06364 if (LastObject < NumObjects -1)
06365 RetVal = ++LastObject;
06366 else
06367 {
06368 m_MirrorSeqAscend = FALSE;
06369 RetVal = NumObjects -1;
06370 }
06371 }
06372 else
06373 {
06374 if (LastObject > 0)
06375 RetVal = --LastObject;
06376 else
06377 {
06378 m_MirrorSeqAscend = TRUE;
06379 RetVal = 0;
06380 }
06381 }
06382 break;
06383 case SEQ_RANDOM:
06384
06385 if (m_pSequenceRNG != NULL)
06386 {
06387 RetVal = m_pSequenceRNG->GetNextRandomNumberScaled(NumObjects, 0);
06388 }
06389 else
06390 {
06391 ERROR3("Trying to get a random number with no RNG");
06392 }
06393
06394 break;
06395 default:
06396 ERROR3("invalid sequence type");
06397 RetVal = 0;
06398 break;
06399 }
06400
06401 if (RetVal >= NumObjects)
06402 RetVal--;
06403
06404
06405 return RetVal;
06406
06407
06408 }
06409
06410
06411
06412
06413
06414
06415
06416
06417
06418
06419
06420
06421
06422
06423
06424
06425
06426 MILLIPOINT PathProcessorBrush::GetNextOffset()
06427 {
06428 ERROR2IF(m_LastOffset < 0, 0, "Invalid last Offset");
06429 ERROR2IF(m_PathOffsetValue < 0, 0, "Invalid Offset value");
06430
06431 MILLIPOINT NewOffset = m_LastOffsetNoRandom;
06432
06433
06434 if (m_PathOffsetIncrProp != 1.0)
06435 NewOffset = (MILLIPOINT)(m_PathOffsetIncrProp * m_LastOffset);
06436
06437
06438 if (m_PathOffsetIncrConst != 0)
06439 NewOffset += m_PathOffsetIncrConst;
06440
06441 m_LastOffsetNoRandom = NewOffset;
06442
06443 #ifdef USE_MTRNG
06444 if (m_OffsetValueMaxRand > 0)
06445 {
06446
06447 {
06448 if (m_pOffsetValueRNG != NULL)
06449 {
06450
06451
06452 UINT32 LowerLimit = 0;
06453
06454
06455
06456
06457 UINT32 Random = m_pOffsetValueRNG->GetNextRandomNumberScaled(m_OffsetValueMaxRand, LowerLimit);
06458
06459 double Mult = (double)Random / 100;
06460
06461 BrushDefinition* pBrushDef = GetOurBrushDefinition();
06462 if (pBrushDef != NULL)
06463 {
06464 DocRect BRect = pBrushDef->GetLargestBoundingBox();
06465 if (!BRect.IsEmpty())
06466 {
06467 double Height = (double)BRect.Height();
06468 Height = Height * Mult;
06469
06470 NewOffset += (INT32)Height;
06471 }
06472 }
06473
06474
06475
06476 }
06477 else
06478 ERROR3("OffsetVal RNG is NULL");
06479 }
06480 }
06481 #endif
06482
06483
06484 if (NewOffset < 0)
06485 NewOffset = 0;
06486 else
06487 {
06488 if (NewOffset > MAX_BRUSH_OFFSET)
06489 NewOffset = MAX_BRUSH_OFFSET;
06490 }
06491 m_LastOffset = NewOffset;
06492
06493 return m_LastOffset;
06494 }
06495
06496
06497
06498
06499
06500
06501
06502
06503
06504
06505
06506
06507
06508
06509
06510
06511
06512
06513
06514
06515 double PathProcessorBrush::GetNextSaturationMultiplier()
06516 {
06517 double NextSat = 0;
06518 #ifdef USE_MTRNG
06519 if (m_BrushSatMaxRand > 0)
06520 {
06521 if (m_pSaturationRNG != NULL)
06522 {
06523
06524 UINT32 UpperLimit = 0;
06525 UINT32 LowerLimit = 0;
06526
06527 GetRandomLimits(100, m_BrushSatMaxRand, &LowerLimit, &UpperLimit);
06528
06529
06530 UINT32 Random = m_pSaturationRNG->GetNextRandomNumberScaled(UpperLimit, LowerLimit);
06531
06532
06533 INT32 NewRand = Random - 100;
06534 double Mult = (double)NewRand / 100;
06535
06536 NextSat = Mult;
06537
06538 }
06539 else
06540 ERROR3("SaturationVal RNG is NULL");
06541 }
06542 #endif
06543 m_LastSatMultiplier = NextSat;
06544 return NextSat;
06545 }
06546
06547
06548
06549
06550
06551
06552
06553
06554
06555
06556
06557
06558
06559
06560
06561
06562
06563
06564
06565
06566 double PathProcessorBrush::GetNextHueMultiplier()
06567 {
06568 double NextHue = 0;
06569 #ifdef USE_MTRNG
06570 if (m_BrushHueMaxRand > 0)
06571 {
06572 if (m_pHueRNG != NULL)
06573 {
06574
06575
06576 UINT32 LowerLimit = 0;
06577
06578
06579
06580
06581 UINT32 Random = m_pHueRNG->GetNextRandomNumberScaled(m_BrushHueMaxRand*2, LowerLimit);
06582
06583
06584
06585 NextHue = (double)Random - m_BrushHueMaxRand ;
06586 }
06587 else
06588 ERROR3("HueVal RNG is NULL");
06589 }
06590 #endif
06591 m_LastHueMultiplier = NextHue;
06592
06593 return NextHue;
06594 }
06595
06596
06597
06598
06599
06600
06601
06602
06603
06604
06605
06606
06607
06608
06609
06610
06611
06612
06613 void PathProcessorBrush::SetNextOffsetType()
06614 {
06615 if (m_PathOffsetType == OFFSET_RANDOM)
06616 m_LastOffsetType = GetNextOffsetType();
06617 else
06618 m_LastOffsetType = OFFSETTYPE_CENTRE;
06619 }
06620
06621
06622
06623
06624
06625
06626
06627
06628
06629
06630
06631
06632
06633
06634
06635 UINT32 PathProcessorBrush::GetNextOffsetType()
06636
06637
06638 {
06639
06640 if (m_PathOffsetType != OFFSET_RANDOM )
06641 {
06642
06643 return OFFSETTYPE_CENTRE;
06644 }
06645
06646 UINT32 Offset = OFFSETTYPE_CENTRE;
06647 #ifdef USE_MTRNG
06648 if (m_pOffsetTypeRNG == NULL)
06649 {
06650 ERROR3("Offset Type RNG is NULL");
06651 return OFFSETTYPE_CENTRE;
06652 }
06653
06654 UINT32 Rand = m_pOffsetTypeRNG->operator ()();
06655 if (Rand % 2 == 0)
06656 Offset = OFFSETTYPE_LEFT;
06657 else
06658 Offset = OFFSETTYPE_RIGHT;
06659
06660
06661 #endif
06662 return Offset;
06663 }
06664
06665
06666
06667
06668
06669
06670
06671
06672
06673
06674
06675
06676
06677
06678
06679
06680
06681
06682 UINT32 PathProcessorBrush::GetCurrentPressureEffect(UINT32 MaxEffect, BOOL FixedMaximum)
06683 {
06684 if (m_CurrentPressure.m_Pressure < 0 || m_CurrentPressure.m_Pressure > MAXPRESSURE)
06685 {
06686 ERROR3("Invalid pressure here Jim");
06687 return 0;
06688 }
06689
06690
06691 UINT32 MaxPercent = 100;
06692 if (!FixedMaximum)
06693 MaxPercent += MaxEffect;
06694
06695 UINT32 MinPercent = 100 - MaxEffect;
06696 UINT32 Range = MaxPercent - MinPercent;
06697
06698 double PressureVal = (double)((double)Range / (double)MAXPRESSURE);
06699 UINT32 CurrentPressure = (UINT32)(PressureVal * m_CurrentPressure.m_Pressure);
06700
06701 return MinPercent + CurrentPressure;
06702 }
06703
06704
06705
06706
06707
06708
06709
06710
06711
06712
06713
06714
06715
06716
06717
06718
06719
06720
06721
06722
06723 double PathProcessorBrush::GetNextTransparencyAdjust()
06724 {
06725 return (double)m_BrushTransparency * 0.01;
06726 }
06727
06728
06729
06730
06731
06732
06733
06734
06735
06736
06737
06738
06739
06740
06741
06742
06743
06744 double PathProcessorBrush::GetNextPressureTranspAdjust()
06745 {
06746 double Retval = 1.0;
06747
06748 if (m_TranspMaxPressure != 0)
06749 {
06750 double PressureEffect = (double)GetCurrentPressureEffect(m_TranspMaxPressure);
06751 if (PressureEffect != 100)
06752 {
06753 Retval = PressureEffect *0.01;
06754
06755 }
06756 }
06757 return Retval;
06758 }
06759
06760
06761
06762
06763
06764
06765
06766
06767
06768
06769
06770
06771 UINT32 PathProcessorBrush::GetCurrentPressure()
06772 {
06773 return m_CurrentPressure.m_Pressure;
06774 }
06775
06776
06777
06778
06779
06780
06781
06782
06783
06784
06785
06786
06787
06788 void PathProcessorBrush::SetCurrentPressure(UINT32 Pressure)
06789 {
06790 if (Pressure < 0 || Pressure > MAXPRESSURE)
06791 return;
06792
06793 m_CurrentPressure.m_Pressure = Pressure;
06794 m_bValidPressure = TRUE;
06795 }
06796
06797
06798
06799
06800
06801
06802
06803
06804
06805
06806
06807
06808
06809
06810
06811
06812
06813
06814
06815
06816
06817
06818 void PathProcessorBrush::GetRandomLimits(UINT32 Base, UINT32 MaxRand, UINT32* pLower, UINT32* pUpper)
06819 {
06820
06821 if (pLower == NULL || pUpper == NULL)
06822 {
06823 ERROR3("Illegal entry parameters in PathProcessorBrush::GetRandomLimits");
06824 return;
06825 }
06826
06827 if (MaxRand > MAX_RANDOM_AMOUNT || MaxRand < MIN_RANDOM_AMOUNT)
06828 {
06829 ERROR3("Illegal entry parameters in PathProcessorBrush::GetRandomLimits");
06830 *pLower = Base;
06831 *pUpper = Base;
06832 return;
06833 }
06834
06835 if (MaxRand == 0)
06836 {
06837 *pLower = Base;
06838 *pUpper = Base;
06839 return;
06840 }
06841
06842
06843 double RandomFactor = (double)MaxRand / 100;
06844 RandomFactor = (RandomFactor * MAX_RANDOM_FACTOR) + MIN_RANDOM_FACTOR;
06845
06846 *pLower = (UINT32)((double)Base / RandomFactor);
06847 *pUpper =(UINT32)((double)Base * RandomFactor);
06848
06849
06850 return;
06851 }
06852
06853
06854
06855
06856
06857
06858
06859
06860
06861
06862
06863
06864
06865
06866
06867
06868
06869
06870
06871
06872
06873
06874 void PathProcessorBrush::GetRotationRandomLimits(UINT32 Base, UINT32 MaxRand, UINT32* pLower, UINT32* pUpper)
06875 {
06876
06877 if (pLower == NULL || pUpper == NULL)
06878 {
06879 ERROR3("Illegal entry parameters in PathProcessorBrush::GetRandomLimits");
06880 return;
06881 }
06882
06883 if (MaxRand > MAX_RANDOM_AMOUNT || MaxRand < MIN_RANDOM_AMOUNT)
06884 {
06885 ERROR3("Illegal entry parameters in PathProcessorBrush::GetRandomLimits");
06886 *pLower = Base;
06887 *pUpper = Base;
06888 return;
06889 }
06890
06891 if (MaxRand == 0)
06892 {
06893 *pLower = Base;
06894 *pUpper = Base;
06895 return;
06896 }
06897
06898
06899 double RandomFactor = (double)MaxRand / 100;
06900 RandomFactor = (RandomFactor * MAX_ROTATION_RANDOM_FACTOR) + MIN_RANDOM_FACTOR;
06901
06902 *pLower = (UINT32)((double)Base / RandomFactor);
06903 *pUpper =(UINT32)((double)Base * RandomFactor);
06904
06905
06906 return;
06907
06908 }
06909
06910
06911
06912
06913
06914
06915
06916
06917
06918
06919
06920
06921
06922
06923
06924
06925
06926
06927
06928
06929
06930
06931
06932
06933
06934
06935
06936
06937
06938
06939
06940
06941
06942
06943
06944
06945
06946
06947
06948
06949
06950
06951
06952
06953
06954
06955
06956
06957
06958
06959
06960
06961
06962
06963
06964
06965
06966
06967
06968
06969
06970
06971
06972
06973
06974
06975
06976
06977
06978
06979
06980
06981
06982
06983
06984
06985
06986
06987
06988
06989
06990
06991
06992
06993
06994
06995
06996 BOOL PathProcessorBrush::ResetRandomNumberGenerators()
06997 {
06998 #ifdef USE_MTRNG
06999 if (m_pSpacingRNG != NULL)
07000 m_pSpacingRNG->seed((UINT32)m_BrushSpacingRandSeed);
07001 if (m_pScalingRNG != NULL)
07002 m_pScalingRNG->seed((UINT32)m_BrushScalingRandSeed);
07003 if (m_pOffsetTypeRNG != NULL)
07004 m_pOffsetTypeRNG->seed((UINT32)m_OffsetTypeRandSeed);
07005 if (m_pOffsetValueRNG != NULL)
07006 m_pOffsetValueRNG->seed((UINT32)m_OffsetValueRandSeed);
07007 if (m_pSaturationRNG != NULL)
07008 m_pSaturationRNG->seed((UINT32)m_BrushSatRandSeed);
07009 if (m_pHueRNG != NULL)
07010 m_pHueRNG->seed((UINT32)m_BrushHueRandSeed);
07011 if (m_pRotationRNG != NULL)
07012 m_pRotationRNG->seed((UINT32) m_RotationRandSeed);
07013 if (m_pSequenceRNG != NULL)
07014 m_pSequenceRNG->seed((UINT32) m_SequenceRandSeed);
07015 #endif
07016 return TRUE;
07017 }
07018
07019
07020
07021
07022
07023
07024
07025
07026
07027
07028
07029
07030
07031
07032
07033 INT32 PathProcessorBrush::HowManyObjectsInDistance(MILLIPOINT Distance)
07034 {
07035 INT32 NumObjects = 0;
07036 MILLIPOINT DistanceSoFar = 0;
07037 MILLIPOINT Spacing = m_BrushSpacing;
07038
07039 while (DistanceSoFar <= Distance)
07040 {
07041 NumObjects++;
07042 Spacing = (MILLIPOINT)(Spacing * m_BrushSpacingIncrProp);
07043 Spacing += m_BrushSpacingIncrConst;
07044 if (Spacing < MIN_BRUSH_SPACING)
07045 Spacing = MIN_BRUSH_SPACING;
07046 else
07047 {
07048 if (Spacing > MAX_BRUSH_SPACING)
07049 Spacing = MAX_BRUSH_SPACING;
07050 }
07051 DistanceSoFar += Spacing;
07052 }
07053 return NumObjects;
07054 }
07055
07056
07057
07058
07059
07060
07061
07062
07063
07064
07065
07066
07067
07068
07069
07070
07071
07072 BOOL PathProcessorBrush::IsThisPathProcessorOnTheStack(RenderRegion* pRender)
07073 {
07074 if (pRender == NULL)
07075 {
07076 ERROR3("Render Region is NULL in PathProcessorBrush::IsThisPathProcessorOnTheStack");
07077 return TRUE;
07078 }
07079
07080 BOOL Retval = FALSE;
07081 PathProcessor* pPathProc = pRender->GetFirstPathProcessor();
07082
07083 while (pPathProc != NULL)
07084 {
07085
07086 if (pPathProc->IsAPathProcessorBrush())
07087 {
07088
07089 if (((PathProcessorBrush*)pPathProc)->GetBrushDefinitionHandle() == m_BrushHandle)
07090 {
07091 if (pPathProc != this)
07092 {
07093 Retval = TRUE;
07094 break;
07095 }
07096 }
07097 }
07098 pPathProc = pPathProc->GetNextProcessor();
07099 }
07100
07101 return Retval;
07102 }
07103
07104
07105
07106
07107
07108
07109
07110
07111
07112
07113
07114
07115
07116
07117
07118
07119
07120 BOOL PathProcessorBrush::PrepareForRenderingLoop(UINT32 NumBrushObjects)
07121 {
07122 ERROR2IF(NumBrushObjects > MAX_BRUSH_OBJECTS, FALSE, "Too many objects in PathProcessorBrush::PrepareForRenderingLoop");
07123 ERROR2IF(NumBrushObjects == 0, FALSE, "No objects in PathProcessorBrush::PrepareForRenderingLoop");
07124
07125
07126 m_pObjectRendered = new BOOL[NumBrushObjects];
07127 if (m_pObjectRendered == NULL)
07128 return FALSE;
07129
07130
07131 for (UINT32 i = 0; i < NumBrushObjects; i++)
07132 m_pObjectRendered[i] = FALSE;
07133
07134
07135 m_pLastScalingRendered = new double[NumBrushObjects];
07136 if (m_pLastScalingRendered == NULL)
07137 {
07138 delete m_pObjectRendered;
07139 m_pObjectRendered = NULL;
07140 return FALSE;
07141 }
07142
07143
07144 for ( UINT32 i = 0; i < NumBrushObjects; i++)
07145 m_pLastScalingRendered[i] = m_BrushScaling;
07146
07147
07148
07149
07150
07151
07152
07153
07154
07155
07156
07157
07158
07159
07160
07161
07162
07163
07164
07165
07166
07167 m_UseActualScaling = TRUE;
07168
07169 return TRUE;
07170 }
07171
07172
07173
07174
07175
07176
07177
07178
07179
07180
07181
07182
07183
07184
07185 void PathProcessorBrush::CleanUpAfterRender()
07186 {
07187 if (m_pObjectRendered != NULL)
07188 {
07189 delete m_pObjectRendered;
07190 m_pObjectRendered = NULL;
07191 }
07192 if (m_pLastScalingRendered != NULL)
07193 {
07194 delete m_pLastScalingRendered;
07195 m_pLastScalingRendered = NULL;
07196 }
07197 if (m_pLastTangent != NULL)
07198 {
07199 delete m_pLastTangent;
07200 m_pLastTangent = NULL;
07201 }
07202 if (m_pLastRotation != NULL)
07203 {
07204 delete m_pLastRotation;
07205 m_pLastRotation = NULL;
07206 }
07207 }
07208
07209
07210
07211
07212
07213
07214
07215
07216
07217
07218
07219
07220
07221
07222
07223
07224
07225
07226
07227
07228
07229
07230
07231 BOOL PathProcessorBrush::SetLastRenderedData(UINT32 BrushObject, double Scaling, double Tangent,
07232 double Rotation)
07233 {
07234 ERROR2IF(m_pObjectRendered == NULL || m_pLastScalingRendered == NULL ||
07235 m_pLastTangent == NULL || m_pLastRotation == NULL, FALSE, "Data caches have not been initialised in PathProcessorBrush::SetLastRenderedData");
07236
07237
07238 #ifdef _DEBUG
07239 if (BrushObject > GetNumBrushObjects())
07240 {
07241 ERROR3("Object index out of bounds in PathProcessorBrush::SetLastRenderedData");
07242 return FALSE;
07243 }
07244
07245 #endif
07246 m_pObjectRendered[BrushObject] = TRUE;
07247 m_pLastScalingRendered[BrushObject] = Scaling;
07248 m_pLastTangent[BrushObject] = Tangent;
07249 m_pLastRotation[BrushObject] = Rotation;
07250
07251 m_LastScalingRendered = Scaling;
07252
07253 return TRUE;
07254 }
07255
07256
07257
07258
07259
07260
07261
07262
07263
07264
07265
07266
07267
07268
07269
07270
07271
07272
07273
07274
07275
07276 void PathProcessorBrush::DecideWhetherToUseActualScaling(UINT32 BrushObject)
07277 {
07278 if (m_pObjectRendered == NULL || m_pLastScalingRendered == NULL)
07279 {
07280 ERROR3("Data caches have not been initialised in PathProcessorBrush::DecideWhetherToUseActualScaling");
07281 return;
07282 }
07283
07284
07285
07286
07287 if (BrushObject >= GetNumBrushObjects())
07288 {
07289 ERROR3("Object index out of bounds in PathProcessorBrush::SetLastRenderedData");
07290 return;
07291 }
07292
07293
07294
07295 if (m_pObjectRendered[BrushObject])
07296 {
07297 m_UseActualScaling = FALSE;
07298 m_LastScalingRendered = m_pLastScalingRendered[BrushObject];
07299 }
07300 else
07301 {
07302 m_UseActualScaling = TRUE;
07303 }
07304
07305
07306
07307
07308 #ifdef NEW_RENDERBRUSHATPOINT
07309 m_UseActualScaling = TRUE;
07310 #endif
07311
07312 }
07313
07314
07315
07316
07317
07318
07319
07320
07321
07322
07323
07324
07325
07326
07327
07328
07329
07330 void PathProcessorBrush::SetStrokeColour(DocColour Col)
07331 {
07332 m_CurrentStrokeCol = Col;
07333 }
07334
07335
07336
07337
07338
07339
07340
07341
07342
07343
07344
07345
07346
07347
07348
07349
07350
07351
07352
07353
07354
07355
07356
07357
07358
07359
07360 BOOL PathProcessorBrush::WriteNative(BaseCamelotFilter *pFilter)
07361 {
07362 ERROR3IF(pFilter == NULL, "Illegal NULL param");
07363
07364 CXaraFileRecord Record(TAG_BRUSHATTR, TAG_BRUSHATTR_SIZE);
07365 BOOL ok = Record.Init();
07366
07367 BYTE Flags = 0;
07368 if (m_bTile)
07369 Flags |= TAG_BRUSHTILE_FLAG;
07370 if (m_bRotate)
07371 Flags |= TAG_BRUSHROTATE_FLAG;
07372
07373
07374
07375 if (ok) ok = Record.WriteUINT32(m_BrushHandle);
07376 if (ok) ok = Record.WriteINT32(m_BrushSpacing);
07377 if (ok) ok = Record.WriteBYTE(Flags);
07378 if (ok) ok = Record.WriteDOUBLE(m_RotateAngle);
07379 if (ok) ok = Record.WriteINT32(m_PathOffsetType);
07380 if (ok) ok = Record.WriteINT32(m_PathOffsetValue);
07381 if (ok) ok = Record.WriteDOUBLE(m_BrushScaling);
07382 if (ok) ok = pFilter->Write(&Record);
07383
07384 CXaraFileRecord NextRec(TAG_MOREBRUSHATTR, TAG_MOREBRUSHATTR_SIZE);
07385 if (ok) ok = NextRec.Init();
07386 if (ok) ok = NextRec.WriteDOUBLE(m_BrushSpacingIncrProp);
07387 if (ok) ok = NextRec.WriteINT32(m_BrushSpacingIncrConst);
07388 if (ok) ok = NextRec.WriteINT32((INT32)m_BrushSpacingMaxRand);
07389 if (ok) ok = NextRec.WriteINT32((INT32)m_BrushSpacingRandSeed);
07390
07391 if (ok) ok = NextRec.WriteDOUBLE(m_BrushScalingIncr);
07392 if (ok) ok = NextRec.WriteINT32((INT32)m_BrushScalingMaxRand);
07393 if (ok) ok = NextRec.WriteINT32((INT32)m_BrushScalingRandSeed);
07394
07395 if (ok) ok = NextRec.WriteINT32((INT32)m_SequenceType);
07396 if (ok) ok = NextRec.WriteINT32((INT32)m_SequenceRandSeed);
07397
07398 if (ok) ok = NextRec.WriteDOUBLE(m_PathOffsetIncrProp);
07399 if (ok) ok = NextRec.WriteINT32(m_PathOffsetIncrConst);
07400 if (ok) ok = NextRec.WriteINT32((INT32)m_OffsetTypeRandSeed);
07401 if (ok) ok = NextRec.WriteINT32((INT32)m_OffsetValueMaxRand);
07402 if (ok) ok = NextRec.WriteINT32((INT32)m_OffsetValueRandSeed);
07403 INT32 UseFill = m_bUseLocalFillColour ? 1234 : 0;
07404 if (ok) ok = NextRec.WriteINT32(UseFill);
07405
07406 if (ok) ok = pFilter->Write(&NextRec);
07407
07408 CXaraFileRecord AnotherRec(TAG_EVENMOREBRUSHATTR, TAG_EVENMOREBRUSHATTR_SIZE);
07409 if (ok) ok = AnotherRec.Init();
07410 if (ok) ok = AnotherRec.WriteINT32((INT32)m_RotationMaxRand);
07411 if (ok) ok = AnotherRec.WriteINT32((INT32)m_RotationRandSeed);
07412 BYTE ScaleFlag = 0;
07413 ScaleFlag |= TAG_SCALETOWIDTH_FLAG;
07414 if (ok) ok = AnotherRec.WriteBYTE(ScaleFlag);
07415 if (ok) ok = pFilter->Write(&AnotherRec);
07416
07417
07418 CXaraFileRecord FillRec(TAG_BRUSHATTRFILLFLAGS, TAG_BRUSHATTRFILLFLAGS_SIZE);
07419 if (ok) ok = FillRec.Init();
07420 BYTE FillFlags = 0;
07421 if (m_bUseLocalFillColour)
07422 FillFlags |= BRUSHFILLFLAG_LOCALFILL;
07423
07424 if (m_bUseLocalTransp)
07425 FillFlags |= BRUSHFILLFLAG_LOCALTRANSP;
07426
07427 if (m_bUseNamedColours)
07428 FillFlags |= BRUSHFILLFLAG_NAMEDCOL;
07429
07430 if (ok) ok = FillRec.WriteBYTE(FillFlags);
07431 if (ok) ok = pFilter->Write(&FillRec);
07432
07433
07434 CXaraFileRecord PressureRec(TAG_BRUSHATTRPRESSUREINFO, TAG_BRUSHATTRPRESSUREINFO_SIZE);
07435 if (ok) ok = PressureRec.Init();
07436 if (ok) ok = PressureRec.WriteINT32((INT32)m_ScalingMaxPressure);
07437 if (ok) ok = PressureRec.WriteINT32((INT32)m_SpacingMaxPressure);
07438 if (ok) ok = PressureRec.WriteINT32((INT32)m_OffsetMaxPressure);
07439 if (ok) ok = PressureRec.WriteINT32((INT32)m_RotationMaxPressure);
07440 if (ok) ok = PressureRec.WriteINT32((INT32)m_HueMaxPressure);
07441 if (ok) ok = PressureRec.WriteINT32((INT32)m_SatMaxPressure);
07442 if (ok) ok = PressureRec.WriteINT32((INT32)m_TimeStampMaxPressure);
07443 if (ok) ok = pFilter->Write(&PressureRec);
07444
07445
07446 CXaraFileRecord TranspRec(TAG_BRUSHATTRTRANSPINFO, TAG_BRUSHATTRTRANSPINFO_SIZE);
07447 if (ok) ok = TranspRec.Init();
07448 if (ok) ok = TranspRec.WriteINT32(m_BrushTransparency);
07449 if (ok) ok = TranspRec.WriteINT32(INT32(m_TranspMaxPressure));
07450 if (ok) ok = TranspRec.WriteDOUBLE(m_RotAngleIncrConst);
07451 if (ok) ok = TranspRec.WriteDOUBLE(m_BrushScalingIncrConst);
07452 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushHueMaxRand));
07453 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushHueRandSeed));
07454 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushSatMaxRand));
07455 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushSatRandSeed));
07456
07457 if (ok) ok = pFilter->Write(&TranspRec);
07458
07459
07460
07461
07462 return ok;
07463 }