fillval.cpp

Go to the documentation of this file.
00001 // $Id: fillval.cpp 1464 2006-07-18 12:32:26Z gerry $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // This file holds all the AttributeValueclasses to do with path
00100 // filling attributes.
00101 
00102 /*
00103 */
00104 
00105 #include "camtypes.h"
00106 
00107 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 #include "grndrgn.h"
00110 #include "osrndrgn.h"
00111 #include "macros.h"
00112 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 #include "opgrad.h"
00114 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 
00116 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00117 #include "lineattr.h"
00118 #include "attrmap.h"
00119 
00120 #include "fracfill.h"
00121 //#include "bitmap.h"   // For Test Only - in camtypes.h [AUTOMATICALLY REMOVED]
00122 #include "bitmpinf.h"
00123 #include "oilbitmap.h"  // For Test Only
00124 //#include "dibutil.h"  // For Test Only - in camtypes.h [AUTOMATICALLY REMOVED]
00125 
00126 #include "progress.h"
00127 
00128 //#include "devcolor.h" // For Test Only
00129 //#include "colcontx.h" // For Test Only
00130 
00131 //#include "will.h"     // For bitmap error ID
00132 //#include "monotime.h" // For Fractal Seed - in camtypes.h [AUTOMATICALLY REMOVED]
00133 
00134 #include "blendatt.h"
00135 //#include "jason.h"        // For Default Colour Text IDs
00136 #include "colormgr.h"
00137 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00138 
00139 #include "nodemold.h"   // For NodeMould definition
00140 #include "moldpers.h"   // For MouldPerspective definition
00141 
00142 //#include "will2.h"
00143 
00144 #ifndef WEBSTER
00145 //#include "bfxalu.h"       // For BfxALU::IsGreyscaleBitmap -- see WEBSTER comment below
00146 #endif
00147 
00148 //#include "gerry.h"        // for _R(IDS_REDNAME) & _R(IDS_YELLOWNAME)
00149 #include "bmpcomp.h"
00150 #include "noisef.h"
00151 
00152 #include "pathstrk.h"   // For PathStrokerVector
00153 #include "fillramp.h"   // For colour/transparency ramps
00154 #include "pathutil.h"
00155 
00156 DECLARE_SOURCE("$Revision: 1464 $");
00157 
00158 
00159 // AttributeValue classes
00160 //
00161 CC_IMPLEMENT_DYNAMIC(FillGeometryAttribute,             AttributeValue)
00162 CC_IMPLEMENT_DYNAMIC(ColourFillAttribute,               FillGeometryAttribute)
00163 CC_IMPLEMENT_DYNAMIC(TranspFillAttribute,               FillGeometryAttribute)
00164 
00165 CC_IMPLEMENT_DYNCREATE(FlatFillAttribute,               ColourFillAttribute)
00166 CC_IMPLEMENT_DYNCREATE(GradFillAttribute,               ColourFillAttribute)
00167 CC_IMPLEMENT_DYNCREATE(LinearFillAttribute,             GradFillAttribute)
00168 CC_IMPLEMENT_DYNCREATE(RadialFillAttribute,             GradFillAttribute)
00169 CC_IMPLEMENT_DYNCREATE(ConicalFillAttribute,            GradFillAttribute)
00170 CC_IMPLEMENT_DYNCREATE(SquareFillAttribute,             GradFillAttribute)
00171 CC_IMPLEMENT_DYNCREATE(BitmapFillAttribute,             GradFillAttribute)
00172 CC_IMPLEMENT_DYNCREATE(FractalFillAttribute,            BitmapFillAttribute)
00173 CC_IMPLEMENT_DYNCREATE(NoiseFillAttribute,              BitmapFillAttribute)
00174 CC_IMPLEMENT_DYNCREATE(ThreeColFillAttribute,           GradFillAttribute)
00175 CC_IMPLEMENT_DYNCREATE(FourColFillAttribute,            ThreeColFillAttribute)
00176 
00177 CC_IMPLEMENT_DYNCREATE(FlatTranspFillAttribute,         TranspFillAttribute)
00178 CC_IMPLEMENT_DYNCREATE(GradTranspFillAttribute,         TranspFillAttribute)
00179 CC_IMPLEMENT_DYNCREATE(LinearTranspFillAttribute,       GradTranspFillAttribute)
00180 CC_IMPLEMENT_DYNCREATE(RadialTranspFillAttribute,       GradTranspFillAttribute)
00181 CC_IMPLEMENT_DYNCREATE(ConicalTranspFillAttribute,      GradTranspFillAttribute)
00182 CC_IMPLEMENT_DYNCREATE(SquareTranspFillAttribute,       GradTranspFillAttribute)
00183 CC_IMPLEMENT_DYNCREATE(BitmapTranspFillAttribute,       GradTranspFillAttribute)
00184 CC_IMPLEMENT_DYNCREATE(FractalTranspFillAttribute,      BitmapTranspFillAttribute)
00185 CC_IMPLEMENT_DYNCREATE(NoiseTranspFillAttribute,        BitmapTranspFillAttribute)
00186 CC_IMPLEMENT_DYNCREATE(ThreeColTranspFillAttribute,     GradTranspFillAttribute)
00187 CC_IMPLEMENT_DYNCREATE(FourColTranspFillAttribute,      ThreeColTranspFillAttribute)
00188 
00189 CC_IMPLEMENT_DYNCREATE(FillEffectAttribute,             AttributeValue)
00190 CC_IMPLEMENT_DYNCREATE(FillEffectFadeAttribute,         FillEffectAttribute)
00191 CC_IMPLEMENT_DYNCREATE(FillEffectRainbowAttribute,      FillEffectAttribute)
00192 CC_IMPLEMENT_DYNCREATE(FillEffectAltRainbowAttribute,   FillEffectAttribute)
00193 
00194 CC_IMPLEMENT_DYNCREATE(FillMappingAttribute,            AttributeValue)
00195 CC_IMPLEMENT_DYNCREATE(FillMappingLinearAttribute,      FillMappingAttribute)
00196 CC_IMPLEMENT_DYNCREATE(FillMappingSinAttribute,         FillMappingAttribute)
00197 
00198 CC_IMPLEMENT_DYNCREATE(TranspFillMappingAttribute,      AttributeValue)
00199 CC_IMPLEMENT_DYNCREATE(TranspFillMappingLinearAttribute,TranspFillMappingAttribute)
00200 CC_IMPLEMENT_DYNCREATE(TranspFillMappingSinAttribute,   TranspFillMappingAttribute)
00201 
00202 CC_IMPLEMENT_DYNCREATE(StrokeColourAttribute,   ColourFillAttribute)
00203 CC_IMPLEMENT_DYNCREATE(StrokeTranspAttribute,   TranspFillAttribute)
00204 
00205 CC_IMPLEMENT_DYNCREATE(MouldAttribute,  AttributeValue)
00206 
00207 // Declare smart memory handling in Debug builds
00208 #define new CAM_DEBUG_NEW
00209 
00210 // funky functions for use with our profile gadgets ....
00211 
00212 // one to set em'
00213 void FillGeometryAttribute::SetProfile (CProfileBiasGain& SetWith)
00214 {
00215     DiagramMapper = SetWith;
00216 }
00217 
00218 // and one to get em'
00219 CProfileBiasGain& FillGeometryAttribute::GetProfile ()
00220 {
00221     return (DiagramMapper);
00222 }
00223 
00224 CProfileBiasGain* FillGeometryAttribute::GetProfilePtr ()
00225 {
00226     return (&DiagramMapper);
00227 }
00228 
00229 
00230 
00232 // Stroke Moulding macros - these are used in most of the MouldIntoStroke functions
00233 // to keep the source code readable & tidy
00235 
00236 #define JCW_MOULDPOINT(pAttr, Point)                                                            \
00237         if ((Get##Point()) != NULL)                                                         \
00238         {                                                                                       \
00239             DocCoord Moulded = pMoulder->MapCoord(Get##Point());                                \
00240             pAttr->Set##Point(&Moulded);                                                        \
00241         }
00242 
00243 #define JCW_MOULDTRANS(pAttr, Point)                                                            \
00244             if ((Get##Point()) != NULL)                                                     \
00245             {                                                                                   \
00246                 UINT32 Trans = 255 - (UINT32) ( ((double)(255 - *(Get##Point()))) * TransScale );   \
00247                 pAttr->Set##Point(&Trans);                                                  \
00248             }
00249 
00250 
00252 //
00253 //                          FillGeometryAttribute class
00254 //
00256 
00257 /********************************************************************************************
00258 
00259 >   FillGeometryAttribute::FillGeometryAttribute()
00260 
00261     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00262     Created:    16/8/94
00263     Purpose:    Default Constuctor for fill attribute values. 
00264                 Sets the default colours to Black and White.
00265                 Sets the Control Points to DocCoord(0,0).
00266     SeeAlso:    AttrFillGeometry::AttrFillGeometry
00267 
00268 ********************************************************************************************/
00269 
00270 FillGeometryAttribute::FillGeometryAttribute()
00271 {
00272 }
00273 
00274 /********************************************************************************************
00275 
00276 >   FillGeometryAttribute& FillGeometryAttribute::operator=(FillGeometryAttribute& FillAttrib)
00277 
00278     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00279     Created:    8/8/94
00280     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
00281 
00282     Returns:    Usual semantics for equality.
00283     Purpose:    Make the Attribute the same as the other. 
00284     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
00285                 runtime class.
00286 
00287 ********************************************************************************************/
00288 
00289 FillGeometryAttribute& FillGeometryAttribute::operator=(FillGeometryAttribute& FillAttrib)
00290 {
00291     SetStartColour(FillAttrib.GetStartColour());
00292     SetEndColour(FillAttrib.GetEndColour());
00293 
00294     SetStartTransp(FillAttrib.GetStartTransp());
00295     SetEndTransp(FillAttrib.GetEndTransp());
00296 
00297     // Copy the profile (CGS)
00298     SetProfile (FillAttrib.GetProfile ());
00299 
00300     // Copy the control points
00301     SetStartPoint(FillAttrib.GetStartPoint());
00302     SetEndPoint(FillAttrib.GetEndPoint());
00303     SetEndPoint2(FillAttrib.GetEndPoint2());
00304 
00305     CopyBitmap(FillAttrib.GetBitmap());
00306     SetAspectLock(FillAttrib.IsAspectLocked());
00307     SetColourRamp(FillAttrib.GetColourRamp());
00308 
00309     return *this;
00310 }
00311 
00312 /********************************************************************************************
00313 
00314 >   INT32 FillGeometryAttribute::operator==(const FillGeometryAttribute& Attrib)
00315 
00316     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00317     Created:    23/8/94
00318     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
00319     Returns:    Usual semantics for equality.
00320     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
00321                 a description of why it's required. 
00322     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
00323                 runtime class.
00324     SeeAlso:    NodeAttribute::operator==
00325 
00326 ********************************************************************************************/
00327 
00328 INT32 FillGeometryAttribute::operator==(const FillGeometryAttribute& Attrib)
00329 {
00330     return FALSE;
00331 }
00332 
00333 /********************************************************************************************
00334 
00335 >   void FillGeometryAttribute::SimpleCopy(AttributeValue *pValue)
00336 
00337     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00338     Created:    23/8/94
00339     Inputs:     pAttr - pointer to the AttributeValue to copy.
00340     Purpose:    See AttributeValue::SimpleCopy
00341     SeeAlso:    FillGeometryAttribute; RenderStack; AttributeValue; NodeAttribute;
00342                 FillGeometryAttribute::Render; FillGeometryAttribute::Restore;
00343                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
00344 
00345 ********************************************************************************************/
00346 
00347 void FillGeometryAttribute::SimpleCopy(AttributeValue *pValue)
00348 {
00349     // We may as well just use our assignment operator.
00350     *this = *((FillGeometryAttribute*)pValue);
00351 }
00352 
00353 
00354 /********************************************************************************************
00355 
00356 >   BOOL FillGeometryAttribute::IsDifferent(AttributeValue *pAttr)
00357 
00358     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00359     Created:    23/8/94
00360     Purpose:    See base class version.
00361     Errors:     The two attributes are not of the same type.
00362     SeeAlso:    AttributeValue::IsDifferent
00363 
00364 ********************************************************************************************/
00365 
00366 BOOL FillGeometryAttribute::IsDifferent(AttributeValue *pAttr)
00367 {
00368     // This must be at least a FillGeometryAttribute...
00369     ERROR3IF(!pAttr->IsKindOf(CC_RUNTIME_CLASS(FillGeometryAttribute)), 
00370                 "Different attribute types in AttributeValue::IsDifferent()");
00371 
00372     // Check they are NOT the same.
00373     return ( !(*((FillGeometryAttribute *)pAttr) == *this) ); 
00374 }
00375 
00376 /********************************************************************************************
00377 
00378 >   KernelBitmap* FillGeometryAttribute::GenerateFractalBitmap( INT32 Seed, double Graininess, 
00379                                                             double Gravity, double Squash, 
00380                                                             UINT32 Dpi)
00381     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00382     Created:    6/10/94
00383     Inputs:     NewDpi - New DPI to generate the Fractal at.
00384     Purpose:    Recalculates the Fractal at a new Dpi.
00385     SeeAlso:    FractalTranspFillAttribute::GetDPI
00386 
00387 ********************************************************************************************/
00388 
00389 KernelBitmap* FillGeometryAttribute::GenerateFractalBitmap( INT32 Seed, double Graininess, 
00390                                                             double Gravity, double Squash, 
00391                                                             UINT32 Dpi)
00392 {
00393     BOOL Tile = GetTileable();
00394 
00395 /*
00396     switch (GetTesselation())
00397     {
00398         case RT_Simple:
00399             Tile = FALSE;
00400             break;
00401 
00402         case RT_Repeating:
00403             Tile = TRUE;
00404             break;
00405 
00406         case RT_RepeatInverted:
00407             Tile = FALSE;
00408             break;
00409 
00410         default:
00411             Tile = TRUE;
00412             break;
00413     }
00414 
00415     SetTileable(Tile);
00416 */
00417 
00418     TRACEUSER( "Mike", _T("Seed          = %d\n"),Seed);
00419     TRACEUSER( "Mike", _T("Graininess    = %f\n"),Graininess);
00420     TRACEUSER( "Mike", _T("Gravity       = %f\n"),Gravity);
00421     TRACEUSER( "Mike", _T("Squash        = %f\n"),Squash);
00422     TRACEUSER( "Mike", _T("Dpi           = %d\n"),Dpi);
00423 
00424     // First make a fractal from the variables stored in the fill.
00425     PlasmaFractalFill TheFractal(Seed, Tile, Squash, Graininess, Gravity);
00426 
00427     // Get the fill control points
00428     DocCoord Start = *GetStartPoint();
00429     DocCoord End   = *GetEndPoint();
00430     DocCoord End2  = *GetEndPoint2();
00431 
00432     if (Dpi == 0)
00433         Dpi = AttrFillGeometry::FractalDPI;
00434 
00435     if (Dpi > 72000)
00436         Dpi = 72000;
00437 
00438     // Find the size of a pixel.  Note: This assumes pixels are square at the moment.
00439     MILLIPOINT PixelWidth = 72000/Dpi;
00440 
00441     INT32 FracWidth  = INT32(Start.Distance(End));
00442     INT32 FracHeight = INT32(Start.Distance(End2));
00443 
00444     TRACEUSER( "Mike", _T("PixelWidth   = %d\n"),PixelWidth);
00445     TRACEUSER( "Mike", _T("Frac Width   = %d\n"),FracWidth);
00446     TRACEUSER( "Mike", _T("Frac Height  = %d\n"),FracHeight);
00447 
00448     // Calculate the size of the fractal (in Pixels) from the control points
00449     INT32 FracPixWidth  = FracWidth / PixelWidth;
00450     INT32 FracPixHeight     = FracHeight/ PixelWidth;
00451 
00452     TRACEUSER( "Mike", _T("Pix Width    = %d\n"),FracPixWidth);
00453     TRACEUSER( "Mike", _T("Pix Height   = %d\n"),FracPixHeight);
00454 
00455     if (FracPixWidth == 0)
00456         FracPixWidth = 2;
00457 
00458     if (FracPixHeight == 0)
00459         FracPixHeight = 2;
00460 
00461     // The 'actual' dimensions of a fractal must be square and a power of 2.
00462     // 'GetDimension' finds an appropriate value for this dimension.
00463     // It will be the next power of 2 higher than Width or Height (whichever is biggest).
00464     INT32 FracPixDim    = TheFractal.GetDimension(FracPixWidth, FracPixHeight);
00465 
00466     if (FracPixDim > AttrFillGeometry::MaxFractalSize)
00467         FracPixDim = AttrFillGeometry::MaxFractalSize;
00468 
00469     // Set the fractal dimensions so we can see if a match is available
00470     // in the fractal cache
00471     SetFractalDim(FracPixDim);
00472 
00473     TRACEUSER( "Mike", _T("Fractal Dim  = %d\n"),FracPixDim);
00474 
00475     CachedFractal* ExistingFrac = 
00476             GetApplication()->GetGlobalFractalList()->CheckFractalBitmap(this);
00477 
00478     if (ExistingFrac != NULL)
00479     {
00480         // This fractal already exist, so lets re-use it
00481         OILBitmap* ExistingBmp = ExistingFrac->GetCachedFractal()->GetBitmap()->ActualBitmap;
00482         KernelBitmap* ExistingFractal = new KernelBitmap(ExistingBmp, TRUE);
00483         return ExistingFractal;
00484     }
00485 
00486     String_64 FracText(_R(IDS_K_FILLVAL_GENFRACT));
00487     BeginSlowJob(-1, FALSE, &FracText);
00488 
00489     Dpi = (FracPixDim * 72000)/(FracWidth >= FracHeight ? FracWidth : FracHeight);
00490 
00491     // Create the Bitmap !!
00492     KernelBitmap* Bitmap = new KernelBitmap(FracPixDim, FracPixDim, 8, Dpi, TRUE);
00493 
00494     if (Bitmap == NULL)
00495     {
00496         EndSlowJob();
00497         ERROR1(NULL, _R(IDE_FRACTMEM));
00498     }
00499 
00500     // Make this into a fractal bitmap
00501     Bitmap->SetAsFractal();
00502 
00503     // Render the Fractal into the bitmap
00504     BOOL ok = TheFractal.DoFill(Bitmap, FracPixDim, 0, 0);
00505 
00506     EndSlowJob();
00507 
00508     if (!ok) TRACEUSER( "Mike", _T("DoFill Failed\n"));
00509     ERROR1IF(!ok, Bitmap, _R(IDE_FRACTFAILED));
00510 
00511     return Bitmap;
00512 }
00513 
00514 FIXED16 FillGeometryAttribute::GetGraininess()
00515 {
00516     return AttrFillGeometry::FractalGraininess;
00517 }
00518 
00519 FIXED16 FillGeometryAttribute::GetGravity()
00520 {
00521     return AttrFillGeometry::FractalGravity;
00522 }
00523 
00524 
00525 
00526 /********************************************************************************************
00527 
00528 >   KernelBitmap* FillGeometryAttribute::GenerateNoiseBitmap(FIXED16 grain,
00529                                                              INT32   seed)
00530 
00531     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00532     Created:    17/01/97
00533     Inputs:     Parameters for a new noisy fractal
00534     Purpose:    Recalculates the Fractal at a new Dpi.
00535     SeeAlso:    
00536 
00537 ********************************************************************************************/
00538 
00539 KernelBitmap* FillGeometryAttribute::GenerateNoiseBitmap(FIXED16 grain, INT32 seed)
00540 {
00541     NoiseFractalFill TheFractal;
00542 
00543     // Get the fill control points
00544     DocCoord Start = *GetStartPoint();
00545     DocCoord End   = *GetEndPoint();
00546     DocCoord End2  = *GetEndPoint2();
00547 
00548     INT32 UAxisLength = INT32(Start.Distance(End));
00549     INT32 VAxisLength = INT32(Start.Distance(End2));
00550 
00551     INT32 Dpi = 0;
00552     if (Dpi == 0)
00553         Dpi = AttrFillGeometry::FractalDPI;
00554 
00555 /*
00556     // Find the size of a pixel.  Note: This assumes pixels are square at the moment.
00557     MILLIPOINT SizeOfPixel = 72000/Dpi;
00558 
00559     // Calculate the size of the fractal (in Pixels) from the control points
00560     INT32 NumPixelsX = UAxisLength / SizeOfPixel;
00561     INT32 NumPixelsY = VAxisLength / SizeOfPixel;
00562 
00563     if (NumPixelsX <= 0) NumPixelsX = 2;
00564     if (NumPixelsY <= 0) NumPixelsY = 2;
00565 
00566     // Make this a square
00567     INT32 FracPixDim = LMax(NumPixelsX, NumPixelsY);
00568 
00569     if (FracPixDim > AttrFillGeometry::MaxFractalSize)
00570         FracPixDim = AttrFillGeometry::MaxFractalSize;
00571 */
00572     INT32 FracPixDim = 256;
00573 
00574     // save this size, we'll use it for caching!
00575     SetFractalDim(FracPixDim);
00576 
00577     // try to find a cached fractal
00578     CachedFractal* ExistingFrac = 
00579         GetApplication()->GetGlobalFractalList()->CheckFractalBitmap(this);
00580 
00581     if (ExistingFrac != NULL)
00582     {
00583         // This fractal already exist, so lets re-use it
00584         OILBitmap* ExistingBmp = ExistingFrac->GetCachedFractal()->GetBitmap()->ActualBitmap;
00585         KernelBitmap* ExistingFractal = new KernelBitmap(ExistingBmp, TRUE);
00586         return ExistingFractal;
00587     }
00588 
00589     String_64 FracText(_R(IDS_K_FILLVAL_GENFRACT));
00590     BeginSlowJob(-1, FALSE, &FracText);
00591 
00592     // calc the dpi of the image
00593     Dpi = (FracPixDim * 72000) / ( LMax( UAxisLength , VAxisLength) );
00594 
00595     // Create the Bitmap
00596     KernelBitmap* Bitmap = new KernelBitmap(FracPixDim, FracPixDim, 8, Dpi, TRUE);
00597 
00598     if (Bitmap == NULL)
00599     {
00600         EndSlowJob();
00601         ERROR1(NULL, _R(IDE_FRACTMEM));
00602     }
00603 
00604     // Make this into a fractal bitmap
00605     Bitmap->SetAsFractal();
00606 
00607     // Render the Fractal into the bitmap
00608     double scale = grain.MakeDouble();
00609     BOOL ok = TheFractal.DoFill(scale, seed, Bitmap);
00610 
00611     EndSlowJob();
00612 
00613     if (!ok) TRACEUSER( "Mike", _T("DoFill Failed\n"));
00614 //  ERROR1IF(!ok, Bitmap, _R(IDE_FRACTFAILED));
00615 
00616     return Bitmap;
00617 }
00618 
00619 
00620 /********************************************************************************************
00621 
00622 >   void FillGeometryAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
00623 
00624     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00625     Created:    21/01/97
00626     Inputs:     pCachedFractal = A pointer to the fractal in the cache
00627     Returns:    -
00628     Purpose:    Copies any data from this FractalFillAttribute into the cached fractal
00629                 pointed to on entry. This data is then checked via IsSameAsCachedFractal
00630 
00631 ********************************************************************************************/
00632 
00633 void FillGeometryAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
00634 {   
00635     ERROR3("FillGeometryAttribute::CacheFractalData() should not have been called");
00636 }
00637 
00638 /********************************************************************************************
00639 
00640 >   BOOL FillGeometryAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
00641 
00642     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00643     Created:    21/01/97
00644     Inputs:     pCachedFractal = A pointer to the fractal in the cache
00645     Returns:    TRUE if this fractal matches the cached fractal
00646                 FALSE if not
00647     Purpose:    A virtual comparison operator used by the fractal cache to check for a
00648                 matching fractal.
00649 
00650 ********************************************************************************************/
00651 
00652 BOOL FillGeometryAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
00653 {
00654     return FALSE;
00655 }
00656 
00658 //
00659 //                          ColourFillAttribute class
00660 //
00662 
00663 /********************************************************************************************
00664 
00665 >   ColourFillAttribute::ColourFillAttribute()
00666 
00667     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00668     Created:    6/9/94
00669     Purpose:    Default Constuctor for fill attribute values. 
00670     SeeAlso:    AttrFillGeometry::AttrFillGeometry
00671 
00672 ********************************************************************************************/
00673 
00674 ColourFillAttribute::ColourFillAttribute()
00675 {
00676     Colour = DocColour(BLACK);
00677 }
00678 
00679 /********************************************************************************************
00680 
00681 >   BOOL ColourFillAttribute::Init()
00682 
00683     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00684     Created:    23/8/94
00685     Returns:    TRUE - initialised ok; FALSE if not.
00686     Purpose:    Registers fill type attribute, and provides a default attribute to give
00687                 transparent flat fills, i.e. actually not filled at all.
00688     Errors:     Out of memory.
00689     SeeAlso:    AttributeManager
00690 
00691 ********************************************************************************************/
00692 
00693 BOOL ColourFillAttribute::Init()
00694 {
00695     // Default to simple transparent fill colour
00696     FlatFillAttribute *pAttr = new FlatFillAttribute;
00697     if (pAttr==NULL)
00698         // just return FALSE, as the error message was set by new
00699         return FALSE;
00700 
00701 //  pAttr->Colour = AttributeManager::DefaultBlack;
00702     pAttr->Colour = DocColour(COLOUR_NONE);
00703     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
00704                                                          pAttr);
00705 
00706     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising ColourFillAttribute");
00707     ERROR2IF(ID != ATTR_FILLGEOMETRY, FALSE, "Incorrect ID for ColourFillAttribute");
00708 
00709     return TRUE;
00710 }
00711 
00712 /********************************************************************************************
00713 
00714 >   FillGeometryAttribute& ColourFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
00715 
00716     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00717     Created:    8/8/94
00718     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
00719     Returns:    Usual semantics for equality.
00720     Purpose:    Make the Attribute the same as the other. 
00721     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
00722                 runtime class.
00723 
00724 ********************************************************************************************/
00725 
00726 FillGeometryAttribute& ColourFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
00727 {
00728     if ( !FillAttrib.IsABitmapFill() && this->IsABitmapFill() )
00729     {
00730         SetStartColour(NULL);
00731         SetEndColour(NULL);
00732     }
00733     else if ( FillAttrib.IsAFlatFill() && this->IsAGradFill() )
00734     {
00735         SetStartColour(NULL);
00736         SetEndColour(FillAttrib.GetStartColour());
00737     }
00738     else if ( FillAttrib.IsAFlatFill() && this->IsAFractalFill() )
00739     {
00740         SetStartColour(NULL);
00741         SetEndColour(FillAttrib.GetStartColour());
00742     }
00743     else if ( FillAttrib.IsAGradFill() && this->IsAFlatFill() )
00744     {
00745         SetStartColour(FillAttrib.GetEndColour());
00746         SetEndColour(NULL);
00747     }
00748     else
00749     {
00750         SetStartColour(FillAttrib.GetStartColour());
00751         SetEndColour(FillAttrib.GetEndColour());
00752         SetEndColour2(FillAttrib.GetEndColour2());
00753         SetEndColour3(FillAttrib.GetEndColour3());
00754     }
00755 
00756     // Copy the fills profile
00757     SetProfile (FillAttrib.GetProfile ());
00758 
00759     // Copy the control points
00760     SetStartPoint(FillAttrib.GetStartPoint());
00761     SetEndPoint(FillAttrib.GetEndPoint());
00762     SetEndPoint2(FillAttrib.GetEndPoint2());
00763 
00764     // Bitmap Virtual points
00765     if ( FillAttrib.IsAKindOfBitmapFill() &&
00766          !this->IsAKindOfBitmapFill() )
00767     {
00768         DocCoord Start = *FillAttrib.GetStartPoint();
00769         DocCoord End   = *FillAttrib.GetEndPoint();
00770         DocCoord End2  = *FillAttrib.GetEndPoint2();
00771 
00772         GetBitmapVirtualPoints( Start, End, End2,
00773                                 GetStartPoint(),  GetEndPoint(),  GetEndPoint2());
00774     }
00775     else if ( !FillAttrib.IsAKindOfBitmapFill() && 
00776               this->IsAKindOfBitmapFill() )
00777     {
00778         GetBitmapRealPoints(*GetStartPoint(), *GetEndPoint(), *GetEndPoint2(),
00779                              GetStartPoint(),  GetEndPoint(),  GetEndPoint2());
00780     }
00781 
00782     if (FillAttrib.IsPerspective())
00783     {
00784         MakePerspective();
00785         SetEndPoint3(FillAttrib.GetEndPoint3());
00786     }
00787     else
00788     {
00789         RemovePerspective();
00790     }
00791 
00792     // are both these fractal fills?
00793     if ( FillAttrib.IsAKindOfBitmapFill() && this->IsAKindOfBitmapFill())
00794     {
00795         // are these bitmap items the same?
00796         if (FillAttrib.GetRuntimeClass() == this->GetRuntimeClass())
00797             CopyBitmap(FillAttrib.GetBitmap());
00798     }
00799     else
00800         CopyBitmap(FillAttrib.GetBitmap());
00801 
00802     SetTesselation(FillAttrib.GetTesselation());
00803     SetAspectLock(FillAttrib.IsAspectLocked());
00804     SetColourRamp(FillAttrib.GetColourRamp());
00805 
00806     return *this;
00807 }
00808 
00809 /********************************************************************************************
00810 
00811 >   INT32 ColourFillAttribute::operator==(const ColourFillAttribute& Attrib)
00812 
00813     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00814     Created:    23/8/94
00815     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
00816     Returns:    Usual semantics for equality.
00817     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
00818                 a description of why it's required. 
00819     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
00820                 runtime class.
00821     SeeAlso:    NodeAttribute::operator==
00822 
00823 ********************************************************************************************/
00824 
00825 INT32 ColourFillAttribute::operator==(const FillGeometryAttribute& Attrib)
00826 {
00827     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
00828         return FALSE;
00829 
00830     return (Colour == ((ColourFillAttribute*)&Attrib)->Colour);
00831 }
00832 
00833 /********************************************************************************************
00834 
00835 >   void ColourFillAttribute::Render(RenderRegion *pRegion)
00836 
00837     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00838     Created:    23/8/94
00839     Inputs:     pRegion - the render region to render this attribute into.
00840     Purpose:    Sets the fill geometry attribute for the given render region. i.e. all
00841                 paths filled will now be filled with this fill geometry.
00842     SeeAlso:    ColourFillAttribute; RenderStack; AttributeValue; NodeAttribute;
00843                 ColourFillAttribute::Restore; ColourFillAttribute::SimpleCopy;
00844                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
00845 
00846 ********************************************************************************************/
00847 
00848 void ColourFillAttribute::Render(RenderRegion *pRegion, BOOL Temp)
00849 {
00850     pRegion->SetFillGeometry(this, Temp);
00851 }
00852 
00853 /********************************************************************************************
00854 
00855 >   void ColourFillAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
00856 
00857     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00858     Created:    23/8/94
00859     Inputs:     pRegion - the render region to restore the attribute into.
00860                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
00861                           permanent (e.g. it's in a document tree).
00862     Purpose:    Restores the fill type attribute for the given render region. i.e. all
00863                 paths filled will now be filled with this fill attribute.
00864     SeeAlso:    ColourFillAttribute; RenderStack; AttributeValue; NodeAttribute;
00865                 ColourFillAttribute::Render; ColourFillAttribute::SimpleCopy;
00866                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
00867 
00868 ********************************************************************************************/
00869 
00870 void ColourFillAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
00871 {
00872     pRegion->RestoreFillGeometry(this, Temp);
00873 }
00874 
00875 /********************************************************************************************
00876 
00877 >   void ColourFillAttribute::SetStartColour(DocColour* NewCol)
00878 
00879     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00880     Created:    5/9/94
00881     Inputs:     -
00882     Purpose:    Sets the Start colour of this fill
00883 
00884 ********************************************************************************************/
00885 
00886 void ColourFillAttribute::SetStartColour(DocColour* NewCol)
00887 {
00888     if (NewCol == NULL)
00889     {
00890         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
00891                                             _R(IDS_WHITENAME), &Colour);
00892     }
00893     else
00894         Colour = *NewCol;
00895 }
00896 
00897 
00898 /********************************************************************************************
00899 
00900 >   BOOL ColourFillAttribute::ContainsNamedColour()
00901 
00902     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00903     Created:    12/4/2000
00904     Inputs:     -
00905     Returns:    TRUE if any one of the colours used by this attribute is a named colour of has
00906                 the reserved flag set that says it was created from a named colour.
00907     Purpose:    
00908 
00909 ********************************************************************************************/
00910 
00911 BOOL ColourFillAttribute::ContainsNamedColour()
00912 {
00913     // check through all the colours and see if they are named
00914 
00915     DocColour* pColour = GetStartColour();
00916     if (pColour != NULL)
00917     {
00918         if (pColour->IsNamed())
00919             return TRUE;
00920     }
00921     pColour = GetEndColour();
00922     if (pColour != NULL)
00923     {
00924         if (pColour->IsNamed())
00925             return TRUE;
00926     }
00927     pColour = GetEndColour2();
00928     if (pColour != NULL)
00929     {
00930         if (pColour->IsNamed())
00931             return TRUE;
00932     }
00933     pColour = GetEndColour3();
00934     if (pColour != NULL)
00935     {
00936         if (pColour->IsNamed())
00937             return TRUE;
00938     }
00939 
00940     return FALSE;
00941 }
00942 
00944 //
00945 //                          FlatFillAttribute class
00946 //
00948 
00949 /********************************************************************************************
00950 
00951 >   FlatFillAttribute::FlatFillAttribute()
00952 
00953     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00954     Created:    6/9/94
00955     Purpose:    Default Constuctor for fill attribute values. 
00956     SeeAlso:    AttrFillGeometry::AttrFillGeometry
00957 
00958 ********************************************************************************************/
00959 
00960 FlatFillAttribute::FlatFillAttribute()
00961 {
00962 }
00963 
00964 /********************************************************************************************
00965 
00966 >   NodeAttribute *FlatFillAttribute::MakeNode()
00967 
00968     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00969     Created:    23/8/94
00970     Returns:    Pointer to the new node, or NULL if out of memory.
00971     Purpose:    Make a AttrFlatColourFill node from this flat fill colour attribute.
00972     Errors:     Out of memory
00973     SeeAlso:    AttributeValue::MakeNode; AttrFlatColourFill
00974 
00975 ********************************************************************************************/
00976 
00977 NodeAttribute *FlatFillAttribute::MakeNode()
00978 {
00979     // Create new attribute node
00980     AttrFlatColourFill *pAttr = new AttrFlatColourFill;
00981     if (pAttr==NULL)
00982         // The error has already been set by new
00983         return NULL;
00984 
00985     // Copy attribute value into the new node.
00986     pAttr->GetAttributeValue()->SimpleCopy(this);
00987 
00988     // Return the new node
00989     return pAttr;
00990 }
00991 
00992 /********************************************************************************************
00993 
00994 >   void FlatFillAttribute::SetStartColour(DocColour* NewCol)
00995 
00996     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00997     Created:    5/9/94
00998     Inputs:     -
00999     Purpose:    Sets the Start colour of this fill
01000 
01001 ********************************************************************************************/
01002 
01003 void FlatFillAttribute::SetStartColour(DocColour* NewCol)
01004 {
01005     if (NewCol == NULL)
01006     {
01007         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
01008                                             _R(IDS_BLACKNAME), &Colour);
01009     }
01010     else
01011         Colour = *NewCol;
01012 }
01013 
01014 /********************************************************************************************
01015 
01016 >   virtual AttributeValue *FlatFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder,
01017                                                                             double TransScale);
01018     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01019     Created:    23/2/97
01020 
01021     Inputs:     pMoulder    - A PathStrokerVector which knows how to translate points to "mould" them
01022                               (May be NULL, in which case moulding of points does not occur)
01023 
01024                 TransScale  - A fraction between 0.0 and 1.0, by which any transparency
01025                               values in this geometry will be scaled, allowing the caller to
01026                               effectively apply a flat transparency level to everything that is
01027                               moulded. Use 1.0 to leave transparency unaltered.
01028 
01029     Returns:    NULL
01030 
01031     Purpose:    Helper function for the PathStrokerVector class, which "moulds" clipart
01032                 subtrees to lie along an arbitrary path.
01033 
01034                 This function is called to mould fill geometries, so that fill endpoints
01035                 are translated to appropriate positions in the destination envelope, and
01036                 allows the caller to effectively apply a flat transparency by scaling
01037                 any transparency values in this geometry by the given fraction.
01038 
01039 ********************************************************************************************/
01040 
01041 AttributeValue *FlatFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale)
01042 {
01043     // There is no need to mould flat fills at all
01044     return(NULL);
01045 }
01046 
01047 
01048 
01050 //
01051 //                          GradFillAttribute class
01052 //
01054 
01055 /********************************************************************************************
01056 
01057 >   GradFillAttribute::GradFillAttribute()
01058 
01059     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01060     Created:    6/9/94
01061     Purpose:    Default Constuctor for fill attribute values. 
01062     SeeAlso:    AttrFillGeometry::AttrFillGeometry
01063 
01064 ********************************************************************************************/
01065 
01066 GradFillAttribute::GradFillAttribute()
01067 {
01068 //  AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
01069 //                                      _R(IDS_WHITENAME), &EndColour);
01070     AttributeManager::FindDefaultColour(NULL,
01071                                         _R(IDS_WHITENAME), &EndColour);
01072 
01073     StartPoint = DocCoord(0,0);
01074     EndPoint   = DocCoord(0,0);
01075     
01076     m_pColourRamp = NULL;
01077 }
01078 
01079 /********************************************************************************************
01080 
01081 >   GradFillAttribute::~GradFillAttribute()
01082 
01083     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01084     Created:    2/3/97
01085     Purpose:    All new destructor used to delete a colour ramp
01086 
01087 ********************************************************************************************/
01088 
01089 GradFillAttribute::~GradFillAttribute()
01090 {
01091     DeleteColourRamp();
01092 }
01093 
01094 /********************************************************************************************
01095 
01096 >   void GradFillAttribute::DeleteColourRamp()
01097 
01098     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01099     Created:    2/3/97
01100     Inputs:     -
01101     Purpose:    Function to remove the colour ramp from this grad fill.
01102 
01103 ********************************************************************************************/
01104 
01105 void GradFillAttribute::DeleteColourRamp()
01106 {
01107     if (m_pColourRamp!=NULL)
01108     {
01109         delete m_pColourRamp;
01110         m_pColourRamp=NULL;
01111     }
01112 }
01113 
01114 /********************************************************************************************
01115 
01116 >   BOOL GradFillAttribute::SameColourRampAs(ColourRamp *pOtherRamp)
01117 
01118     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01119     Created:    2/3/97
01120     Inputs:     pOtherRamp = the colour ramp to match this one agains
01121     Returns:    TRUE if the colour ramps are the same
01122                 FALSE if not
01123     Purpose:    Check whether this colour ramp matches that pointed to by pOtherRamp
01124 
01125 ********************************************************************************************/
01126 
01127 BOOL GradFillAttribute::SameColourRampAs(ColourRamp *pOtherRamp)
01128 {
01129     // Have we got a transparency ramp at the moment?
01130     if (m_pColourRamp==NULL)
01131         return (pOtherRamp==NULL);
01132 
01133     if (pOtherRamp==NULL)
01134         return FALSE;
01135 
01136     return (!(m_pColourRamp->IsDifferentTo(pOtherRamp)));
01137 }
01138 
01139 /********************************************************************************************
01140 
01141 >   BOOL GradFillAttribute::SetColourRamp(ColourRamp *pRamp)
01142 
01143     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01144     Created:    2/3/97
01145     Inputs:     pRamp = a pointer to a colour ramp
01146     Returns:    TRUE if the colour ramp was set, FALSE if not
01147     Purpose:    Set this colour ramp to the version passed in. If pRamp is NULL, the colour
01148                 ramp in this object will be emptied
01149 
01150 ********************************************************************************************/
01151 
01152 BOOL GradFillAttribute::SetColourRamp(ColourRamp *pRamp)
01153 {
01154     DeleteColourRamp();
01155     if (pRamp==NULL)
01156         return TRUE;
01157     
01158     m_pColourRamp = new ColourRamp();
01159     if (m_pColourRamp==NULL)
01160         return FALSE;
01161 
01162     *m_pColourRamp = *pRamp;
01163     return TRUE;
01164 }
01165 
01166 
01167 /********************************************************************************************
01168 
01169 >   ColourRamp* GradFillAttribute::MakeNewColourRamp()
01170 
01171     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01172     Created:    2/3/97
01173     Inputs:     -
01174     Returns:    TRUE if the colour ramp was set, FALSE if not
01175     Purpose:    Set this colour ramp to the version passed in. If pRamp is NULL, the colour
01176                 ramp in this object will be emptied
01177 
01178 ********************************************************************************************/
01179 
01180 ColourRamp* GradFillAttribute::MakeNewColourRamp()
01181 {
01182     DeleteColourRamp();
01183     m_pColourRamp = new ColourRamp();
01184     return m_pColourRamp;
01185 }
01186 
01187 
01188 /********************************************************************************************
01189 
01190 >   DocCoord GradFillAttribute::GetGeometryCoord(float pos) const
01191 
01192     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01193     Created:    11/3/97
01194     Inputs:     pos = a parameter between 0 and 1
01195     Returns:    A coordinate which relates the input parameter to a coordinate space
01196                 on this geometry. For instance a linear fill would have a linear parameter
01197                 space, 0 at the start coordinate, increasing to 1 at the end coordinate
01198     Purpose:    Find the absolute position in geometry coordinate space for the given
01199                 parameter.
01200 
01201 ********************************************************************************************/
01202 
01203 DocCoord GradFillAttribute::GetGeometryCoord(float pos) const
01204 {
01205     // This and all derived classes will inherit a linear coordinate space
01206     return DocCoord::PositionPointFromRatio(StartPoint,EndPoint,(double)pos);
01207 }
01208 
01209 
01210 /********************************************************************************************
01211 
01212 >   float GradFillAttribute::GetGeometryParam(const DocCoord& c) const
01213 
01214     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01215     Created:    11/3/97
01216     Inputs:     c = a coordinate
01217     Returns:    A parameter p, 0<=p<=1, such that GetGeometryCoord(p) is the closest
01218                 coordinate in the geometry to the input c.
01219     Purpose:    Find the parameter for the closest point to c on this geometry.
01220 
01221 ********************************************************************************************/
01222 
01223 float GradFillAttribute::GetGeometryParam(const DocCoord& c) const
01224 {
01225     // ok we're a linear geometry so find the closest point to a line type of thing.
01226     // use a handy util written by that other fab bloke called Mike.
01227     DocCoord Coords[2];
01228     Coords[0] = StartPoint;
01229     Coords[1] = EndPoint;
01230     double p;
01231     PathUtil::SqrDistanceToLine(Coords, c, &p);
01232     return (float)p;
01233 }
01234 
01235 
01236 
01237 /********************************************************************************************
01238 
01239 >   FillGeometryAttribute& GradFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
01240 
01241     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01242     Created:    8/8/94
01243     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
01244     Returns:    Usual semantics for equality.
01245     Purpose:    Make the Attribute the same as the other. 
01246     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
01247                 runtime class.
01248 
01249 ********************************************************************************************/
01250 
01251 FillGeometryAttribute& GradFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
01252 {
01253     return ColourFillAttribute::operator=(FillAttrib);
01254 }
01255 
01256 /********************************************************************************************
01257 
01258 >   INT32 GradFillAttribute::operator==(const FillGeometryAttribute& Attrib)
01259 
01260     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01261     Created:    23/8/94
01262     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
01263     Returns:    Usual semantics for equality.
01264     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
01265                 a description of why it's required. 
01266     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
01267                 runtime class.
01268     SeeAlso:    NodeAttribute::operator==
01269 
01270 ********************************************************************************************/
01271 
01272 INT32 GradFillAttribute::operator==(const FillGeometryAttribute& Attrib)
01273 {
01274     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
01275         return FALSE;
01276 
01277     GradFillAttribute* pAttrib = (GradFillAttribute*)&Attrib;
01278 
01279     if (IsPerspective())
01280     { 
01281         if (!pAttrib->IsPerspective())
01282             return FALSE;
01283 
01284         if (*GetEndPoint2() != *pAttrib->GetEndPoint2())
01285             return FALSE;
01286 
01287         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
01288             return FALSE;
01289     }
01290     
01291     // check the colour ramps match
01292     if (!SameColourRampAs(pAttrib->GetColourRamp()))
01293         return FALSE;
01294     
01295     // Are the Colours and Control points all the same ?
01296     return (
01297     
01298         Colour      == pAttrib->Colour      &&
01299         EndColour   == pAttrib->EndColour   &&
01300 
01301         StartPoint  == pAttrib->StartPoint  &&
01302         EndPoint    == pAttrib->EndPoint
01303     );
01304 }
01305 
01306 
01307 
01308 
01309 /********************************************************************************************
01310 
01311 >   BOOL GradFillAttribute::RenderFill(RenderRegion *pRegion, Path *pPath)
01312 
01313     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
01314     Created:    12/8/96
01315     Inputs:     pRegion - the render region of interest
01316                 pPath - the path to fill.
01317     Returns:    FALSE => let the Render region fill the path, TRUE = we have done it.
01318     Purpose:    Render the fill, if poss. (override to do something different)
01319 
01320 ********************************************************************************************/
01321 
01322 BOOL GradFillAttribute::RenderFill(RenderRegion *pRegion, Path *pPath)
01323 {
01324     if ( pRegion->IsKindOf(CC_RUNTIME_CLASS(GRenderRegion)) )
01325     {
01326         // Safe to cast now
01327         GRenderRegion *gRnd = (GRenderRegion*)pRegion;
01328 
01329         // Do the rendering
01330         return gRnd->RenderGradFillPath(pPath, this);
01331     }
01332     else if ( pRegion->IsKindOf(CC_RUNTIME_CLASS(OSRenderRegion)) )
01333     {
01334         // Safe to cast now
01335         OSRenderRegion *oRnd = (OSRenderRegion*)pRegion;
01336 
01337         // Do the rendering
01338         return oRnd->RenderGradFillPath(pPath, this);
01339     }
01340     return FALSE;
01341 }
01342 
01343 
01344 /********************************************************************************************
01345 
01346 >   void GradFillAttribute::SetStartPoint(DocCoord* Pos)
01347 
01348     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01349     Created:    5/9/94
01350     Inputs:     -
01351     Purpose:    Sets the Start Point of this fill
01352 
01353 ********************************************************************************************/
01354 
01355 void GradFillAttribute::SetStartPoint(DocCoord* Pos)
01356 {
01357     if (Pos == NULL)
01358         StartPoint = DocCoord(0,0);
01359     else
01360         StartPoint = *Pos;
01361 }
01362 
01363 /********************************************************************************************
01364 
01365 >   void GradFillAttribute::SetEndPoint(DocCoord* Pos)
01366 
01367     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01368     Created:    5/9/94
01369     Inputs:     -
01370     Purpose:    Sets the End Point of this fill
01371 
01372 ********************************************************************************************/
01373 
01374 void GradFillAttribute::SetEndPoint(DocCoord* Pos)
01375 {
01376     if (Pos == NULL)
01377         EndPoint = DocCoord(0,0);
01378     else
01379         EndPoint = *Pos;
01380 }
01381 
01382 /********************************************************************************************
01383 
01384 >   void GradFillAttribute::SetEndColour(DocColour* NewCol)
01385 
01386     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01387     Created:    5/9/94
01388     Inputs:     -
01389     Purpose:    Sets the End Colour of this fill
01390 
01391 ********************************************************************************************/
01392 
01393 void GradFillAttribute::SetEndColour(DocColour* NewCol)
01394 {
01395     if (NewCol == NULL)
01396     {
01397         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
01398                                             _R(IDS_BLACKNAME), &EndColour);
01399     }
01400     else
01401         EndColour = *NewCol;
01402 }
01403 
01404 /********************************************************************************************
01405 
01406 >   void GradFillAttribute::SimpleCopy(AttributeValue *pValue)
01407 
01408     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01409     Created:    23/8/94
01410     Inputs:     pAttr - pointer to the AttributeValue to copy.
01411     Purpose:    See AttributeValue::SimpleCopy
01412     SeeAlso:    GradFillAttribute; RenderStack; AttributeValue; NodeAttribute;
01413                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
01414 
01415 ********************************************************************************************/
01416 
01417 void GradFillAttribute::SimpleCopy(AttributeValue *pValue)
01418 {
01419     *(this) = *((FillGeometryAttribute*)pValue);
01420 }
01421 
01422 
01423 
01425 //
01426 //                          LinearFillAttribute class
01427 //
01429 
01430 /********************************************************************************************
01431 
01432 >   LinearFillAttribute::LinearFillAttribute()
01433 
01434     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01435     Created:    6/9/94
01436     Purpose:    Default Constuctor for fill attribute values. 
01437     SeeAlso:    AttrFillGeometry::AttrFillGeometry
01438 
01439 ********************************************************************************************/
01440 
01441 LinearFillAttribute::LinearFillAttribute()
01442 {
01443     IsPersp = FALSE;
01444 }
01445 
01446 /********************************************************************************************
01447 
01448 >   NodeAttribute *LinearFillAttribute::MakeNode()
01449 
01450     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01451     Created:    23/8/94
01452     Returns:    Pointer to the new node, or NULL if out of memory.
01453     Purpose:    Make a AttrLinearFill node from this graduated fill attribute.
01454     Errors:     Out of memory
01455     SeeAlso:    AttributeValue::MakeNode
01456 
01457 ********************************************************************************************/
01458 
01459 NodeAttribute *LinearFillAttribute::MakeNode()
01460 {
01461     // Create new attribute node
01462     AttrLinearFill *pAttr = new AttrLinearColourFill;
01463     if (pAttr==NULL)
01464         // error message has already been set by new
01465         return NULL;
01466 
01467     // Copy attribute value into the new node.
01468     pAttr->GetAttributeValue()->SimpleCopy(this);
01469 
01470     // Return the new node
01471     return pAttr;
01472 }
01473 
01474 
01475 /********************************************************************************************
01476 
01477 >   void LinearFillAttribute::SetEndPoint2(DocCoord* Pos)
01478 
01479     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01480     Created:    5/9/94
01481     Inputs:     -
01482     Purpose:    Sets the End Point of this fill
01483 
01484 ********************************************************************************************/
01485 
01486 void LinearFillAttribute::SetEndPoint2(DocCoord* Pos)
01487 {
01488     if (Pos == NULL)
01489     {
01490         EndPoint2 = MakeLineAtAngle(StartPoint, EndPoint, 90);
01491     }
01492     else
01493     {
01494         EndPoint2 = *Pos;
01495     }
01496 }
01497 
01498 
01499 /********************************************************************************************
01500 
01501 >   void LinearFillAttribute::SetEndPoint3(DocCoord* Pos)
01502 
01503     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01504     Created:    5/9/94
01505     Inputs:     -
01506     Purpose:    Sets the End Point of this fill
01507 
01508 ********************************************************************************************/
01509 
01510 void LinearFillAttribute::SetEndPoint3(DocCoord* Pos)
01511 {
01512     if (Pos == NULL)
01513         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
01514     else
01515         EndPoint3 = *Pos;
01516 }
01517 
01518 
01519 /********************************************************************************************
01520 
01521 >   void LinearFillAttribute::MakePerspective()
01522 
01523     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01524     Created:    17/4/95
01525     Inputs:     -
01526     Purpose:    Make the fill perspectived.
01527                 This should be called just before it is transformed by the moulder,
01528                 so it can validate the 4th control point.
01529 
01530 ********************************************************************************************/
01531 
01532 void LinearFillAttribute::MakePerspective()
01533 {
01534     IsPersp = TRUE;
01535 
01536     INT32 dx1 = EndPoint.x - StartPoint.x;
01537     INT32 dx2 = EndPoint2.x - StartPoint.x;
01538 
01539     INT32 dy1 = EndPoint.y - StartPoint.y;
01540     INT32 dy2 = EndPoint2.y - StartPoint.y;
01541 
01542     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
01543     SetEndPoint3(&Pos3);
01544 }
01545 
01546 /********************************************************************************************
01547 
01548 >   void LinearFillAttribute::RemovePerspective()
01549 
01550     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01551     Created:    17/4/95
01552     Inputs:     -
01553     Purpose:    Removes perspective from this fill.
01554 
01555 ********************************************************************************************/
01556 
01557 void LinearFillAttribute::RemovePerspective()
01558 {
01559     IsPersp = FALSE;
01560 }
01561 
01562 
01563 
01564 /********************************************************************************************
01565 
01566 >   virtual AttributeValue *LinearFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder,
01567                                                                             double TransScale);
01568     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01569     Created:    23/2/97
01570 
01571     Inputs:     pMoulder    - A PathStrokerVector which knows how to translate points to "mould" them
01572                               (May be NULL, in which case moulding of points does not occur)
01573 
01574                 TransScale  - A fraction between 0.0 and 1.0, by which any transparency
01575                               values in this geometry will be scaled, allowing the caller to
01576                               effectively apply a flat transparency level to everything that is
01577                               moulded. Use 1.0 to leave transparency unaltered.
01578 
01579     Returns:    NULL if the original attribute can be used, else
01580                 A pointer to a copy of this object, suitably moulded and adjusted for
01581                 the transparency scaling. The caller must delete the copy when finished
01582                 with it.
01583 
01584     Purpose:    Helper function for the PathStrokerVector class, which "moulds" clipart
01585                 subtrees to lie along an arbitrary path.
01586 
01587                 This function is called to mould fill geometries, so that fill endpoints
01588                 are translated to appropriate positions in the destination envelope, and
01589                 allows the caller to effectively apply a flat transparency by scaling
01590                 any transparency values in this geometry by the given fraction.
01591 
01592 ********************************************************************************************/
01593 
01594 AttributeValue *LinearFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale)
01595 {
01596 // Taken out of WEBSTER Neville 6/8/97
01597 // Taken out by vector stroking code Neville 2/10/97
01598 #ifdef VECTOR_STROKING
01599     if (pMoulder == NULL)
01600         return(NULL);
01601 
01602     FillGeometryAttribute *pCopy = (FillGeometryAttribute *) GetRuntimeClass()->CreateObject();
01603     if (pCopy != NULL)
01604     {
01605         // Copy this object's values across
01606         *pCopy = *this;
01607 
01608         // And mould all of the geometry points across
01609         JCW_MOULDPOINT(pCopy, StartPoint);
01610         JCW_MOULDPOINT(pCopy, EndPoint);
01611 
01612         if (IsPerspective())
01613         {
01614             // If it's perspectivised, just map all the points and hope for the best
01615             JCW_MOULDPOINT(pCopy, EndPoint2);
01616             JCW_MOULDPOINT(pCopy, EndPoint3);
01617         }
01618         else
01619         {
01620             // Otherwise, we have mapped the start/end points, and we pass NULL in for
01621             // the remaining points so that they are re-generated to get the fill going
01622             // in the start->end direction (because the fill direction is not controlled
01623             // by the start->end line, but by the end->end2 line)
01624             pCopy->SetEndPoint2(NULL);
01625             pCopy->SetEndPoint3(NULL);
01626         }
01627     }
01628     return(pCopy);
01629 #else
01630     return NULL;
01631 #endif // VECTOR_STROKING
01632 }
01633 
01634 
01636 //
01637 //                          RadialFillAttribute class
01638 //
01640 
01641 /********************************************************************************************
01642 
01643 >   RadialFillAttribute::RadialFillAttribute()
01644 
01645     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01646     Created:    6/9/94
01647     Purpose:    Default Constuctor for fill attribute values. 
01648     SeeAlso:    AttrFillGeometry::AttrFillGeometry
01649 
01650 ********************************************************************************************/
01651 
01652 RadialFillAttribute::RadialFillAttribute()
01653 {
01654     Circular = FALSE;
01655     IsPersp = FALSE;
01656 
01657     EndPoint2 = DocCoord(0,0);
01658 }
01659 
01660 /********************************************************************************************
01661 
01662 >   NodeAttribute *RadialFillAttribute::MakeNode()
01663 
01664     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01665     Created:    23/8/94
01666     Returns:    Pointer to the new node, or NULL if out of memory.
01667     Purpose:    Make a AttrRadialFill node from this graduated fill attribute.
01668     Errors:     Out of memory
01669     SeeAlso:    AttributeValue::MakeNode
01670 
01671 ********************************************************************************************/
01672 
01673 NodeAttribute *RadialFillAttribute::MakeNode()
01674 {
01675     // Create new attribute node
01676     AttrRadialFill *pAttr = new AttrRadialColourFill;
01677     if (pAttr==NULL)
01678         // error message has already been set by new
01679         return NULL;
01680 
01681     // Copy attribute value into the new node.
01682     pAttr->GetAttributeValue()->SimpleCopy(this);
01683 
01684     // Return the new node
01685     return pAttr;
01686 }
01687 
01688 /********************************************************************************************
01689 
01690 >   void RadialFillAttribute::SetEndPoint2(DocCoord* Pos)
01691 
01692     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01693     Created:    5/9/94
01694     Inputs:     -
01695     Purpose:    Sets the End Point of this fill
01696 
01697 ********************************************************************************************/
01698 
01699 void RadialFillAttribute::SetEndPoint2(DocCoord* Pos)
01700 {
01701     if (Pos == NULL)
01702         EndPoint2 = DocCoord(0,0);
01703     else
01704         EndPoint2 = *Pos;
01705 }
01706 
01707 /********************************************************************************************
01708 
01709 >   FillGeometryAttribute& RadialFillAttribute::operator=(FillGeometryAttribute& Attrib)
01710 
01711     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01712     Created:    8/8/94
01713     Inputs:     Attrib - the attribute to copy, which must be an AttrFillGeometry
01714     Returns:    A reference to the copy
01715     Purpose:    A virtual assignment operator. 
01716 
01717 ********************************************************************************************/
01718 
01719 FillGeometryAttribute& RadialFillAttribute::operator=(FillGeometryAttribute& Attrib)
01720 {
01721     return GradFillAttribute::operator=(Attrib);
01722 }
01723 
01724 /********************************************************************************************
01725 
01726 >   INT32 RadialFillAttribute::operator==(const FillGeometryAttribute& Attrib)
01727 
01728     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01729     Created:    23/8/94
01730     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
01731     Returns:    Usual semantics for equality.
01732     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
01733                 a description of why it's required. 
01734     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
01735                 runtime class.
01736     SeeAlso:    NodeAttribute::operator==
01737 
01738 ********************************************************************************************/
01739 
01740 INT32 RadialFillAttribute::operator==(const FillGeometryAttribute& Attrib)
01741 {
01742     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
01743         return FALSE;
01744 
01745     RadialFillAttribute* pAttrib = (RadialFillAttribute*)&Attrib;
01746 
01747     if (IsPerspective())
01748     { 
01749         if (!pAttrib->IsPerspective())
01750             return FALSE;
01751 
01752         if (EndPoint3 != pAttrib->EndPoint3)
01753             return FALSE;
01754     }
01755 
01756     // check the colour ramps match
01757     if (!SameColourRampAs(pAttrib->GetColourRamp()))
01758         return FALSE;
01759 
01760     // Are the Colours and Control points all the same ?
01761     return (
01762     
01763         Colour      == pAttrib->Colour      &&
01764         EndColour   == pAttrib->EndColour   &&
01765                        
01766         StartPoint  == pAttrib->StartPoint  &&
01767         EndPoint    == pAttrib->EndPoint    &&
01768         EndPoint2   == pAttrib->EndPoint2   &&
01769 
01770         Circular    == pAttrib->Circular
01771     );
01772 }
01773 
01774 /********************************************************************************************
01775 
01776 >   void RadialFillAttribute::SimpleCopy(AttributeValue *pValue)
01777 
01778     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01779     Created:    23/8/94
01780     Inputs:     pAttr - pointer to the AttributeValue to copy.
01781     Purpose:    See AttributeValue::SimpleCopy
01782     SeeAlso:    RadialFillAttribute; RenderStack; AttributeValue; NodeAttribute;
01783                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
01784 
01785 ********************************************************************************************/
01786 
01787 void RadialFillAttribute::SimpleCopy(AttributeValue *pValue)
01788 {
01789     // Base class does most of the work...
01790     GradFillAttribute::SimpleCopy(pValue);
01791 }
01792 
01793 
01794 /********************************************************************************************
01795 
01796 >   void RadialFillAttribute::MakeCircular()
01797 
01798     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01799     Created:    12/8/94
01800     Purpose:    Forces this radial fill into a circular one.
01801 
01802 ********************************************************************************************/
01803 
01804 void RadialFillAttribute::MakeCircular()
01805 {
01806     // Set a flag so we can tell we're circular
01807     Circular = TRUE;
01808 
01809     // Make sure the second end point is on the same radius as the other
01810     EndPoint2 = MakeLineAtAngle(StartPoint, EndPoint, 90);
01811 }
01812 
01813 /********************************************************************************************
01814 
01815 >   void RadialFillAttribute::MakeElliptical()
01816 
01817     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01818     Created:    12/8/94
01819     Purpose:    Forces this radial fill into an elliptical one.
01820 
01821 ********************************************************************************************/
01822 
01823 void RadialFillAttribute::MakeElliptical()
01824 {
01825     // Just clear the flag, so we don't try and lock the secondary point
01826     Circular = FALSE;
01827 }
01828 
01829 /********************************************************************************************
01830 
01831 >   void RadialFillAttribute::SetEndPoint3(DocCoord* Pos)
01832 
01833     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01834     Created:    5/9/94
01835     Inputs:     -
01836     Purpose:    Sets the End Point of this fill
01837 
01838 ********************************************************************************************/
01839 
01840 void RadialFillAttribute::SetEndPoint3(DocCoord* Pos)
01841 {
01842     if (Pos == NULL)
01843         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
01844     else
01845         EndPoint3 = *Pos;
01846 }
01847 
01848 
01849 /********************************************************************************************
01850 
01851 >   void RadialFillAttribute::MakePerspective()
01852 
01853     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01854     Created:    17/4/95
01855     Inputs:     -
01856     Purpose:    Make the fill perspectived.
01857                 This should be called just before it is transformed by the moulder,
01858                 so it can validate the 4th control point.
01859 
01860 ********************************************************************************************/
01861 
01862 void RadialFillAttribute::MakePerspective()
01863 {
01864     IsPersp = TRUE;
01865 
01866     INT32 dx1 = EndPoint.x - StartPoint.x;
01867     INT32 dx2 = EndPoint2.x - StartPoint.x;
01868 
01869     INT32 dy1 = EndPoint.y - StartPoint.y;
01870     INT32 dy2 = EndPoint2.y - StartPoint.y;
01871 
01872     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
01873     SetEndPoint3(&Pos3);
01874 }
01875 
01876 /********************************************************************************************
01877 
01878 >   void RadialFillAttribute::RemovePerspective()
01879 
01880     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01881     Created:    17/4/95
01882     Inputs:     -
01883     Purpose:    Removes perspective from this fill.
01884 
01885 ********************************************************************************************/
01886 
01887 void RadialFillAttribute::RemovePerspective()
01888 {
01889     IsPersp = FALSE;
01890 }
01891 
01892 
01893 /********************************************************************************************
01894 
01895 >   virtual AttributeValue *RadialFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder,
01896                                                                             double TransScale);
01897     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01898     Created:    23/2/97
01899 
01900     Inputs:     pMoulder    - A PathStrokerVector which knows how to translate points to "mould" them
01901                               (May be NULL, in which case moulding of points does not occur)
01902 
01903                 TransScale  - A fraction between 0.0 and 1.0, by which any transparency
01904                               values in this geometry will be scaled, allowing the caller to
01905                               effectively apply a flat transparency level to everything that is
01906                               moulded. Use 1.0 to leave transparency unaltered.
01907 
01908     Returns:    NULL if the original attribute can be used, else
01909                 A pointer to a copy of this object, suitably moulded and adjusted for
01910                 the transparency scaling. The caller must delete the copy when finished
01911                 with it.
01912 
01913     Purpose:    Helper function for the PathStrokerVector class, which "moulds" clipart
01914                 subtrees to lie along an arbitrary path.
01915 
01916                 This function is called to mould fill geometries, so that fill endpoints
01917                 are translated to appropriate positions in the destination envelope, and
01918                 allows the caller to effectively apply a flat transparency by scaling
01919                 any transparency values in this geometry by the given fraction.
01920 
01921 ********************************************************************************************/
01922 
01923 AttributeValue *RadialFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale)
01924 {
01925 // Taken out of WEBSTER Neville 6/8/97
01926 // Taken out by vector stroking code Neville 2/10/97
01927 #ifdef VECTOR_STROKING
01928     if (pMoulder == NULL)
01929         return(NULL);
01930 
01931     RadialFillAttribute *pCopy = (RadialFillAttribute *) GetRuntimeClass()->CreateObject();
01932     if (pCopy != NULL)
01933     {
01934         // Copy this object's values across
01935         *pCopy = *this;
01936 
01937         // Make sure it's defined as an elliptical fill, to ensure all points are set up correctly
01938         pCopy->MakeElliptical();
01939 
01940         // And mould all of the geometry points across
01941         JCW_MOULDPOINT(pCopy, StartPoint);
01942         JCW_MOULDPOINT(pCopy, EndPoint);
01943         JCW_MOULDPOINT(pCopy, EndPoint2);
01944         JCW_MOULDPOINT(pCopy, EndPoint3);
01945     }
01946     return(pCopy);
01947 #else
01948     return NULL;
01949 #endif // VECTOR_STROKING
01950 }
01951 
01952 
01953 
01955 //
01956 //                          ConicalFillAttribute class
01957 //
01959 
01960 /********************************************************************************************
01961 
01962 >   ConicalFillAttribute::ConicalFillAttribute()
01963 
01964     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01965     Created:    6/9/94
01966     Purpose:    Default Constuctor for fill attribute values. 
01967     SeeAlso:    AttrFillGeometry::AttrFillGeometry
01968 
01969 ********************************************************************************************/
01970 
01971 ConicalFillAttribute::ConicalFillAttribute()
01972 {
01973 }
01974 
01975 /********************************************************************************************
01976 
01977 >   NodeAttribute *ConicalFillAttribute::MakeNode()
01978 
01979     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01980     Created:    23/8/94
01981     Returns:    Pointer to the new node, or NULL if out of memory.
01982     Purpose:    Make a AttrConicalFill node from this graduated fill attribute.
01983     Errors:     Out of memory
01984     SeeAlso:    AttributeValue::MakeNode
01985 
01986 ********************************************************************************************/
01987 
01988 NodeAttribute *ConicalFillAttribute::MakeNode()
01989 {
01990     // Create new attribute node
01991     AttrConicalFill *pAttr = new AttrConicalColourFill;
01992     if (pAttr==NULL)
01993         // error message has already been set by new
01994         return NULL;
01995 
01996     // Copy attribute value into the new node.
01997     pAttr->GetAttributeValue()->SimpleCopy(this);
01998 
01999     // Return the new node
02000     return pAttr;
02001 }
02002 
02003 
02004 /********************************************************************************************
02005 
02006 >   DocCoord ConicalFillAttribute::GetGeometryCoord(float pos) const
02007 
02008     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
02009     Created:    11/3/97
02010     Inputs:     pos = a parameter between 0 and 1
02011     Returns:    A coordinate which relates the input parameter to a coordinate space
02012                 on this geometry. For instance a linear fill would have a linear parameter
02013                 space, 0 at the start coordinate, increasing to 1 at the end coordinate
02014     Purpose:    Find the absolute position in geometry coordinate space for the given
02015                 parameter.
02016 
02017 ********************************************************************************************/
02018 
02019 DocCoord ConicalFillAttribute::GetGeometryCoord(float pos) const
02020 {
02021     // Here we calculate a circular coordinate space
02022     return PathUtil::PointOnSemiCircle(StartPoint,EndPoint,(double)pos);
02023 }
02024 
02025 
02026 
02027 /********************************************************************************************
02028 
02029 >   float ConicalFillAttribute::GetGeometryParam(const DocCoord& c) const
02030 
02031     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
02032     Created:    11/3/97
02033     Inputs:     c = a coordinate
02034     Returns:    A parameter p, 0<=p<=1, such that GetGeometryCoord(p) is the closest
02035                 coordinate in the geometry to the input c.
02036     Purpose:    Find the parameter for the closest point to c on this geometry.
02037 
02038 ********************************************************************************************/
02039 
02040 float ConicalFillAttribute::GetGeometryParam(const DocCoord& c) const
02041 {
02042     // ok we're a linear geometry so find the closest point to a line type of thing.
02043     // use a handy util written by that other fab bloke called Mike.
02044     DocCoord Coords[2];
02045     Coords[0] = StartPoint;
02046     Coords[1] = EndPoint;
02047     double p;
02048     PathUtil::SqrDistanceToSemiCircle(Coords, c, &p);
02049     return (float)p;
02050 }
02051 
02052 
02054 //
02055 //                          SquareFillAttribute class
02056 //
02058 
02059 /********************************************************************************************
02060 
02061 >   SquareFillAttribute::SquareFillAttribute()
02062 
02063     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
02064     Created:    9/8/96
02065     Purpose:    Default Constuctor for fill attribute values. 
02066     SeeAlso:    AttrFillGeometry::AttrFillGeometry
02067 
02068 ********************************************************************************************/
02069 
02070 SquareFillAttribute::SquareFillAttribute()
02071 {
02072     IsPersp = FALSE;
02073 
02074     EndPoint2 = DocCoord(0,0);
02075 }
02076 
02077 /********************************************************************************************
02078 
02079 >   NodeAttribute *SquareFillAttribute::MakeNode()
02080 
02081     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
02082     Created:    9/8/96
02083     Returns:    Pointer to the new node, or NULL if out of memory.
02084     Purpose:    Make a AttrSquareFill node from this graduated fill attribute.
02085     Errors:     Out of memory
02086     SeeAlso:    AttributeValue::MakeNode
02087 
02088 ********************************************************************************************/
02089 
02090 NodeAttribute *SquareFillAttribute::MakeNode()
02091 {
02092     // Create new attribute node
02093     AttrSquareFill *pAttr = new AttrSquareColourFill;
02094     if (pAttr==NULL)
02095         // error message has already been set by new
02096         return NULL;
02097 
02098     // Copy attribute value into the new node.
02099     pAttr->GetAttributeValue()->SimpleCopy(this);
02100 
02101     // Return the new node
02102     return pAttr;
02103 }
02104 
02105 
02106 /********************************************************************************************
02107 
02108 >   void SquareFillAttribute::SetEndPoint2(DocCoord* Pos)
02109 
02110     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
02111     Created:    9/8/96
02112     Inputs:     -
02113     Purpose:    Sets the End Point of this fill
02114 
02115 ********************************************************************************************/
02116 
02117 void SquareFillAttribute::SetEndPoint2(DocCoord* Pos)
02118 {
02119     if (Pos == NULL)
02120         EndPoint2 = MakeLineAtAngle(*GetStartPoint(), *GetEndPoint(), 90);
02121     else
02122         EndPoint2 = *Pos;
02123 }
02124 
02125 
02126 /********************************************************************************************
02127 
02128 >   void SquareFillAttribute::SetEndPoint3(DocCoord* Pos)
02129 
02130     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
02131     Created:    9/8/96
02132     Inputs:     -
02133     Purpose:    Sets the End Point of this fill
02134 
02135 ********************************************************************************************/
02136 
02137 void SquareFillAttribute::SetEndPoint3(DocCoord* Pos)
02138 {
02139     if (Pos == NULL)
02140         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
02141     else
02142         EndPoint3 = *Pos;
02143 }
02144 
02145 
02146 /********************************************************************************************
02147 
02148 >   void SquareFillAttribute::MakePerspective()
02149 
02150     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
02151     Created:    9/8/96
02152     Inputs:     -
02153     Purpose:    Make the fill perspectived.
02154                 This should be called just before it is transformed by the moulder,
02155                 so it can validate the 4th control point.
02156 
02157 ********************************************************************************************/
02158 
02159 void SquareFillAttribute::MakePerspective()
02160 {
02161     IsPersp = TRUE;
02162 
02163     INT32 dx1 = EndPoint.x - StartPoint.x;
02164     INT32 dx2 = EndPoint2.x - StartPoint.x;
02165 
02166     INT32 dy1 = EndPoint.y - StartPoint.y;
02167     INT32 dy2 = EndPoint2.y - StartPoint.y;
02168 
02169     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
02170     SetEndPoint3(&Pos3);
02171 }
02172 
02173 /********************************************************************************************
02174 
02175 >   void SquareFillAttribute::RemovePerspective()
02176 
02177     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
02178     Created:    9/8/96
02179     Inputs:     -
02180     Purpose:    Removes perspective from this fill.
02181 
02182 ********************************************************************************************/
02183 
02184 void SquareFillAttribute::RemovePerspective()
02185 {
02186     IsPersp = FALSE;
02187 }
02188 
02189 
02190 
02191 
02193 //
02194 //                          BitmapFillAttribute class
02195 //
02197 
02198 BOOL BitmapFillAttribute::m_doBitmapSmoothing = TRUE;
02199 
02200 /********************************************************************************************
02201 
02202 >   BitmapFillAttribute::BitmapFillAttribute()
02203 
02204     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02205     Created:    6/9/94
02206     Purpose:    Default Constuctor for fill attribute values. 
02207     SeeAlso:    AttrFillGeometry::AttrFillGeometry
02208 
02209 ********************************************************************************************/
02210 
02211 BitmapFillAttribute::BitmapFillAttribute()
02212 {
02213     Colour    = DocColour(COLOUR_NONE);
02214     EndColour = DocColour(COLOUR_NONE);
02215 
02216     StartPoint = DocCoord(0,0);
02217     EndPoint   = DocCoord(0,0);
02218     EndPoint2  = DocCoord(0,0);
02219 
02220     Tesselation = RT_Repeating;
02221 
02222     IsPersp = FALSE;
02223 
02224     m_CanBlurRender = TRUE;
02225 }
02226 
02227 /********************************************************************************************
02228 
02229 >   BitmapFillAttribute::~BitmapFillAttribute()
02230 
02231     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02232     Created:    6/9/94
02233     Purpose:    Destructor for bitmap fill attribute values. 
02234     SeeAlso:    AttrFillGeometry::AttrFillGeometry
02235 
02236 ********************************************************************************************/
02237 
02238 BitmapFillAttribute::~BitmapFillAttribute()
02239 {
02240 }
02241 
02242 KernelBitmapRef* BitmapFillAttribute::GetBitmapRef()
02243 {
02244     return &BitmapRef;
02245 }
02246 
02247 /********************************************************************************************
02248 
02249 >   NodeAttribute *BitmapFillAttribute::MakeNode()
02250 
02251     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02252     Created:    10/8/94
02253     Returns:    Pointer to the new node, or NULL if out of memory.
02254     Purpose:    Make a AttrFlatColourFill node from this flat fill colour attribute.
02255     Errors:     Out of memory
02256     SeeAlso:    AttributeValue::MakeNode; AttrFlatColourFill
02257 
02258 ********************************************************************************************/
02259 
02260 NodeAttribute *BitmapFillAttribute::MakeNode()
02261 {
02262     // Create new attribute node
02263     AttrBitmapFill *pAttr = new AttrBitmapColourFill;
02264     if (pAttr==NULL)
02265         // error message has already been set by new
02266         return NULL;
02267 
02268     // Copy attribute value into the new node.
02269     pAttr->GetAttributeValue()->SimpleCopy(this);
02270 
02271     // Return the new node
02272     return pAttr;
02273 }
02274 
02275 
02276 /********************************************************************************************
02277 
02278 >   KernelBitmap* BitmapFillAttribute::GetBitmap()
02279 
02280     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02281     Created:    3/12/94
02282     Purpose:    Get the bitmap referenced by this attribute. 
02283     SeeAlso:    BitmapFillAttribute::AttachBitmap()
02284 
02285 ********************************************************************************************/
02286 
02287 KernelBitmap* BitmapFillAttribute::GetBitmap()
02288 {
02289     KernelBitmap* pBitmap = BitmapRef.GetBitmap();
02290     
02291     // Check for a deleted bitmap
02292     if (pBitmap && pBitmap->HasBeenDeleted())
02293     {
02294         ERROR2IF(pBitmap->GetParentBitmapList() == NULL, NULL, "Deleted bitmap has no parent list");
02295         
02296         // Use the default bitmap instead
02297         pBitmap = pBitmap->GetParentBitmapList()->FindDefaultBitmap();
02298 
02299         // There should always be a default bitmap in the list
02300         ERROR2IF(pBitmap == NULL, 0L, "Couldn't find the default bitmap");
02301     }
02302 
02303     return pBitmap;
02304 }
02305 
02306 /********************************************************************************************
02307 
02308 >   BOOL BitmapFillAttribute::AttachBitmap(KernelBitmap* pBitmap)
02309 
02310     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02311     Created:    20/9/94
02312     Purpose:    Attaches a bitmap to this fill. 
02313     SeeAlso:    BitmapFillAttribute::DetachBitmap()
02314 
02315 ********************************************************************************************/
02316 
02317 BOOL BitmapFillAttribute::AttachBitmap(KernelBitmap* NewBitmap)
02318 {
02319     BitmapRef.Attach(NewBitmap);
02320 
02321     return TRUE;
02322 }
02323 
02324 /********************************************************************************************
02325 
02326 >   BOOL BitmapFillAttribute::DetachBitmap()
02327 
02328     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02329     Created:    20/9/94
02330     Purpose:    Detaches a bitmap from this fill. 
02331     SeeAlso:    BitmapFillAttribute::AttachBitmap()
02332 
02333 ********************************************************************************************/
02334 
02335 BOOL BitmapFillAttribute::DetachBitmap()
02336 {
02337     BitmapRef.Detach();
02338 
02339     return TRUE;
02340 }
02341 
02342 /********************************************************************************************
02343 
02344 >   BOOL BitmapFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
02345 
02346     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02347     Created:    20/9/94
02348     Purpose:    Used to copy a bitmap from one fill to another. 
02349     SeeAlso:    BitmapFillAttribute::AttachBitmap()
02350 
02351 ********************************************************************************************/
02352 
02353 BOOL BitmapFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
02354 {
02355     if (BmpToCopy != NULL)  // Is there a bitmap to copy ?
02356     {
02357         BitmapRef.Detach();
02358 
02359         OILBitmap* Bmp = BmpToCopy->ActualBitmap;
02360         if (Bmp->IsTemp())
02361         {
02362             BitmapRef.SetBitmap(BmpToCopy);
02363             return TRUE;
02364         }
02365 
02366         BitmapRef.Attach(BmpToCopy);
02367     }
02368 
02369     return TRUE;
02370 }
02371 
02372 
02373 /********************************************************************************************
02374 
02375 >   void BitmapFillAttribute::Render(RenderRegion *pRegion)
02376 
02377     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02378     Created:    23/8/94
02379     Inputs:     pRegion - the render region to render this attribute into.
02380     Purpose:    Sets the fill geometry attribute for the given render region. i.e. all
02381                 paths filled will now be filled with this fill geometry.
02382     SeeAlso:    BitmapFillAttribute; RenderStack; AttributeValue; NodeAttribute;
02383                 BitmapFillAttribute::Restore; BitmapFillAttribute::SimpleCopy;
02384                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
02385 
02386 ********************************************************************************************/
02387 
02388 void BitmapFillAttribute::Render(RenderRegion *pRegion, BOOL Temp)
02389 {
02390     pRegion->SetFillGeometry(this, Temp);
02391 }
02392 
02393 /********************************************************************************************
02394 
02395 >   void BitmapFillAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
02396 
02397     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02398     Created:    23/8/94
02399     Inputs:     pRegion - the render region to restore the attribute into.
02400                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
02401                           permanent (e.g. it's in a document tree).
02402     Purpose:    Restores the fill type attribute for the given render region. i.e. all
02403                 paths filled will now be filled with this fill attribute.
02404     SeeAlso:    BitmapFillAttribute; RenderStack; AttributeValue; NodeAttribute;
02405                 BitmapFillAttribute::Render; BitmapFillAttribute::SimpleCopy;
02406                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
02407 
02408 ********************************************************************************************/
02409 
02410 void BitmapFillAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
02411 {
02412     pRegion->RestoreFillGeometry(this, Temp);
02413 }
02414 
02415 /********************************************************************************************
02416 
02417 >   void BitmapFillAttribute::SetStartPoint(DocCoord* Pos)
02418 
02419     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02420     Created:    5/9/94
02421     Inputs:     -
02422     Purpose:    Sets the Start Point of this fill
02423 
02424 ********************************************************************************************/
02425 
02426 void BitmapFillAttribute::SetStartPoint(DocCoord* Pos)
02427 {
02428     if (Pos == NULL)
02429         StartPoint = DocCoord(0,0);
02430     else
02431         StartPoint = *Pos;
02432 }
02433 
02434 /********************************************************************************************
02435 
02436 >   void BitmapFillAttribute::SetEndPoint(DocCoord* Pos)
02437 
02438     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02439     Created:    5/9/94
02440     Inputs:     -
02441     Purpose:    Sets the End Point of this fill
02442 
02443 ********************************************************************************************/
02444 
02445 void BitmapFillAttribute::SetEndPoint(DocCoord* Pos)
02446 {
02447     if (Pos == NULL)
02448         EndPoint = DocCoord(0,0);
02449     else
02450         EndPoint = *Pos;
02451 }
02452 
02453 /********************************************************************************************
02454 
02455 >   void BitmapFillAttribute::SetEndPoint2(DocCoord* Pos)
02456 
02457     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02458     Created:    5/9/94
02459     Inputs:     -
02460     Purpose:    Sets the End Point of this fill
02461 
02462 ********************************************************************************************/
02463 
02464 void BitmapFillAttribute::SetEndPoint2(DocCoord* Pos)
02465 {
02466     if (Pos == NULL)
02467         EndPoint2 = MakeLineAtAngle(*GetStartPoint(), *GetEndPoint(), 90);
02468     else
02469         EndPoint2 = *Pos;
02470 }
02471 
02472 /********************************************************************************************
02473 
02474 >   void BitmapFillAttribute::SetEndPoint3(DocCoord* Pos)
02475 
02476     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02477     Created:    5/9/94
02478     Inputs:     -
02479     Purpose:    Sets the End Point of this fill
02480 
02481 ********************************************************************************************/
02482 
02483 void BitmapFillAttribute::SetEndPoint3(DocCoord* Pos)
02484 {
02485     if (Pos == NULL)
02486         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
02487     else
02488         EndPoint3 = *Pos;
02489 }
02490 
02491 
02492 
02493 /********************************************************************************************
02494 
02495 >   void BitmapFillAttribute::MakePerspective()
02496 
02497     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02498     Created:    1/4/94
02499     Inputs:     -
02500     Purpose:    Make the fill perspectived.
02501                 This should be called just before it is transformed by the moulder,
02502                 so it can validate the 4th control point.
02503 
02504 ********************************************************************************************/
02505 
02506 void BitmapFillAttribute::MakePerspective()
02507 {
02508     IsPersp = TRUE;
02509 
02510     INT32 dx1 = EndPoint.x - StartPoint.x;
02511     INT32 dx2 = EndPoint2.x - StartPoint.x;
02512 
02513     INT32 dy1 = EndPoint.y - StartPoint.y;
02514     INT32 dy2 = EndPoint2.y - StartPoint.y;
02515 
02516     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
02517     SetEndPoint3(&Pos3);
02518 }
02519 
02520 /********************************************************************************************
02521 
02522 >   void BitmapFillAttribute::RemovePerspective()
02523 
02524     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02525     Created:    1/4/94
02526     Inputs:     -
02527     Purpose:    Removes perspective from this fill.
02528 
02529 ********************************************************************************************/
02530 
02531 void BitmapFillAttribute::RemovePerspective()
02532 {
02533     IsPersp = FALSE;
02534 }
02535 
02536 /********************************************************************************************
02537 
02538 >   FillGeometryAttribute& BitmapFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
02539 
02540     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02541     Created:    8/8/94
02542     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
02543     Returns:    A reference
02544     Purpose:    Make the Attribute the same as the other. 
02545 
02546 ********************************************************************************************/
02547 
02548 FillGeometryAttribute& BitmapFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
02549 {
02550     return ColourFillAttribute::operator=(FillAttrib);
02551 }
02552 
02553 /********************************************************************************************
02554 
02555 >   INT32 BitmapFillAttribute::operator==(const FillGeometryAttribute& Attrib)
02556 
02557     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02558     Created:    23/8/94
02559     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
02560     Returns:    Usual semantics for equality.
02561     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
02562                 a description of why it's required. 
02563     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
02564                 runtime class.
02565     SeeAlso:    NodeAttribute::operator==
02566 
02567 ********************************************************************************************/
02568 
02569 INT32 BitmapFillAttribute::operator==(const FillGeometryAttribute& Attrib)
02570 {
02571     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
02572         return FALSE;
02573 
02574     BitmapFillAttribute* pAttrib = (BitmapFillAttribute*)&Attrib;
02575 
02576     if (GetBitmapRef()->GetBitmap() != pAttrib->GetBitmapRef()->GetBitmap())
02577         return FALSE;
02578 
02579     if (IsPerspective())
02580     { 
02581         if (!pAttrib->IsPerspective())
02582             return FALSE;
02583 
02584         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
02585             return FALSE;
02586     }
02587 
02588     if (GetStartColour() != NULL)
02589     {
02590         if (pAttrib->GetStartColour() == NULL)
02591             return FALSE;
02592 
02593         if (*GetStartColour() != *pAttrib->GetStartColour())
02594             return FALSE;
02595     }
02596     else if (pAttrib->GetStartColour() != NULL)
02597     {
02598         return FALSE;
02599     }
02600 
02601     if (GetEndColour() != NULL)
02602     {
02603         if (pAttrib->GetEndColour() == NULL)
02604             return FALSE;
02605 
02606         if (*GetEndColour() != *pAttrib->GetEndColour())
02607             return FALSE;
02608     }
02609     else if (pAttrib->GetStartColour() != NULL)
02610     {
02611         return FALSE;
02612     }
02613 
02614     // check the colour ramps match
02615     if (!SameColourRampAs(pAttrib->GetColourRamp()))
02616         return FALSE;
02617 
02618     // Are the Colours and Control points all the same ?
02619     return (
02620     
02621         StartPoint  == pAttrib->StartPoint  &&
02622         EndPoint    == pAttrib->EndPoint    &&
02623         EndPoint2   == pAttrib->EndPoint2
02624 
02625     );
02626 }
02627 
02628 /********************************************************************************************
02629 
02630 >   void BitmapFillAttribute::SimpleCopy(AttributeValue *pValue)
02631 
02632     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02633     Created:    10/8/94
02634     Inputs:     pAttr - pointer to the AttributeValue to copy.
02635     Purpose:    See AttributeValue::SimpleCopy
02636     SeeAlso:    GradFillAttribute; RenderStack; AttributeValue; NodeAttribute;
02637                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
02638 
02639 ********************************************************************************************/
02640 
02641 void BitmapFillAttribute::SimpleCopy(AttributeValue *pValue)
02642 {
02643     // Just use the assignment operator
02644     *this = *(FillGeometryAttribute*)pValue;
02645 }
02646 
02647 /********************************************************************************************
02648 
02649 >   BOOL BitmapFillAttribute::RenderFill(RenderRegion *pRegion, Path *pPath)
02650 
02651     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02652     Created:    10/8/94
02653     Inputs:     pRegion - the render region of interest
02654                 pPath - the path to fill.
02655     Returns:    FALSE => let the Render region fill the path, TRUE = we have done it.
02656     Purpose:    Render the fill, if possible - it depends on what kind of render region
02657                 we have been given.
02658 
02659 ********************************************************************************************/
02660 
02661 BOOL BitmapFillAttribute::RenderFill(RenderRegion *pRegion, Path *pPath)
02662 {
02663     if ( pRegion->IsKindOf(CC_RUNTIME_CLASS(GRenderRegion)) )
02664     {
02665         // Safe to cast now
02666         GRenderRegion *gRnd = (GRenderRegion*)pRegion;
02667 
02668         // Do the rendering
02669         return gRnd->RenderBitmapFill(pPath, this);
02670     }
02671     else if ( pRegion->IsKindOf(CC_RUNTIME_CLASS(OSRenderRegion)) )
02672     {
02673         // Safe to cast now
02674         OSRenderRegion *oRnd = (OSRenderRegion*)pRegion;
02675 
02676         // Do the rendering
02677         return oRnd->RenderBitmapFill(pPath, this);
02678     }
02679 
02680     // Can't render this fill with this render region.
02681     return FALSE;
02682 }
02683 
02684 /********************************************************************************************
02685 
02686 >   BOOL BitmapFillAttribute::SetDPI(UINT32 NewDpi)
02687 
02688     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02689     Created:    6/10/94
02690     Inputs:     NewDpi
02691     Purpose:    Sets the DPI of a bitmap.
02692     SeeAlso:    FractalFillAttribute::SetDPI
02693 
02694 ********************************************************************************************/
02695 
02696 BOOL BitmapFillAttribute::SetDPI(UINT32 NewDpi)
02697 {
02698     if (IsPerspective())
02699         return FALSE;
02700 
02701     if (NewDpi == 0)
02702         return FALSE;
02703 
02704     if (GetBitmap() == NULL)
02705         return FALSE;
02706 
02707     OILBitmap *OilBM = GetBitmap()->ActualBitmap;
02708 
02709     if (OilBM == NULL)
02710         return FALSE;
02711 
02712     BitmapInfo Info;
02713     OilBM->GetInfo(&Info);
02714 
02715     INT32 PixWidth  = Info.PixelWidth;
02716     INT32 PixHeight = Info.PixelHeight;
02717 
02718     DocCoord Start = *GetStartPoint();
02719     DocCoord End   = *GetEndPoint();
02720     DocCoord End2  = *GetEndPoint2();
02721 
02722     INT32 Width  = INT32(Start.Distance(End));
02723     INT32 Height = INT32(Start.Distance(End2));
02724 
02725     INT32 HDpi = (Width  == 0) ? 0 : (PixWidth*72000)/Width;
02726     INT32 VDpi = (Height == 0) ? 0 : (PixHeight*72000)/Height;
02727 
02728     INT32 OldDpi = HDpi;
02729     if (VDpi < OldDpi)
02730         OldDpi = VDpi;
02731 
02732     TRACEUSER( "Mike", _T("Bitmap Dpi is currently %d\n"),OldDpi);
02733     TRACEUSER( "Mike", _T("Setting Bitmap Dpi to %d\n"),NewDpi);
02734 
02735     FIXED16 Ratio   = FIXED16(double(OldDpi)/double(NewDpi));
02736     Matrix Scale    = Matrix(Ratio, Ratio);
02737 
02738     GetBitmapVirtualPoints(Start, End, End2,
02739                             &Start, &End, &End2);
02740 
02741     DocCoord Centre = Start;
02742 
02743     Start.translate(-Centre.x, -Centre.y);  
02744     Scale.transform(&Start);
02745     Start.translate(Centre.x, Centre.y);    
02746 
02747     End.translate(-Centre.x, -Centre.y);    
02748     Scale.transform(&End);
02749     End.translate(Centre.x, Centre.y);  
02750 
02751     End2.translate(-Centre.x, -Centre.y);   
02752     Scale.transform(&End2);
02753     End2.translate(Centre.x, Centre.y); 
02754 
02755     GetBitmapRealPoints(Start, End, End2,
02756                         &Start, &End, &End2);
02757 
02758     INT32 NewWidth  = INT32(Start.Distance(End));
02759     INT32 NewHeight = INT32(Start.Distance(End2));
02760 
02761     if (NewWidth == 0 || NewHeight == 0)
02762         return FALSE;
02763 
02764     SetStartPoint(&Start);
02765     SetEndPoint(&End);
02766     SetEndPoint2(&End2);
02767 
02768     SetFractalDPI(GetDPI());
02769 
02770     return TRUE;
02771 }
02772 
02773 /********************************************************************************************
02774 
02775 >   UINT32 BitmapFillAttribute::GetDPI()
02776 
02777     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02778     Created:    6/10/94
02779     Returns:    The current DPI of the bitmap
02780     Purpose:    Gets the DPI of a bitmap.
02781     SeeAlso:    FractalFillAttribute::SetDPI
02782 
02783 ********************************************************************************************/
02784 
02785 UINT32 BitmapFillAttribute::GetDPI()
02786 {
02787     UINT32 Dpi = 0;
02788 
02789     if (GetBitmap() == NULL)
02790         return 0;
02791 
02792     OILBitmap *OilBM = GetBitmap()->ActualBitmap;
02793 
02794     if (OilBM != NULL)
02795     {
02796         BitmapInfo Info;
02797         OilBM->GetInfo(&Info);
02798 
02799         INT32 PixWidth  = Info.PixelWidth;
02800         INT32 PixHeight = Info.PixelHeight;
02801 
02802         DocCoord Start = *GetStartPoint();
02803         DocCoord End   = *GetEndPoint();
02804         DocCoord End2  = *GetEndPoint2();
02805 
02806         INT32 Width  = INT32(Start.Distance(End));
02807         INT32 Height = INT32(Start.Distance(End2));
02808 
02809         UINT32 HDpi = 0;
02810         UINT32 VDpi = 0;
02811 
02812         if (Width > 0)
02813             HDpi = (PixWidth*72000)/Width;
02814 
02815         if (Height > 0)
02816             VDpi = (PixHeight*72000)/Height;
02817 
02818         Dpi = HDpi;
02819         if (VDpi < Dpi)
02820             Dpi = VDpi;
02821     }
02822 
02823     return Dpi;
02824 }
02825 
02826 /********************************************************************************************
02827 
02828 >   void ColourFillAttribute::SetStartColour(DocColour* NewCol)
02829 
02830     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02831     Created:    5/9/94
02832     Inputs:     -
02833     Purpose:    Sets the start colour of this fill
02834 
02835 ********************************************************************************************/
02836 
02837 void BitmapFillAttribute::SetStartColour(DocColour* NewCol)
02838 {
02839     if (NewCol == NULL)
02840         Colour = COLOUR_NONE;
02841     else
02842         Colour = *NewCol;
02843 
02844     if (Colour == COLOUR_NONE)
02845         EndColour = COLOUR_NONE;
02846 
02847     if (Colour != COLOUR_NONE && GetEndColour() == NULL)
02848     {
02849         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
02850                                             _R(IDS_WHITENAME), &EndColour);
02851 
02852         if (Colour == EndColour)
02853         {
02854             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
02855                                                 _R(IDS_BLACKNAME), &EndColour);
02856         }
02857     }
02858 }
02859 
02860 /********************************************************************************************
02861 
02862 >   void BitmapFillAttribute::SetEndColour(DocColour* NewCol)
02863 
02864     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02865     Created:    5/9/94
02866     Inputs:     -
02867     Purpose:    Sets the end colour of this fill
02868 
02869 ********************************************************************************************/
02870 
02871 void BitmapFillAttribute::SetEndColour(DocColour* NewCol)
02872 {
02873     if (NewCol == NULL)
02874         EndColour = COLOUR_NONE;
02875     else
02876         EndColour = *NewCol;
02877 
02878     if (EndColour == COLOUR_NONE)
02879         Colour = COLOUR_NONE;
02880 
02881     if (EndColour != COLOUR_NONE && GetStartColour() == NULL)
02882     {
02883         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
02884                                             _R(IDS_BLACKNAME), &Colour);
02885 
02886         if (Colour == EndColour)
02887         {
02888             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
02889                                                 _R(IDS_WHITENAME), &Colour);
02890         }
02891     }
02892 }
02893 
02894 /********************************************************************************************
02895 
02896 >   DocColour* ColourFillAttribute::GetStartColour()
02897 
02898     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02899     Created:    24/1/95
02900     Inputs:     -
02901     Purpose:    Gets the Start colour of this fill
02902 
02903 ********************************************************************************************/
02904 
02905 DocColour* BitmapFillAttribute::GetStartColour()
02906 {
02907     if (Colour == COLOUR_NONE)
02908         return NULL;
02909     else
02910         return &Colour;
02911 }
02912 
02913 /********************************************************************************************
02914 
02915 >   DocColour* ColourFillAttribute::GetEndColour()
02916 
02917     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02918     Created:    24/1/95
02919     Inputs:     -
02920     Purpose:    Gets the End colour of this fill
02921 
02922 ********************************************************************************************/
02923 
02924 DocColour* BitmapFillAttribute::GetEndColour()
02925 {
02926     if (EndColour == COLOUR_NONE)
02927         return NULL;
02928     else
02929         return &EndColour;
02930 }
02931 
02932 void BitmapFillAttribute::SetTesselation(INT32 NewTess)
02933 {
02934     if (NewTess == RT_NoRepeatType)
02935         NewTess = RT_Repeating;
02936 
02937     Tesselation = NewTess;
02938 }
02939 
02941 //
02942 //                          FractalFillAttribute class
02943 //
02945 
02946 /********************************************************************************************
02947 
02948 >   FractalFillAttribute::FractalFillAttribute()
02949 
02950     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02951     Created:    6/9/94
02952     Purpose:    Default Constuctor for fill attribute values. 
02953     SeeAlso:    AttrFillGeometry::AttrFillGeometry
02954 
02955 ********************************************************************************************/
02956 
02957 FractalFillAttribute::FractalFillAttribute()
02958 {
02959     MonotonicTime time;
02960     Seed = time.Sample();
02961 
02962     Graininess = AttrFillGeometry::FractalGraininess;
02963     Gravity    = AttrFillGeometry::FractalGravity;
02964     Dpi        = AttrFillGeometry::FractalDPI;
02965 
02966     Squash = 0;
02967     Dim    = 0;
02968     Tileable = FALSE;
02969 
02970     Tesselation = RT_RepeatInverted;
02971 }
02972 
02973 /********************************************************************************************
02974 
02975 >   FractalFillAttribute::~FractalFillAttribute()
02976 
02977     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02978     Created:    6/9/94
02979     Purpose:    Destructor for fractal fill attribute values. 
02980     SeeAlso:    AttrFillGeometry::AttrFillGeometry
02981 
02982 ********************************************************************************************/
02983 
02984 FractalFillAttribute::~FractalFillAttribute()
02985 {
02986     DetachBitmap();
02987 }
02988 
02989 /********************************************************************************************
02990 
02991 >   NodeAttribute *FractalFillAttribute::MakeNode()
02992 
02993     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02994     Created:    10/8/94
02995     Returns:    Pointer to the new node, or NULL if out of memory.
02996     Purpose:    Make a AttrFlatColourFill node from this flat fill colour attribute.
02997     Errors:     Out of memory
02998     SeeAlso:    AttributeValue::MakeNode; AttrFlatColourFill
02999 
03000 ********************************************************************************************/
03001 
03002 NodeAttribute *FractalFillAttribute::MakeNode()
03003 {
03004     // Create new attribute node
03005     AttrFractalColourFill *pAttr = new AttrFractalColourFill;
03006     if (pAttr==NULL)
03007         // error message has already been set by new
03008         return NULL;
03009 
03010     // Copy attribute value into the new node.
03011     pAttr->GetAttributeValue()->SimpleCopy(this);
03012 
03013     // Return the new node
03014     return pAttr;
03015 }
03016 
03017 /********************************************************************************************
03018 
03019 >   FillGeometryAttribute& FractalFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
03020 
03021     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03022     Created:    8/8/94
03023     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
03024     Returns:    a reference to this
03025     Purpose:    Assign this with the value of FillAttrib
03026 
03027 ********************************************************************************************/
03028 
03029 FillGeometryAttribute& FractalFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
03030 {
03031     if (FillAttrib.IsKindOf(CC_RUNTIME_CLASS(FractalFillAttribute)))
03032     {
03033         Seed        = ((FractalFillAttribute*)&FillAttrib)->Seed;
03034         Graininess  = ((FractalFillAttribute*)&FillAttrib)->Graininess;
03035         Gravity     = ((FractalFillAttribute*)&FillAttrib)->Gravity;
03036         Squash      = ((FractalFillAttribute*)&FillAttrib)->Squash;
03037         Dpi         = ((FractalFillAttribute*)&FillAttrib)->Dpi;
03038         Tileable    = ((FractalFillAttribute*)&FillAttrib)->Tileable;
03039         Dim         = ((FractalFillAttribute*)&FillAttrib)->Dim;
03040     }
03041 
03042     return ColourFillAttribute::operator=(FillAttrib);
03043 }
03044 
03045 /********************************************************************************************
03046 
03047 >   INT32 FractalFillAttribute::operator==(const FillGeometryAttribute& Attrib)
03048 
03049     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03050     Created:    23/8/94
03051     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
03052     Returns:    Usual semantics for equality.
03053     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
03054                 a description of why it's required. 
03055     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
03056                 runtime class.
03057     SeeAlso:    NodeAttribute::operator==
03058 
03059 ********************************************************************************************/
03060 
03061 INT32 FractalFillAttribute::operator==(const FillGeometryAttribute& Attrib)
03062 {
03063     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
03064         return FALSE;
03065 
03066     FractalFillAttribute* pAttrib = (FractalFillAttribute*)&Attrib;
03067 
03068     if (IsPerspective())
03069     { 
03070         if (!pAttrib->IsPerspective())
03071             return FALSE;
03072 
03073         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
03074             return FALSE;
03075     }
03076 
03077     // check the colour ramps match
03078     if (!SameColourRampAs(pAttrib->GetColourRamp()))
03079         return FALSE;
03080 
03081     // Are the Colours and Control points all the same ?
03082     
03083     return (
03084 
03085         *GetStartColour()   == *pAttrib->GetStartColour()   &&
03086         *GetEndColour()     == *pAttrib->GetEndColour()     &&
03087     
03088         *GetStartPoint()    == *pAttrib->GetStartPoint()    &&
03089         *GetEndPoint()      == *pAttrib->GetEndPoint()      &&
03090         *GetEndPoint2()     == *pAttrib->GetEndPoint2()     &&
03091 
03092         Seed        == pAttrib->Seed        &&
03093         Graininess  == pAttrib->Graininess  &&
03094         Gravity     == pAttrib->Gravity     &&
03095         Squash      == pAttrib->Squash      &&
03096         Dpi         == pAttrib->Dpi         &&
03097         Tileable    == pAttrib->Tileable    &&
03098         Dim         == pAttrib->Dim
03099     );
03100 }
03101 
03102 
03103 /********************************************************************************************
03104 
03105 >   void FractalFillAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
03106 
03107     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
03108     Created:    21/01/97
03109     Inputs:     pCachedFractal = A pointer to the fractal in the cache
03110     Returns:    -
03111     Purpose:    Copies any data from this FractalFillAttribute into the cached fractal
03112                 pointed to on entry. This data is then checked via IsSameAsCachedFractal
03113 
03114 ********************************************************************************************/
03115 
03116 void FractalFillAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
03117 {
03118     ERROR3IF(pCachedFractal==NULL, "NULL pointer passed to FractalFillAttribute::CacheFractalData");
03119     ERROR3IF(!IS_A(pCachedFractal,FractalFillAttribute), "Not a FractalFillAttribute during FractalFillAttribute::CacheFractalData");
03120 
03121     pCachedFractal->SetStartPoint(GetStartPoint());
03122     pCachedFractal->SetEndPoint(GetEndPoint());
03123     pCachedFractal->SetEndPoint2(GetEndPoint2());
03124 
03125     pCachedFractal->SetSeed(GetSeed());
03126     pCachedFractal->SetGraininess(GetGraininess());
03127     pCachedFractal->SetGravity(GetGravity());
03128     pCachedFractal->SetSquash(GetSquash());
03129     pCachedFractal->SetTileable(GetTileable());
03130     pCachedFractal->SetFractalDPI(GetFractalDPI());
03131     pCachedFractal->SetFractalDim(GetFractalDim());
03132 }
03133 
03134 
03135 /********************************************************************************************
03136 
03137 >   BOOL FractalFillAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
03138 
03139     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
03140     Created:    21/01/97
03141     Inputs:     pCachedFractal = A pointer to the fractal in the cache
03142     Returns:    TRUE if this fractal matches the cached fractal
03143                 FALSE if not
03144     Purpose:    A virtual comparison operator used by the fractal cache to check for a
03145                 matching fractal.
03146 
03147 ********************************************************************************************/
03148 
03149 BOOL FractalFillAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
03150 {
03151     ERROR3IF(pCachedFractal==NULL, "NULL pointer passed to FractalFillAttribute::IsSameAsCachedFractal");
03152     ERROR3IF(!IS_A(pCachedFractal,FractalFillAttribute), "Not a FractalFillAttribute during FractalFillAttribute::IsSameAsCachedFractal");
03153 
03154     // a long winded check but separate lines help in debugging, i.e. when does ok go FALSE
03155     BOOL ok =  (Seed        == pCachedFractal->GetSeed());
03156     ok = ok && (Graininess  == pCachedFractal->GetGraininess());
03157     ok = ok && (Gravity     == pCachedFractal->GetGravity());
03158     ok = ok && (Squash      == pCachedFractal->GetSquash());
03159     ok = ok && (Tileable    == pCachedFractal->GetTileable());
03160     ok = ok && ((UINT32)Dim     == pCachedFractal->GetFractalDim());
03161     //ok = ok && (Dpi           == pCachedFractal->GetFractalDpi());         // not checked in Will's original code
03162     return ok;
03163 }
03164 
03165 
03166 /********************************************************************************************
03167 
03168 >   BOOL FractalFillAttribute::AttachBitmap(KernelBitmap* pBitmap)
03169 
03170     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03171     Created:    20/9/94
03172     Purpose:    Attaches a bitmap to this fill. 
03173     SeeAlso:    BitmapFillAttribute::DetachBitmap()
03174 
03175 ********************************************************************************************/
03176 
03177 BOOL FractalFillAttribute::AttachBitmap(KernelBitmap* NewBitmap)
03178 {
03179     // Sometimes we are asked to attach the same bitmap to the attribute
03180     // So if we try to detach it and then attach it, during the detach
03181     // the bitmap can get deleted, so then we will effectivelly attach
03182     // a deleted bitmap. To avoid this we add this fractal to the list again in
03183     // order to increment the usage count, then do the normal detach & attach 
03184     // and finally remove the additional fractal from the list
03185     BOOL NeedUsageIncrement = FALSE;
03186     if ((NewBitmap != NULL) && (GetBitmap() != NULL))
03187     {
03188         // only if the bitmap we have is the same as the one we are to attach
03189         if ((GetBitmap()->ActualBitmap != NULL) && 
03190             (GetBitmap()->ActualBitmap == NewBitmap->ActualBitmap))
03191             {
03192                 NeedUsageIncrement = TRUE; // set the flag
03193                 GetApplication()->GetGlobalFractalList()->AddFractal(this); // inc the usage count
03194                 TRACEUSER( "Stefan", _T("NeedUsageIncrement = TRUE\n"));
03195             }
03196     }
03197 
03198     // get rid of the old bitmap
03199     DetachBitmap();
03200     
03201     if (NewBitmap == NULL)
03202         return FALSE;
03203 
03204     OILBitmap* Bmp = NewBitmap->ActualBitmap;
03205     if (Bmp == NULL || !Bmp->IsTemp())
03206         return FALSE;
03207 
03208     NewBitmap = new KernelBitmap(Bmp, TRUE);
03209     BitmapRef.SetBitmap(NewBitmap);
03210     GetApplication()->GetGlobalFractalList()->AddFractal(this);
03211 
03212     // if we added an additional fractal, remove it
03213     if (NeedUsageIncrement)
03214         GetApplication()->GetGlobalFractalList()->RemoveFractal(this);
03215     
03216     return TRUE;
03217 }
03218 
03219 /********************************************************************************************
03220 
03221 >   BOOL FractalFillAttribute::DetachBitmap()
03222 
03223     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03224     Created:    20/9/94
03225     Purpose:    Detaches a bitmap from this fill. 
03226     SeeAlso:    BitmapFillAttribute::AttachBitmap()
03227 
03228 ********************************************************************************************/
03229 
03230 BOOL FractalFillAttribute::DetachBitmap()
03231 {
03232     if (GetBitmap() == NULL)
03233         return FALSE;
03234 
03235     if (GetApplication()->GetGlobalFractalList()->RemoveFractal(this) && BitmapRef.GetBitmap())
03236     {
03237         // The fractal was deleted, so make sure we NULL our pointer
03238         BitmapRef.GetBitmap()->ActualBitmap = NULL;
03239     }
03240 
03241     // now make sure the kernelbitmap is dead too
03242     BitmapRef.DeleteBmp();
03243 
03244     return TRUE;
03245 }
03246 
03247 /********************************************************************************************
03248 
03249 >   BOOL FractalFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
03250 
03251     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03252     Created:    20/9/94
03253     Purpose:    Used to copy a bitmap from one fill to another. 
03254     SeeAlso:    BitmapFillAttribute::AttachBitmap()
03255 
03256 ********************************************************************************************/
03257 
03258 BOOL FractalFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
03259 {
03260     if (BmpToCopy != NULL)  // Is there a bitmap to copy ?
03261     {
03262         return AttachBitmap(BmpToCopy);
03263     }
03264 
03265     return TRUE;
03266 }
03267 
03268 /********************************************************************************************
03269 
03270 >   void FractalFillAttribute::SimpleCopy(AttributeValue *pValue)
03271 
03272     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03273     Created:    10/8/94
03274     Inputs:     pAttr - pointer to the AttributeValue to copy.
03275     Purpose:    See AttributeValue::SimpleCopy
03276     SeeAlso:    GradFillAttribute; RenderStack; AttributeValue; NodeAttribute;
03277                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
03278 
03279 ********************************************************************************************/
03280 
03281 void FractalFillAttribute::SimpleCopy(AttributeValue *pValue)
03282 {
03283     // Just use the assignment operator
03284     *this = *(FillGeometryAttribute*)pValue;
03285 }
03286 
03287 
03288 
03289 /********************************************************************************************
03290 
03291 >   void FractalFillAttribute::SetStartColour(DocColour* NewCol)
03292 
03293     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03294     Created:    5/9/94
03295     Inputs:     -
03296     Purpose:    Sets the Start colour of this fill
03297 
03298 ********************************************************************************************/
03299 
03300 void FractalFillAttribute::SetStartColour(DocColour* NewCol)
03301 {
03302     if (NewCol == NULL)
03303     {
03304         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03305                                             _R(IDS_WHITENAME), &Colour);
03306 
03307         if (Colour == EndColour)
03308         {
03309             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03310                                                 _R(IDS_BLACKNAME), &Colour);
03311         }
03312     }
03313     else
03314         Colour = *NewCol;
03315 }
03316 
03317 /********************************************************************************************
03318 
03319 >   void FractalFillAttribute::SetEndColour(DocColour* NewCol)
03320 
03321     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03322     Created:    5/9/94
03323     Inputs:     -
03324     Purpose:    Sets the Start colour of this fill
03325 
03326 ********************************************************************************************/
03327 
03328 void FractalFillAttribute::SetEndColour(DocColour* NewCol)
03329 {
03330     if (NewCol == NULL)
03331     {
03332         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03333                                             _R(IDS_BLACKNAME), &EndColour);
03334 
03335         if (Colour == EndColour)
03336         {
03337             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03338                                                 _R(IDS_WHITENAME), &EndColour);
03339         }
03340     }
03341     else
03342         EndColour = *NewCol;
03343 }
03344 
03345 
03346 
03347 /********************************************************************************************
03348 
03349 >   BOOL FractalFillAttribute::RecalcFractal()
03350 
03351     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03352     Created:    6/10/94
03353     Purpose:    Recalculates the Fractal.
03354     SeeAlso:    FractalFillAttribute::SetDPI
03355 
03356 ********************************************************************************************/
03357 
03358 BOOL FractalFillAttribute::RecalcFractal()
03359 {
03360     if (*GetStartPoint() == *GetEndPoint() ||
03361         *GetStartPoint() == *GetEndPoint2())
03362     {
03363         return FALSE;
03364     }
03365 
03366     UINT32 OldDim = GetFractalDim();
03367 
03368     KernelBitmap* pBitmap = GenerateFractalBitmap(  Seed, 
03369                                                     Graininess.MakeDouble(),
03370                                                     Gravity.MakeDouble(),
03371                                                     Squash.MakeDouble(), 
03372                                                     Dpi);
03373 
03374     if (pBitmap == NULL)
03375     {
03376         TRACEUSER( "Mike", _T("Fractal Failed !!!\n"));
03377         return FALSE;   // Error set by GenerateFractalBitmap
03378     }
03379 
03380     // When asking GenerateFractalBitmap above to give us a bitmap, it might modify the Dim value.
03381     // DetachBitmap then tries to match this fractal with the cached fractals, so it could find a 
03382     // wrong cached fractal (one with the same parameters as this, but with Dim value as set by
03383     // GenerateFractalBitmap, rather then the original value). In this case DetachBitmap acts on
03384     // the wrong fractal and could even cause destroying its bitmap, even though it is used by 
03385     // some other attribute. To fix this we temporarily set Dim to the old value, call DetachBitmap
03386     // and then set the new value back.
03387     UINT32 NewDim = GetFractalDim();
03388     if (NewDim != OldDim)
03389     {
03390         SetFractalDim(OldDim);
03391         DetachBitmap();
03392 
03393         SetFractalDim(NewDim);
03394     }
03395 
03396     AttachBitmap(pBitmap);
03397     delete pBitmap;
03398 
03399     return TRUE;
03400 }
03401 
03402 
03403 
03404 /********************************************************************************************
03405 
03406 >   void FractalFillAttribute::SetTesselation(INT32 NewTess)
03407 
03408     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03409     Created:    6/10/94
03410     Returns:    -
03411     Purpose:    Set the prefered tesselation of this fractal
03412     SeeAlso:    
03413 
03414 ********************************************************************************************/
03415 
03416 void FractalFillAttribute::SetTesselation(INT32 NewTess)
03417 {
03418     if (NewTess == RT_NoRepeatType)
03419         NewTess = RT_RepeatInverted;
03420 
03421     Tesselation = NewTess;
03422 }
03423 
03424 void FractalFillAttribute::SetFractalDim(UINT32 NewDim) 
03425 { 
03426     Dim = NewDim; 
03427 }
03428 
03429 BOOL FractalFillAttribute::SetTileable(BOOL NewTile)
03430 {
03431     DetachBitmap();     // Ensure the current fractal is removed from cache
03432 
03433     Tileable = NewTile;
03434 
03435     return TRUE;
03436 }
03437 
03438 /********************************************************************************************
03439 
03440 >   BOOL FractalFillAttribute::SetFractalDPI(UINT32 NewDpi)
03441 
03442     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03443     Created:    6/10/94
03444     Inputs:     NewDpi - New DPI to generate the Fractal at.
03445     Purpose:    Recalculates the Fractal at a new Dpi.
03446     SeeAlso:    FractalFillAttribute::GetFractalDPI
03447 
03448 ********************************************************************************************/
03449 
03450 BOOL FractalFillAttribute::SetFractalDPI(UINT32 NewDpi)
03451 {
03452     Dpi = NewDpi;
03453 
03454     return TRUE;
03455 }
03456 
03457 
03458 /*******************************************************************************************
03459   Values local to this fractal type
03460 *******************************************************************************************/
03461 
03462 BOOL FractalFillAttribute::SetSeed(INT32 NewSeed)
03463 {
03464     DetachBitmap();     // Ensure the current fractal is removed from cache
03465 
03466     Seed = NewSeed;
03467 
03468     return TRUE;
03469 }
03470 
03471 BOOL FractalFillAttribute::SetGraininess(FIXED16 NewGrain)
03472 {
03473     DetachBitmap();     // Ensure the current fractal is removed from cache
03474 
03475     Graininess = NewGrain;
03476 
03477     return TRUE;
03478 }
03479 
03480 BOOL FractalFillAttribute::SetGravity(FIXED16 NewGrav)
03481 {
03482     DetachBitmap();     // Ensure the current fractal is removed from cache
03483 
03484     Gravity = NewGrav;
03485 
03486     return TRUE;
03487 }
03488 
03489 BOOL FractalFillAttribute::SetSquash(FIXED16 NewSquash)
03490 {
03491     DetachBitmap();     // Ensure the current fractal is removed from cache
03492 
03493     Squash = NewSquash;
03494 
03495     return TRUE;
03496 }
03497 
03498 
03499 BOOL FractalFillAttribute::Randomise()
03500 {
03501     DetachBitmap();     // Ensure the current fractal is removed from cache
03502 
03503     MonotonicTime time;
03504     Seed = time.Sample();
03505 
03506     return TRUE;
03507 }
03508 
03509 
03511 //
03512 //                          NoiseFillAttribute class
03513 //
03515 
03516 /********************************************************************************************
03517 
03518 >   NoiseFillAttribute::NoiseFillAttribute()
03519 
03520     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
03521     Created:    16/01/97
03522     Inputs:     -
03523     Purpose:    Implementation of NoiseFillAttribute
03524 
03525 ********************************************************************************************/
03526 
03527 NoiseFillAttribute::NoiseFillAttribute()
03528 {
03529     MonotonicTime time;
03530     seed = time.Sample();
03531 
03532     dpi          = AttrFillGeometry::FractalDPI;
03533     dim          = 0;
03534     tileable     = TRUE;
03535 
03536     grain        = FIXED16(30.0);
03537 }
03538 
03539 
03540 NoiseFillAttribute::~NoiseFillAttribute()
03541 {
03542     DetachBitmap();
03543 }
03544 
03545 
03546 NodeAttribute* NoiseFillAttribute::MakeNode()
03547 {
03548     // Create new attribute node
03549     AttrNoiseColourFill *pAttr = new AttrNoiseColourFill;
03550     if (pAttr==NULL)
03551         // error message has already been set by new
03552         return NULL;
03553 
03554     // Copy attribute value into the new node.
03555     pAttr->GetAttributeValue()->SimpleCopy(this);
03556 
03557     // Return the new node
03558     return pAttr;
03559 }
03560 
03561 
03562 FillGeometryAttribute& NoiseFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
03563 {
03564     if (FillAttrib.IsKindOf(CC_RUNTIME_CLASS(NoiseFillAttribute)))
03565     {
03566         tileable    = ((NoiseFillAttribute*)&FillAttrib)->tileable;
03567         grain       = ((NoiseFillAttribute*)&FillAttrib)->grain;
03568         seed        = ((NoiseFillAttribute*)&FillAttrib)->seed;
03569         dim         = ((NoiseFillAttribute*)&FillAttrib)->dim;
03570         dpi         = ((NoiseFillAttribute*)&FillAttrib)->dpi;
03571     }
03572     
03573     return ColourFillAttribute::operator=(FillAttrib);
03574 }
03575 
03576 
03577 INT32 NoiseFillAttribute::operator==(const FillGeometryAttribute& Attrib)
03578 {
03579     // is this the same class of object?
03580     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
03581         return FALSE;
03582 
03583     NoiseFillAttribute* pAttrib = (NoiseFillAttribute*)&Attrib;
03584 
03585     if (IsPerspective())
03586     { 
03587         if (!pAttrib->IsPerspective())
03588             return FALSE;
03589 
03590         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
03591             return FALSE;
03592     }
03593 
03594     // check the colour ramps match
03595     if (!SameColourRampAs(pAttrib->GetColourRamp()))
03596         return FALSE;
03597 
03598     return 
03599     (
03600         *GetStartColour()   == *pAttrib->GetStartColour()   &&
03601         *GetEndColour()     == *pAttrib->GetEndColour()     &&
03602     
03603         *GetStartPoint()    == *pAttrib->GetStartPoint()    &&
03604         *GetEndPoint()      == *pAttrib->GetEndPoint()      &&
03605         *GetEndPoint2()     == *pAttrib->GetEndPoint2()     &&
03606 
03607         dim                 == pAttrib->dim                 &&
03608         dpi                 == pAttrib->dpi                 &&
03609         tileable            == pAttrib->tileable            &&
03610 
03611         grain               == pAttrib->grain               &&
03612         seed                == pAttrib->seed
03613     ); 
03614 }
03615 
03616 
03617 void NoiseFillAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
03618 {
03619     ERROR3IF(pCachedFractal==NULL, "NULL pointer passed to NoiseFillAttribute::CacheFractalData");
03620     ERROR3IF(!IS_A(pCachedFractal,NoiseFillAttribute), "Not a NoiseFillAttribute during NoiseFillAttribute::CacheFractalData");
03621 
03622     pCachedFractal->SetStartPoint(GetStartPoint());
03623     pCachedFractal->SetEndPoint(GetEndPoint());
03624     pCachedFractal->SetEndPoint2(GetEndPoint2());
03625 
03626     pCachedFractal->SetFractalDPI(GetFractalDPI());
03627     pCachedFractal->SetFractalDim(GetFractalDim());
03628     pCachedFractal->SetTileable(GetTileable());
03629     pCachedFractal->SetSeed(GetSeed());
03630 
03631     pCachedFractal->SetGraininess(GetGraininess());
03632 }
03633 
03634 
03635 BOOL NoiseFillAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
03636 {
03637     ERROR3IF(pCachedFractal==NULL, "NULL pointer passed to NoiseFillAttribute::IsSameAsCachedFractal");
03638     ERROR3IF(!IS_A(pCachedFractal,NoiseFillAttribute), "Not a NoiseFillAttribute during NoiseFillAttribute::IsSameAsCachedFractal");
03639 
03640     return
03641     (   
03642         dim          == pCachedFractal->GetFractalDim()     &&
03643         tileable     == pCachedFractal->GetTileable()       &&
03644         seed         == pCachedFractal->GetSeed()           &&
03645         grain        == pCachedFractal->GetGraininess() 
03646     );
03647 }
03648 
03649 
03650 BOOL NoiseFillAttribute::AttachBitmap(KernelBitmap* NewBitmap)
03651 {
03652     DetachBitmap();
03653 
03654     if (NewBitmap == NULL)
03655         return FALSE;
03656 
03657     OILBitmap* Bmp = NewBitmap->ActualBitmap;
03658     if (Bmp == NULL || !Bmp->IsTemp())
03659         return FALSE;
03660 
03661     NewBitmap = new KernelBitmap(Bmp, TRUE);
03662     BitmapRef.SetBitmap(NewBitmap);
03663     GetApplication()->GetGlobalFractalList()->AddFractal(this);
03664     
03665     return TRUE;
03666 }
03667 
03668 
03669 BOOL NoiseFillAttribute::DetachBitmap()
03670 {
03671     if (GetBitmap() == NULL)
03672         return FALSE;
03673 
03674     if (GetApplication()->GetGlobalFractalList()->RemoveFractal(this) &&
03675         BitmapRef.GetBitmap())
03676     {
03677         // The fractal was deleted, so make sure we NULL our pointer
03678         BitmapRef.GetBitmap()->ActualBitmap = NULL;
03679     }
03680 
03681     // now make sure the kernelbitmap is dead too
03682     BitmapRef.DeleteBmp();
03683 
03684     return TRUE;
03685 }
03686 
03687 
03688 BOOL NoiseFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
03689 {
03690     if (BmpToCopy != NULL)  // Is there a bitmap to copy ?
03691     {
03692         DetachBitmap();
03693 
03694         return AttachBitmap(BmpToCopy);
03695     }
03696 
03697     return TRUE;
03698 }
03699 
03700 
03701 void NoiseFillAttribute::SimpleCopy(AttributeValue *pValue)
03702 {
03703     // Just use the assignment operator
03704     *this = *(FillGeometryAttribute*)pValue;
03705 }
03706 
03707 
03708 void NoiseFillAttribute::SetStartColour(DocColour* NewCol)
03709 {
03710     if (NewCol == NULL)
03711     {
03712         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03713                                             _R(IDS_WHITENAME), &Colour);
03714 
03715         if (Colour == EndColour)
03716         {
03717             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03718                                                 _R(IDS_BLACKNAME), &Colour);
03719         }
03720     }
03721     else
03722         Colour = *NewCol;
03723 }
03724 
03725 
03726 void NoiseFillAttribute::SetEndColour(DocColour* NewCol)
03727 {
03728     if (NewCol == NULL)
03729     {
03730         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03731                                             _R(IDS_BLACKNAME), &EndColour);
03732 
03733         if (Colour == EndColour)
03734         {
03735             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03736                                                 _R(IDS_WHITENAME), &EndColour);
03737         }
03738     }
03739     else
03740         EndColour = *NewCol;
03741 }
03742 
03743 
03744 
03745 BOOL NoiseFillAttribute::RecalcFractal()
03746 {
03747     if (*GetStartPoint() == *GetEndPoint() ||
03748         *GetStartPoint() == *GetEndPoint2())
03749     {
03750         return FALSE;
03751     }
03752 
03753     KernelBitmap* pBitmap = GenerateNoiseBitmap(grain,seed);
03754     if (pBitmap == NULL)
03755     {
03756         TRACEUSER( "Mike", _T("Noisy fractal Failed !!!\n"));
03757         return FALSE;   // Error set by GenerateFractalBitmap
03758     }
03759 
03760     AttachBitmap(pBitmap);
03761     delete pBitmap;
03762 
03763     return TRUE;
03764 }
03765 
03766 
03767 void NoiseFillAttribute::SetTesselation(INT32 NewTess)
03768 {
03769     if (NewTess == RT_NoRepeatType)
03770         NewTess = RT_Repeating;
03771 
03772     Tesselation = NewTess;
03773 }
03774 
03775 void NoiseFillAttribute::SetFractalDim(UINT32 NewDim)
03776 {
03777     dim=NewDim;
03778 }
03779 
03780 BOOL NoiseFillAttribute::SetTileable(BOOL NewTile)
03781 {
03782     DetachBitmap();     // Ensure the current fractal is removed from cache
03783 
03784     tileable = NewTile;
03785 
03786     return TRUE;
03787 }
03788 
03789 BOOL NoiseFillAttribute::SetFractalDPI(UINT32 NewDpi)
03790 {
03791     dpi = NewDpi;
03792 
03793     return TRUE;
03794 }
03795 
03796 
03797 BOOL NoiseFillAttribute::SetGraininess(FIXED16 NewGrain)
03798 {
03799     DetachBitmap();     // Ensure the current fractal is removed from cache
03800 
03801     if (NewGrain<0) NewGrain=0;
03802     if (NewGrain>100) NewGrain=100;
03803     grain = NewGrain;   
03804 
03805     return TRUE;
03806 }
03807 
03808 
03809 BOOL NoiseFillAttribute::SetSeed(INT32 NewSeed)
03810 {
03811     DetachBitmap();     // Ensure the current fractal is removed from cache
03812 
03813     seed = NewSeed; 
03814 
03815     return TRUE;
03816 }
03817     
03818 
03819 
03821 //
03822 //                          ThreeColFillAttribute class
03823 //
03825 
03826 /********************************************************************************************
03827 
03828 >   ThreeColFillAttribute::ThreeColFillAttribute()
03829 
03830     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
03831     Created:    9/8/96
03832     Purpose:    Default Constuctor for fill attribute values. 
03833     SeeAlso:    AttrFillGeometry::AttrFillGeometry
03834 
03835 ********************************************************************************************/
03836 
03837 ThreeColFillAttribute::ThreeColFillAttribute()
03838 {
03839     IsPersp = FALSE;
03840 
03841     EndPoint2 = DocCoord(0,0);
03842     AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
03843                                         _R(IDS_REDNAME), &EndColour2);
03844 }
03845 
03846 
03847 /********************************************************************************************
03848 
03849 >   INT32 ThreeColFillAttribute::operator==(const FillGeometryAttribute& Attrib)
03850 
03851     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
03852     Created:    15/8/96
03853     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
03854     Returns:    Usual semantics for equality.
03855     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
03856                 a description of why it's required. 
03857     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
03858                 runtime class.
03859     SeeAlso:    NodeAttribute::operator==
03860 
03861 ********************************************************************************************/
03862 
03863 INT32 ThreeColFillAttribute::operator==(const FillGeometryAttribute& Attrib)
03864 {
03865     ThreeColFillAttribute* pAttrib = (ThreeColFillAttribute*) &Attrib;
03866     
03867     return(GradFillAttribute::operator==(Attrib) && 
03868             (EndColour2 == pAttrib->EndColour2) &&
03869             (EndPoint2 == pAttrib->EndPoint2) );
03870 }
03871 
03872 
03873 
03874 /********************************************************************************************
03875 
03876 >   NodeAttribute *ThreeColFillAttribute::MakeNode()
03877 
03878     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
03879     Created:    9/8/96
03880     Returns:    Pointer to the new node, or NULL if out of memory.
03881     Purpose:    Make a AttrThreeColFill node from this graduated fill attribute.
03882     Errors:     Out of memory
03883     SeeAlso:    AttributeValue::MakeNode
03884 
03885 ********************************************************************************************/
03886 
03887 NodeAttribute *ThreeColFillAttribute::MakeNode()
03888 {
03889     // Create new attribute node
03890     AttrThreeColFill *pAttr = new AttrThreeColColourFill;
03891     if (pAttr==NULL)
03892         // error message has already been set by new
03893         return NULL;
03894 
03895     // Copy attribute value into the new node.
03896     pAttr->GetAttributeValue()->SimpleCopy(this);
03897 
03898     // Return the new node
03899     return pAttr;
03900 }
03901 
03902 
03903 /********************************************************************************************
03904 
03905 >   void ThreeColFillAttribute::SetEndPoint2(DocCoord* Pos)
03906 
03907     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
03908     Created:    9/8/96
03909     Inputs:     -
03910     Purpose:    Sets the End Point of this fill
03911 
03912 ********************************************************************************************/
03913 
03914 void ThreeColFillAttribute::SetEndPoint2(DocCoord* Pos)
03915 {
03916     if (Pos == NULL)
03917         EndPoint2 = MakeLineAtAngle(*GetStartPoint(), *GetEndPoint(), 90);
03918     else
03919         EndPoint2 = *Pos;
03920 }
03921 
03922 
03923 /********************************************************************************************
03924 
03925 >   void ThreeColFillAttribute::SetEndPoint3(DocCoord* Pos)
03926 
03927     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
03928     Created:    9/8/96
03929     Inputs:     -
03930     Purpose:    Sets the End Point of this fill
03931 
03932 ********************************************************************************************/
03933 
03934 void ThreeColFillAttribute::SetEndPoint3(DocCoord* Pos)
03935 {
03936     if (Pos == NULL)
03937         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
03938     else
03939         EndPoint3 = *Pos;
03940 }
03941 
03942 
03943 /********************************************************************************************
03944 
03945 >   void ThreeColFillAttribute::MakePerspective()
03946 
03947     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
03948     Created:    9/8/96
03949     Inputs:     -
03950     Purpose:    Make the fill perspectived.
03951                 This should be called just before it is transformed by the moulder,
03952                 so it can validate the 4th control point.
03953 
03954 ********************************************************************************************/
03955 
03956 void ThreeColFillAttribute::MakePerspective()
03957 {
03958     IsPersp = TRUE;
03959 
03960     INT32 dx1 = EndPoint.x - StartPoint.x;
03961     INT32 dx2 = EndPoint2.x - StartPoint.x;
03962 
03963     INT32 dy1 = EndPoint.y - StartPoint.y;
03964     INT32 dy2 = EndPoint2.y - StartPoint.y;
03965 
03966     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
03967     SetEndPoint3(&Pos3);
03968 }
03969 
03970 /********************************************************************************************
03971 
03972 >   void ThreeColFillAttribute::RemovePerspective()
03973 
03974     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
03975     Created:    9/8/96
03976     Inputs:     -
03977     Purpose:    Removes perspective from this fill.
03978 
03979 ********************************************************************************************/
03980 
03981 void ThreeColFillAttribute::RemovePerspective()
03982 {
03983     IsPersp = FALSE;
03984 }
03985 
03986 
03987 /********************************************************************************************
03988 
03989 >   void ThreeColFillAttribute::SetEndColour2(DocColour* NewCol)
03990 
03991     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
03992     Created:    12/8/96
03993     Inputs:     -
03994     Purpose:    Sets the third colour of this fill (defaults to Red)
03995 
03996 ********************************************************************************************/
03997 
03998 void ThreeColFillAttribute::SetEndColour2(DocColour* NewCol)
03999 {
04000     if (NewCol == NULL)
04001     {
04002         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
04003                                             _R(IDS_REDNAME), &EndColour2);
04004     }
04005     else
04006         EndColour2 = *NewCol;
04007 }
04008 
04009 
04011 //
04012 //                          FourColFillAttribute class
04013 //
04015 
04016 /********************************************************************************************
04017 
04018 >   FourColFillAttribute::FourColFillAttribute()
04019 
04020     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
04021     Created:    9/8/96
04022     Purpose:    Default Constuctor for fill attribute values. 
04023     SeeAlso:    AttrFillGeometry::AttrFillGeometry
04024 
04025 ********************************************************************************************/
04026 
04027 FourColFillAttribute::FourColFillAttribute()
04028 {
04029     AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
04030                                         _R(IDS_YELLOWNAME), &EndColour3);
04031 }
04032 
04033 
04034 /********************************************************************************************
04035 
04036 >   INT32 FourColFillAttribute::operator==(const FillGeometryAttribute& Attrib)
04037 
04038     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
04039     Created:    15/8/96
04040     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
04041     Returns:    Usual semantics for equality.
04042     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
04043                 a description of why it's required. 
04044     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
04045                 runtime class.
04046     SeeAlso:    NodeAttribute::operator==
04047 
04048 ********************************************************************************************/
04049 
04050 INT32 FourColFillAttribute::operator==(const FillGeometryAttribute& Attrib)
04051 {
04052     FourColFillAttribute* pAttrib = (FourColFillAttribute*) &Attrib;
04053     
04054     return(ThreeColFillAttribute::operator==(Attrib) && (EndColour3 == pAttrib->EndColour3));
04055 }
04056 
04057 
04058 /********************************************************************************************
04059 
04060 >   NodeAttribute *FourColFillAttribute::MakeNode()
04061 
04062     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
04063     Created:    9/8/96
04064     Returns:    Pointer to the new node, or NULL if out of memory.
04065     Purpose:    Make a AttrFourColFill node from this graduated fill attribute.
04066     Errors:     Out of memory
04067     SeeAlso:    AttributeValue::MakeNode
04068 
04069 ********************************************************************************************/
04070 
04071 NodeAttribute *FourColFillAttribute::MakeNode()
04072 {
04073     // Create new attribute node
04074     AttrFourColFill *pAttr = new AttrFourColColourFill;
04075     if (pAttr==NULL)
04076         // error message has already been set by new
04077         return NULL;
04078 
04079     // Copy attribute value into the new node.
04080     pAttr->GetAttributeValue()->SimpleCopy(this);
04081 
04082     // Return the new node
04083     return pAttr;
04084 }
04085 
04086 /********************************************************************************************
04087 
04088 >   void FourColFillAttribute::SetEndColour3(DocColour* NewCol)
04089 
04090     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
04091     Created:    12/8/96
04092     Inputs:     -
04093     Purpose:    Sets the third colour of this fill (default to Yellow)
04094 
04095 ********************************************************************************************/
04096 
04097 void FourColFillAttribute::SetEndColour3(DocColour* NewCol)
04098 {
04099     if (NewCol == NULL)
04100     {
04101         AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
04102                                             _R(IDS_YELLOWNAME), &EndColour3);
04103     }
04104     else
04105         EndColour3 = *NewCol;
04106 }
04107 
04108 
04109 
04110 
04112 //
04113 //                          TranspFillAttribute class
04114 //
04116 
04117 /********************************************************************************************
04118 
04119 >   TranspFillAttribute::TranspFillAttribute()
04120 
04121     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04122     Created:    6/9/94
04123     Purpose:    Default Constuctor for fill attribute values. 
04124     SeeAlso:    AttrFillGeometry::AttrFillGeometry
04125 
04126 ********************************************************************************************/
04127 
04128 TranspFillAttribute::TranspFillAttribute()
04129 {
04130     Transp = 0;
04131     TranspType = TT_Mix;
04132 }
04133 
04134 /********************************************************************************************
04135 
04136 >   void TranspFillAttribute::SetTranspType(UINT32 NewType)
04137 
04138     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04139     Created:    5/9/94
04140     Inputs:     -
04141     Purpose:    Sets the Transparency type of this fill
04142 
04143 ********************************************************************************************/
04144 
04145 void TranspFillAttribute::SetTranspType(UINT32 NewType)
04146 {
04147     if (NewType == TT_NoTranspType)
04148         NewType = TT_Mix;
04149 
04150     TranspType = NewType;
04151 }
04152 
04153 /********************************************************************************************
04154 
04155 >   void TranspFillAttribute::SetStartTransp(UINT32* NewTransp)
04156 
04157     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04158     Created:    5/9/94
04159     Inputs:     -
04160     Purpose:    Sets the Start colour of this fill
04161 
04162 ********************************************************************************************/
04163 
04164 void TranspFillAttribute::SetStartTransp(UINT32* NewTransp)
04165 {
04166     if (NewTransp == NULL)
04167         Transp = 0;
04168     else
04169         Transp = *NewTransp;
04170 }
04171 
04172 /********************************************************************************************
04173 
04174 >   TranspFillAttribute& TranspFillAttribute::operator=(TranspFillAttribute& FillAttrib)
04175 
04176     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04177     Created:    8/8/94
04178     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
04179     Returns:    A refernce to this object
04180     Purpose:    Make the Attribute the same as the other. 
04181     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
04182                 runtime class.
04183 
04184 ********************************************************************************************/
04185 
04186 FillGeometryAttribute& TranspFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
04187 {
04188     SetStartTransp(FillAttrib.GetStartTransp());
04189     SetEndTransp(FillAttrib.GetEndTransp());
04190     SetEndTransp2(FillAttrib.GetEndTransp2());
04191     SetEndTransp3(FillAttrib.GetEndTransp3());
04192 
04193     SetTranspType(FillAttrib.GetTranspType());
04194 
04195     // Copy the fills profile
04196     SetProfile (FillAttrib.GetProfile ());
04197 
04198     // Copy the control points
04199     SetStartPoint(FillAttrib.GetStartPoint());
04200     SetEndPoint(FillAttrib.GetEndPoint());
04201     SetEndPoint2(FillAttrib.GetEndPoint2());
04202 
04203     // Bitmap Virtual point stuff
04204     if ( FillAttrib.IsAKindOfBitmapFill() &&
04205          !this->IsAKindOfBitmapFill() )
04206     {
04207         DocCoord Start = *FillAttrib.GetStartPoint();
04208         DocCoord End   = *FillAttrib.GetEndPoint();
04209         DocCoord End2  = *FillAttrib.GetEndPoint2();
04210 
04211         GetBitmapVirtualPoints( Start, End, End2,
04212                                 GetStartPoint(),  GetEndPoint(),  GetEndPoint2());
04213     }
04214     else if ( !FillAttrib.IsAKindOfBitmapFill() &&
04215          this->IsAKindOfBitmapFill() )
04216     {
04217         GetBitmapRealPoints(*GetStartPoint(), *GetEndPoint(), *GetEndPoint2(),
04218                              GetStartPoint(),  GetEndPoint(),  GetEndPoint2());
04219     }
04220 
04221     if (FillAttrib.IsPerspective())
04222     {
04223         MakePerspective();
04224         SetEndPoint3(FillAttrib.GetEndPoint3());
04225     }
04226     else
04227     {
04228         RemovePerspective();
04229     }
04230 
04231     CopyBitmap(FillAttrib.GetBitmap());
04232     SetTesselation(FillAttrib.GetTesselation());
04233     SetAspectLock(FillAttrib.IsAspectLocked());
04234     SetTranspRamp(FillAttrib.GetTranspRamp());
04235 
04236     return *this;
04237 }
04238 
04239 /********************************************************************************************
04240 
04241 >   INT32 TranspFillAttribute::operator==(const TranspFillAttribute& Attrib)
04242 
04243     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04244     Created:    23/8/94
04245     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
04246     Returns:    Usual semantics for equality.
04247     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
04248                 a description of why it's required. 
04249     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
04250                 runtime class.
04251     SeeAlso:    NodeAttribute::operator==
04252 
04253 ********************************************************************************************/
04254 
04255 INT32 TranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
04256 {
04257     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
04258         return FALSE;
04259 
04260     return ((Transp == ((TranspFillAttribute*)&Attrib)->Transp) && 
04261             (TranspType == ((TranspFillAttribute*)&Attrib)->TranspType) );
04262 }
04263 
04264 /********************************************************************************************
04265 
04266 >   void TranspFillAttribute::Render(RenderRegion *pRegion)
04267 
04268     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04269     Created:    23/8/94
04270     Inputs:     pRegion - the render region to render this attribute into.
04271     Purpose:    Sets the fill geometry attribute for the given render region. i.e. all
04272                 paths filled will now be filled with this fill geometry.
04273     SeeAlso:    TranspFillAttribute; RenderStack; AttributeValue; NodeAttribute;
04274                 TranspFillAttribute::Restore; TranspFillAttribute::SimpleCopy;
04275                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
04276 
04277 ********************************************************************************************/
04278 
04279 void TranspFillAttribute::Render(RenderRegion *pRegion, BOOL Temp)
04280 {
04281     pRegion->SetTranspFillGeometry(this, Temp);
04282 }
04283 
04284 /********************************************************************************************
04285 
04286 >   void TranspFillAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
04287 
04288     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04289     Created:    23/8/94
04290     Inputs:     pRegion - the render region to restore the attribute into.
04291                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
04292                           permanent (e.g. it's in a document tree).
04293     Purpose:    Restores the fill type attribute for the given render region. i.e. all
04294                 paths filled will now be filled with this fill attribute.
04295     SeeAlso:    TranspFillAttribute; RenderStack; AttributeValue; NodeAttribute;
04296                 TranspFillAttribute::Render; TranspFillAttribute::SimpleCopy;
04297                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
04298 
04299 ********************************************************************************************/
04300 
04301 void TranspFillAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
04302 {
04303     pRegion->RestoreTranspFillGeometry(this, Temp);
04304 }
04305 
04306 /********************************************************************************************
04307 
04308 >   BOOL TranspFillAttribute::Init()
04309 
04310     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04311     Created:    23/8/94
04312     Returns:    TRUE - initialised ok; FALSE if not.
04313     Purpose:    Registers fill type attribute, and provides a default attribute to give
04314                 transparent flat fills, i.e. actually not filled at all.
04315     Errors:     Out of memory.
04316     SeeAlso:    AttributeManager
04317 
04318 ********************************************************************************************/
04319 
04320 BOOL TranspFillAttribute::Init()
04321 {
04322     // Default to simple transparent fill colour
04323     FlatTranspFillAttribute *pAttr = new FlatTranspFillAttribute;
04324     if (pAttr==NULL)
04325         // error message has already been set by new
04326         return FALSE;
04327 
04328     pAttr->Transp    = 0;
04329     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
04330                                                          pAttr);
04331 
04332     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising TranspFillAttribute");
04333     ERROR2IF(ID != ATTR_TRANSPFILLGEOMETRY, FALSE, "Incorrect ID for TranspFillAttribute");
04334 
04335     return TRUE;
04336 }
04337 
04338 
04339 
04341 //
04342 //                          FlatTranspFillAttribute class
04343 //
04345 
04346 /********************************************************************************************
04347 
04348 >   FlatTranspFillAttribute::FlatTranspFillAttribute()
04349 
04350     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04351     Created:    6/9/94
04352     Purpose:    Default Constuctor for fill attribute values. 
04353     SeeAlso:    AttrFillGeometry::AttrFillGeometry
04354 
04355 ********************************************************************************************/
04356 
04357 FlatTranspFillAttribute::FlatTranspFillAttribute()
04358 {
04359 }
04360 
04361 /********************************************************************************************
04362 
04363 >   NodeAttribute *FlatTranspFillAttribute::MakeNode()
04364 
04365     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04366     Created:    23/8/94
04367     Returns:    Pointer to the new node, or NULL if out of memory.
04368     Purpose:    Make a AttrFlatColourFill node from this flat fill colour attribute.
04369     Errors:     Out of memory
04370     SeeAlso:    AttributeValue::MakeNode; AttrFlatFill
04371 
04372 ********************************************************************************************/
04373 
04374 NodeAttribute *FlatTranspFillAttribute::MakeNode()
04375 {
04376     // Create new attribute node
04377     AttrFlatTranspFill *pAttr = new AttrFlatTranspFill;
04378     if (pAttr==NULL)
04379         // error message has already been set by new
04380         return NULL;
04381 
04382     // Copy attribute value into the new node.
04383     pAttr->GetAttributeValue()->SimpleCopy(this);
04384 
04385     // Return the new node
04386     return pAttr;
04387 }
04388 
04389 
04390 /********************************************************************************************
04391 
04392 >   virtual ColourFillAttribute *FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry(
04393                                                                      double TransparencyScale)
04394 
04395     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04396     Created:    19/02/97
04397     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
04398                                       the function will scale the transparency. 0 means
04399                                       totally transparent.
04400 
04401     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
04402 
04403     Purpose:    Creates a non-transparent version of this transparent fill attribute.
04404                 For Flat fills we just return a FlatFillAttribute whose start colour is
04405                 set to a greyscale version of the intensity of the transparency.
04406                 (The original use of this was so airbrushes could maintain their fill's
04407                 transparency geometry)
04408 
04409     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
04410 
04411 ********************************************************************************************/
04412 
04413 ColourFillAttribute *FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
04414 {
04415     UINT32 *pStartTransparency = GetStartTransp();
04416     if(pStartTransparency == NULL)
04417         return NULL;
04418 
04419     FlatFillAttribute *pNewAttr = new FlatFillAttribute;
04420     if (pNewAttr != NULL)
04421     {
04422         INT32 Transparency = 255 - (INT32)(((double)(255 - *pStartTransparency)) * TransparencyScale);
04423         DocColour       color(Transparency, Transparency, Transparency);
04424         pNewAttr->SetStartColour( &color );
04425     }
04426 
04427     return(pNewAttr);
04428 }
04429 
04430 
04431 
04433 //
04434 //                          GradTranspFillAttribute class
04435 //
04437 
04438 /********************************************************************************************
04439 
04440 >   GradTranspFillAttribute::GradTranspFillAttribute()
04441 
04442     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04443     Created:    6/9/94
04444     Purpose:    Default Constuctor for fill attribute values. 
04445     SeeAlso:    AttrFillGeometry::AttrFillGeometry
04446 
04447 ********************************************************************************************/
04448 
04449 GradTranspFillAttribute::GradTranspFillAttribute()
04450 {                      
04451     EndTransp = 255;
04452 
04453     StartPoint = DocCoord(0,0);
04454     EndPoint = DocCoord(0,0);
04455 
04456     m_pTranspRamp = NULL;
04457 }
04458 
04459 GradTranspFillAttribute::~GradTranspFillAttribute()
04460 {
04461     DeleteTranspRamp();
04462 }
04463 
04464 void GradTranspFillAttribute::DeleteTranspRamp()
04465 {
04466     if (m_pTranspRamp!=NULL)
04467     {
04468         delete m_pTranspRamp;
04469         m_pTranspRamp=NULL;
04470     }
04471 }
04472 
04473 
04474 /********************************************************************************************
04475 
04476     BOOL GradTranspFillAttribute::SameTransparencyRampAs(TransparencyRamp *pOtherRamp)
04477 
04478     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
04479     Created:    02/03/97
04480     Purpose:    Check whether this transparency ramp matches that of the attribute
04481 
04482 ********************************************************************************************/
04483 
04484 BOOL GradTranspFillAttribute::SameTransparencyRampAs(TransparencyRamp *pOtherRamp)
04485 {
04486     // Have we got a transparency ramp at the moment?
04487     if (m_pTranspRamp==NULL)
04488         return (pOtherRamp==NULL);
04489 
04490     if (pOtherRamp==NULL)
04491         return FALSE;
04492 
04493     return (!( m_pTranspRamp->IsDifferentTo(pOtherRamp)));
04494 }
04495 
04496 
04497 /********************************************************************************************
04498 
04499 >   TranspFillAttribute& GradTranspFillAttribute::operator=(TranspFillAttribute& FillAttrib)
04500 
04501     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04502     Created:    8/8/94
04503     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
04504     Returns:    Usual semantics for equality.
04505     Purpose:    Make the Attribute the same as the other. 
04506     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
04507                 runtime class.
04508     SeeAlso:    AttrFillGeometry::operator==; NodeAttribute::operator==
04509 
04510 ********************************************************************************************/
04511 
04512 FillGeometryAttribute& GradTranspFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
04513 {
04514     return TranspFillAttribute::operator=(FillAttrib);
04515 }
04516 
04517 /********************************************************************************************
04518 
04519 >   INT32 GradTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
04520 
04521     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04522     Created:    23/8/94
04523     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
04524     Returns:    Usual semantics for equality.
04525     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
04526                 a description of why it's required. 
04527     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
04528                 runtime class.
04529     SeeAlso:    NodeAttribute::operator==
04530 
04531 ********************************************************************************************/
04532 
04533 INT32 GradTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
04534 {
04535     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
04536         return FALSE;
04537 
04538     GradTranspFillAttribute* pAttrib = (GradTranspFillAttribute*)&Attrib;
04539 
04540     if (IsPerspective())
04541     { 
04542         if (!pAttrib->IsPerspective())
04543             return FALSE;
04544 
04545         if (*GetEndPoint2() != *pAttrib->GetEndPoint2())
04546             return FALSE;
04547 
04548         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
04549             return FALSE;
04550     }
04551 
04552     // check the transparency ramp matches
04553     if (!SameTransparencyRampAs(pAttrib->GetTranspRamp()))
04554         return FALSE;
04555     
04556     // Are the Colours and Control points all the same ?
04557     return (
04558 
04559         Transp      == pAttrib->Transp      &&
04560         EndTransp   == pAttrib->EndTransp   &&
04561 
04562         TranspType  == pAttrib->TranspType  &&
04563 
04564         StartPoint  == pAttrib->StartPoint  &&
04565         EndPoint    == pAttrib->EndPoint
04566     );
04567 }
04568 
04569 
04570 /********************************************************************************************
04571 
04572 >   BOOL GradTranspFillAttribute::SetTranspRamp(TransparencyRamp *pRamp)
04573 
04574     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
04575     Created:    3/3/97
04576     Inputs:     pRamp, a pointer to a transparency ramp or NULL
04577     Purpose:    Sets this transparency ramp from pRamp passed in. If pRamp is NULL on entry
04578                 this objects ramp will be emptied.
04579 
04580 ********************************************************************************************/
04581 
04582 BOOL GradTranspFillAttribute::SetTranspRamp(TransparencyRamp *pRamp)
04583 {
04584     DeleteTranspRamp();
04585     if (pRamp==NULL)
04586         return TRUE;
04587     
04588     m_pTranspRamp = new TransparencyRamp();
04589     if (m_pTranspRamp==NULL)
04590         return FALSE;
04591 
04592     *m_pTranspRamp = *pRamp;
04593     return TRUE;
04594 }
04595 
04596 /********************************************************************************************
04597 
04598 >   DocCoord GradTranspFillAttribute::GetGeometryCoord(float pos) const
04599 
04600     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
04601     Created:    11/3/97
04602     Inputs:     pos = a parameter between 0 and 1
04603     Returns:    A coordinate which relates the input parameter to a coordinate space
04604                 on this geometry. For instance a linear fill would have a linear parameter
04605                 space, 0 at the start coordinate, increasing to 1 at the end coordinate
04606     Purpose:    Find the absolute position in geometry coordinate space for the given
04607                 parameter.
04608 
04609 ********************************************************************************************/
04610 
04611 DocCoord GradTranspFillAttribute::GetGeometryCoord(float pos) const
04612 {
04613     // This and all derived classes will inherit a linear coordinate space
04614     return DocCoord::PositionPointFromRatio(StartPoint,EndPoint,(double)pos);
04615 }
04616 
04617 
04618 /********************************************************************************************
04619 
04620 >   float GradTranspFillAttribute::GetGeometryParam(const DocCoord& c) const
04621 
04622     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
04623     Created:    11/3/97
04624     Inputs:     c = a coordinate
04625     Returns:    A parameter p, 0<=p<=1, such that GetGeometryCoord(p) is the closest
04626                 coordinate in the geometry to the input c.
04627     Purpose:    Find the parameter for the closest point to c on this geometry.
04628 
04629 ********************************************************************************************/
04630 
04631 float GradTranspFillAttribute::GetGeometryParam(const DocCoord& c) const
04632 {
04633     // ok we're a linear geometry so find the closest point to a line type of thing.
04634     // use a handy util written by that other fab bloke called Mike.
04635     DocCoord Coords[2];
04636     Coords[0] = StartPoint;
04637     Coords[1] = EndPoint;
04638     double p;
04639     PathUtil::SqrDistanceToLine(Coords, c, &p);
04640     return (float)p;
04641 }
04642 
04643 
04644 /********************************************************************************************
04645 
04646 >   TransparencyRamp* GradTranspFillAttribute::MakeNewTranspRamp()
04647 
04648     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
04649     Created:    3/3/97
04650     Inputs:     -
04651     Purpose:    Create a blank transparency ramp
04652 
04653 ********************************************************************************************/
04654 
04655 TransparencyRamp* GradTranspFillAttribute::MakeNewTranspRamp()
04656 {
04657     DeleteTranspRamp();
04658     m_pTranspRamp=new TransparencyRamp();
04659     return m_pTranspRamp;
04660 }
04661 
04662 
04663 /********************************************************************************************
04664 
04665 >   void GradTranspFillAttribute::SetStartPoint(DocCoord* Pos)
04666 
04667     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04668     Created:    5/9/94
04669     Inputs:     -
04670     Purpose:    Sets the Start Point of this fill
04671 
04672 ********************************************************************************************/
04673 
04674 void GradTranspFillAttribute::SetStartPoint(DocCoord* Pos)
04675 {
04676     if (Pos == NULL)
04677         StartPoint = DocCoord(0,0);
04678     else
04679         StartPoint = *Pos;
04680 }
04681 
04682 /********************************************************************************************
04683 
04684 >   void GradTranspFillAttribute::SetEndPoint(DocCoord* Pos)
04685 
04686     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04687     Created:    5/9/94
04688     Inputs:     -
04689     Purpose:    Sets the End Point of this fill
04690 
04691 ********************************************************************************************/
04692 
04693 void GradTranspFillAttribute::SetEndPoint(DocCoord* Pos)
04694 {
04695     if (Pos == NULL)
04696         EndPoint = DocCoord(0,0);
04697     else
04698         EndPoint = *Pos;
04699 }
04700 
04701 /********************************************************************************************
04702 
04703 >   void GradTranspFillAttribute::SetEndTransp(UINT32* NewTransp)
04704 
04705     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04706     Created:    5/9/94
04707     Inputs:     -
04708     Purpose:    Sets the End Colour of this fill
04709 
04710 ********************************************************************************************/
04711 
04712 void GradTranspFillAttribute::SetEndTransp(UINT32* NewTransp)
04713 {
04714     if (NewTransp == NULL)
04715         EndTransp = 255;
04716     else
04717         EndTransp = *NewTransp;
04718 }
04719 
04720 /********************************************************************************************
04721 
04722 >   void GradTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
04723 
04724     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04725     Created:    23/8/94
04726     Inputs:     pAttr - pointer to the AttributeValue to copy.
04727     Purpose:    See AttributeValue::SimpleCopy
04728     SeeAlso:    GradFillAttribute; RenderStack; AttributeValue; NodeAttribute;
04729                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
04730 
04731 ********************************************************************************************/
04732 
04733 void GradTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
04734 {
04735     *(this) = *((FillGeometryAttribute*)pValue);
04736 }
04737 
04738 
04739 
04740 /********************************************************************************************
04741 
04742 >   virtual ColourFillAttribute *GradTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
04743 
04744     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04745     Created:    19/02/97
04746     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
04747                                       the function will scale the transparency
04748 
04749     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
04750 
04751     Purpose:    Creates a non-transparent version of this transparent fill attribute.
04752                 (The original use of this was so airbrushes could maintain their fill's
04753                 transparency geometry)
04754 
04755     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
04756                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
04757 
04758 ********************************************************************************************/
04759 
04760 ColourFillAttribute *GradTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
04761 {
04762     UINT32 *pStartTransp = GetStartTransp();
04763     UINT32 *pEndTransp = GetEndTransp();
04764 
04765     if(pStartTransp == NULL || pEndTransp == NULL)
04766         return NULL;
04767 
04768     // This one's a bit dodgy I think   
04769     GradFillAttribute *pNewAttr = new GradFillAttribute;    
04770     if (pNewAttr != NULL)
04771     {
04772         pNewAttr->SetStartPoint(GetStartPoint());
04773         pNewAttr->SetEndPoint(GetEndPoint());
04774 
04775         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
04776         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
04777 
04778         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
04779         DocColour       colorEnd(EndTransparency, EndTransparency, EndTransparency);
04780         pNewAttr->SetStartColour(&colorStart);
04781         pNewAttr->SetEndColour(&colorEnd);
04782     
04783         // if this transparency has a transparency ramp then make
04784         // a colour ramp version in pNewAttr
04785         if (m_pTranspRamp)
04786         {
04787             ColourRamp* pColRamp = pNewAttr->MakeNewColourRamp();
04788             if (pColRamp)
04789             {
04790                 INT32 Col;
04791                 TranspRampItem *pItem = m_pTranspRamp->GetFirstTransp();
04792                 while (pItem!=NULL)
04793                 {
04794                     Col = 255 - (INT32)(((double)(255 - pItem->GetTransparency())) * TransparencyScale);
04795                     DocColour colorEntry(Col,Col,Col);
04796                     pColRamp->AddEntry(pItem->GetPosition(), &colorEntry );
04797                     pItem=m_pTranspRamp->GetNextTransp(pItem);
04798                 }
04799             }
04800         }
04801     }
04802 
04803     return(pNewAttr);
04804 }
04805 
04806 
04808 //
04809 //                          LinearTranspFillAttribute class
04810 //
04812 
04813 /********************************************************************************************
04814 
04815 >   LinearTranspFillAttribute::LinearTranspFillAttribute()
04816 
04817     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04818     Created:    6/9/94
04819     Purpose:    Default Constuctor for fill attribute values. 
04820     SeeAlso:    AttrFillGeometry::AttrFillGeometry
04821 
04822 ********************************************************************************************/
04823 
04824 LinearTranspFillAttribute::LinearTranspFillAttribute()
04825 {
04826     IsPersp = FALSE;
04827 }
04828 
04829 /********************************************************************************************
04830 
04831 >   NodeAttribute *LinearTranspFillAttribute::MakeNode()
04832 
04833     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04834     Created:    23/8/94
04835     Returns:    Pointer to the new node, or NULL if out of memory.
04836     Purpose:    Make a AttrLinearFill node from this graduated fill attribute.
04837     Errors:     Out of memory
04838     SeeAlso:    AttributeValue::MakeNode
04839 
04840 ********************************************************************************************/
04841 
04842 NodeAttribute *LinearTranspFillAttribute::MakeNode()
04843 {
04844     // Create new attribute node
04845     AttrLinearTranspFill *pAttr = new AttrLinearTranspFill;
04846     if (pAttr==NULL)
04847         // error message has already been set by new
04848         return NULL;
04849 
04850     // Copy attribute value into the new node.
04851     pAttr->GetAttributeValue()->SimpleCopy(this);
04852 
04853     // Return the new node
04854     return pAttr;
04855 }
04856 
04857 /********************************************************************************************
04858 
04859 >   void LinearTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
04860 
04861     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04862     Created:    5/9/94
04863     Inputs:     -
04864     Purpose:    Sets the End Point of this fill
04865 
04866 ********************************************************************************************/
04867 
04868 void LinearTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
04869 {
04870     if (Pos == NULL)
04871     {
04872         EndPoint2 = MakeLineAtAngle(StartPoint, EndPoint, 90);
04873     }
04874     else
04875         EndPoint2 = *Pos;
04876 }
04877 
04878 
04879 /********************************************************************************************
04880 
04881 >   void LinearTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
04882 
04883     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04884     Created:    5/9/94
04885     Inputs:     -
04886     Purpose:    Sets the End Point of this fill
04887 
04888 ********************************************************************************************/
04889 
04890 void LinearTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
04891 {
04892     if (Pos == NULL)
04893         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
04894     else
04895         EndPoint3 = *Pos;
04896 }
04897 
04898 
04899 /********************************************************************************************
04900 
04901 >   void LinearTranspFillAttribute::MakePerspective()
04902 
04903     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04904     Created:    17/4/95
04905     Inputs:     -
04906     Purpose:    Make the fill perspectived.
04907                 This should be called just before it is transformed by the moulder,
04908                 so it can validate the 4th control point.
04909 
04910 ********************************************************************************************/
04911 
04912 void LinearTranspFillAttribute::MakePerspective()
04913 {
04914     IsPersp = TRUE;
04915 
04916     INT32 dx1 = EndPoint.x - StartPoint.x;
04917     INT32 dx2 = EndPoint2.x - StartPoint.x;
04918 
04919     INT32 dy1 = EndPoint.y - StartPoint.y;
04920     INT32 dy2 = EndPoint2.y - StartPoint.y;
04921 
04922     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
04923     SetEndPoint3(&Pos3);
04924 }
04925 
04926 /********************************************************************************************
04927 
04928 >   void LinearTranspFillAttribute::RemovePerspective()
04929 
04930     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04931     Created:    17/4/95
04932     Inputs:     -
04933     Purpose:    Removes perspective from this fill.
04934 
04935 ********************************************************************************************/
04936 
04937 void LinearTranspFillAttribute::RemovePerspective()
04938 {
04939     IsPersp = FALSE;
04940 }
04941 
04942 /********************************************************************************************
04943 
04944 >   virtual ColourFillAttribute *LinearTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
04945 
04946     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04947     Created:    19/02/97
04948     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
04949                                       the function will scale the transparency
04950 
04951     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
04952 
04953     Purpose:    Creates a non-transparent version of this transparent fill attribute.
04954                 (The original use of this was so airbrushes could maintain their fill's
04955                 transparency geometry)
04956 
04957     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
04958                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
04959 
04960 ********************************************************************************************/
04961 
04962 ColourFillAttribute *LinearTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
04963 {
04964     UINT32 *pStartTransp = GetStartTransp();
04965     UINT32 *pEndTransp = GetEndTransp();
04966 
04967     if(pStartTransp == NULL || pEndTransp == NULL)
04968         return NULL;
04969     
04970     LinearFillAttribute *pNewAttr = new LinearFillAttribute;    
04971     if (pNewAttr != NULL)
04972     {
04973         pNewAttr->SetStartPoint(GetStartPoint());
04974         pNewAttr->SetEndPoint(GetEndPoint());
04975         pNewAttr->SetEndPoint2(GetEndPoint2());
04976         pNewAttr->SetEndPoint3(GetEndPoint3());
04977 
04978         if(IsPerspective())
04979             pNewAttr->MakePerspective();
04980 
04981         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
04982         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
04983 
04984         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
04985         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
04986         pNewAttr->SetStartColour(&colorStart);
04987         pNewAttr->SetEndColour(&colorEnd1);
04988     }
04989 
04990     return(pNewAttr);
04991 }
04992 
04993 
04994 
04995 /********************************************************************************************
04996 
04997 >   virtual AttributeValue *LinearTranspFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder,
04998                                                                             double TransScale);
04999     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05000     Created:    23/2/97
05001 
05002     Inputs:     pMoulder    - A PathStrokerVector which knows how to translate points to "mould" them
05003                               (May be NULL, in which case moulding of points does not occur)
05004 
05005                 TransScale  - A fraction between 0.0 and 1.0, by which any transparency
05006                               values in this geometry will be scaled, allowing the caller to
05007                               effectively apply a flat transparency level to everything that is
05008                               moulded. Use 1.0 to leave transparency unaltered.
05009 
05010     Returns:    NULL if the original attribute can be used, else
05011                 A pointer to a copy of this object, suitably moulded and adjusted for
05012                 the transparency scaling. The caller must delete the copy when finished
05013                 with it.
05014 
05015     Purpose:    Helper function for the PathStrokerVector class, which "moulds" clipart
05016                 subtrees to lie along an arbitrary path.
05017 
05018                 This function is called to mould fill geometries, so that fill endpoints
05019                 are translated to appropriate positions in the destination envelope, and
05020                 allows the caller to effectively apply a flat transparency by scaling
05021                 any transparency values in this geometry by the given fraction.
05022 
05023 ********************************************************************************************/
05024 
05025 AttributeValue *LinearTranspFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale)
05026 {
05027 // Taken out of WEBSTER Neville 6/8/97
05028 // Taken out by vector stroking code Neville 2/10/97
05029 #ifdef VECTOR_STROKING
05030     if (pMoulder == NULL)
05031         return(NULL);
05032 
05033     FillGeometryAttribute *pCopy = (FillGeometryAttribute *) GetRuntimeClass()->CreateObject();
05034     if (pCopy != NULL)
05035     {
05036         // Copy this object's values across
05037         *pCopy = *this;
05038 
05039         // And mould all of the geometry points across
05040         JCW_MOULDPOINT(pCopy, StartPoint);
05041         JCW_MOULDPOINT(pCopy, EndPoint);
05042 
05043         if (IsPerspective())
05044         {
05045             // If it's perspectivised, just map all the points and hope for the best
05046             JCW_MOULDPOINT(pCopy, EndPoint2);
05047             JCW_MOULDPOINT(pCopy, EndPoint3);
05048         }
05049         else
05050         {
05051             // Otherwise, we have mapped the start/end points, and we pass NULL in for
05052             // the remaining points so that they are re-generated to get the fill going
05053             // in the start->end direction (because the fill direction is not controlled
05054             // by the start->end line, but by the end->end2 line)
05055             pCopy->SetEndPoint2(NULL);
05056             pCopy->SetEndPoint3(NULL);
05057         }
05058 
05059         ERROR3IF(TransScale < 0.0 || TransScale > 1.0, "Out of range TransScale parameter");
05060         if (TransScale >= 0.0 && TransScale < 1.0)
05061         {
05062             JCW_MOULDTRANS(pCopy, StartTransp);
05063             JCW_MOULDTRANS(pCopy, EndTransp);
05064         }
05065     }
05066     return(pCopy);
05067 
05068 #else
05069     return NULL;
05070 #endif // VECTOR_STROKING
05071 }
05072 
05073 
05074 
05076 //
05077 //                          RadialTranspFillAttribute class
05078 //
05080 
05081 /********************************************************************************************
05082 
05083 >   RadialTranspFillAttribute::RadialTranspFillAttribute()
05084 
05085     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05086     Created:    6/9/94
05087     Purpose:    Default Constuctor for fill attribute values. 
05088     SeeAlso:    AttrFillGeometry::AttrFillGeometry
05089 
05090 ********************************************************************************************/
05091 
05092 RadialTranspFillAttribute::RadialTranspFillAttribute()
05093 {
05094     Circular = FALSE;
05095     IsPersp = FALSE;
05096 
05097     EndPoint2 = DocCoord(0,0);
05098 }
05099 
05100 /********************************************************************************************
05101 
05102 >   void RadialTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
05103 
05104     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05105     Created:    5/9/94
05106     Inputs:     -
05107     Purpose:    Sets the End Point of this fill
05108 
05109 ********************************************************************************************/
05110 
05111 void RadialTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
05112 {
05113     if (Pos == NULL)
05114         EndPoint2 = DocCoord(0,0);
05115     else
05116         EndPoint2 = *Pos;
05117 }
05118 
05119 /********************************************************************************************
05120 
05121 >   TranspFillAttribute& RadialTranspFillAttribute::operator=(TranspFillAttribute& Attrib)
05122 
05123     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05124     Created:    8/8/94
05125     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
05126     Returns:    Usual semantics for equality.
05127     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
05128                 a description of why it's required. 
05129     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
05130                 runtime class.
05131     SeeAlso:    NodeAttribute::operator==
05132 
05133 ********************************************************************************************/
05134 
05135 FillGeometryAttribute& RadialTranspFillAttribute::operator=(FillGeometryAttribute& Attrib)
05136 {
05137     return GradTranspFillAttribute::operator=(Attrib);
05138 }
05139 
05140 /********************************************************************************************
05141 
05142 >   INT32 RadialTranspFillAttribute::operator==(const TranspFillAttribute& Attrib)
05143 
05144     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05145     Created:    23/8/94
05146     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
05147     Returns:    Usual semantics for equality.
05148     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
05149                 a description of why it's required. 
05150     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
05151                 runtime class.
05152     SeeAlso:    NodeAttribute::operator==
05153 
05154 ********************************************************************************************/
05155 
05156 INT32 RadialTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
05157 {
05158     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
05159         return FALSE;
05160 
05161     RadialTranspFillAttribute* pAttrib = (RadialTranspFillAttribute*)&Attrib;
05162 
05163     if (IsPerspective())
05164     { 
05165         if (!pAttrib->IsPerspective())
05166             return FALSE;
05167 
05168         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
05169             return FALSE;
05170     }
05171 
05172     // check the transparency ramp matches
05173     if (!SameTransparencyRampAs(pAttrib->GetTranspRamp()))
05174         return FALSE;
05175 
05176     // Are the Colours and Control points all the same ?
05177     return (
05178     
05179         Transp      == pAttrib->Transp      &&
05180         EndTransp   == pAttrib->EndTransp   &&
05181 
05182         TranspType  == pAttrib->TranspType  &&
05183                        
05184         StartPoint  == pAttrib->StartPoint  &&
05185         EndPoint    == pAttrib->EndPoint    &&
05186         EndPoint2   == pAttrib->EndPoint2   &&
05187 
05188         Circular    == pAttrib->Circular
05189     );
05190 }
05191 
05192 /********************************************************************************************
05193 
05194 >   NodeAttribute *RadialTranspFillAttribute::MakeNode()
05195 
05196     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05197     Created:    23/8/94
05198     Returns:    Pointer to the new node, or NULL if out of memory.
05199     Purpose:    Make a AttrRadialFill node from this graduated fill attribute.
05200     Errors:     Out of memory
05201     SeeAlso:    AttributeValue::MakeNode
05202 
05203 ********************************************************************************************/
05204 
05205 NodeAttribute *RadialTranspFillAttribute::MakeNode()
05206 {
05207     // Create new attribute node
05208     AttrRadialTranspFill *pAttr = new AttrRadialTranspFill;
05209     if (pAttr==NULL)
05210         // error message has already been set by new
05211         return NULL;
05212 
05213     // Copy attribute value into the new node.
05214     pAttr->GetAttributeValue()->SimpleCopy(this);
05215 
05216     // Return the new node
05217     return pAttr;
05218 }
05219 
05220 
05221 /********************************************************************************************
05222 
05223 >   void RadialTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
05224 
05225     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05226     Created:    23/8/94
05227     Inputs:     pAttr - pointer to the AttributeValue to copy.
05228     Purpose:    See AttributeValue::SimpleCopy
05229     SeeAlso:    RadialTranspFillAttribute; RenderStack; AttributeValue; NodeAttribute;
05230                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
05231 
05232 ********************************************************************************************/
05233 
05234 void RadialTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
05235 {
05236     // Base class does most of the work...
05237     GradTranspFillAttribute::SimpleCopy(pValue);
05238 }
05239 
05240 /********************************************************************************************
05241 
05242 >   void RadialTranspFillAttribute::MakeCircular()
05243 
05244     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05245     Created:    12/8/94
05246     Purpose:    Forces this radial fill into a circular one.
05247 
05248 ********************************************************************************************/
05249 
05250 void RadialTranspFillAttribute::MakeCircular()
05251 {
05252     // Set a flag so we can tell we're circular
05253     Circular = TRUE;
05254 
05255     // Make sure the second end point is on the same radius as the other
05256     EndPoint2 = MakeLineAtAngle(StartPoint, EndPoint, 90);
05257 }
05258 
05259 /********************************************************************************************
05260 
05261 >   void RadialTranspFillAttribute::MakeElliptical()
05262 
05263     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05264     Created:    12/8/94
05265     Purpose:    Forces this radial fill into an elliptical one.
05266 
05267 ********************************************************************************************/
05268 
05269 void RadialTranspFillAttribute::MakeElliptical()
05270 {
05271     // Just clear the flag, so we don't try and lock the secondary point
05272     Circular = FALSE;
05273 }
05274 
05275 /********************************************************************************************
05276 
05277 >   void RadialTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
05278 
05279     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05280     Created:    5/9/94
05281     Inputs:     -
05282     Purpose:    Sets the End Point of this fill
05283 
05284 ********************************************************************************************/
05285 
05286 void RadialTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
05287 {
05288     if (Pos == NULL)
05289         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
05290     else
05291         EndPoint3 = *Pos;
05292 }
05293 
05294 
05295 /********************************************************************************************
05296 
05297 >   void RadialTranspFillAttribute::MakePerspective()
05298 
05299     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05300     Created:    17/4/95
05301     Inputs:     -
05302     Purpose:    Make the fill perspectived.
05303                 This should be called just before it is transformed by the moulder,
05304                 so it can validate the 4th control point.
05305 
05306 ********************************************************************************************/
05307 
05308 void RadialTranspFillAttribute::MakePerspective()
05309 {
05310     IsPersp = TRUE;
05311 
05312     INT32 dx1 = EndPoint.x - StartPoint.x;
05313     INT32 dx2 = EndPoint2.x - StartPoint.x;
05314 
05315     INT32 dy1 = EndPoint.y - StartPoint.y;
05316     INT32 dy2 = EndPoint2.y - StartPoint.y;
05317 
05318     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
05319     SetEndPoint3(&Pos3);
05320 }
05321 
05322 /********************************************************************************************
05323 
05324 >   void RadialTranspFillAttribute::RemovePerspective()
05325 
05326     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05327     Created:    17/4/95
05328     Inputs:     -
05329     Purpose:    Removes perspective from this fill.
05330 
05331 ********************************************************************************************/
05332 
05333 void RadialTranspFillAttribute::RemovePerspective()
05334 {
05335     IsPersp = FALSE;
05336 }
05337 
05338 /********************************************************************************************
05339 
05340 >   virtual ColourFillAttribute *RadialTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
05341 
05342     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05343     Created:    19/02/97
05344     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
05345                                       the function will scale the transparency
05346 
05347     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
05348 
05349     Purpose:    Creates a non-transparent version of this transparent fill attribute.
05350                 (The original use of this was so airbrushes could maintain their fill's
05351                 transparency geometry)
05352 
05353     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
05354                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
05355 
05356 ********************************************************************************************/
05357 
05358 ColourFillAttribute *RadialTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
05359 {
05360     UINT32 *pStartTransp = GetStartTransp();
05361     UINT32 *pEndTransp = GetEndTransp();
05362 
05363     if(pStartTransp == NULL || pEndTransp == NULL)
05364         return NULL;
05365     
05366     RadialFillAttribute *pNewAttr = new RadialFillAttribute;    
05367     if (pNewAttr != NULL)
05368     {
05369         pNewAttr->SetStartPoint(GetStartPoint());
05370         pNewAttr->SetEndPoint(GetEndPoint());
05371         pNewAttr->SetEndPoint2(GetEndPoint2());
05372         pNewAttr->SetEndPoint3(GetEndPoint3());
05373 
05374         if(IsCircular())
05375             pNewAttr->MakeCircular();
05376         else
05377             pNewAttr->MakeElliptical();
05378 
05379         if(IsPerspective())
05380             pNewAttr->MakePerspective();
05381 
05382         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
05383         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
05384 
05385         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
05386         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
05387         pNewAttr->SetStartColour(&colorStart);
05388         pNewAttr->SetEndColour(&colorEnd1);
05389     }
05390 
05391     return(pNewAttr);
05392 }
05393 
05394 
05395 
05396 /********************************************************************************************
05397 
05398 >   virtual AttributeValue *RadialTranspFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder,
05399                                                                             double TransScale);
05400     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05401     Created:    23/2/97
05402 
05403     Inputs:     pMoulder    - A PathStrokerVector which knows how to translate points to "mould" them
05404                               (May be NULL, in which case moulding of points does not occur)
05405 
05406                 TransScale  - A fraction between 0.0 and 1.0, by which any transparency
05407                               values in this geometry will be scaled, allowing the caller to
05408                               effectively apply a flat transparency level to everything that is
05409                               moulded. Use 1.0 to leave transparency unaltered.
05410 
05411     Returns:    NULL if the original attribute can be used, else
05412                 A pointer to a copy of this object, suitably moulded and adjusted for
05413                 the transparency scaling. The caller must delete the copy when finished
05414                 with it.
05415 
05416     Purpose:    Helper function for the PathStrokerVector class, which "moulds" clipart
05417                 subtrees to lie along an arbitrary path.
05418 
05419                 This function is called to mould fill geometries, so that fill endpoints
05420                 are translated to appropriate positions in the destination envelope, and
05421                 allows the caller to effectively apply a flat transparency by scaling
05422                 any transparency values in this geometry by the given fraction.
05423 
05424 ********************************************************************************************/
05425 
05426 AttributeValue *RadialTranspFillAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale)
05427 {
05428 // Taken out of WEBSTER Neville 6/8/97
05429 // Taken out by vector stroking code Neville 2/10/97
05430 #ifdef VECTOR_STROKING
05431     if (pMoulder == NULL)
05432         return(NULL);
05433 
05434     RadialFillAttribute *pCopy = (RadialFillAttribute *) GetRuntimeClass()->CreateObject();
05435     if (pCopy != NULL)
05436     {
05437         // Copy this object's values across
05438         *pCopy = *this;
05439 
05440         // Make sure it's defined as an elliptical fill, to ensure all points are set up correctly
05441         pCopy->MakeElliptical();
05442 
05443         // And mould all of the geometry points across
05444         JCW_MOULDPOINT(pCopy, StartPoint);
05445         JCW_MOULDPOINT(pCopy, EndPoint);
05446         JCW_MOULDPOINT(pCopy, EndPoint2);
05447         JCW_MOULDPOINT(pCopy, EndPoint3);
05448 
05449         ERROR3IF(TransScale < 0.0 || TransScale > 1.0, "Out of range TransScale parameter");
05450         if (TransScale >= 0.0 && TransScale < 1.0)
05451         {
05452             JCW_MOULDTRANS(pCopy, StartTransp);
05453             JCW_MOULDTRANS(pCopy, EndTransp);
05454         }
05455     }
05456     return(pCopy);
05457 #else
05458     return NULL;
05459 #endif // VECTOR_STROKING
05460 }
05461 
05462 
05463 
05465 //
05466 //                          ConicalTranspFillAttribute class
05467 //
05469 
05470 /********************************************************************************************
05471 
05472 >   ConicalTranspFillAttribute::ConicalTranspFillAttribute()
05473 
05474     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05475     Created:    6/9/94
05476     Purpose:    Default Constuctor for fill attribute values. 
05477     SeeAlso:    AttrFillGeometry::AttrFillGeometry
05478 
05479 ********************************************************************************************/
05480 
05481 ConicalTranspFillAttribute::ConicalTranspFillAttribute()
05482 {
05483 }
05484 
05485 /********************************************************************************************
05486 
05487 >   NodeAttribute *ConicalTranspFillAttribute::MakeNode()
05488 
05489     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05490     Created:    23/8/94
05491     Returns:    Pointer to the new node, or NULL if out of memory.
05492     Purpose:    Make a AttrConicalFill node from this graduated fill attribute.
05493     Errors:     Out of memory
05494     SeeAlso:    AttributeValue::MakeNode
05495 
05496 ********************************************************************************************/
05497 
05498 NodeAttribute *ConicalTranspFillAttribute::MakeNode()
05499 {
05500     // Create new attribute node
05501     AttrConicalTranspFill *pAttr = new AttrConicalTranspFill;
05502     if (pAttr==NULL)
05503         // error message has already been set by new
05504         return NULL;
05505 
05506     // Copy attribute value into the new node.
05507     pAttr->GetAttributeValue()->SimpleCopy(this);
05508 
05509     // Return the new node
05510     return pAttr;
05511 }
05512 
05513 /********************************************************************************************
05514 
05515 >   DocCoord ConicalTranspFillAttribute::GetGeometryCoord(float pos) const
05516 
05517     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
05518     Created:    11/3/97
05519     Inputs:     pos = a parameter between 0 and 1
05520     Returns:    A coordinate which relates the input parameter to a coordinate space
05521                 on this geometry. For instance a linear fill would have a linear parameter
05522                 space, 0 at the start coordinate, increasing to 1 at the end coordinate
05523     Purpose:    Find the absolute position in geometry coordinate space for the given
05524                 parameter.
05525 
05526 ********************************************************************************************/
05527 
05528 DocCoord ConicalTranspFillAttribute::GetGeometryCoord(float pos) const
05529 {
05530     // Here we calculate a circular coordinate space
05531     return PathUtil::PointOnSemiCircle(StartPoint,EndPoint,(double)pos);
05532 }
05533 
05534 
05535 
05536 /********************************************************************************************
05537 
05538 >   float ConicalTranspFillAttribute::GetGeometryParam(const DocCoord& c) const
05539 
05540     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
05541     Created:    11/3/97
05542     Inputs:     c = a coordinate
05543     Returns:    A parameter p, 0<=p<=1, such that GetGeometryCoord(p) is the closest
05544                 coordinate in the geometry to the input c.
05545     Purpose:    Find the parameter for the closest point to c on this geometry.
05546 
05547 ********************************************************************************************/
05548 
05549 float ConicalTranspFillAttribute::GetGeometryParam(const DocCoord& c) const
05550 {
05551     // ok we're a linear geometry so find the closest point to a line type of thing.
05552     // use a handy util written by that other fab bloke called Mike.
05553     DocCoord Coords[2];
05554     Coords[0] = StartPoint;
05555     Coords[1] = EndPoint;
05556     double p;
05557     PathUtil::SqrDistanceToSemiCircle(Coords, c, &p);
05558     return (float)p;
05559 }
05560 
05561 /********************************************************************************************
05562 
05563 >   virtual ColourFillAttribute *ConicalTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
05564 
05565     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05566     Created:    19/02/97
05567     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
05568                                       the function will scale the transparency
05569 
05570     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
05571 
05572     Purpose:    Creates a non-transparent version of this transparent fill attribute.
05573                 (The original use of this was so airbrushes could maintain their fill's
05574                 transparency geometry)
05575 
05576     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
05577                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
05578 
05579 ********************************************************************************************/
05580 
05581 ColourFillAttribute *ConicalTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
05582 {
05583     UINT32 *pStartTransp = GetStartTransp();
05584     UINT32 *pEndTransp = GetEndTransp();
05585 
05586     if(pStartTransp == NULL || pEndTransp == NULL)
05587         return NULL;
05588     
05589     ConicalFillAttribute *pNewAttr = new ConicalFillAttribute;  
05590     if (pNewAttr != NULL)
05591     {
05592         pNewAttr->SetStartPoint(GetStartPoint());
05593         pNewAttr->SetEndPoint(GetEndPoint());
05594 
05595         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
05596         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
05597 
05598         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
05599         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
05600         pNewAttr->SetStartColour(&colorStart);
05601         pNewAttr->SetEndColour(&colorEnd1);
05602     }
05603 
05604     return(pNewAttr);
05605 }
05606 
05608 //
05609 //                          BitmapTranspFillAttribute class
05610 //
05612 
05613 BOOL BitmapTranspFillAttribute::m_doBitmapSmoothing = TRUE;
05614 
05615 /********************************************************************************************
05616 
05617 >   BitmapTranspFillAttribute::BitmapTranspFillAttribute()
05618 
05619     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05620     Created:    6/9/94
05621     Purpose:    Default Constuctor for fill attribute values. 
05622     SeeAlso:    AttrFillGeometry::AttrFillGeometry
05623 
05624 ********************************************************************************************/
05625 
05626 BitmapTranspFillAttribute::BitmapTranspFillAttribute()
05627 {
05628     Transp = EndTransp = 0;
05629 
05630     StartPoint = DocCoord(0,0);
05631     EndPoint   = DocCoord(0,0);
05632     EndPoint2  = DocCoord(0,0);
05633     EndPoint3  = DocCoord(0,0);
05634 
05635     Tesselation = RT_Repeating;
05636 
05637     IsPersp = FALSE;
05638 }
05639 
05640 /********************************************************************************************
05641 
05642 >   BitmapTranspFillAttribute::~BitmapTranspFillAttribute()
05643 
05644     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05645     Created:    6/9/94
05646     Purpose:    Destructor for bitmap fill attribute values. 
05647     SeeAlso:    AttrFillGeometry::AttrFillGeometry
05648 
05649 ********************************************************************************************/
05650 
05651 BitmapTranspFillAttribute::~BitmapTranspFillAttribute()
05652 {
05653 }
05654 
05655 /********************************************************************************************
05656 
05657 >   NodeAttribute *BitmapTranspFillAttribute::MakeNode()
05658 
05659     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05660     Created:    10/8/94
05661     Returns:    Pointer to the new node, or NULL if out of memory.
05662     Purpose:    Make a AttrFlatColourFill node from this flat fill colour attribute.
05663     Errors:     Out of memory
05664     SeeAlso:    AttributeValue::MakeNode; AttrFlatColourFill
05665 
05666 ********************************************************************************************/
05667 
05668 NodeAttribute *BitmapTranspFillAttribute::MakeNode()
05669 {
05670     // Create new attribute node
05671     AttrBitmapFill *pAttr = new AttrBitmapTranspFill;
05672     if (pAttr==NULL)
05673         // error message has already been set by new
05674         return NULL;
05675 
05676     // Copy attribute value into the new node.
05677     pAttr->GetAttributeValue()->SimpleCopy(this);
05678 
05679     // Return the new node
05680     return pAttr;
05681 }
05682 
05683 /********************************************************************************************
05684 
05685 >   KernelBitmap* BitmapTranspFillAttribute::GetBitmap()
05686 
05687     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05688     Created:    3/12/94
05689     Purpose:    Get the bitmap referenced by this attribute. 
05690     SeeAlso:    BitmapTranspFillAttribute::AttachBitmap()
05691 
05692 ********************************************************************************************/
05693 
05694 KernelBitmap* BitmapTranspFillAttribute::GetBitmap()
05695 {
05696     KernelBitmap* pBitmap = BitmapRef.GetBitmap();
05697     
05698     // Check for a deleted bitmap
05699     if (pBitmap && pBitmap->HasBeenDeleted())
05700     {
05701         ERROR2IF(pBitmap->GetParentBitmapList() == NULL, NULL, "Deleted bitmap has no parent list");
05702         
05703         // Use the default bitmap instead
05704         pBitmap = pBitmap->GetParentBitmapList()->FindDefaultBitmap();
05705 
05706         // There should always be a default bitmap in the list
05707         ERROR2IF(pBitmap == NULL, 0L, "Couldn't find the default bitmap");
05708     }
05709 
05710     return pBitmap;
05711 }
05712 
05713 /********************************************************************************************
05714 
05715 >   BOOL BitmapTranspFillAttribute::AttachBitmap(KernelBitmap* pBitmap)
05716 
05717     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05718     Created:    20/9/94
05719     Purpose:    Attaches a bitmap to this fill. 
05720     SeeAlso:    BitmapTranspFillAttribute::DetachBitmap()
05721 
05722 ********************************************************************************************/
05723 
05724 BOOL BitmapTranspFillAttribute::AttachBitmap(KernelBitmap* NewBitmap)
05725 {
05726     BitmapRef.Detach();
05727     BitmapRef.Attach(NewBitmap);
05728 
05729     return TRUE;
05730 }
05731 
05732 /********************************************************************************************
05733 
05734 >   BOOL BitmapTranspFillAttribute::DetachBitmap()
05735 
05736     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05737     Created:    20/9/94
05738     Purpose:    Detaches a bitmap from this fill. 
05739     SeeAlso:    BitmapTranspFillAttribute::AttachBitmap()
05740 
05741 ********************************************************************************************/
05742 
05743 BOOL BitmapTranspFillAttribute::DetachBitmap()
05744 {
05745     BitmapRef.Detach();
05746 
05747     return FALSE;
05748 }
05749 
05750 /********************************************************************************************
05751 
05752 >   BOOL BitmapTranspFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
05753 
05754     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05755     Created:    20/9/94
05756     Purpose:    Used to copy a bitmap from one fill to another. 
05757     SeeAlso:    BitmapTranspFillAttribute::AttachBitmap()
05758 
05759 ********************************************************************************************/
05760 
05761 BOOL BitmapTranspFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
05762 {
05763     if (BmpToCopy != NULL)  // Is there a bitmap to copy ?
05764     {
05765         BitmapRef.Detach();
05766 
05767         OILBitmap* Bmp = BmpToCopy->ActualBitmap;
05768         if (Bmp->IsTemp())
05769         {
05770             BitmapRef.SetBitmap(BmpToCopy);
05771             return FALSE;
05772         }
05773 
05774         BitmapRef.Attach(BmpToCopy);
05775     }
05776 
05777     return TRUE;
05778 }
05779 
05780 /********************************************************************************************
05781 
05782 >   void BitmapTranspFillAttribute::Render(RenderRegion *pRegion)
05783 
05784     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05785     Created:    23/8/94
05786     Inputs:     pRegion - the render region to render this attribute into.
05787     Purpose:    Sets the fill geometry attribute for the given render region. i.e. all
05788                 paths filled will now be filled with this fill geometry.
05789     SeeAlso:    BitmapFillAttribute; RenderStack; AttributeValue; NodeAttribute;
05790                 BitmapFillAttribute::Restore; BitmapFillAttribute::SimpleCopy;
05791                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
05792 
05793 ********************************************************************************************/
05794 
05795 void BitmapTranspFillAttribute::Render(RenderRegion *pRegion, BOOL Temp)
05796 {
05797     pRegion->SetTranspFillGeometry(this, Temp);
05798 }
05799 
05800 /********************************************************************************************
05801 
05802 >   void BitmapTranspFillAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
05803 
05804     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05805     Created:    23/8/94
05806     Inputs:     pRegion - the render region to restore the attribute into.
05807                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
05808                           permanent (e.g. it's in a document tree).
05809     Purpose:    Restores the fill type attribute for the given render region. i.e. all
05810                 paths filled will now be filled with this fill attribute.
05811     SeeAlso:    BitmapFillAttribute; RenderStack; AttributeValue; NodeAttribute;
05812                 BitmapFillAttribute::Render; BitmapFillAttribute::SimpleCopy;
05813                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
05814 
05815 ********************************************************************************************/
05816 
05817 void BitmapTranspFillAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
05818 {
05819     pRegion->RestoreTranspFillGeometry(this, Temp);
05820 }
05821 
05822 /********************************************************************************************
05823 
05824 >   void BitmapTranspFillAttribute::SetStartPoint(DocCoord* Pos)
05825 
05826     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05827     Created:    5/9/94
05828     Inputs:     -
05829     Purpose:    Sets the Start Point of this fill
05830 
05831 ********************************************************************************************/
05832 
05833 void BitmapTranspFillAttribute::SetStartPoint(DocCoord* Pos)
05834 {
05835     if (Pos == NULL)
05836         StartPoint = DocCoord(0,0);
05837     else
05838         StartPoint = *Pos;
05839 }
05840 
05841 /********************************************************************************************
05842 
05843 >   void BitmapTranspFillAttribute::SetEndPoint(DocCoord* Pos)
05844 
05845     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05846     Created:    5/9/94
05847     Inputs:     -
05848     Purpose:    Sets the End Point of this fill
05849 
05850 ********************************************************************************************/
05851 
05852 void BitmapTranspFillAttribute::SetEndPoint(DocCoord* Pos)
05853 {
05854     if (Pos == NULL)
05855         EndPoint = DocCoord(0,0);
05856     else
05857         EndPoint = *Pos;
05858 }
05859 
05860 /********************************************************************************************
05861 
05862 >   void BitmapTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
05863 
05864     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05865     Created:    5/9/94
05866     Inputs:     -
05867     Purpose:    Sets the End Point of this fill
05868 
05869 ********************************************************************************************/
05870 
05871 void BitmapTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
05872 {
05873     if (Pos == NULL)
05874         EndPoint2 = MakeLineAtAngle(*GetStartPoint(), *GetEndPoint(), 90);
05875     else
05876         EndPoint2 = *Pos;
05877 }
05878 
05879 /********************************************************************************************
05880 
05881 >   void BitmapTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
05882 
05883     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05884     Created:    5/9/94
05885     Inputs:     -
05886     Purpose:    Sets the End Point of this fill
05887 
05888 ********************************************************************************************/
05889 
05890 void BitmapTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
05891 {
05892     if (Pos == NULL)
05893         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
05894     else
05895         EndPoint3 = *Pos;
05896 }
05897 
05898 
05899 
05900 /********************************************************************************************
05901 
05902 >   void BitmapTranspFillAttribute::MakePerspective()
05903 
05904     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05905     Created:    1/4/94
05906     Inputs:     -
05907     Purpose:    Make the fill perspectived.
05908                 This should be called just before it is transformed by the moulder,
05909                 so it can validate the 4th control point.
05910 
05911 ********************************************************************************************/
05912 
05913 void BitmapTranspFillAttribute::MakePerspective()
05914 {
05915     IsPersp = TRUE;
05916 
05917     INT32 dx1 = EndPoint.x - StartPoint.x;
05918     INT32 dx2 = EndPoint2.x - StartPoint.x;
05919 
05920     INT32 dy1 = EndPoint.y - StartPoint.y;
05921     INT32 dy2 = EndPoint2.y - StartPoint.y;
05922 
05923     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
05924     SetEndPoint3(&Pos3);
05925 }
05926 
05927 /********************************************************************************************
05928 
05929 >   void BitmapTranspFillAttribute::RemovePerspective()
05930 
05931     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05932     Created:    1/4/94
05933     Inputs:     -
05934     Purpose:    Removes perspective from this fill.
05935 
05936 ********************************************************************************************/
05937 
05938 void BitmapTranspFillAttribute::RemovePerspective()
05939 {
05940     IsPersp = FALSE;
05941 }
05942 
05943 /********************************************************************************************
05944 
05945 >   void BitmapTranspFillAttribute::SetStartTransp(UINT32* NewTransp)
05946 
05947     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05948     Created:    5/9/94
05949     Inputs:     -
05950     Purpose:    Sets the Start transp of this fill
05951 
05952 ********************************************************************************************/
05953 
05954 void BitmapTranspFillAttribute::SetStartTransp(UINT32* NewTransp)
05955 {
05956     if (NewTransp == NULL)
05957         Transp = 0;
05958     else
05959         Transp = *NewTransp;
05960 }
05961 
05962 /********************************************************************************************
05963 
05964 >   void BitmapTranspFillAttribute::SetEndTransp(UINT32* NewTransp)
05965 
05966     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05967     Created:    5/9/94
05968     Inputs:     -
05969     Purpose:    Sets the Start transp of this fill
05970 
05971 ********************************************************************************************/
05972 
05973 void BitmapTranspFillAttribute::SetEndTransp(UINT32* NewTransp)
05974 {
05975     if (NewTransp == NULL)
05976         EndTransp = 255;
05977     else
05978         EndTransp = *NewTransp;
05979 }
05980 
05981 /********************************************************************************************
05982 
05983 >   UINT32* BitmapTranspFillAttribute::GetStartTransp()
05984 
05985     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05986     Created:    5/9/94
05987     Inputs:     -
05988     Purpose:    Gets the Start transp of this fill
05989 
05990 ********************************************************************************************/
05991 
05992 UINT32* BitmapTranspFillAttribute::GetStartTransp()
05993 {
05994     return &Transp;
05995 }
05996 
05997 /********************************************************************************************
05998 
05999 >   UINT32* BitmapTranspFillAttribute::GetEndTransp()
06000 
06001     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06002     Created:    5/9/94
06003     Inputs:     -
06004     Purpose:    Gets the Start transp of this fill
06005 
06006 ********************************************************************************************/
06007 
06008 UINT32* BitmapTranspFillAttribute::GetEndTransp()
06009 {
06010     return &EndTransp;
06011 }
06012 
06013 /********************************************************************************************
06014 
06015 >   FillGeometryAttribute& BitmapTranspFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
06016 
06017     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06018     Created:    8/8/94
06019     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
06020     Returns:    Usual semantics for equality.
06021     Purpose:    Make the Attribute the same as the other. 
06022     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
06023                 runtime class.
06024     SeeAlso:    AttrFillGeometry::operator==; NodeAttribute::operator==
06025 
06026 ********************************************************************************************/
06027 
06028 FillGeometryAttribute& BitmapTranspFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
06029 {
06030 //  Bitmap = FillAttrib.Bitmap;
06031 
06032     return TranspFillAttribute::operator=(FillAttrib);
06033 }
06034 
06035 /********************************************************************************************
06036 
06037 >   INT32 BitmapTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
06038 
06039     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06040     Created:    23/8/94
06041     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
06042     Returns:    Usual semantics for equality.
06043     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
06044                 a description of why it's required. 
06045     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
06046                 runtime class.
06047     SeeAlso:    NodeAttribute::operator==
06048 
06049 ********************************************************************************************/
06050 
06051 INT32 BitmapTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
06052 {
06053     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
06054         return FALSE;
06055 
06056     BitmapTranspFillAttribute* pAttrib = (BitmapTranspFillAttribute*)&Attrib;
06057 
06058     if (GetBitmapRef()->GetBitmap() != pAttrib->GetBitmapRef()->GetBitmap())
06059         return FALSE;
06060 
06061     if (IsPerspective())
06062     { 
06063         if (!pAttrib->IsPerspective())
06064             return FALSE;
06065 
06066         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
06067             return FALSE;
06068     }
06069 
06070     // check the transparency ramp matches
06071     if (!SameTransparencyRampAs(pAttrib->GetTranspRamp()))
06072         return FALSE;
06073 
06074     // Are the Colours and Control points all the same ?
06075     return (
06076         
06077         Transp      == pAttrib->Transp      &&
06078         EndTransp   == pAttrib->EndTransp   &&
06079 
06080         TranspType  == pAttrib->TranspType  &&
06081     
06082         StartPoint  == pAttrib->StartPoint  &&
06083         EndPoint    == pAttrib->EndPoint    &&
06084         EndPoint2   == pAttrib->EndPoint2
06085 
06086     );
06087 }
06088 
06089 /********************************************************************************************
06090 
06091 >   void BitmapTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
06092 
06093     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06094     Created:    10/8/94
06095     Inputs:     pAttr - pointer to the AttributeValue to copy.
06096     Purpose:    See AttributeValue::SimpleCopy
06097     SeeAlso:    GradFillAttribute; RenderStack; AttributeValue; NodeAttribute;
06098                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
06099 
06100 ********************************************************************************************/
06101 
06102 void BitmapTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
06103 {
06104     // Just use the assignment operator
06105     *this = *(FillGeometryAttribute*)pValue;
06106 }
06107 
06108 BOOL BitmapTranspFillAttribute::SetDPI(UINT32 NewDpi)
06109 {
06110     if (IsPerspective())
06111         return FALSE;
06112 
06113     if (NewDpi == 0)
06114         return FALSE;
06115 
06116     if (GetBitmap() == NULL)
06117         return FALSE;
06118 
06119     OILBitmap *OilBM = GetBitmap()->ActualBitmap;
06120 
06121     if (OilBM == NULL)
06122         return FALSE;
06123 
06124     BitmapInfo Info;
06125     OilBM->GetInfo(&Info);
06126 
06127     INT32 PixWidth  = Info.PixelWidth;
06128     INT32 PixHeight = Info.PixelHeight;
06129 
06130     DocCoord Start = *GetStartPoint();
06131     DocCoord End   = *GetEndPoint();
06132     DocCoord End2  = *GetEndPoint2();
06133 
06134     INT32 Width  = INT32(Start.Distance(End));
06135     INT32 Height = INT32(Start.Distance(End2));
06136 
06137     INT32 HDpi = (Width  == 0) ? 0 : (PixWidth*72000)/Width;
06138     INT32 VDpi = (Height == 0) ? 0 : (PixHeight*72000)/Height;
06139 
06140     INT32 OldDpi = HDpi;
06141     if (VDpi < OldDpi)
06142         OldDpi = VDpi;
06143 
06144     TRACEUSER( "Mike", _T("Bitmap Dpi is currently %d\n"),OldDpi);
06145     TRACEUSER( "Mike", _T("Setting Bitmap Dpi to %d\n"),NewDpi);
06146 
06147     FIXED16 Ratio   = FIXED16(double(OldDpi)/double(NewDpi));
06148     Matrix Scale    = Matrix(Ratio, Ratio);
06149 
06150     GetBitmapVirtualPoints(Start, End, End2,
06151                             &Start, &End, &End2);
06152 
06153     DocCoord Centre = Start;
06154 
06155     Start.translate(-Centre.x, -Centre.y);  
06156     Scale.transform(&Start);
06157     Start.translate(Centre.x, Centre.y);    
06158 
06159     End.translate(-Centre.x, -Centre.y);    
06160     Scale.transform(&End);
06161     End.translate(Centre.x, Centre.y);  
06162 
06163     End2.translate(-Centre.x, -Centre.y);   
06164     Scale.transform(&End2);
06165     End2.translate(Centre.x, Centre.y); 
06166 
06167     GetBitmapRealPoints(Start, End, End2,
06168                         &Start, &End, &End2);
06169 
06170     INT32 NewWidth  = INT32(Start.Distance(End));
06171     INT32 NewHeight = INT32(Start.Distance(End2));
06172 
06173     if (NewWidth == 0 || NewHeight == 0)
06174         return FALSE;
06175 
06176     SetStartPoint(&Start);
06177     SetEndPoint(&End);
06178     SetEndPoint2(&End2);
06179 
06180     SetFractalDPI(GetDPI());
06181 
06182     return TRUE;
06183 }
06184 
06185 /********************************************************************************************
06186 
06187 >   UINT32 BitmapTranspFillAttribute::GetDPI()
06188 
06189     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06190     Created:    6/10/94
06191     Returns:    The current DPI of the fractal.
06192     Purpose:    Gets the DPI of a Fractal bitmap.
06193     SeeAlso:    FractalFillAttribute::SetDPI
06194 
06195 ********************************************************************************************/
06196 
06197 UINT32 BitmapTranspFillAttribute::GetDPI()
06198 {
06199     UINT32 Dpi = 0;
06200 
06201     KernelBitmap* KerBM = GetBitmap();
06202     if (KerBM == NULL)
06203         return 0;
06204 
06205     OILBitmap *OilBM = KerBM->ActualBitmap;
06206 
06207     if (OilBM != NULL)
06208     {
06209         BitmapInfo Info;
06210         OilBM->GetInfo(&Info);
06211 
06212         INT32 PixWidth  = Info.PixelWidth;
06213         INT32 PixHeight = Info.PixelHeight;
06214 
06215         DocCoord Start = *GetStartPoint();
06216         DocCoord End   = *GetEndPoint();
06217         DocCoord End2  = *GetEndPoint2();
06218 
06219         INT32 Width  = INT32(Start.Distance(End));
06220         INT32 Height = INT32(Start.Distance(End2));
06221 
06222         UINT32 HDpi = 0;
06223         UINT32 VDpi = 0;
06224 
06225         if (Width > 0)
06226             HDpi = (PixWidth*72000)/Width;
06227 
06228         if (Height > 0)
06229             VDpi = (PixHeight*72000)/Height;
06230 
06231         Dpi = HDpi;
06232         if (VDpi < Dpi)
06233             Dpi = VDpi;
06234     }
06235 
06236     return Dpi;
06237 }
06238 
06239 void BitmapTranspFillAttribute::SetTesselation(INT32 NewTess)
06240 {
06241     if (NewTess == RT_NoRepeatType)
06242         NewTess = RT_Repeating;
06243 
06244     Tesselation = NewTess;
06245 }
06246 
06247 
06248 /********************************************************************************************
06249 
06250 >   virtual ColourFillAttribute *BitmapTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
06251 
06252     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06253     Created:    19/02/97
06254     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
06255                                       the function will scale the transparency
06256 
06257     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
06258 
06259     Purpose:    Creates a non-transparent version of this transparent fill attribute.
06260                 (The original use of this was so airbrushes could maintain their fill's
06261                 transparency geometry)
06262 
06263     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
06264                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
06265 
06266 ********************************************************************************************/
06267 
06268 ColourFillAttribute *BitmapTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
06269 {
06270     UINT32 *pStartTransp = GetStartTransp();
06271     UINT32 *pEndTransp = GetEndTransp();
06272 
06273     if(pStartTransp == NULL || pEndTransp == NULL)
06274         return NULL;
06275     
06276     BitmapFillAttribute *pNewAttr = new BitmapFillAttribute;    
06277     if (pNewAttr != NULL)
06278     {
06279         pNewAttr->SetStartPoint(GetStartPoint());
06280         pNewAttr->SetEndPoint(GetEndPoint());
06281         pNewAttr->SetEndPoint2(GetEndPoint2());
06282         pNewAttr->SetEndPoint3(GetEndPoint3());
06283 
06284         pNewAttr->SetTesselation(GetTesselation());
06285         pNewAttr->SetDPI(GetDPI());
06286         if(IsPerspective())
06287             pNewAttr->MakePerspective();
06288 
06289         pNewAttr->AttachBitmap(GetBitmap());
06290 
06291         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
06292         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
06293 
06294         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
06295         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
06296         pNewAttr->SetStartColour(&colorStart);
06297         pNewAttr->SetEndColour(&colorEnd1);
06298     }
06299 
06300     return(pNewAttr);
06301 }
06302 
06303 
06304 
06305 
06307 //
06308 //                          NoiseTranspFillAttribute class
06309 //
06311 
06312 /********************************************************************************************
06313 
06314 >   NoiseTranspFillAttribute::NoiseTranspFillAttribute()
06315 
06316     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06317     Created:    16/01/97
06318     Inputs:     -
06319     Purpose:    Implementation of NoiseTranspFillAttribute
06320 
06321 ********************************************************************************************/
06322 
06323 NoiseTranspFillAttribute::NoiseTranspFillAttribute()
06324 {
06325     MonotonicTime time;
06326     seed = time.Sample();
06327 
06328     dpi          = AttrFillGeometry::FractalDPI;
06329     dim          = 0;
06330     tileable     = TRUE;
06331 
06332     grain        = FIXED16(30);
06333 }
06334 
06335 
06336 /********************************************************************************************
06337 
06338 >   NoiseTranspFillAttribute::~NoiseTranspFillAttribute()
06339 
06340     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06341     Created:    21/01/97
06342     Purpose:    Destructor for NoiseTranspFillAttribute attribute values. 
06343     SeeAlso:    AttrFillGeometry::AttrFillGeometry
06344 
06345 ********************************************************************************************/
06346 
06347 NoiseTranspFillAttribute::~NoiseTranspFillAttribute()
06348 {
06349     DetachBitmap();
06350 }
06351 
06352 
06353 /********************************************************************************************
06354 
06355 >   NodeAttribute *NoiseTranspFillAttribute::MakeNode()
06356 
06357     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06358     Created:    21/01/97
06359     Returns:    Pointer to the new node, or NULL if out of memory.
06360     Purpose:    Make a AttrNoiseTranspFill node from this flat fill colour attribute.
06361     Errors:     Out of memory
06362     SeeAlso:    AttributeValue::MakeNode; AttrFlatColourFill
06363 
06364 ********************************************************************************************/
06365 
06366 NodeAttribute* NoiseTranspFillAttribute::MakeNode()
06367 {
06368     // Create new attribute node
06369     AttrNoiseTranspFill *pAttr = new AttrNoiseTranspFill;
06370     if (pAttr==NULL)
06371         // error message has already been set by new
06372         return NULL;
06373 
06374     // Copy attribute value into the new node.
06375     pAttr->GetAttributeValue()->SimpleCopy(this);
06376 
06377     // Return the new node
06378     return pAttr;
06379 }
06380 
06381 /********************************************************************************************
06382 
06383 >   FillGeometryAttribute& FractalTranspFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
06384 
06385     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06386     Created:    21/01/97
06387     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
06388     Returns:    Usual semantics for equality.
06389     Purpose:    Make this Attribute the same as FillAttrib. 
06390     Errors:     No copy is made if the attributes are different runtime classes
06391     SeeAlso:    TranspFillAttribute::operator=;
06392 
06393 ********************************************************************************************/
06394 
06395 FillGeometryAttribute& NoiseTranspFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
06396 {
06397     if (FillAttrib.IsKindOf(CC_RUNTIME_CLASS(NoiseTranspFillAttribute)))
06398     {
06399         dpi         = ((NoiseTranspFillAttribute*)&FillAttrib)->dpi;
06400         dim         = ((NoiseTranspFillAttribute*)&FillAttrib)->dim;
06401         tileable    = ((NoiseTranspFillAttribute*)&FillAttrib)->tileable;
06402         seed        = ((NoiseTranspFillAttribute*)&FillAttrib)->seed;
06403         grain       = ((NoiseTranspFillAttribute*)&FillAttrib)->grain;
06404     }
06405     
06406     return TranspFillAttribute::operator=(FillAttrib);
06407 }
06408 
06409 
06410 /********************************************************************************************
06411 
06412 >   INT32 NoiseTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
06413 
06414     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06415     Created:    23/8/94
06416     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
06417     Returns:    Usual semantics for equality.
06418     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
06419                 a description of why it's required. 
06420     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
06421                 runtime class.
06422     SeeAlso:    NodeAttribute::operator==
06423 
06424 ********************************************************************************************/
06425 
06426 INT32 NoiseTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
06427 {
06428     // is this the same class of object?
06429     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
06430         return FALSE;
06431 
06432     NoiseTranspFillAttribute* pAttrib = (NoiseTranspFillAttribute*)&Attrib;
06433 
06434     if (IsPerspective())
06435     { 
06436         if (!pAttrib->IsPerspective())
06437             return FALSE;
06438 
06439         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
06440             return FALSE;
06441     }
06442 
06443     // check the transparency ramp matches
06444     if (!SameTransparencyRampAs(pAttrib->GetTranspRamp()))
06445         return FALSE;
06446 
06447     return 
06448     (
06449         *GetStartTransp()   == *pAttrib->GetStartTransp()   &&  
06450         *GetEndTransp()     == *pAttrib->GetEndTransp()     &&
06451     
06452         *GetStartPoint()    == *pAttrib->GetStartPoint()    &&
06453         *GetEndPoint()      == *pAttrib->GetEndPoint()      &&
06454         *GetEndPoint2()     == *pAttrib->GetEndPoint2()     &&
06455         
06456         GetTranspType()     == pAttrib->GetTranspType()     &&
06457 
06458         dpi                 == pAttrib->dpi                 &&  
06459         dim                 == pAttrib->dim                 &&
06460         tileable            == pAttrib->tileable            &&
06461         seed                == pAttrib->seed                &&
06462         
06463         grain               == pAttrib->grain
06464     ); 
06465 }
06466 
06467 /********************************************************************************************
06468 
06469 >   void NoiseTranspFillAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
06470 
06471     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06472     Created:    21/01/97
06473     Inputs:     pCachedFractal = A pointer to the fractal in the cache
06474     Returns:    -
06475     Purpose:    Copies any data from this FractalFillAttribute into the cached fractal
06476                 pointed to on entry. This data is then checked via IsSameAsCachedFractal
06477     SeeAlso:    CachedFractal, FracList.h / .cpp
06478 
06479 ********************************************************************************************/
06480 
06481 void NoiseTranspFillAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
06482 {
06483     ERROR3IF(pCachedFractal==NULL, "NULL pointer passed to NoiseTranspFillAttribute::CacheFractalData");
06484     ERROR3IF(!IS_A(pCachedFractal,NoiseTranspFillAttribute), "Not a NoiseTranspFillAttribute during NoiseTranspFillAttribute::CacheFractalData");
06485 
06486     pCachedFractal->SetStartPoint(GetStartPoint());
06487     pCachedFractal->SetEndPoint(GetEndPoint());
06488     pCachedFractal->SetEndPoint2(GetEndPoint2());
06489 
06490     pCachedFractal->SetFractalDPI(GetFractalDPI());
06491     pCachedFractal->SetFractalDim(GetFractalDim());
06492     pCachedFractal->SetTileable(GetTileable());
06493     pCachedFractal->SetSeed(GetSeed());
06494 
06495     pCachedFractal->SetGraininess(GetGraininess());
06496 }
06497 
06498 /********************************************************************************************
06499 
06500 >   BOOL NoiseTranspFillAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
06501 
06502     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06503     Created:    21/01/97
06504     Inputs:     pCachedFractal = A pointer to the fractal in the cache
06505     Returns:    TRUE if this fractal matches the cached fractal
06506                 FALSE if not
06507     Purpose:    A virtual comparison operator used by the fractal cache to check for a
06508                 matching fractal.
06509 
06510 ********************************************************************************************/
06511 
06512 BOOL NoiseTranspFillAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
06513 {
06514     ERROR3IF(pCachedFractal==NULL, "NULL pointer passed to NoiseTranspFillAttribute::IsSameAsCachedFractal");
06515     ERROR3IF(!IS_A(pCachedFractal,NoiseTranspFillAttribute), "Not a NoiseTranspFillAttribute during NoiseTranspFillAttribute::IsSameAsCachedFractal");
06516 
06517     BOOL ok =  (dim          == pCachedFractal->GetFractalDim());
06518     ok = ok && (tileable     == pCachedFractal->GetTileable());
06519     ok = ok && (seed         == pCachedFractal->GetSeed());
06520     ok = ok && (grain        == pCachedFractal->GetGraininess());
06521     
06522     return ok;  
06523 }
06524 
06525 /********************************************************************************************
06526 
06527 >   BOOL NoiseTranspFillAttribute::AttachBitmap(KernelBitmap* pBitmap)
06528 
06529     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06530     Created:    21/1/97
06531     Purpose:    Attaches a bitmap to this fill. 
06532     SeeAlso:    NoiseTranspFillAttribute::DetachBitmap()
06533 
06534 ********************************************************************************************/
06535 
06536 BOOL NoiseTranspFillAttribute::AttachBitmap(KernelBitmap* NewBitmap)
06537 {
06538     DetachBitmap();
06539 
06540     if (NewBitmap == NULL)
06541         return FALSE;
06542 
06543     OILBitmap* Bmp = NewBitmap->ActualBitmap;
06544     if (Bmp == NULL || !Bmp->IsTemp())
06545         return FALSE;
06546 
06547     NewBitmap = new KernelBitmap(Bmp, TRUE);
06548     BitmapRef.SetBitmap(NewBitmap);
06549     GetApplication()->GetGlobalFractalList()->AddFractal(this);
06550 
06551     return TRUE;
06552 }
06553 
06554 /********************************************************************************************
06555 
06556 >   BOOL NoiseTranspFillAttribute::DetachBitmap()
06557 
06558     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06559     Created:    21/1/97
06560     Purpose:    Detaches a bitmap from this fill. 
06561     SeeAlso:    BitmapFillAttribute::AttachBitmap()
06562 
06563 ********************************************************************************************/
06564 
06565 BOOL NoiseTranspFillAttribute::DetachBitmap()
06566 {
06567     if (GetBitmap() == NULL)
06568         return FALSE;
06569 
06570     if (GetApplication()->GetGlobalFractalList()->RemoveFractal(this) && BitmapRef.GetBitmap())
06571     {
06572         // The fractal was deleted, so make sure we NULL our pointer
06573         BitmapRef.GetBitmap()->ActualBitmap = NULL;
06574     }
06575 
06576     // now make sure the kernelbitmap is dead too
06577     BitmapRef.DeleteBmp();
06578 
06579     return TRUE;
06580 }
06581 
06582 /********************************************************************************************
06583 
06584 >   BOOL NoiseTranspFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
06585 
06586     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06587     Created:    21/1/97
06588     Purpose:    Used to copy a bitmap from one fill to another. 
06589     SeeAlso:    NoiseTranspFillAttribute::AttachBitmap()
06590 
06591 ********************************************************************************************/
06592 
06593 BOOL NoiseTranspFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
06594 {
06595     if (BmpToCopy != NULL)  // Is there a bitmap to copy ?
06596     {
06597         DetachBitmap();
06598 
06599         return AttachBitmap(BmpToCopy);
06600     }
06601 
06602     return TRUE;
06603 }
06604 
06605 
06606 /********************************************************************************************
06607 
06608 >   void NoiseTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
06609 
06610     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06611     Created:    10/8/94
06612     Inputs:     pAttr - pointer to the AttributeValue to copy.
06613     Purpose:    See AttributeValue::SimpleCopy
06614     SeeAlso:    GradFillAttribute; RenderStack; AttributeValue; NodeAttribute;
06615                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
06616 
06617 ********************************************************************************************/
06618 
06619 void NoiseTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
06620 {
06621     // Just use the assignment operator
06622     *this = *(FillGeometryAttribute*)pValue;
06623 }
06624 
06625 
06626 /********************************************************************************************
06627 
06628 >   BOOL NoiseTranspFillAttribute::RecalcFractal()
06629 
06630     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06631     Created:    6/10/94
06632     Purpose:    Recalculates the Fractal.
06633     SeeAlso:    NoiseTranspFillAttribute::SetDPI
06634 
06635 ********************************************************************************************/
06636 
06637 BOOL NoiseTranspFillAttribute::RecalcFractal()
06638 {
06639     if (*GetStartPoint() == *GetEndPoint() ||
06640         *GetStartPoint() == *GetEndPoint2())
06641     {
06642         return FALSE;
06643     }
06644 
06645     KernelBitmap* pBitmap = GenerateNoiseBitmap(grain,seed);
06646     if (pBitmap == NULL)
06647     {
06648         TRACEUSER( "Mike", _T("Noisy fractal Failed !!!\n"));
06649         return FALSE;   // Error set by GenerateFractalBitmap
06650     }
06651 
06652     AttachBitmap(pBitmap);
06653     delete pBitmap;
06654 
06655     return TRUE;
06656 }
06657 
06658 
06659 
06660 void NoiseTranspFillAttribute::SetTesselation(INT32 NewTess)
06661 {
06662     if (NewTess == RT_NoRepeatType)
06663         NewTess = RT_Repeating;
06664 
06665     Tesselation = NewTess;
06666 }
06667 
06668 void NoiseTranspFillAttribute::SetFractalDim(UINT32 NewDim)
06669 {
06670     dim = NewDim;
06671 }
06672 
06673 BOOL NoiseTranspFillAttribute::SetTileable(BOOL NewTile)
06674 {
06675     DetachBitmap();     // Ensure the current fractal is removed from cache
06676 
06677     tileable = NewTile;
06678 
06679     return TRUE;
06680 }
06681 
06682 BOOL NoiseTranspFillAttribute::SetFractalDPI(UINT32 NewDpi)
06683 {
06684     dpi = NewDpi;
06685 
06686     return TRUE;
06687 }
06688 
06689 
06690 
06691 BOOL NoiseTranspFillAttribute::SetGraininess(FIXED16 NewGrain)
06692 {
06693     DetachBitmap();     // Ensure the current fractal is removed from cache
06694 
06695     if (NewGrain<0) NewGrain=0;
06696     if (NewGrain>100) NewGrain=100;
06697     grain = NewGrain;
06698 
06699     return TRUE;
06700 }
06701 
06702 /********************************************************************************************
06703 
06704 >   virtual ColourFillAttribute *NoiseTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
06705 
06706     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06707     Created:    19/02/97
06708     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
06709                                       the function will scale the transparency
06710 
06711     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
06712 
06713     Purpose:    Creates a non-transparent version of this transparent fill attribute.
06714                 (The original use of this was so airbrushes could maintain their fill's
06715                 transparency geometry)
06716 
06717     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
06718                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
06719 
06720 ********************************************************************************************/
06721 
06722 ColourFillAttribute *NoiseTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
06723 {
06724     UINT32 *pStartTransp = GetStartTransp();
06725     UINT32 *pEndTransp = GetEndTransp();
06726 
06727     if(pStartTransp == NULL || pEndTransp == NULL)
06728         return NULL;
06729     
06730     NoiseFillAttribute *pNewAttr = new NoiseFillAttribute;  
06731     if (pNewAttr != NULL)
06732     {
06733         pNewAttr->SetStartPoint(GetStartPoint());
06734         pNewAttr->SetEndPoint(GetEndPoint());
06735         pNewAttr->SetEndPoint2(GetEndPoint2());
06736         pNewAttr->SetEndPoint3(GetEndPoint3());
06737 
06738         pNewAttr->SetTesselation(GetTesselation());
06739         pNewAttr->SetDPI(GetDPI());
06740         if(IsPerspective())
06741             pNewAttr->MakePerspective();
06742 
06743         pNewAttr->AttachBitmap(GetBitmap());
06744         pNewAttr->SetFractalDim(GetFractalDim());
06745         pNewAttr->SetTileable(GetTileable());
06746         pNewAttr->SetFractalDPI(GetFractalDPI());
06747         pNewAttr->SetSeed(GetSeed());
06748         pNewAttr->SetNoiseScale(GetNoiseScale());
06749 
06750         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
06751         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
06752 
06753         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
06754         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
06755         pNewAttr->SetStartColour(&colorStart);
06756         pNewAttr->SetEndColour(&colorEnd1);
06757 
06758         pNewAttr->RecalcFractal();
06759     }
06760 
06761     return(pNewAttr);
06762 }
06763 
06764 /*******************************************************************************************
06765   Values local to this fractal type
06766 *******************************************************************************************/
06767 
06768 BOOL NoiseTranspFillAttribute::SetSeed(INT32 NewSeed)
06769 {
06770     DetachBitmap();     // Ensure the current fractal is removed from cache
06771 
06772     seed = NewSeed;
06773 
06774     return TRUE;
06775 }
06776 
06777 
06778 
06779 
06780 
06781 
06783 //
06784 //                          FractalTranspFillAttribute class
06785 //
06787 
06788 /********************************************************************************************
06789 
06790 >   FractalTranspFillAttribute::FractalTranspFillAttribute()
06791 
06792     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06793     Created:    6/9/94
06794     Purpose:    Default Constuctor for fill attribute values. 
06795     SeeAlso:    AttrFillGeometry::AttrFillGeometry
06796 
06797 ********************************************************************************************/
06798 
06799 FractalTranspFillAttribute::FractalTranspFillAttribute()
06800 {
06801     MonotonicTime time;
06802     Seed = time.Sample();
06803 
06804     Graininess = AttrFillGeometry::FractalGraininess;
06805     Gravity    = AttrFillGeometry::FractalGravity;
06806     Dpi        = AttrFillGeometry::FractalDPI;
06807     
06808     Squash = 0;
06809     Dim    = 0;
06810     Tileable = FALSE;
06811 
06812     Tesselation = RT_RepeatInverted;
06813 }
06814 
06815 /********************************************************************************************
06816 
06817 >   FractalTranspFillAttribute::~FractalTranspFillAttribute()
06818 
06819     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06820     Created:    6/9/94
06821     Purpose:    Destructor for fractal fill attribute values. 
06822     SeeAlso:    AttrFillGeometry::AttrFillGeometry
06823 
06824 ********************************************************************************************/
06825 
06826 FractalTranspFillAttribute::~FractalTranspFillAttribute()
06827 {
06828     DetachBitmap();
06829 }
06830 
06831 /********************************************************************************************
06832 
06833 >   NodeAttribute *FractalTranspFillAttribute::MakeNode()
06834 
06835     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06836     Created:    10/8/94
06837     Returns:    Pointer to the new node, or NULL if out of memory.
06838     Purpose:    Make a AttrFlatColourFill node from this flat fill colour attribute.
06839     Errors:     Out of memory
06840     SeeAlso:    AttributeValue::MakeNode; AttrFlatColourFill
06841 
06842 ********************************************************************************************/
06843 
06844 NodeAttribute *FractalTranspFillAttribute::MakeNode()
06845 {
06846     // Create new attribute node
06847     AttrFractalFill *pAttr = new AttrFractalTranspFill;
06848     if (pAttr==NULL)
06849         // error message has already been set by new
06850         return NULL;
06851 
06852     // Copy attribute value into the new node.
06853     pAttr->GetAttributeValue()->SimpleCopy(this);
06854 
06855     // Return the new node
06856     return pAttr;
06857 }
06858 
06859 /********************************************************************************************
06860 
06861 >   FillGeometryAttribute& FractalTranspFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
06862 
06863     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06864     Created:    8/8/94
06865     Inputs:     FillAttrib - the attribute to copy, which must be an AttrFillGeometry
06866     Returns:    Usual semantics for equality.
06867     Purpose:    Make the Attribute the same as the other. 
06868     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
06869                 runtime class.
06870     SeeAlso:    AttrFillGeometry::operator==; NodeAttribute::operator==
06871 
06872 ********************************************************************************************/
06873 
06874 FillGeometryAttribute& FractalTranspFillAttribute::operator=(FillGeometryAttribute& FillAttrib)
06875 {
06876     if (FillAttrib.IsKindOf(CC_RUNTIME_CLASS(FractalTranspFillAttribute)))
06877     {
06878         Seed        = ((FractalTranspFillAttribute*)&FillAttrib)->Seed;
06879         Graininess  = ((FractalTranspFillAttribute*)&FillAttrib)->Graininess;
06880         Gravity     = ((FractalTranspFillAttribute*)&FillAttrib)->Gravity;
06881         Squash      = ((FractalTranspFillAttribute*)&FillAttrib)->Squash;
06882         Dpi         = ((FractalTranspFillAttribute*)&FillAttrib)->Dpi;
06883         Tileable    = ((FractalTranspFillAttribute*)&FillAttrib)->Tileable;
06884         Dim         = ((FractalTranspFillAttribute*)&FillAttrib)->Dim;
06885     }
06886 
06887     return TranspFillAttribute::operator=(FillAttrib);
06888 }
06889 
06890 /********************************************************************************************
06891 
06892 >   INT32 FractalTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
06893 
06894     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06895     Created:    23/8/94
06896     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
06897     Returns:    Usual semantics for equality.
06898     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
06899                 a description of why it's required. 
06900     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
06901                 runtime class.
06902     SeeAlso:    NodeAttribute::operator==
06903 
06904 ********************************************************************************************/
06905 
06906 INT32 FractalTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
06907 {
06908     if (GetRuntimeClass() != Attrib.GetRuntimeClass())
06909         return FALSE;
06910 
06911     FractalTranspFillAttribute* pAttrib = (FractalTranspFillAttribute*)&Attrib;
06912 
06913     if (IsPerspective())
06914     { 
06915         if (!pAttrib->IsPerspective())
06916             return FALSE;
06917 
06918         if (*GetEndPoint3() != *pAttrib->GetEndPoint3())
06919             return FALSE;
06920     }
06921 
06922     // check the transparency ramp matches
06923     if (!SameTransparencyRampAs(pAttrib->GetTranspRamp()))
06924         return FALSE;
06925 
06926     // Are the Colours and Control points all the same ?
06927     return (
06928 
06929         *GetStartTransp()   == *pAttrib->GetStartTransp()   &&  
06930         *GetEndTransp()     == *pAttrib->GetEndTransp()     &&
06931     
06932         *GetStartPoint()    == *pAttrib->GetStartPoint()    &&
06933         *GetEndPoint()      == *pAttrib->GetEndPoint()      &&
06934         *GetEndPoint2()     == *pAttrib->GetEndPoint2()     &&
06935 
06936         GetTranspType()     == pAttrib->GetTranspType()     &&
06937 
06938         Seed        == pAttrib->Seed        &&
06939         Graininess  == pAttrib->Graininess  &&
06940         Gravity     == pAttrib->Gravity     &&
06941         Squash      == pAttrib->Squash      &&
06942         Dpi         == pAttrib->Dpi         &&
06943         Tileable    == pAttrib->Tileable    &&
06944         Dim         == pAttrib->Dim
06945     );
06946 }
06947 
06948 /********************************************************************************************
06949 
06950 >   void FractalTranspFillAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
06951 
06952     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06953     Created:    21/01/97
06954     Inputs:     pCachedFractal = A pointer to the fractal in the cache
06955     Returns:    -
06956     Purpose:    Copies any data from this FractalFillAttribute into the cached fractal
06957                 pointed to on entry. This data is then checked via IsSameAsCachedFractal
06958     SeeAlso:    CachedFractal, FracList.h / .cpp
06959 
06960 ********************************************************************************************/
06961 
06962 void FractalTranspFillAttribute::CacheFractalData(FillGeometryAttribute *pCachedFractal)
06963 {
06964     ERROR3IF(pCachedFractal==NULL, "NULL pointer passed to FractalTranspFillAttribute::CacheFractalData");
06965     ERROR3IF(!IS_A(pCachedFractal,FractalTranspFillAttribute), "Not a FractalTranspFillAttribute during FractalTranspFillAttribute::CacheFractalData");
06966 
06967     pCachedFractal->SetStartPoint(GetStartPoint());
06968     pCachedFractal->SetEndPoint(GetEndPoint());
06969     pCachedFractal->SetEndPoint2(GetEndPoint2());
06970 
06971     pCachedFractal->SetFractalDPI(GetFractalDPI());
06972     pCachedFractal->SetFractalDim(GetFractalDim());
06973     pCachedFractal->SetTileable(GetTileable());
06974 
06975     pCachedFractal->SetSeed(GetSeed());
06976     pCachedFractal->SetGraininess(GetGraininess());
06977     pCachedFractal->SetGravity(GetGravity());
06978     pCachedFractal->SetSquash(GetSquash());
06979 }
06980 
06981 
06982 /********************************************************************************************
06983 
06984 >   BOOL FractalTranspFillAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
06985 
06986     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
06987     Created:    21/01/97
06988     Inputs:     pCachedFractal = A pointer to the fractal in the cache
06989     Returns:    TRUE if this fractal matches the cached fractal
06990                 FALSE if not
06991     Purpose:    A virtual comparison operator used by the fractal cache to check for a
06992                 matching fractal.
06993 
06994 ********************************************************************************************/
06995 
06996 BOOL FractalTranspFillAttribute::IsSameAsCachedFractal(FillGeometryAttribute *pCachedFractal)
06997 {
06998     ERROR3IF(pCachedFractal==NULL, "NULL pointer passed to FractalTranspFillAttribute::IsSameAsCachedFractal");
06999     ERROR3IF(!IS_A(pCachedFractal,FractalTranspFillAttribute), "Not a FractalTranspFillAttribute during FractalTranspFillAttribute::IsSameAsCachedFractal");
07000 
07001     // a long winded check but separate lines help in debugging, i.e. when does ok go FALSE?
07002     BOOL ok =  ((UINT32)Dim     == pCachedFractal->GetFractalDim());
07003 //  ok = ok && (Dpi         == pCachedFractal->GetFractalDpi());         // not checked in Will's original code
07004     ok = ok && (Tileable    == pCachedFractal->GetTileable());
07005 
07006     ok = ok && (Seed        == pCachedFractal->GetSeed());
07007     ok = ok && (Graininess  == pCachedFractal->GetGraininess());
07008     ok = ok && (Gravity     == pCachedFractal->GetGravity());
07009     ok = ok && (Squash      == pCachedFractal->GetSquash());
07010     
07011     return ok;
07012 }
07013 
07014 
07015 /********************************************************************************************
07016 
07017 >   BOOL FractalTranspFillAttribute::AttachBitmap(KernelBitmap* pBitmap)
07018 
07019     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07020     Created:    20/9/94
07021     Purpose:    Attaches a bitmap to this fill. 
07022     SeeAlso:    BitmapFillAttribute::DetachBitmap()
07023 
07024 ********************************************************************************************/
07025 
07026 BOOL FractalTranspFillAttribute::AttachBitmap(KernelBitmap* NewBitmap)
07027 {
07028     // Sometimes we are asked to attach the same bitmap to the attribute
07029     // So if we try to detach it and then attach it, during the detach
07030     // the bitmap can get deleted, so then we will effectivelly attach
07031     // a deleted bitmap. To avoid this we add this fractal to the list again in
07032     // order to increment the usage count, then do the normal detach & attach 
07033     // and finally remove the additional fractal from the list
07034     BOOL NeedUsageIncrement = FALSE;
07035     if ((NewBitmap != NULL) && (GetBitmap() != NULL))
07036     {
07037         // only if the bitmap we have is the same as the one we are to attach
07038         if ((GetBitmap()->ActualBitmap != NULL) && 
07039             (GetBitmap()->ActualBitmap == NewBitmap->ActualBitmap))
07040             {
07041                 NeedUsageIncrement = TRUE; // set the flag
07042                 GetApplication()->GetGlobalFractalList()->AddFractal(this); // inc the usage count
07043                 TRACEUSER( "Stefan", _T("NeedUsageIncrement = TRUE\n"));
07044             }
07045     }
07046 
07047     // get rid of the old bitmap
07048     DetachBitmap();
07049 
07050     if (NewBitmap == NULL)
07051         return FALSE;
07052 
07053     OILBitmap* Bmp = NewBitmap->ActualBitmap;
07054     if (Bmp == NULL || !Bmp->IsTemp())
07055         return FALSE;
07056 
07057     NewBitmap = new KernelBitmap(Bmp, TRUE);
07058     BitmapRef.SetBitmap(NewBitmap);
07059     GetApplication()->GetGlobalFractalList()->AddFractal(this);
07060 
07061     // if we added an additional fractal, remove it
07062     if (NeedUsageIncrement)
07063         GetApplication()->GetGlobalFractalList()->RemoveFractal(this);
07064     
07065     return TRUE;
07066 }
07067 
07068 /********************************************************************************************
07069 
07070 >   BOOL FractalTranspFillAttribute::DetachBitmap()
07071 
07072     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07073     Created:    20/9/94
07074     Purpose:    Detaches a bitmap from this fill. 
07075     SeeAlso:    BitmapFillAttribute::AttachBitmap()
07076 
07077 ********************************************************************************************/
07078 
07079 BOOL FractalTranspFillAttribute::DetachBitmap()
07080 {
07081     if (GetBitmap() == NULL)
07082         return FALSE;
07083 
07084     if (GetApplication()->GetGlobalFractalList()->RemoveFractal(this) && BitmapRef.GetBitmap())
07085     {
07086         // The fractal was deleted, so make sure we NULL our pointer
07087         BitmapRef.GetBitmap()->ActualBitmap = NULL;
07088     }
07089 
07090     BitmapRef.DeleteBmp();
07091 
07092     return TRUE;
07093 }
07094 
07095 /********************************************************************************************
07096 
07097 >   BOOL FractalTranspFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
07098 
07099     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07100     Created:    20/9/94
07101     Purpose:    Used to copy a bitmap from one fill to another. 
07102     SeeAlso:    BitmapFillAttribute::AttachBitmap()
07103 
07104 ********************************************************************************************/
07105 
07106 BOOL FractalTranspFillAttribute::CopyBitmap(KernelBitmap* BmpToCopy)
07107 {
07108     if (BmpToCopy != NULL)  // Is there a bitmap to copy ?
07109     {
07110         DetachBitmap();
07111 
07112         return AttachBitmap(BmpToCopy);
07113     }
07114 
07115     return TRUE;
07116 }
07117 
07118 /********************************************************************************************
07119 
07120 >   void FractalTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
07121 
07122     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07123     Created:    10/8/94
07124     Inputs:     pAttr - pointer to the AttributeValue to copy.
07125     Purpose:    See AttributeValue::SimpleCopy
07126     SeeAlso:    GradFillAttribute; RenderStack; AttributeValue; NodeAttribute;
07127                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
07128 
07129 ********************************************************************************************/
07130 
07131 void FractalTranspFillAttribute::SimpleCopy(AttributeValue *pValue)
07132 {
07133     // Just use the assignment operator
07134     *this = *(FillGeometryAttribute*)pValue;
07135 }
07136 
07137 
07138 /********************************************************************************************
07139 
07140 >   BOOL FractalTranspFillAttribute::RecalcFractal()
07141 
07142     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07143     Created:    6/10/94
07144     Purpose:    Recalculates the Fractal.
07145     SeeAlso:    FractalTranspFillAttribute::SetDPI
07146 
07147 ********************************************************************************************/
07148 
07149 BOOL FractalTranspFillAttribute::RecalcFractal()
07150 {
07151     if (*GetStartPoint() == *GetEndPoint() ||
07152         *GetStartPoint() == *GetEndPoint2())
07153     {
07154         return FALSE;
07155     }
07156 
07157     UINT32 OldDim = GetFractalDim();
07158 
07159     KernelBitmap* pBitmap = GenerateFractalBitmap(  Seed, 
07160                                                     Graininess.MakeDouble(),
07161                                                     Gravity.MakeDouble(),
07162                                                     Squash.MakeDouble(), 
07163                                                     Dpi);
07164     if (pBitmap == NULL)
07165     {
07166         TRACEUSER( "Mike", _T("Fractal Failed !!!\n"));
07167         return FALSE;   // Error set by GenerateFractalBitmap
07168     }
07169 
07170     // When asking GenerateFractalBitmap above to give us a bitmap, it might modify the Dim value.
07171     // DetachBitmap then tries to match this fractal with the cached fractals, so it could find a 
07172     // wrong cached fractal (one with the same parameters as this, but with Dim value as set by
07173     // GenerateFractalBitmap, rather then the original value). In this case DetachBitmap acts on
07174     // the wrong fractal and could even cause destroying its bitmap, even though it is used by 
07175     // some other attribute. To fix this we temporarily set Dim to the old value, call DetachBitmap
07176     // and then set the new value back.
07177     UINT32 NewDim = GetFractalDim();
07178     if (NewDim != OldDim)
07179     {
07180         SetFractalDim(OldDim);
07181         DetachBitmap();
07182 
07183         SetFractalDim(NewDim);
07184     }
07185 
07186     AttachBitmap(pBitmap);
07187     delete pBitmap;
07188 
07189     return TRUE;
07190 }
07191 
07192 
07193 
07194 void FractalTranspFillAttribute::SetTesselation(INT32 NewTess)
07195 {
07196     if (NewTess == RT_NoRepeatType)
07197         NewTess = RT_RepeatInverted;
07198 
07199     Tesselation = NewTess;
07200 }
07201 
07202 void FractalTranspFillAttribute::SetFractalDim(UINT32 NewDim) 
07203 {
07204     Dim = NewDim; 
07205 }
07206 
07207 BOOL FractalTranspFillAttribute::SetTileable(BOOL NewTile)
07208 {
07209     DetachBitmap();     // Ensure the current fractal is removed from cache
07210 
07211     Tileable = NewTile;
07212 
07213     return TRUE;
07214 }
07215 
07216 BOOL FractalTranspFillAttribute::SetFractalDPI(UINT32 NewDpi)
07217 {
07218     Dpi = NewDpi;
07219 
07220     return TRUE;
07221 }
07222 
07223 
07224 
07225 BOOL FractalTranspFillAttribute::SetSeed(INT32 NewSeed)
07226 {
07227     DetachBitmap();     // Ensure the current fractal is removed from cache
07228 
07229     Seed = NewSeed;
07230 
07231     return TRUE;
07232 }
07233 
07234 BOOL FractalTranspFillAttribute::SetGraininess(FIXED16 NewGrain)
07235 {
07236     DetachBitmap();     // Ensure the current fractal is removed from cache
07237 
07238     Graininess = NewGrain;
07239 
07240     return TRUE;
07241 }
07242 
07243 BOOL FractalTranspFillAttribute::SetGravity(FIXED16 NewGrav)
07244 {
07245     DetachBitmap();     // Ensure the current fractal is removed from cache
07246 
07247     Gravity = NewGrav;
07248 
07249     return TRUE;
07250 }
07251 
07252 BOOL FractalTranspFillAttribute::SetSquash(FIXED16 NewSquash)
07253 {
07254     DetachBitmap();     // Ensure the current fractal is removed from cache
07255 
07256     Squash = NewSquash;
07257 
07258     return TRUE;
07259 }
07260 
07261 BOOL FractalTranspFillAttribute::Randomise()
07262 {
07263     DetachBitmap();     // Ensure the current fractal is removed from cache
07264 
07265     MonotonicTime time;
07266     Seed = time.Sample();
07267 
07268     return TRUE;
07269 }
07270 
07271 /********************************************************************************************
07272 
07273 >   virtual ColourFillAttribute *FractalTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
07274 
07275     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
07276     Created:    19/02/97
07277     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
07278                                       the function will scale the transparency
07279 
07280     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
07281 
07282     Purpose:    Creates a non-transparent version of this transparent fill attribute.
07283                 (The original use of this was so airbrushes could maintain their fill's
07284                 transparency geometry)
07285 
07286     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
07287                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
07288 
07289 ********************************************************************************************/
07290 
07291 ColourFillAttribute *FractalTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
07292 {
07293     UINT32 *pStartTransp = GetStartTransp();
07294     UINT32 *pEndTransp = GetEndTransp();
07295 
07296     if(pStartTransp == NULL || pEndTransp == NULL)
07297         return NULL;
07298     
07299     FractalFillAttribute *pNewAttr = new FractalFillAttribute;
07300     if (pNewAttr != NULL)
07301     {
07302         pNewAttr->SetStartPoint(GetStartPoint());
07303         pNewAttr->SetEndPoint(GetEndPoint());
07304         pNewAttr->SetEndPoint2(GetEndPoint2());
07305         pNewAttr->SetEndPoint3(GetEndPoint3());
07306 
07307         pNewAttr->SetTesselation(GetTesselation());
07308         pNewAttr->SetDPI(GetDPI());
07309         if(IsPerspective())
07310             pNewAttr->MakePerspective();
07311 
07312         pNewAttr->AttachBitmap(GetBitmap());
07313         pNewAttr->SetFractalDim(GetFractalDim());
07314         pNewAttr->SetTileable(GetTileable());
07315         pNewAttr->SetFractalDPI(GetFractalDPI());
07316         pNewAttr->SetSeed(GetSeed());
07317         pNewAttr->SetNoiseScale(GetNoiseScale());
07318 
07319         pNewAttr->SetGraininess(GetGraininess());
07320         pNewAttr->SetGravity(GetGravity());
07321         pNewAttr->SetSquash(GetSquash());
07322 
07323         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
07324         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
07325 
07326         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
07327         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
07328         pNewAttr->SetStartColour(&colorStart);
07329         pNewAttr->SetEndColour(&colorEnd1);
07330 
07331         pNewAttr->RecalcFractal();
07332     }
07333 
07334     return(pNewAttr);
07335 }
07336 
07337 
07338 
07340 //
07341 //                          SquareTranspFillAttribute class
07342 //
07344 
07345 /********************************************************************************************
07346 
07347 >   SquareTranspFillAttribute::SquareTranspFillAttribute()
07348 
07349     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07350     Created:    9/8/96
07351     Purpose:    Default Constuctor for fill attribute values. 
07352     SeeAlso:    AttrFillGeometry::AttrFillGeometry
07353 
07354 ********************************************************************************************/
07355 
07356 SquareTranspFillAttribute::SquareTranspFillAttribute()
07357 {
07358     IsPersp = FALSE;
07359 
07360     EndPoint2 = DocCoord(0,0);
07361 }
07362 
07363 /********************************************************************************************
07364 
07365 >   NodeAttribute *SquareTranspFillAttribute::MakeNode()
07366 
07367     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07368     Created:    9/8/96
07369     Returns:    Pointer to the new node, or NULL if out of memory.
07370     Purpose:    Make a AttrSquareFill node from this graduated fill attribute.
07371     Errors:     Out of memory
07372     SeeAlso:    AttributeValue::MakeNode
07373 
07374 ********************************************************************************************/
07375 
07376 NodeAttribute *SquareTranspFillAttribute::MakeNode()
07377 {
07378     // Create new attribute node
07379     AttrSquareTranspFill *pAttr = new AttrSquareTranspFill;
07380     if (pAttr==NULL)
07381         // error message has already been set by new
07382         return NULL;
07383 
07384     // Copy attribute value into the new node.
07385     pAttr->GetAttributeValue()->SimpleCopy(this);
07386 
07387     // Return the new node
07388     return pAttr;
07389 }
07390 
07391 /********************************************************************************************
07392 
07393 >   void SquareTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
07394 
07395     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07396     Created:    9/8/96
07397     Inputs:     -
07398     Purpose:    Sets the End Point of this fill
07399 
07400 ********************************************************************************************/
07401 
07402 void SquareTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
07403 {
07404     if (Pos == NULL)
07405         EndPoint2 = MakeLineAtAngle(*GetStartPoint(), *GetEndPoint(), 90);
07406     else
07407         EndPoint2 = *Pos;
07408 }
07409 
07410 
07411 /********************************************************************************************
07412 
07413 >   void SquareTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
07414 
07415     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07416     Created:    9/8/96
07417     Inputs:     -
07418     Purpose:    Sets the End Point of this fill
07419 
07420 ********************************************************************************************/
07421 
07422 void SquareTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
07423 {
07424     if (Pos == NULL)
07425         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
07426     else
07427         EndPoint3 = *Pos;
07428 }
07429 
07430 
07431 /********************************************************************************************
07432 
07433 >   void SquareTranspFillAttribute::MakePerspective()
07434 
07435     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07436     Created:    9/8/96
07437     Inputs:     -
07438     Purpose:    Make the fill perspectived.
07439                 This should be called just before it is transformed by the moulder,
07440                 so it can validate the 4th control point.
07441 
07442 ********************************************************************************************/
07443 
07444 void SquareTranspFillAttribute::MakePerspective()
07445 {
07446     IsPersp = TRUE;
07447 
07448     INT32 dx1 = EndPoint.x - StartPoint.x;
07449     INT32 dx2 = EndPoint2.x - StartPoint.x;
07450 
07451     INT32 dy1 = EndPoint.y - StartPoint.y;
07452     INT32 dy2 = EndPoint2.y - StartPoint.y;
07453 
07454     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
07455     SetEndPoint3(&Pos3);
07456 }
07457 
07458 /********************************************************************************************
07459 
07460 >   void SquareTranspFillAttribute::RemovePerspective()
07461 
07462     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07463     Created:    9/8/96
07464     Inputs:     -
07465     Purpose:    Removes perspective from this fill.
07466 
07467 ********************************************************************************************/
07468 
07469 void SquareTranspFillAttribute::RemovePerspective()
07470 {
07471     IsPersp = FALSE;
07472 }
07473 
07474 /********************************************************************************************
07475 
07476 >   virtual ColourFillAttribute *SquareTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
07477 
07478     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
07479     Created:    19/02/97
07480     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
07481                                       the function will scale the transparency
07482 
07483     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
07484 
07485     Purpose:    Creates a non-transparent version of this transparent fill attribute.
07486                 (The original use of this was so airbrushes could maintain their fill's
07487                 transparency geometry)
07488 
07489     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
07490                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
07491 
07492 ********************************************************************************************/
07493 
07494 ColourFillAttribute *SquareTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
07495 {
07496     UINT32 *pStartTransp = GetStartTransp();
07497     UINT32 *pEndTransp = GetEndTransp();
07498 
07499     if(pStartTransp == NULL || pEndTransp == NULL)
07500         return NULL;
07501     
07502     SquareFillAttribute *pNewAttr = new SquareFillAttribute;    
07503     if (pNewAttr != NULL)
07504     {
07505         pNewAttr->SetStartPoint(GetStartPoint());
07506         pNewAttr->SetEndPoint(GetEndPoint());
07507         pNewAttr->SetEndPoint2(GetEndPoint2());
07508         pNewAttr->SetEndPoint3(GetEndPoint3());
07509 
07510         if(IsPerspective())
07511             pNewAttr->MakePerspective();
07512 
07513         pNewAttr->AttachBitmap(GetBitmap());
07514 
07515         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
07516         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
07517 
07518         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
07519         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
07520         pNewAttr->SetStartColour(&colorStart);
07521         pNewAttr->SetEndColour(&colorEnd1);
07522     }
07523 
07524     return(pNewAttr);
07525 }
07526 
07527 
07528 
07530 //
07531 //                          ThreeColTranspFillAttribute class
07532 //
07534 
07535 /********************************************************************************************
07536 
07537 >   ThreeColTranspFillAttribute::ThreeColTranspFillAttribute()
07538 
07539     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07540     Created:    9/8/96
07541     Purpose:    Default Constuctor for fill attribute values. 
07542     SeeAlso:    AttrFillGeometry::AttrFillGeometry
07543 
07544 ********************************************************************************************/
07545 
07546 ThreeColTranspFillAttribute::ThreeColTranspFillAttribute()
07547 {
07548     IsPersp = FALSE;
07549 
07550     EndPoint2 = DocCoord(0,0);
07551     EndTransp2 = 128;
07552 }
07553 
07554 /********************************************************************************************
07555 
07556 >   INT32 ThreeColTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
07557 
07558     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07559     Created:    15/8/96
07560     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
07561     Returns:    Usual semantics for equality.
07562     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
07563                 a description of why it's required. 
07564     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
07565                 runtime class.
07566     SeeAlso:    NodeAttribute::operator==
07567 
07568 ********************************************************************************************/
07569 
07570 INT32 ThreeColTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
07571 {
07572     ThreeColTranspFillAttribute* pAttrib = (ThreeColTranspFillAttribute*) &Attrib;
07573     
07574     return(GradTranspFillAttribute::operator==(Attrib) && (EndTransp2 == pAttrib->EndTransp2));
07575 }
07576 
07577 
07578 /********************************************************************************************
07579 
07580 >   NodeAttribute *ThreeColTranspFillAttribute::MakeNode()
07581 
07582     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07583     Created:    9/8/96
07584     Returns:    Pointer to the new node, or NULL if out of memory.
07585     Purpose:    Make a AttrThreeColFill node from this graduated fill attribute.
07586     Errors:     Out of memory
07587     SeeAlso:    AttributeValue::MakeNode
07588 
07589 ********************************************************************************************/
07590 
07591 NodeAttribute *ThreeColTranspFillAttribute::MakeNode()
07592 {
07593     // Create new attribute node
07594     AttrThreeColTranspFill *pAttr = new AttrThreeColTranspFill;
07595     if (pAttr==NULL)
07596         // error message has already been set by new
07597         return NULL;
07598 
07599     // Copy attribute value into the new node.
07600     pAttr->GetAttributeValue()->SimpleCopy(this);
07601 
07602     // Return the new node
07603     return pAttr;
07604 }
07605 
07606 /********************************************************************************************
07607 
07608 >   void ThreeColTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
07609 
07610     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07611     Created:    9/8/96
07612     Inputs:     -
07613     Purpose:    Sets the End Point of this fill
07614 
07615 ********************************************************************************************/
07616 
07617 void ThreeColTranspFillAttribute::SetEndPoint2(DocCoord* Pos)
07618 {
07619     if (Pos == NULL)
07620         EndPoint2 = MakeLineAtAngle(*GetStartPoint(), *GetEndPoint(), 90);
07621     else
07622         EndPoint2 = *Pos;
07623 }
07624 
07625 
07626 /********************************************************************************************
07627 
07628 >   void ThreeColTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
07629 
07630     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07631     Created:    9/8/96
07632     Inputs:     -
07633     Purpose:    Sets the End Point of this fill
07634 
07635 ********************************************************************************************/
07636 
07637 void ThreeColTranspFillAttribute::SetEndPoint3(DocCoord* Pos)
07638 {
07639     if (Pos == NULL)
07640         EndPoint3 = MakeLineAtAngle(*GetEndPoint(), *GetEndPoint2(), 90);
07641     else
07642         EndPoint3 = *Pos;
07643 }
07644 
07645 
07646 /********************************************************************************************
07647 
07648 >   void ThreeColTranspFillAttribute::SetEndTransp2(DocColour* NewCol)
07649 
07650     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07651     Created:    12/8/96
07652     Inputs:     -
07653     Purpose:    Sets the second colour of this fill
07654 
07655 ********************************************************************************************/
07656 
07657 void ThreeColTranspFillAttribute::SetEndTransp2(UINT32* NewTransp)
07658 {
07659     if (NewTransp == NULL)
07660         EndTransp2 = 128;
07661     else
07662         EndTransp2 = *NewTransp;
07663 }
07664 
07665 
07666 
07667 
07668 /********************************************************************************************
07669 
07670 >   void ThreeColTranspFillAttribute::MakePerspective()
07671 
07672     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07673     Created:    9/8/96
07674     Inputs:     -
07675     Purpose:    Make the fill perspectived.
07676                 This should be called just before it is transformed by the moulder,
07677                 so it can validate the 4th control point.
07678 
07679 ********************************************************************************************/
07680 
07681 void ThreeColTranspFillAttribute::MakePerspective()
07682 {
07683     IsPersp = TRUE;
07684 
07685     INT32 dx1 = EndPoint.x - StartPoint.x;
07686     INT32 dx2 = EndPoint2.x - StartPoint.x;
07687 
07688     INT32 dy1 = EndPoint.y - StartPoint.y;
07689     INT32 dy2 = EndPoint2.y - StartPoint.y;
07690 
07691     DocCoord Pos3(StartPoint.x + dx1 + dx2, StartPoint.y + dy1 + dy2);
07692     SetEndPoint3(&Pos3);
07693 }
07694 
07695 /********************************************************************************************
07696 
07697 >   void ThreeColTranspFillAttribute::RemovePerspective()
07698 
07699     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07700     Created:    9/8/96
07701     Inputs:     -
07702     Purpose:    Removes perspective from this fill.
07703 
07704 ********************************************************************************************/
07705 
07706 void ThreeColTranspFillAttribute::RemovePerspective()
07707 {
07708     IsPersp = FALSE;
07709 }
07710 
07711 
07712 /********************************************************************************************
07713 
07714 >   virtual ColourFillAttribute *ThreeColTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
07715 
07716     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
07717     Created:    19/02/97
07718     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
07719                                       the function will scale the transparency
07720 
07721     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
07722 
07723     Purpose:    Creates a non-transparent version of this transparent fill attribute.
07724                 (The original use of this was so airbrushes could maintain their fill's
07725                 transparency geometry)
07726 
07727     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
07728                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
07729 
07730 ********************************************************************************************/
07731 
07732 ColourFillAttribute *ThreeColTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
07733 {
07734     UINT32 *pStartTransp = GetStartTransp();
07735     UINT32 *pEndTransp = GetEndTransp();
07736     UINT32 *pEndTransp2 = GetEndTransp2();
07737 
07738     if(pStartTransp == NULL || pEndTransp == NULL || pEndTransp2 == NULL)
07739         return NULL;
07740     
07741     ThreeColFillAttribute *pNewAttr = new ThreeColFillAttribute;    
07742     if (pNewAttr != NULL)
07743     {
07744         pNewAttr->SetStartPoint(GetStartPoint());
07745         pNewAttr->SetEndPoint(GetEndPoint());
07746         pNewAttr->SetEndPoint2(GetEndPoint2());
07747         pNewAttr->SetEndPoint3(GetEndPoint3());
07748 
07749         if(IsPerspective())
07750             pNewAttr->MakePerspective();
07751 
07752         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
07753         INT32 EndTransparency = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
07754         INT32 EndTransparency2 = 255 - (INT32)(((double)(255 - *pEndTransp2)) * TransparencyScale);
07755 
07756         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
07757         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
07758         DocColour       colorEnd2(EndTransparency2, EndTransparency2, EndTransparency2);
07759         pNewAttr->SetStartColour(&colorStart);
07760         pNewAttr->SetEndColour(&colorEnd1);
07761         pNewAttr->SetEndColour2(&colorEnd2);
07762     }
07763 
07764     return(pNewAttr);
07765 }
07766 
07767 
07769 //
07770 //                          FourColTranspFillAttribute class
07771 //
07773 
07774 /********************************************************************************************
07775 
07776 >   FourColTranspFillAttribute::FourColTranspFillAttribute()
07777 
07778     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07779     Created:    9/8/96
07780     Purpose:    Default Constuctor for fill attribute values. 
07781     SeeAlso:    AttrFillGeometry::AttrFillGeometry
07782 
07783 ********************************************************************************************/
07784 
07785 FourColTranspFillAttribute::FourColTranspFillAttribute()
07786 {
07787     EndTransp3 = 192;
07788 }
07789 
07790 
07791 /********************************************************************************************
07792 
07793 >   INT32 FourColTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
07794 
07795     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07796     Created:    15/8/96
07797     Inputs:     Attrib - the attribute to compare, which must be an AttrFillGeometry
07798     Returns:    Usual semantics for equality.
07799     Purpose:    A virtual comparison operator. See NodeAttribute::operator== for 
07800                 a description of why it's required. 
07801     Errors:     An ENSURE failure will occur if Attrib does not have a AttrFlatGeometry 
07802                 runtime class.
07803     SeeAlso:    NodeAttribute::operator==
07804 
07805 ********************************************************************************************/
07806 
07807 INT32 FourColTranspFillAttribute::operator==(const FillGeometryAttribute& Attrib)
07808 {
07809     FourColTranspFillAttribute* pAttrib = (FourColTranspFillAttribute*) &Attrib;
07810     
07811     return(ThreeColTranspFillAttribute::operator==(Attrib) && (EndTransp3 == pAttrib->EndTransp3));
07812 }
07813 
07814 
07815 /********************************************************************************************
07816 
07817 >   NodeAttribute *FourColTranspFillAttribute::MakeNode()
07818 
07819     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07820     Created:    9/8/96
07821     Returns:    Pointer to the new node, or NULL if out of memory.
07822     Purpose:    Make a AttrFourColTranspFill node from this graduated fill attribute.
07823     Errors:     Out of memory
07824     SeeAlso:    AttributeValue::MakeNode
07825 
07826 ********************************************************************************************/
07827 
07828 NodeAttribute *FourColTranspFillAttribute::MakeNode()
07829 {
07830     // Create new attribute node
07831     AttrFourColTranspFill *pAttr = new AttrFourColTranspFill;
07832     if (pAttr==NULL)
07833         // error message has already been set by new
07834         return NULL;
07835 
07836     // Copy attribute value into the new node.
07837     pAttr->GetAttributeValue()->SimpleCopy(this);
07838 
07839     // Return the new node
07840     return pAttr;
07841 }
07842 
07843 /********************************************************************************************
07844 
07845 >   void FourColTranspFillAttribute::SetEndTransp3(DocColour* NewCol)
07846 
07847     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
07848     Created:    12/8/96
07849     Inputs:     -
07850     Purpose:    Sets the third transparency of this fill
07851 
07852 ********************************************************************************************/
07853 
07854 void FourColTranspFillAttribute::SetEndTransp3(UINT32* NewTransp)
07855 {
07856     if (NewTransp == NULL)
07857         EndTransp3 = 192;
07858     else
07859         EndTransp3 = *NewTransp;
07860 }
07861 
07862 /********************************************************************************************
07863 
07864 >   virtual ColourFillAttribute *FourColTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
07865 
07866     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
07867     Created:    19/02/97
07868     Inputs:     TransparencyScale   - Value between 0.0 and 1.0 which denotes by how much
07869                                       the function will scale the transparency
07870 
07871     Returns:    Pointer to the new attribute, or NULL if out of memory, problems, etc.
07872 
07873     Purpose:    Creates a non-transparent version of this transparent fill attribute.
07874                 (The original use of this was so airbrushes could maintain their fill's
07875                 transparency geometry)
07876 
07877     SeeAlso:    TranspFillAttribute::MakeSimilarNonTranspFillGeometry; AttrFlatFill
07878                 FlatTranspFillAttribute::MakeSimilarNonTranspFillGeometry
07879 
07880 ********************************************************************************************/
07881 
07882 ColourFillAttribute *FourColTranspFillAttribute::MakeSimilarNonTranspFillGeometry(double TransparencyScale)
07883 {
07884     UINT32 *pStartTransp = GetStartTransp();
07885     UINT32 *pEndTransp = GetEndTransp();
07886     UINT32 *pEndTransp2 = GetEndTransp2();
07887     UINT32 *pEndTransp3 = GetEndTransp3();
07888 
07889     if(pStartTransp == NULL || pEndTransp == NULL || pEndTransp2 == NULL || pEndTransp3 == NULL)
07890         return NULL;
07891     
07892     FourColFillAttribute *pNewAttr = new FourColFillAttribute;  
07893     if (pNewAttr != NULL)
07894     {
07895         pNewAttr->SetStartPoint(GetStartPoint());
07896         pNewAttr->SetEndPoint(GetEndPoint());
07897         pNewAttr->SetEndPoint2(GetEndPoint2());
07898         pNewAttr->SetEndPoint3(GetEndPoint3());
07899 
07900         if(IsPerspective())
07901             pNewAttr->MakePerspective();
07902 
07903         INT32 StartTransparency = 255 - (INT32)(((double)(255 - *pStartTransp)) * TransparencyScale);
07904         INT32 EndTransparency  = 255 - (INT32)(((double)(255 - *pEndTransp)) * TransparencyScale);
07905         INT32 EndTransparency2 = 255 - (INT32)(((double)(255 - *pEndTransp2)) * TransparencyScale);
07906         INT32 EndTransparency3 = 255 - (INT32)(((double)(255 - *pEndTransp3)) * TransparencyScale);
07907 
07908         DocColour       colorStart(StartTransparency, StartTransparency, StartTransparency);
07909         DocColour       colorEnd1(EndTransparency, EndTransparency, EndTransparency);
07910         DocColour       colorEnd2(EndTransparency2, EndTransparency2, EndTransparency2);
07911         DocColour       colorEnd3(EndTransparency3, EndTransparency3, EndTransparency3);
07912         pNewAttr->SetStartColour(&colorStart);
07913         pNewAttr->SetEndColour(&colorEnd1);
07914         pNewAttr->SetEndColour2(&colorEnd2);
07915         pNewAttr->SetEndColour3(&colorEnd3);
07916     }
07917 
07918     return(pNewAttr);
07919 }
07920 
07921 
07922 
07924 //
07925 //                          FillMappingAttribute class
07926 //
07928 
07929 /********************************************************************************************
07930 
07931 >   FillMappingAttribute::FillMappingAttribute()
07932 
07933     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07934     Created:    23/11/94
07935     Purpose:    Constructor for mapping attributes.
07936     SeeAlso:    FillMappingAttribute; RenderStack; AttributeValue; NodeAttribute;
07937                 FillMappingAttribute::Restore;
07938                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
07939 
07940 ********************************************************************************************/
07941 
07942 FillMappingAttribute::FillMappingAttribute()
07943 {
07944     Repeat = 2;
07945 }
07946 
07947 /********************************************************************************************
07948 
07949 >   BOOL FillMappingAttribute::Init()
07950 
07951     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07952     Created:    23/8/94
07953     Returns:    TRUE - initialised ok; FALSE if not.
07954     Purpose:    Registers fill mapping attribute, and provides a default attribute to give
07955                 linear graduations.
07956     Errors:     Out of memory.
07957     SeeAlso:    AttributeManager
07958 
07959 ********************************************************************************************/
07960 
07961 BOOL FillMappingAttribute::Init()
07962 {
07963     // Default to simple linear mapping (ignored for flat fills, obviously)
07964     FillMappingAttribute *pAttr = new FillMappingLinearAttribute;
07965     if (pAttr==NULL)
07966         // error message has already been set by new
07967         return FALSE;
07968 
07969     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
07970                                                          pAttr);
07971 
07972     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising FillMappingAttribute");
07973     ERROR2IF(ID != ATTR_FILLMAPPING, FALSE, "Incorrect ID for FillMappingAttribute");
07974 
07975     return TRUE;
07976 }
07977 
07978 /********************************************************************************************
07979 
07980 >   void FillMappingAttribute::SimpleCopy(AttributeValue *pValue)
07981 
07982     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07983     Created:    23/11/94
07984     Inputs:     pAttr - pointer to the AttributeValue to copy.
07985     Purpose:    See AttributeValue::SimpleCopy
07986 
07987 ********************************************************************************************/
07988 
07989 void FillMappingAttribute::SimpleCopy(AttributeValue *pValue)
07990 {
07991     Repeat = ((FillMappingAttribute *) pValue)->Repeat;
07992 }
07993 
07994 /********************************************************************************************
07995 
07996 >   void FillMappingAttribute::Render(RenderRegion *pRegion)
07997 
07998     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
07999     Created:    23/8/94
08000     Inputs:     pRegion - the render region to render this attribute into.
08001     Purpose:    Sets the fill type attribute for the given render region. i.e. all
08002                 paths filled will now be filled with this fill attribute.
08003     SeeAlso:    FillMappingAttribute; RenderStack; AttributeValue; NodeAttribute;
08004                 FillMappingAttribute::Restore;
08005                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08006 
08007 ********************************************************************************************/
08008 
08009 void FillMappingAttribute::Render(RenderRegion *pRegion, BOOL Temp)
08010 {
08011     pRegion->SetFillMapping(this, Temp);
08012 }
08013 
08014 /********************************************************************************************
08015 
08016 >   void FillMappingAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08017 
08018     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08019     Created:    23/8/94
08020     Inputs:     pRegion - the render region to restore the attribute into.
08021                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
08022                           permanent (e.g. it's in a document tree).
08023     Purpose:    Restores the fill type attribute for the given render region. i.e. all
08024                 paths filled will now be filled with this fill attribute.
08025     SeeAlso:    FillMappingAttribute; RenderStack; AttributeValue; NodeAttribute;
08026                 FillMappingAttribute::Render;
08027                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08028 
08029 ********************************************************************************************/
08030 
08031 void FillMappingAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08032 {
08033     pRegion->RestoreFillMapping(this, Temp);
08034 }
08035 
08036 BOOL FillMappingAttribute::IsDifferent(AttributeValue* pVal)
08037 {
08038     if (pVal->GetRuntimeClass() != GetRuntimeClass())
08039         return TRUE;
08040 
08041     return (Repeat != ((FillMappingAttribute*)pVal)->Repeat);
08042 }
08043 
08044 FillMappingAttribute& FillMappingAttribute::operator=(FillMappingAttribute& Attrib)
08045 {
08046     Repeat = Attrib.Repeat;
08047 
08048     return *this;
08049 }
08050 
08051 INT32 FillMappingAttribute::operator==(const FillMappingAttribute& Attrib)
08052 {
08053     if (Attrib.GetRuntimeClass() != GetRuntimeClass())
08054         return FALSE;
08055 
08056     return (Repeat == Attrib.Repeat);
08057 }
08058 
08059 /********************************************************************************************
08060 
08061 >   NodeAttribute *FillMappingLinearAttribute::MakeNode()
08062 
08063     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08064     Created:    23/8/94
08065     Returns:    Pointer to the new node, or NULL if out of memory.
08066     Purpose:    Make a AttrFillMappingLinear node from this fill mapping attribute.
08067     Errors:     Out of memory
08068     SeeAlso:    AttributeValue::MakeNode
08069 
08070 ********************************************************************************************/
08071 
08072 NodeAttribute *FillMappingLinearAttribute::MakeNode()
08073 {
08074     // Create new attribute node
08075     AttrFillMappingLinear *pAttr = new AttrFillMappingLinear();
08076     if (pAttr==NULL)
08077         // error message has already been set by new
08078         return NULL;
08079 
08080     // Copy attribute value into the new node.
08081     pAttr->Value.SimpleCopy(this);
08082 
08083     // Return the new node
08084     return pAttr;
08085 }
08086 
08087 
08088 /********************************************************************************************
08089 
08090 >   NodeAttribute *FillMappingSinAttribute::MakeNode()
08091 
08092     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08093     Created:    23/8/94
08094     Returns:    Pointer to the new node, or NULL if out of memory.
08095     Purpose:    Make a AttrFillMappingSin node from this fill mapping attribute.
08096     Errors:     Out of memory
08097     SeeAlso:    AttributeValue::MakeNode
08098 
08099 ********************************************************************************************/
08100 
08101 NodeAttribute *FillMappingSinAttribute::MakeNode()
08102 {
08103     // Create new attribute node
08104     AttrFillMappingSin *pAttr = new AttrFillMappingSin();
08105     if (pAttr==NULL)
08106         // error message has already been set by new
08107         return NULL;
08108 
08109     // Copy attribute value into the new node.
08110     pAttr->Value.SimpleCopy(this);
08111 
08112     // Return the new node
08113     return pAttr;
08114 }
08115 
08116 
08117 /********************************************************************************************
08118 
08119 >   BOOL FillEffectAttribute::Init()
08120 
08121     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08122     Created:    23/8/94
08123     Returns:    TRUE - initialised ok; FALSE if not.
08124     Purpose:    Registers fill effect attribute, and provides a default attribute to give
08125                 standard RGB fade between two colours.
08126     Errors:     Out of memory.
08127     SeeAlso:    AttributeManager
08128 
08129 ********************************************************************************************/
08130 
08131 BOOL FillEffectAttribute::Init()
08132 {
08133     // Default to simple RGB fade effect (ignored for flat fills, obviously)
08134     FillEffectAttribute *pAttr = new FillEffectFadeAttribute;
08135     if (pAttr==NULL)
08136         // error message has already been set by new
08137         return FALSE;
08138 
08139     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
08140                                                          pAttr);
08141 
08142     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising FillEffectAttribute");
08143     ERROR2IF(ID != ATTR_FILLEFFECT, FALSE, "Incorrect ID for FillEffectAttribute");
08144 
08145     return TRUE;
08146 }
08147 
08148 /********************************************************************************************
08149 
08150 >   void FillEffectAttribute::Render(RenderRegion *pRegion)
08151 
08152     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08153     Created:    23/8/94
08154     Inputs:     pRegion - the render region to render this attribute into.
08155     Purpose:    Sets the fill type attribute for the given render region. i.e. all
08156                 paths filled will now be filled with this fill attribute.
08157     SeeAlso:    FillEffectAttribute; RenderStack; AttributeValue; NodeAttribute;
08158                 FillEffectAttribute::Restore;
08159                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08160 
08161 ********************************************************************************************/
08162 
08163 void FillEffectAttribute::Render(RenderRegion *pRegion, BOOL Temp)
08164 {
08165     pRegion->SetFillEffect(this, Temp);
08166 }
08167 
08168 /********************************************************************************************
08169 
08170 >   void FillEffectAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08171 
08172     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08173     Created:    23/8/94
08174     Inputs:     pRegion - the render region to restore the attribute into.
08175                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
08176                           permanent (e.g. it's in a document tree).
08177     Purpose:    Restores the fill type attribute for the given render region. i.e. all
08178                 paths filled will now be filled with this fill attribute.
08179     SeeAlso:    FillEffectAttribute; RenderStack; AttributeValue; NodeAttribute;
08180                 FillEffectAttribute::Render;
08181                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08182 
08183 ********************************************************************************************/
08184 
08185 void FillEffectAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08186 {
08187     pRegion->RestoreFillEffect(this, Temp);
08188 }
08189 
08190 /********************************************************************************************
08191 
08192 >   void FillEffectAttribute::SimpleCopy(AttributeValue* pVal)
08193 
08194     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08195     Created:    8/6/95
08196     Inputs:     pVal - pointer to the AttributeValue to copy.
08197     Purpose:    See AttributeValue::SimpleCopy
08198 
08199 ********************************************************************************************/
08200 
08201 void FillEffectAttribute::SimpleCopy(AttributeValue* pVal)
08202 {
08203 }
08204 
08205 /********************************************************************************************
08206 
08207 >   BOOL FillEffectAttribute::IsDifferent(AttributeValue* pVal)
08208 
08209     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08210     Created:    8/6/95
08211     Inputs:     pVal - pointer to the AttributeValue to copy.
08212     Purpose:    See AttributeValue::IsDifferent
08213 
08214 ********************************************************************************************/
08215 
08216 BOOL FillEffectAttribute::IsDifferent(AttributeValue* pVal)
08217 {
08218     return (pVal->GetRuntimeClass() != GetRuntimeClass());
08219 }
08220 
08221 /********************************************************************************************
08222 
08223 >   FillEffectAttribute& FillEffectAttribute::operator=(FillEffectAttribute& Attrib)
08224 
08225     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08226     Created:    8/6/95
08227     Inputs:     Attrib - the AttributeValue to copy.
08228     Purpose:    Make this effect the same as another.
08229 
08230 ********************************************************************************************/
08231 
08232 FillEffectAttribute& FillEffectAttribute::operator=(FillEffectAttribute& Attrib)
08233 {
08234     return (*this);
08235 }
08236 
08237 /********************************************************************************************
08238 
08239 >   INT32 FillEffectAttribute::operator==(const FillEffectAttribute& Attrib)
08240 
08241     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08242     Created:    8/6/95
08243     Inputs:     Attrib - The AttributeValue to test.
08244     Purpose:    See if two effects are the same.
08245 
08246 ********************************************************************************************/
08247 
08248 INT32 FillEffectAttribute::operator==(const FillEffectAttribute& Attrib)
08249 {
08250     return (Attrib.GetRuntimeClass() == GetRuntimeClass());
08251 }
08252 
08253 /********************************************************************************************
08254 
08255 >   NodeAttribute *FillEffectFadeAttribute::MakeNode()
08256 
08257     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08258     Created:    23/8/94
08259     Returns:    Pointer to the new node, or NULL if out of memory.
08260     Purpose:    Make a AttrFillEffectFade node from this fill effect attribute.
08261     Errors:     Out of memory
08262     SeeAlso:    AttributeValue::MakeNode
08263 
08264 ********************************************************************************************/
08265 
08266 NodeAttribute *FillEffectFadeAttribute::MakeNode()
08267 {
08268     // Create new attribute node
08269     AttrFillEffectFade *pAttr = new AttrFillEffectFade();
08270     if (pAttr==NULL)
08271         // error message has already been set by new
08272         return NULL;
08273 
08274     // Copy attribute value into the new node.
08275     pAttr->Value.SimpleCopy(this);
08276 
08277     // Return the new node
08278     return pAttr;
08279 }
08280 
08281 
08282 /********************************************************************************************
08283 
08284 >   NodeAttribute *FillEffectRainbowAttribute::MakeNode()
08285 
08286     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08287     Created:    23/8/94
08288     Returns:    Pointer to the new node, or NULL if out of memory.
08289     Purpose:    Make a AttrFillEffectRainbow node from this fill effect attribute.
08290     Errors:     Out of memory
08291     SeeAlso:    AttributeValue::MakeNode
08292 
08293 ********************************************************************************************/
08294 
08295 NodeAttribute *FillEffectRainbowAttribute::MakeNode()
08296 {
08297     // Create new attribute node
08298     AttrFillEffectRainbow *pAttr = new AttrFillEffectRainbow();
08299     if (pAttr==NULL)
08300         // error message has already been set by new
08301         return NULL;
08302 
08303     // Copy attribute value into the new node.
08304     pAttr->Value.SimpleCopy(this);
08305 
08306     // Return the new node
08307     return pAttr;
08308 }
08309 
08310 
08311 /********************************************************************************************
08312 
08313 >   NodeAttribute *FillEffectAltRainbowAttribute::MakeNode()
08314 
08315     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08316     Created:    23/8/94
08317     Returns:    Pointer to the new node, or NULL if out of memory.
08318     Purpose:    Make a AttrFillEffectAltRainbow node from this fill effect attribute.
08319     Errors:     Out of memory
08320     SeeAlso:    AttributeValue::MakeNode
08321 
08322 ********************************************************************************************/
08323 
08324 NodeAttribute *FillEffectAltRainbowAttribute::MakeNode()
08325 {
08326     // Create new attribute node
08327     AttrFillEffectAltRainbow *pAttr = new AttrFillEffectAltRainbow();
08328     if (pAttr==NULL)
08329         // error message has already been set by new
08330         return NULL;
08331 
08332     // Copy attribute value into the new node.
08333     pAttr->Value.SimpleCopy(this);
08334 
08335     // Return the new node
08336     return pAttr;
08337 }
08338 
08339 
08340 
08341 
08342 
08343 
08344 
08345 /********************************************************************************************
08346 
08347 >   TranspFillMappingAttribute::TranspFillMappingAttribute()
08348 
08349     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08350     Created:    23/11/94
08351     Purpose:    Constructor for transp mapping attributes.
08352     SeeAlso:    FillMappingAttribute; RenderStack; AttributeValue; NodeAttribute;
08353                 FillMappingAttribute::Restore;
08354                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08355 
08356 ********************************************************************************************/
08357 
08358 TranspFillMappingAttribute::TranspFillMappingAttribute()
08359 {
08360     Repeat = 2;
08361 }
08362 
08363 /********************************************************************************************
08364 
08365 >   BOOL TranspFillMappingAttribute::Init()
08366 
08367     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08368     Created:    23/8/94
08369     Returns:    TRUE - initialised ok; FALSE if not.
08370     Purpose:    Registers fill mapping attribute, and provides a default attribute to give
08371                 linear graduations.
08372     Errors:     Out of memory.
08373     SeeAlso:    AttributeManager
08374 
08375 ********************************************************************************************/
08376 
08377 BOOL TranspFillMappingAttribute::Init()
08378 {
08379     // Default to simple linear mapping (ignored for flat fills, obviously)
08380     TranspFillMappingAttribute *pAttr = new TranspFillMappingLinearAttribute;
08381     if (pAttr==NULL)
08382         // error message has already been set by new
08383         return FALSE;
08384 
08385     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
08386                                                          pAttr);
08387     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising TranspFillMappingAttribute");
08388     ERROR2IF(ID != ATTR_TRANSPFILLMAPPING, FALSE, "Incorrect ID for TranspFillMappingAttribute");
08389 
08390     return TRUE;
08391 }
08392 
08393 /********************************************************************************************
08394 
08395 >   void TranspFillMappingAttribute::SimpleCopy(AttributeValue *pValue)
08396 
08397     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08398     Created:    23/11/94
08399     Inputs:     pAttr - pointer to the AttributeValue to copy.
08400     Purpose:    See AttributeValue::SimpleCopy
08401 
08402 ********************************************************************************************/
08403 
08404 void TranspFillMappingAttribute::SimpleCopy(AttributeValue *pValue)
08405 {
08406     Repeat = ((TranspFillMappingAttribute *) pValue)->Repeat;
08407 }
08408 
08409 /********************************************************************************************
08410 
08411 >   void TranspFillMappingAttribute::Render(RenderRegion *pRegion)
08412 
08413     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08414     Created:    23/8/94
08415     Inputs:     pRegion - the render region to render this attribute into.
08416     Purpose:    Sets the fill type attribute for the given render region. i.e. all
08417                 paths filled will now be filled with this fill attribute.
08418     SeeAlso:    FillMappingAttribute; RenderStack; AttributeValue; NodeAttribute;
08419                 FillMappingAttribute::Restore;
08420                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08421 
08422 ********************************************************************************************/
08423 
08424 void TranspFillMappingAttribute::Render(RenderRegion *pRegion, BOOL Temp)
08425 {
08426     pRegion->SetTranspFillMapping(this, Temp);
08427 }
08428 
08429 /********************************************************************************************
08430 
08431 >   void TranspFillMappingAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08432 
08433     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08434     Created:    23/8/94
08435     Inputs:     pRegion - the render region to restore the attribute into.
08436                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
08437                           permanent (e.g. it's in a document tree).
08438     Purpose:    Restores the fill type attribute for the given render region. i.e. all
08439                 paths filled will now be filled with this fill attribute.
08440     SeeAlso:    FillMappingAttribute; RenderStack; AttributeValue; NodeAttribute;
08441                 FillMappingAttribute::Render;
08442                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08443 
08444 ********************************************************************************************/
08445 
08446 void TranspFillMappingAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08447 {
08448     pRegion->RestoreTranspFillMapping(this, Temp);
08449 }
08450 
08451 BOOL TranspFillMappingAttribute::IsDifferent(AttributeValue* pVal)
08452 {
08453     if (pVal->GetRuntimeClass() != GetRuntimeClass())
08454         return TRUE;
08455 
08456     return (Repeat != ((TranspFillMappingAttribute*)pVal)->Repeat);
08457 }
08458 
08459 TranspFillMappingAttribute& TranspFillMappingAttribute::operator=(TranspFillMappingAttribute& Attrib)
08460 {
08461     Repeat = Attrib.Repeat;
08462 
08463     return *this;
08464 }
08465 
08466 INT32 TranspFillMappingAttribute::operator==(const TranspFillMappingAttribute& Attrib)
08467 {
08468     if (Attrib.GetRuntimeClass() != GetRuntimeClass())
08469         return FALSE;
08470 
08471     return (Repeat == Attrib.Repeat);
08472 }
08473 
08474 
08475 // These create a non-transparent version of the relevant fillmapping for use by
08476 // the airbrush / stroking stuff
08477 
08478 FillMappingAttribute *TranspFillMappingAttribute::MakeSimilarNonTranspFillMapping(void)
08479 {
08480     FillMappingAttribute *pNewAttr = new FillMappingAttribute;  
08481     if (pNewAttr != NULL)
08482     {
08483         pNewAttr->Repeat = Repeat;
08484     }
08485 
08486     return pNewAttr;
08487 }
08488 
08489 FillMappingAttribute *TranspFillMappingSinAttribute::MakeSimilarNonTranspFillMapping(void)
08490 {
08491     FillMappingSinAttribute *pNewAttr = new FillMappingSinAttribute;    
08492     if (pNewAttr != NULL)
08493     {
08494         pNewAttr->Repeat = Repeat;
08495     }
08496 
08497     return pNewAttr;
08498 }
08499 
08500 FillMappingAttribute *TranspFillMappingLinearAttribute::MakeSimilarNonTranspFillMapping(void)
08501 {
08502     FillMappingLinearAttribute *pNewAttr = new FillMappingLinearAttribute;  
08503     if (pNewAttr != NULL)
08504     {
08505         pNewAttr->Repeat = Repeat;
08506     }
08507 
08508     return pNewAttr;
08509 }
08510 
08511 /********************************************************************************************
08512 
08513 >   NodeAttribute *TranspFillMappingLinearAttribute::MakeNode()
08514 
08515     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08516     Created:    23/8/94
08517     Returns:    Pointer to the new node, or NULL if out of memory.
08518     Purpose:    Make a AttrFillMappingLinear node from this fill mapping attribute.
08519     Errors:     Out of memory
08520     SeeAlso:    AttributeValue::MakeNode
08521 
08522 ********************************************************************************************/
08523 
08524 NodeAttribute *TranspFillMappingLinearAttribute::MakeNode()
08525 {
08526     // Create new attribute node
08527     AttrTranspFillMappingLinear *pAttr = new AttrTranspFillMappingLinear();
08528     if (pAttr==NULL)
08529         // error message has already been set by new
08530         return NULL;
08531 
08532     // Copy attribute value into the new node.
08533     pAttr->Value.SimpleCopy(this);
08534 
08535     // Return the new node
08536     return pAttr;
08537 }
08538 
08539 /********************************************************************************************
08540 
08541 >   NodeAttribute *TranspFillMappingSinAttribute::MakeNode()
08542 
08543     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08544     Created:    23/8/94
08545     Returns:    Pointer to the new node, or NULL if out of memory.
08546     Purpose:    Make a AttrFillMappingSin node from this fill mapping attribute.
08547     Errors:     Out of memory
08548     SeeAlso:    AttributeValue::MakeNode
08549 
08550 ********************************************************************************************/
08551 
08552 NodeAttribute *TranspFillMappingSinAttribute::MakeNode()
08553 {
08554     // Create new attribute node
08555     AttrTranspFillMappingSin *pAttr = new AttrTranspFillMappingSin();
08556     if (pAttr==NULL)
08557         // error message has already been set by new
08558         return NULL;
08559 
08560     // Copy attribute value into the new node.
08561     pAttr->Value.SimpleCopy(this);
08562 
08563     // Return the new node
08564     return pAttr;
08565 }
08566 
08567 
08568 
08569 
08570 
08571 
08572 /********************************************************************************************
08573 
08574 >   StrokeColourAttribute::StrokeColourAttribute(DocColour& NewCol)
08575 
08576     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08577     Created:    03/02/94
08578     Inputs:     NewCol - the new stroke colour
08579     Purpose:    Sets the line colour for this attribute.
08580 
08581 ********************************************************************************************/
08582 
08583 StrokeColourAttribute::StrokeColourAttribute(DocColour& NewCol)
08584 {
08585     SetStartColour(&NewCol);
08586 }
08587 
08588 /********************************************************************************************
08589 
08590 >   void StrokeColourAttribute::Render(RenderRegion *pRegion)
08591 
08592     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08593     Created:    03/02/94
08594     Inputs:     pRegion - the render region to render this attribute into.
08595     Purpose:    Sets the line colour attribute for the given render region. i.e. all
08596                 lines drawn will now be drawn in this colour.
08597     SeeAlso:    StrokeColourAttribute; RenderStack; AttributeValue; NodeAttribute;
08598                 StrokeColourAttribute::Restore; StrokeColourAttribute::SimpleCopy;
08599                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08600 
08601 ********************************************************************************************/
08602 
08603 void StrokeColourAttribute::Render(RenderRegion *pRegion, BOOL Temp)
08604 {
08605     pRegion->SetLineColour(this, Temp);
08606 }
08607 
08608 /********************************************************************************************
08609 
08610 >   void StrokeColourAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08611 
08612     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08613     Created:    03/02/94
08614     Inputs:     pRegion - the render region to restore the attribute into.
08615                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
08616                           permanent (e.g. it's in a document tree).
08617     Purpose:    Restores the line colour attribute for the given render region. i.e. all
08618                 lines drawn will now be drawn in this colour.
08619     SeeAlso:    StrokeColourAttribute; RenderStack; AttributeValue; NodeAttribute;
08620                 StrokeColourAttribute::Render; StrokeColourAttribute::SimpleCopy;
08621                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08622 
08623 ********************************************************************************************/
08624 
08625 void StrokeColourAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08626 {
08627     pRegion->RestoreLineColour(this, Temp);
08628 }
08629 
08630 /********************************************************************************************
08631 
08632 >   NodeAttribute *StrokeColourAttribute::MakeNode()
08633 
08634     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08635     Created:    11/04/94
08636     Returns:    Pointer to the new node, or NULL if out of memory.
08637     Purpose:    Make a AttrStrokeColour node from this fill colour attribute.
08638     Errors:     Out of memory
08639     SeeAlso:    AttributeValue::MakeNode
08640 
08641 ********************************************************************************************/
08642 
08643 NodeAttribute *StrokeColourAttribute::MakeNode()
08644 {
08645     // Create new attribute node
08646     AttrStrokeColour *pAttr = new AttrStrokeColour();
08647 
08648     // Copy attribute value into the new node.
08649     pAttr->Value.SimpleCopy(this);
08650 
08651     // Return the new node
08652     return pAttr;
08653 }
08654 
08655 /********************************************************************************************
08656 
08657 >   void StrokeColourAttribute::SimpleCopy(AttributeValue *pValue)
08658 
08659     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08660     Created:    03/02/94
08661     Inputs:     pAttr - pointer to the AttributeValue to copy.
08662     Purpose:    See AttributeValue::SimpleCopy
08663     SeeAlso:    FillColourAttribute; RenderStack; AttributeValue; NodeAttribute;
08664                 FillColourAttribute::Render; FillColourAttribute::Restore;
08665                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08666 
08667 ********************************************************************************************/
08668 
08669 void StrokeColourAttribute::SimpleCopy(AttributeValue *pValue)
08670 {
08671     Colour = ((StrokeColourAttribute *) pValue)->Colour;
08672 }
08673 
08674 /********************************************************************************************
08675 
08676 >   BOOL StrokeColourAttribute::Init()
08677 
08678     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08679     Created:    11/04/94
08680     Returns:    TRUE - initialised ok; FALSE if not.
08681     Purpose:    Registers line colour attribute, and provides a default attribute to give
08682                 black lines.
08683     Errors:     Out of memory.
08684     SeeAlso:    AttributeManager
08685 
08686 ********************************************************************************************/
08687 
08688 BOOL StrokeColourAttribute::Init()
08689 {
08690     // Default to black lines
08691     StrokeColourAttribute *pAttr = new StrokeColourAttribute;
08692     if (pAttr == NULL)
08693         return FALSE;
08694 
08695     AttributeManager::FindDefaultColour( ColourManager::GetCurrentColourList(),
08696                                         _R(IDS_BLACKNAME), &pAttr->Colour );
08697 
08698 //  pAttr->Colour = AttributeManager::DefaultBlack;
08699     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
08700                                                          pAttr);
08701     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising StrokeColourAttribute");
08702     ERROR2IF(ID != ATTR_STROKECOLOUR, FALSE, "Incorrect ID for StrokeColourAttribute");
08703 
08704     return TRUE;
08705 }
08706 
08707 
08708 
08709 
08710 
08711 
08712 
08713 /********************************************************************************************
08714 
08715 >   StrokeTranspAttribute::StrokeTranspAttribute(UINT32 NewTransp)
08716 
08717     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08718     Created:    03/02/94
08719     Inputs:     NewTransp - the new stroke transparency
08720     Purpose:    Sets the line transparency for this attribute.
08721 
08722 ********************************************************************************************/
08723 
08724 StrokeTranspAttribute::StrokeTranspAttribute(UINT32 NewTransp)
08725 {
08726     SetStartTransp(&NewTransp);
08727 }
08728 
08729 /********************************************************************************************
08730 
08731 >   void StrokeTranspAttribute::Render(RenderRegion *pRegion)
08732 
08733     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08734     Created:    30/11/94
08735     Inputs:     pRegion - the render region to render this attribute into.
08736     Purpose:    Sets the line colour attribute for the given render region. i.e. all
08737                 lines drawn will now be drawn in this colour.
08738     SeeAlso:    StrokeTranspAttribute; RenderStack; AttributeValue; NodeAttribute;
08739                 StrokeTranspAttribute::Restore; StrokeTranspAttribute::SimpleCopy;
08740                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08741 
08742 ********************************************************************************************/
08743 
08744 void StrokeTranspAttribute::Render(RenderRegion *pRegion, BOOL Temp)
08745 {
08746     pRegion->SetLineTransp(this, Temp);
08747 }
08748 
08749 /********************************************************************************************
08750 
08751 >   void StrokeTranspAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08752 
08753     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08754     Created:    03/02/94
08755     Inputs:     pRegion - the render region to restore the attribute into.
08756                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
08757                           permanent (e.g. it's in a document tree).
08758     Purpose:    Restores the line colour attribute for the given render region. i.e. all
08759                 lines drawn will now be drawn in this colour.
08760     SeeAlso:    StrokeTranspAttribute; RenderStack; AttributeValue; NodeAttribute;
08761                 StrokeTranspAttribute::Render; StrokeTranspAttribute::SimpleCopy;
08762                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08763 
08764 ********************************************************************************************/
08765 
08766 void StrokeTranspAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
08767 {
08768     pRegion->RestoreLineTransp(this, Temp);
08769 }
08770 
08771 /********************************************************************************************
08772 
08773 >   NodeAttribute *StrokeTranspAttribute::MakeNode()
08774 
08775     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08776     Created:    11/04/94
08777     Returns:    Pointer to the new node, or NULL if out of memory.
08778     Purpose:    Make a AttrStrokeTransp node from this fill colour attribute.
08779     Errors:     Out of memory
08780     SeeAlso:    AttributeValue::MakeNode
08781 
08782 ********************************************************************************************/
08783 
08784 NodeAttribute *StrokeTranspAttribute::MakeNode()
08785 {
08786     // Create new attribute node
08787     AttrStrokeTransp *pAttr = new AttrStrokeTransp();
08788 
08789     // Copy attribute value into the new node.
08790     pAttr->Value.SimpleCopy(this);
08791 
08792     // Return the new node
08793     return pAttr;
08794 }
08795 
08796 /********************************************************************************************
08797 
08798 >   void StrokeTranspAttribute::SimpleCopy(AttributeValue *pValue)
08799 
08800     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08801     Created:    03/02/94
08802     Inputs:     pAttr - pointer to the AttributeValue to copy.
08803     Purpose:    See AttributeValue::SimpleCopy
08804     SeeAlso:    FillColourAttribute; RenderStack; AttributeValue; NodeAttribute;
08805                 FillColourAttribute::Render; FillColourAttribute::Restore;
08806                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
08807 
08808 ********************************************************************************************/
08809 
08810 void StrokeTranspAttribute::SimpleCopy(AttributeValue *pValue)
08811 {
08812     Transp = ((StrokeTranspAttribute *) pValue)->Transp;
08813     TranspType = ((StrokeTranspAttribute *) pValue)->TranspType;
08814 }
08815 
08816 /********************************************************************************************
08817 
08818 >   BOOL StrokeTranspAttribute::Init()
08819 
08820     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
08821     Created:    11/04/94
08822     Returns:    TRUE - initialised ok; FALSE if not.
08823     Purpose:    Registers line colour attribute, and provides a default attribute to give
08824                 black lines.
08825     Errors:     Out of memory.
08826     SeeAlso:    AttributeManager
08827 
08828 ********************************************************************************************/
08829 
08830 BOOL StrokeTranspAttribute::Init()
08831 {
08832     // Default to black lines
08833     StrokeTranspAttribute *pAttr = new StrokeTranspAttribute;
08834     if (pAttr == NULL)
08835         return FALSE;
08836 
08837     pAttr->Transp = 0;
08838     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
08839                                                          pAttr);
08840     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising StrokeTranspAttribute");
08841     ERROR2IF(ID != ATTR_STROKETRANSP, FALSE, "Incorrect ID for StrokeTranspAttribute");
08842 
08843     return TRUE;
08844 }
08845 
08846 
08847 
08848 /********************************************************************************************
08849 
08850         Mouldy bits
08851 
08852 ********************************************************************************************/
08853 
08854 /********************************************************************************************
08855 
08856 >   INT32 FillGeometryAttribute::Mould(AttrMould* pMouldAttr, DocCoord* pOutputCoords, INT32 NumCoords)
08857 
08858     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
08859     Created:    14/03/95
08860     Purpose:    Moulds a Fill attribute
08861 
08862 ********************************************************************************************/
08863 
08864 INT32 FillGeometryAttribute::Mould( MouldAttribute* pMouldAttr,
08865                                     DocCoord* SourcePoints, INT32 NumCoords,
08866                                     DocCoord* OutputCoords  )
08867 {
08868     if (pMouldAttr == NULL || pMouldAttr->GetMouldShape() == NULL)
08869         return 0;
08870 
08871     if (pMouldAttr->IsPerspective() && NumCoords >= 4)  // Is it a perspective mould ?
08872     {
08873         // Yes, so we'll need to make a fourth control point
08874         INT32 dx1 = SourcePoints[1].x - SourcePoints[0].x;
08875         INT32 dx2 = SourcePoints[2].x - SourcePoints[0].x;
08876 
08877         INT32 dy1 = SourcePoints[1].y - SourcePoints[0].y;
08878         INT32 dy2 = SourcePoints[2].y - SourcePoints[0].y;
08879 
08880         SourcePoints[3] = SourcePoints[2];
08881 
08882         SourcePoints[2].x = SourcePoints[0].x + dx1 + dx2;      
08883         SourcePoints[2].y = SourcePoints[0].y + dy1 + dy2;
08884     }
08885 
08886     // Lets get the mould geometry
08887     MouldGeometry* pMould = pMouldAttr->GetMouldShape();
08888     if (pMould == NULL)
08889         return 0;
08890 
08891     // If it's a perspective mould, then we need 4 Control points,
08892     // otherwise just 3 are needed.
08893     INT32 MouldPoints = pMouldAttr->IsPerspective() ? 4 : 3;
08894 
08895     // Ensure we don't overrun the output array
08896     if (MouldPoints > NumCoords)
08897         MouldPoints = NumCoords;
08898 
08899     // It is possible for a point to fail to Mould,
08900     // (eg if it's outside the Mould Bounds),
08901     // so we'll keep an array of BOOL's to say whether
08902     // each point moulded ok or not.
08903     BOOL* PointOK = new BOOL[MouldPoints];
08904 
08905     Node* MouldParent = pMouldAttr->GetParentMould();
08906     while (pMould != NULL)
08907     {
08908         BOOL AllPointsOK = TRUE;
08909         
08910         for ( INT32 point = 0; point < MouldPoints; point++)
08911         {
08912             // Mould each points in turn
08913             if (pMould->MouldPoint(SourcePoints[point], OutputCoords[point]))
08914             {
08915                 // The point moulded ok
08916                 PointOK[point] = TRUE;
08917             }
08918             else
08919             {
08920                 // The point failed to mould
08921                 PointOK[point] = FALSE;
08922                 AllPointsOK = FALSE;
08923             }
08924         }
08925 
08926         if (!AllPointsOK)
08927         {
08928             // One or more of the control points failed to mould,
08929             // (probably because it is outside the bounds of the mould)
08930             // so we will make sure it is sensible.
08931             TidyMouldPoints(SourcePoints, OutputCoords, PointOK, MouldPoints);
08932         }
08933 
08934         // Now lets have a look at the parent of the Mould
08935         MouldParent = MouldParent->FindParent();
08936 
08937         while (MouldParent != NULL)
08938         {
08939             if ( IS_A(MouldParent,NodeMould) )      // Is the Parent another Mould ?
08940             {
08941                 // This mould has been moulded itself, so get the parent
08942                 // mould geometry, and transform all the points again
08943                 pMould = ((NodeMould*)MouldParent)->GetGeometry();
08944 
08945                 // We're going to transform the transformed points
08946                 for ( INT32 point = 0; point < MouldPoints; point++)
08947                 {
08948                     SourcePoints[point] = OutputCoords[point];
08949                 }
08950     
08951                 break;  // Get out of this loop
08952             }           
08953 
08954             if (MouldParent->IsLayer()) // Have we reached the parent Layer yet ?
08955             {
08956                 // There can't be any more Moulds now !
08957                 pMould = NULL;
08958                 break;
08959             }           
08960             else
08961             {
08962                 // Try the next parent
08963                 MouldParent = MouldParent->FindParent();
08964             }
08965         }
08966     }
08967 
08968     delete PointOK;     // Delete the array of BOOL's
08969 
08970     return MouldPoints; // Return the number of Points Moulded
08971 }
08972 
08973 
08974 
08975 /********************************************************************************************
08976 
08977 >   virtual AttributeValue *FillGeometryAttribute::MouldIntoStroke(PathStrokerVector *pMoulder,
08978                                                                             double TransScale);
08979     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
08980     Created:    23/2/97
08981 
08982     Inputs:     pMoulder    - A PathStrokerVector which knows how to translate points to "mould" them
08983                               (May be NULL, in which case moulding of points does not occur)
08984 
08985                 TransScale  - A fraction between 0.0 and 1.0, by which any transparency
08986                               values in this geometry will be scaled, allowing the caller to
08987                               effectively apply a flat transparency level to everything that is
08988                               moulded. Use 1.0 to leave transparency unaltered.
08989 
08990     Returns:    NULL if the original attribute can be used, else
08991                 A pointer to a copy of this object, suitably moulded and adjusted for
08992                 the transparency scaling. The caller must delete the copy when finished
08993                 with it.
08994 
08995     Purpose:    Helper function for the PathStrokerVector class, which "moulds" clipart
08996                 subtrees to lie along an arbitrary path.
08997 
08998                 This function is called to mould fill geometries, so that fill endpoints
08999                 are translated to appropriate positions in the destination envelope, and
09000                 allows the caller to effectively apply a flat transparency by scaling
09001                 any transparency values in this geometry by the given fraction.
09002 
09003 ********************************************************************************************/
09004 
09005 AttributeValue *FillGeometryAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale)
09006 {
09007 // Taken out of WEBSTER Neville 6/8/97
09008 // Taken out by vector stroking code Neville 2/10/97
09009 #ifdef VECTOR_STROKING
09010     FillGeometryAttribute *pCopy = (FillGeometryAttribute *) GetRuntimeClass()->CreateObject();
09011     if (pCopy != NULL)
09012     {
09013         // Copy this object's values across
09014         *pCopy = *this;
09015 
09016         // And mould all of the geometry points across
09017         if (pMoulder != NULL)
09018         {
09019             JCW_MOULDPOINT(pCopy, StartPoint);
09020             JCW_MOULDPOINT(pCopy, EndPoint);
09021             JCW_MOULDPOINT(pCopy, EndPoint2);
09022             JCW_MOULDPOINT(pCopy, EndPoint3);
09023         }
09024 
09025         ERROR3IF(TransScale < 0.0 || TransScale > 1.0, "Out of range TransScale parameter");
09026         if (TransScale >= 0.0 && TransScale < 1.0)
09027         {
09028             JCW_MOULDTRANS(pCopy, StartTransp);
09029             JCW_MOULDTRANS(pCopy, EndTransp);
09030             JCW_MOULDTRANS(pCopy, EndTransp2);
09031             JCW_MOULDTRANS(pCopy, EndTransp3);
09032         }
09033     }
09034 
09035     return(pCopy);
09036 #else
09037     return NULL;
09038 #endif // VECTOR_STROKING
09039 }
09040 
09041 
09042 
09043 /********************************************************************************************
09044 
09045 >   void FillGeometryAttribute::TidyMouldPoints(DocCoord* SrcPoints, DocCoord* DestPoints, 
09046                                                 BOOL* PointOK, INT32 MouldPoints)
09047     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09048     Created:    14/03/95
09049     Purpose:    Tidies up control points that fail to mould correctly
09050 
09051 ********************************************************************************************/
09052 
09053 void FillGeometryAttribute::TidyMouldPoints(DocCoord* SrcPoints, DocCoord* DestPoints, 
09054                                             BOOL* PointOK, INT32 MouldPoints)
09055 {
09056     if (!PointOK[0])  // Did the Start Point transform ?
09057     {
09058         if (PointOK[1]) // So, did the End Point transform ?
09059         {
09060             // Work out how the End Point moved
09061             INT32 dx = DestPoints[1].x - SrcPoints[1].x;            
09062             INT32 dy = DestPoints[1].y - SrcPoints[1].y;            
09063 
09064             // and move the start point the same amount
09065             DestPoints[0] = SrcPoints[0];
09066             DestPoints[0].translate(dx,dy);
09067         }
09068         else if (PointOK[2])
09069         {
09070             // Work out how the End2 Point moved
09071             INT32 dx = DestPoints[2].x - SrcPoints[2].x;            
09072             INT32 dy = DestPoints[2].y - SrcPoints[2].y;            
09073 
09074             // and move the start point the same amount
09075             DestPoints[0] = SrcPoints[0];
09076             DestPoints[0].translate(dx,dy);
09077         }
09078     }
09079 
09080     if (!PointOK[1])
09081     {
09082         if (PointOK[0]) // So, did the Start Point transform ?
09083         {
09084             // Work out how the Start Point moved
09085             INT32 dx = DestPoints[0].x - SrcPoints[0].x;            
09086             INT32 dy = DestPoints[0].y - SrcPoints[0].y;            
09087 
09088             // and move the end point the same amount
09089             DestPoints[1] = SrcPoints[1];
09090             DestPoints[1].translate(dx,dy);
09091         }
09092         else if (PointOK[2])
09093         {
09094             // Work out how the End2 Point moved
09095             INT32 dx = DestPoints[2].x - SrcPoints[2].x;            
09096             INT32 dy = DestPoints[2].y - SrcPoints[2].y;            
09097 
09098             // and move the end point the same amount
09099             DestPoints[1] = SrcPoints[1];
09100             DestPoints[1].translate(dx,dy);
09101         }
09102     }
09103 
09104     if (!PointOK[2])
09105     {
09106         if (PointOK[0]) // So, did the Start Point transform ?
09107         {
09108             // Work out how the Start Point moved
09109             INT32 dx = DestPoints[0].x - SrcPoints[0].x;            
09110             INT32 dy = DestPoints[0].y - SrcPoints[0].y;            
09111 
09112             // and move the end2 point the same amount
09113             DestPoints[2] = SrcPoints[2];
09114             DestPoints[2].translate(dx,dy);
09115         }
09116         else if (PointOK[1])
09117         {
09118             // Work out how the End Point moved
09119             INT32 dx = DestPoints[1].x - SrcPoints[1].x;            
09120             INT32 dy = DestPoints[1].y - SrcPoints[1].y;            
09121 
09122             // and move the end2 point the same amount
09123             DestPoints[2] = SrcPoints[2];
09124             DestPoints[2].translate(dx,dy);
09125         }
09126     }
09127 
09128     if (MouldPoints>3 && !PointOK[3])
09129     {
09130         TRACEUSER( "Mike", _T("Perspective Point failed to mould\n"));
09131     }
09132 }
09133 
09134 /********************************************************************************************
09135 
09136 >   MouldAttribute::MouldAttribute()
09137 
09138     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09139     Created:    03/02/94
09140     Purpose:    Default constructor for Mould Attribute.
09141 
09142 ********************************************************************************************/
09143 
09144 MouldAttribute::MouldAttribute()
09145 {
09146     SetParentMould(NULL);
09147     SetMouldShape(NULL);
09148 }
09149 
09150 /********************************************************************************************
09151 
09152 >   MouldAttribute::MouldAttribute(NodeMould* pMould, MouldGeometry* pMouldShape)
09153 
09154     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09155     Created:    03/02/94
09156     Inputs:     pMould - the Mould to associate with this attribute
09157     Purpose:    Constructor for Mould attribute.
09158 
09159 ********************************************************************************************/
09160 
09161 MouldAttribute::MouldAttribute(NodeMould* pMould, MouldGeometry* pMouldShape)
09162 {
09163     SetParentMould(pMould);
09164     SetMouldShape(pMouldShape);
09165 }
09166 
09167 /********************************************************************************************
09168 
09169 >   void MouldAttribute::Render(RenderRegion *pRegion)
09170 
09171     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09172     Created:    30/11/94
09173     Inputs:     pRegion - the render region to render this attribute into.
09174     Purpose:    Sets the line colour attribute for the given render region. i.e. all
09175                 lines drawn will now be drawn in this colour.
09176     SeeAlso:    MouldAttribute; RenderStack; AttributeValue; NodeAttribute;
09177                 MouldAttribute::Restore; MouldAttribute::SimpleCopy;
09178                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
09179 
09180 ********************************************************************************************/
09181 
09182 void MouldAttribute::Render(RenderRegion *pRegion, BOOL Temp)
09183 {
09184 //  pRegion->SetMould(this, Temp);
09185 }
09186 
09187 /********************************************************************************************
09188 
09189 >   void MouldAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
09190 
09191     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09192     Created:    03/02/94
09193     Inputs:     pRegion - the render region to restore the attribute into.
09194                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
09195                           permanent (e.g. it's in a document tree).
09196     Purpose:    Restores the line colour attribute for the given render region. i.e. all
09197                 lines drawn will now be drawn in this colour.
09198     SeeAlso:    MouldAttribute; RenderStack; AttributeValue; NodeAttribute;
09199                 MouldAttribute::Render; MouldAttribute::SimpleCopy;
09200                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
09201 
09202 ********************************************************************************************/
09203 
09204 void MouldAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
09205 {
09206 //  pRegion->RestoreMould(this, Temp);
09207 }
09208 
09209 /********************************************************************************************
09210 
09211 >   NodeAttribute *MouldAttribute::MakeNode()
09212 
09213     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09214     Created:    11/04/94
09215     Returns:    Pointer to the new node, or NULL if out of memory.
09216     Purpose:    Make a AttrMould node from this fill colour attribute.
09217     Errors:     Out of memory
09218     SeeAlso:    AttributeValue::MakeNode
09219 
09220 ********************************************************************************************/
09221 
09222 NodeAttribute *MouldAttribute::MakeNode()
09223 {
09224     // Create new attribute node
09225     AttrMould *pAttr = new AttrMould();
09226 
09227     // Copy attribute value into the new node.
09228     pAttr->Value.SimpleCopy(this);
09229 
09230     // Return the new node
09231     return pAttr;
09232 }
09233 
09234 /********************************************************************************************
09235 
09236 >   void MouldAttribute::SimpleCopy(AttributeValue *pValue)
09237 
09238     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09239     Created:    03/02/94
09240     Inputs:     pAttr - pointer to the AttributeValue to copy.
09241     Purpose:    See AttributeValue::SimpleCopy
09242     SeeAlso:    FillColourAttribute; RenderStack; AttributeValue; NodeAttribute;
09243                 FillColourAttribute::Render; FillColourAttribute::Restore;
09244                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
09245 
09246 ********************************************************************************************/
09247 
09248 void MouldAttribute::SimpleCopy(AttributeValue *pValue)
09249 {
09250     ERROR3IF(!pValue->IsKindOf(CC_RUNTIME_CLASS(MouldAttribute)), "MouldAttribute::SimpleCopy can only copy MouldAttributes");
09251     SetParentMould(((MouldAttribute*)pValue)->GetParentMould());
09252     SetMouldShape(((MouldAttribute*)pValue)->GetMouldShape());
09253 }
09254 
09255 /********************************************************************************************
09256 
09257 >   BOOL MouldAttribute::Init()
09258 
09259     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09260     Created:    11/04/94
09261     Returns:    TRUE - initialised ok; FALSE if not.
09262     Purpose:    Registers line colour attribute, and provides a default attribute to give
09263                 black lines.
09264     Errors:     Out of memory.
09265     SeeAlso:    AttributeManager
09266 
09267 ********************************************************************************************/
09268 
09269 BOOL MouldAttribute::Init()
09270 {
09271     // Default to no Mould
09272     MouldAttribute *pAttr = new MouldAttribute;
09273     if (pAttr == NULL)
09274         return FALSE;
09275 
09276     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
09277                                                          pAttr);
09278     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising MouldAttribute");
09279     ERROR2IF(ID != ATTR_MOULD, FALSE, "Incorrect ID for MouldAttribute");
09280 
09281     return TRUE;
09282 }
09283 
09284 /********************************************************************************************
09285 
09286 >   void MouldAttribute::SetMouldShape(MouldGeometry* pMould)
09287 
09288     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09289     Created:    13/03/95
09290     Purpose:    Set the mould shape associated with this Attr.
09291 
09292 ********************************************************************************************/
09293 
09294 void MouldAttribute::SetMouldShape(MouldGeometry* pMould)
09295 {
09296     pMouldShape = pMould;
09297     IsPerspectiveMould = FALSE;
09298 
09299     if (pMouldShape == NULL)
09300         return;
09301 
09302     if (pMouldShape->IsKindOf(CC_RUNTIME_CLASS(MouldPerspective)))
09303     {
09304         IsPerspectiveMould = TRUE;
09305     }
09306 }
09307 
09308 /********************************************************************************************
09309 
09310 >   void MouldAttribute::SetParentMould(NodeMould* pMould)
09311 
09312     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09313     Created:    13/03/95
09314     Purpose:    Set the parent mould associated with this Attr.
09315 
09316 ********************************************************************************************/
09317 
09318 void MouldAttribute::SetParentMould(NodeMould* pMould)
09319 {
09320     pParentMould = pMould;
09321 }
09322 
09323 /********************************************************************************************
09324 
09325         Blendy bits
09326 
09327 ********************************************************************************************/
09328 
09329 /********************************************************************************************
09330 
09331 >   BOOL FillGeometryAttribute::Blend(BlendAttrParam* pBlendParam)
09332 
09333     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09334     Created:    28/11/94
09335     Returns:    TRUE - Blend went ok, the blended attr val is valid; FALSE if not.
09336     Purpose:    Blends between two fill attributes.
09337                 This is a general blend function for all fill attributes.
09338                 It will blend between any types of fill, but will always use the 'type'
09339                 of the first fill, taking control points, colours, and transparency
09340                 from the end fill if it can.
09341 
09342     Errors:     Out of memory.
09343     SeeAlso:    FillGeometryAttribute::BlendFillColours;
09344                 FillGeometryAttribute::BlendFillTransp;
09345                 FillGeometryAttribute::BlendControlPoints;
09346                 FlatFillAttribute::Blend;
09347                 GradFillAttribute::Blend
09348 
09349 ********************************************************************************************/
09350 
09351 BOOL FillGeometryAttribute::Blend(BlendAttrParam* pBlendParam)
09352 {
09353     // First make a new object of the same type as this one
09354     CCRuntimeClass* ObjectType = GetRuntimeClass();
09355     FillGeometryAttribute* pNewAttr = (FillGeometryAttribute*)ObjectType->CreateObject();
09356 
09357     if (pNewAttr == NULL)
09358     {
09359         // Fail if we couldn't create the new fill
09360         pBlendParam->SetBlendedAttrVal(NULL);
09361         return FALSE;
09362     }
09363 
09364     // Make the new fill an exact copy of this one
09365     pNewAttr->SimpleCopy(this);
09366 
09367     // Now get the fill that we are blending to
09368     FillGeometryAttribute* OtherFill = 
09369                 (FillGeometryAttribute*)pBlendParam->GetOtherAttrVal();
09370 
09371     // and what point along the blend we are at
09372     double Ratio = pBlendParam->GetBlendRatio();
09373     double objectRatio = pBlendParam->GetObjectRatio();
09374 
09375     // Blend the profiles (if there are any ....)
09376 
09377     CProfileBiasGain Default;
09378     
09379     CProfileBiasGain BiasGain = DiagramMapper;                      // the first fills profile
09380     CProfileBiasGain OtherBiasGain = OtherFill->DiagramMapper;      // the other fills profile
09381 
09382     // only blend profiles if we need to ....
09383 
09384     if (!((BiasGain == Default) && (OtherBiasGain == Default)))
09385     {
09386         // then we need to blend the profiles ....
09387 
09388         CProfileBiasGain BlendedProfile;                            // test for now ....
09389 
09390         double InvRatio = 1 - Ratio;
09391         double BlendedBias = (BiasGain.GetBias () * InvRatio) + (OtherBiasGain.GetBias () * Ratio);
09392         double BlendedGain = (BiasGain.GetGain () * InvRatio) + (OtherBiasGain.GetGain () * Ratio);
09393 
09394         BlendedProfile.SetBias (BlendedBias);
09395         BlendedProfile.SetGain (BlendedGain);
09396 
09397         pNewAttr->SetProfile (BlendedProfile);
09398     }
09399 
09400     // CGS:  don't worry if pNewAttr->GetColourRamp () is NULL, this is handled internally by pNewAttr->GetColourRamp ()->Blend ()
09401     // (even if it is NULL, this code is still perfectly valid:  it means blend a no0n-multi-stage fill to something ....)
09402     pNewAttr->GetColourRamp ()->Blend (pNewAttr, pBlendParam, OtherFill/*->GetColourRamp ()*/);
09403 
09404     // Blend the Start and End Colours
09405     DocColour BlendColour;
09406 
09407     DocColour* StartCol         = GetStartColour();
09408     DocColour* OtherStartCol    = OtherFill->GetStartColour();
09409     DocColour* EndCol           = GetEndColour();
09410     DocColour* OtherEndCol      = OtherFill->GetEndColour();
09411     DocColour* EndCol2          = GetEndColour2();
09412     DocColour* OtherEndCol2     = OtherFill->GetEndColour2();
09413     DocColour* EndCol3          = GetEndColour3();
09414     DocColour* OtherEndCol3     = OtherFill->GetEndColour3();
09415     DocColour* NonNullCol       = NULL;
09416     DocColour* OtherNonNullCol  = NULL;
09417 
09418     DocColour TempStartCol;
09419     DocColour TempEndCol;
09420     DocColour TempOtherStartCol;
09421     DocColour TempOtherEndCol;
09422 
09423     // Check for a Greyscale Bitmap fill with no start or end colours
09424     // and use Black and White instead of 'No Colour'
09425     if (IsABitmapFill() && StartCol == NULL && EndCol == NULL)
09426     {
09427         if (GetBitmapRef() != NULL)
09428         {
09429             if (CheckForGreyscaleBitmapBlend(GetBitmapRef()->GetBitmap(), &TempStartCol, &TempEndCol))
09430             {
09431                 StartCol    = &TempStartCol;
09432                 EndCol      = &TempEndCol;
09433             }
09434         }
09435     }
09436 
09437     // Same as above, but for the 'Other Fill'
09438     if (OtherFill->IsABitmapFill() && OtherStartCol == NULL && OtherEndCol == NULL)
09439     {
09440         if (OtherFill->GetBitmapRef() != NULL)
09441         {
09442             if (CheckForGreyscaleBitmapBlend(OtherFill->GetBitmapRef()->GetBitmap(), &TempOtherStartCol, &TempOtherEndCol))
09443             {
09444                 OtherStartCol   = &TempOtherStartCol;
09445                 OtherEndCol     = &TempOtherEndCol;
09446             }
09447         }
09448     }
09449 
09450     // Handle blending of non bitmap fill colours
09451     if (BlendFillColours(StartCol, OtherStartCol, &BlendColour, Ratio, pBlendParam))
09452         pNewAttr->SetStartColour(&BlendColour);
09453 
09454     if (EndCol == NULL)
09455         NonNullCol = StartCol;
09456     else
09457         NonNullCol = EndCol;
09458     
09459     if (OtherEndCol == NULL)
09460     {
09461         OtherNonNullCol = OtherStartCol;
09462 
09463         if (BlendFillColours(EndCol, OtherStartCol, &BlendColour, Ratio, pBlendParam))
09464             pNewAttr->SetEndColour(&BlendColour);
09465     }
09466     else 
09467     {
09468         OtherNonNullCol = OtherEndCol;
09469 
09470         if (BlendFillColours(EndCol, OtherEndCol, &BlendColour, Ratio, pBlendParam))
09471             pNewAttr->SetEndColour(&BlendColour);
09472     }
09473 
09474     if ((EndCol2 != NULL) || (OtherEndCol2 != NULL) || (EndCol3 != NULL) || (OtherEndCol3 != NULL))
09475     {
09476         if (EndCol2 == NULL)
09477             EndCol2 = NonNullCol;
09478         if (OtherEndCol2 == NULL)
09479             OtherEndCol2 = OtherNonNullCol;
09480         if (EndCol3 == NULL)
09481             EndCol3 = NonNullCol;
09482         if (OtherEndCol3 == NULL)
09483             OtherEndCol3 = OtherNonNullCol;
09484     
09485         if (BlendFillColours(EndCol2, OtherEndCol2, &BlendColour, Ratio, pBlendParam))
09486                 pNewAttr->SetEndColour2(&BlendColour);
09487 
09488         if (BlendFillColours(EndCol3, OtherEndCol3, &BlendColour, Ratio, pBlendParam))
09489                 pNewAttr->SetEndColour3(&BlendColour);
09490     }
09491 
09492     // Blend the Start and End Transparencies
09493     UINT32 BlendTransp;
09494 
09495     if (BlendFillTransp(GetStartTransp(), OtherFill->GetStartTransp(), &BlendTransp, Ratio, pBlendParam))
09496         pNewAttr->SetStartTransp(&BlendTransp);
09497 
09498     if (BlendFillTransp(GetEndTransp(), OtherFill->GetEndTransp(), &BlendTransp, Ratio, pBlendParam))
09499         pNewAttr->SetEndTransp(&BlendTransp);
09500 
09501     if (BlendFillTransp(GetEndTransp2(), OtherFill->GetEndTransp2(), &BlendTransp, Ratio, pBlendParam))
09502         pNewAttr->SetEndTransp2(&BlendTransp);
09503 
09504     if (BlendFillTransp(GetEndTransp3(), OtherFill->GetEndTransp3(), &BlendTransp, Ratio, pBlendParam))
09505         pNewAttr->SetEndTransp3(&BlendTransp);
09506 
09507     // Blend the Control Points
09508     DocCoord BlendPoint;
09509 
09510     if (!pBlendParam->GetObjectProfileProcessing ())
09511     {
09512         // were not doing object processing - fill positions are affected by attribute ratio ....
09513         if (BlendControlPoints(GetStartPoint(), OtherFill->GetStartPoint(), &BlendPoint, Ratio, pBlendParam))
09514             pNewAttr->SetStartPoint(&BlendPoint);
09515 
09516         if (BlendControlPoints(GetEndPoint(), OtherFill->GetEndPoint(), &BlendPoint, Ratio, pBlendParam))
09517             pNewAttr->SetEndPoint(&BlendPoint);
09518 
09519         if (BlendControlPoints(GetEndPoint2(), OtherFill->GetEndPoint2(), &BlendPoint, Ratio, pBlendParam))
09520             pNewAttr->SetEndPoint2(&BlendPoint);
09521     }
09522     else
09523     {
09524         // were are doing object processing - fill positions are affected by object ratio ....
09525         if (BlendControlPoints(GetStartPoint(), OtherFill->GetStartPoint(), &BlendPoint, objectRatio, pBlendParam))
09526             pNewAttr->SetStartPoint(&BlendPoint);
09527 
09528         if (BlendControlPoints(GetEndPoint(), OtherFill->GetEndPoint(), &BlendPoint, objectRatio, pBlendParam))
09529             pNewAttr->SetEndPoint(&BlendPoint);
09530 
09531         if (BlendControlPoints(GetEndPoint2(), OtherFill->GetEndPoint2(), &BlendPoint, objectRatio, pBlendParam))
09532             pNewAttr->SetEndPoint2(&BlendPoint);
09533     }
09534 
09535     // Make sure that any BitmapRefs in the Blended attributes,
09536     // are Tempory ones, so we don't try to detach the bitmap
09537     // when the Blend Attrs are destroyed.
09538 
09539 // ****************************************************
09540 //
09541 // Temporarily removed to fix problem with saving Blended bitmaps.
09542 // May re-intruduce problems with deleting bitmaps within blends,
09543 // but the saving problem is more important at the moment ....
09544 // .... Will, 15/12/95
09545 
09546 //  if (GetBitmapRef() != NULL)
09547 //      GetBitmapRef()->TempRef = TRUE;
09548 
09549 //  if (OtherFill->GetBitmapRef() != NULL)
09550 //      OtherFill->GetBitmapRef()->TempRef = TRUE;
09551 
09552 // ****************************************************
09553 
09554 //  if (pNewAttr->GetBitmapRef() != NULL)
09555 //      pNewAttr->GetBitmapRef()->TempRef = TRUE;
09556 
09557     // Set the new fill as the blended attribute
09558     pBlendParam->SetBlendedAttrVal(pNewAttr);
09559 
09560     return TRUE;
09561 }
09562 
09563 
09564 /********************************************************************************************
09565 
09566 >   BOOL FlatFillAttribute::Blend(BlendAttrParam* pBlendParam)
09567 
09568     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09569     Created:    28/11/94
09570     Returns:    TRUE - Blend went ok, the blended attr val is valid; FALSE if not.
09571     Purpose:    Blends between two flat fill attributes.
09572                 This current calls the general fill blend function.
09573                 (See FillGeometryAttribute::Blend).
09574 
09575     Errors:     Out of memory.
09576     SeeAlso:    FillGeometryAttribute::Blend;
09577                 FillGeometryAttribute::BlendFillColours;
09578                 FillGeometryAttribute::BlendFillTransp;
09579                 FillGeometryAttribute::BlendControlPoints;
09580                 GradFillAttribute::Blend
09581 
09582 ********************************************************************************************/
09583 
09584 BOOL FlatFillAttribute::Blend(BlendAttrParam* pBlendParam)
09585 {
09586     // Since this is a flat fill, we will use the other fill's geometry
09587     // (mainly for ArtWorks compatability)
09588 
09589     // First get the fill that we are blending to
09590     FillGeometryAttribute* OtherFill = 
09591                 (FillGeometryAttribute*)pBlendParam->GetOtherAttrVal();
09592 
09593     // Make a new object of the same type
09594     CCRuntimeClass* ObjectType = OtherFill->GetRuntimeClass();
09595     FillGeometryAttribute* pNewAttr = (FillGeometryAttribute*)ObjectType->CreateObject();
09596 
09597     if (pNewAttr == NULL)
09598     {
09599         // Fail if we couldn't create the new fill
09600         pBlendParam->SetBlendedAttrVal(NULL);
09601         return FALSE;
09602     }
09603 
09604     // Make the new fill an exact copy of the other one
09605     pNewAttr->SimpleCopy(OtherFill);
09606 
09607     // and what point along the blend we are at
09608     double Ratio = pBlendParam->GetBlendRatio();
09609     double objectRatio = pBlendParam->GetObjectRatio();
09610 
09611     // Blend the Start and End Colours
09612     DocColour BlendColour;
09613 
09614     DocColour* OtherStartCol    = OtherFill->GetStartColour();
09615     DocColour* OtherEndCol      = OtherFill->GetEndColour();
09616 
09617     DocColour TempOtherStartCol;
09618     DocColour TempOtherEndCol;
09619 
09620     // Check for a Greyscale Bitmap fill with no start or end colours
09621     // and use Black and White instead of 'No Colour'
09622     if (OtherFill->IsABitmapFill() && OtherStartCol == NULL && OtherEndCol == NULL)
09623     {
09624         if (OtherFill->GetBitmapRef() != NULL)
09625         {
09626             if (CheckForGreyscaleBitmapBlend(OtherFill->GetBitmapRef()->GetBitmap(), &TempOtherStartCol, &TempOtherEndCol))
09627             {
09628                 OtherStartCol   = &TempOtherStartCol;
09629                 OtherEndCol     = &TempOtherEndCol;
09630             }
09631         }
09632     }
09633 
09634     if (BlendFillColours(GetStartColour(), OtherStartCol, &BlendColour, Ratio, pBlendParam))
09635         pNewAttr->SetStartColour(&BlendColour);
09636 
09637     if (BlendFillColours(GetStartColour(), OtherEndCol, &BlendColour, Ratio, pBlendParam))
09638         pNewAttr->SetEndColour(&BlendColour);
09639 
09640     // CGS:  don't worry if pNewAttr->GetColourRamp () is NULL, this is handled internally by pNewAttr->GetColourRamp ()->Blend ()
09641     // (even if it is NULL, this code is still perfectly valid:  it means blend a no0n-multi-stage fill to something ....)
09642     pNewAttr->GetColourRamp ()->Blend (pNewAttr, pBlendParam, this/*->GetColourRamp ()*/, TRUE);
09643 
09644     // Blend the Control Points
09645     DocCoord BlendPoint;
09646 
09647     if (!pBlendParam->GetObjectProfileProcessing ())
09648     {
09649         // were not doing object processing - fill positions are affected by attribute ratio ....
09650         if (BlendControlPoints(GetStartPoint(), OtherFill->GetStartPoint(), &BlendPoint, Ratio, pBlendParam))
09651             pNewAttr->SetStartPoint(&BlendPoint);
09652 
09653         if (BlendControlPoints(GetEndPoint(), OtherFill->GetEndPoint(), &BlendPoint, Ratio, pBlendParam))
09654             pNewAttr->SetEndPoint(&BlendPoint);
09655 
09656         if (BlendControlPoints(GetEndPoint2(), OtherFill->GetEndPoint2(), &BlendPoint, Ratio, pBlendParam))
09657             pNewAttr->SetEndPoint2(&BlendPoint);
09658     }
09659     else
09660     {
09661         // were are doing object processing - fill positions are affected by object ratio ....
09662         if (BlendControlPoints(OtherFill->GetStartPoint(), GetStartPoint(), &BlendPoint, objectRatio, pBlendParam, TRUE))
09663             pNewAttr->SetStartPoint(&BlendPoint);
09664 
09665         if (BlendControlPoints(OtherFill->GetEndPoint(), GetEndPoint(), &BlendPoint, objectRatio, pBlendParam, TRUE))
09666             pNewAttr->SetEndPoint(&BlendPoint);
09667 
09668         if (BlendControlPoints(OtherFill->GetEndPoint2(), GetEndPoint2(), &BlendPoint, objectRatio, pBlendParam, TRUE))
09669             pNewAttr->SetEndPoint2(&BlendPoint);
09670     }
09671 
09672     // Set the new fill as the blended attribute
09673     pBlendParam->SetBlendedAttrVal(pNewAttr);
09674 
09675     return TRUE;
09676 }
09677 
09678 /********************************************************************************************
09679 
09680 >   BOOL FlatTranspFillAttribute::Blend(BlendAttrParam* pBlendParam)
09681 
09682     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09683     Created:    28/11/94
09684     Returns:    TRUE - Blend went ok, the blended attr val is valid; FALSE if not.
09685     Purpose:    Blends between two flat fill attributes.
09686                 This current calls the general fill blend function.
09687                 (See FillGeometryAttribute::Blend).
09688 
09689     Errors:     Out of memory.
09690     SeeAlso:    FillGeometryAttribute::Blend;
09691                 FillGeometryAttribute::BlendFillColours;
09692                 FillGeometryAttribute::BlendFillTransp;
09693                 FillGeometryAttribute::BlendControlPoints;
09694                 GradFillAttribute::Blend
09695 
09696 ********************************************************************************************/
09697 
09698 BOOL FlatTranspFillAttribute::Blend(BlendAttrParam* pBlendParam)
09699 {
09700     // Since this is a flat fill, we will use the other fill's geometry
09701     // (mainly for ArtWorks compatability)
09702 
09703     // First get the fill that we are blending to
09704     FillGeometryAttribute* OtherFill = 
09705                 (FillGeometryAttribute*)pBlendParam->GetOtherAttrVal();
09706 
09707     // Make a new object of the same type
09708     CCRuntimeClass* ObjectType = OtherFill->GetRuntimeClass();
09709     FillGeometryAttribute* pNewAttr = (FillGeometryAttribute*)ObjectType->CreateObject();
09710 
09711     if (pNewAttr == NULL)
09712     {
09713         // Fail if we couldn't create the new fill
09714         pBlendParam->SetBlendedAttrVal(NULL);
09715         return FALSE;
09716     }
09717 
09718     // Make the new fill an exact copy of the other one
09719     pNewAttr->SimpleCopy(OtherFill);
09720 
09721     // and what point along the blend we are at
09722     double Ratio = pBlendParam->GetBlendRatio();
09723     double objectRatio = pBlendParam->GetObjectRatio();
09724 
09725     // Blend the Start and End Transparencies
09726     UINT32 BlendTransp;
09727 
09728     if (BlendFillTransp(GetStartTransp(), OtherFill->GetStartTransp(), &BlendTransp, Ratio, pBlendParam))
09729         pNewAttr->SetStartTransp(&BlendTransp);
09730 
09731     if (BlendFillTransp(GetStartTransp(), OtherFill->GetEndTransp(), &BlendTransp, Ratio, pBlendParam))
09732         pNewAttr->SetEndTransp(&BlendTransp);
09733 
09734 
09735     // Blend the Control Points
09736     DocCoord BlendPoint;
09737 
09738     if (!pBlendParam->GetObjectProfileProcessing ())
09739     {
09740         // were not doing object processing - fill positions are affected by attribute ratio ....
09741         if (BlendControlPoints(GetStartPoint(), OtherFill->GetStartPoint(), &BlendPoint, Ratio, pBlendParam))
09742             pNewAttr->SetStartPoint(&BlendPoint);
09743 
09744         if (BlendControlPoints(GetEndPoint(), OtherFill->GetEndPoint(), &BlendPoint, Ratio, pBlendParam))
09745             pNewAttr->SetEndPoint(&BlendPoint);
09746 
09747         if (BlendControlPoints(GetEndPoint2(), OtherFill->GetEndPoint2(), &BlendPoint, Ratio, pBlendParam))
09748             pNewAttr->SetEndPoint2(&BlendPoint);
09749     }
09750     else
09751     {
09752         // were are doing object processing - fill positions are affected by object ratio ....
09753         if (BlendControlPoints(GetStartPoint(), OtherFill->GetStartPoint(), &BlendPoint, objectRatio, pBlendParam))
09754             pNewAttr->SetStartPoint(&BlendPoint);
09755 
09756         if (BlendControlPoints(GetEndPoint(), OtherFill->GetEndPoint(), &BlendPoint, objectRatio, pBlendParam))
09757             pNewAttr->SetEndPoint(&BlendPoint);
09758 
09759         if (BlendControlPoints(GetEndPoint2(), OtherFill->GetEndPoint2(), &BlendPoint, objectRatio, pBlendParam))
09760             pNewAttr->SetEndPoint2(&BlendPoint);
09761     }
09762 
09763     // Set the new fill as the blended attribute
09764     pBlendParam->SetBlendedAttrVal(pNewAttr);
09765 
09766     return TRUE;
09767 }
09768 
09769 /********************************************************************************************
09770 
09771 >   BOOL GradFillAttribute::Blend(BlendAttrParam* pBlendParam)
09772 
09773     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09774     Created:    28/11/94
09775     Returns:    TRUE - Blend went ok, the blended attr val is valid; FALSE if not.
09776     Purpose:    Blends between two graduated fill attributes.
09777                 This current calls the general fill blend function.
09778                 (See FillGeometryAttribute::Blend).
09779 
09780     Errors:     Out of memory.
09781     SeeAlso:    FillGeometryAttribute::Blend;
09782                 FillGeometryAttribute::BlendFillColours;
09783                 FillGeometryAttribute::BlendFillTransp;
09784                 FillGeometryAttribute::BlendControlPoints;
09785                 FlatFillAttribute::Blend
09786 
09787 ********************************************************************************************/
09788 
09789 BOOL GradFillAttribute::Blend(BlendAttrParam* pBlendParam)
09790 {
09791     return FillGeometryAttribute::Blend(pBlendParam);
09792 }
09793 
09794 /********************************************************************************************
09795 
09796 >   BOOL GradTranspFillAttribute::Blend(BlendAttrParam* pBlendParam)
09797 
09798     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09799     Created:    28/11/94
09800     Returns:    TRUE - Blend went ok, the blended attr val is valid; FALSE if not.
09801     Purpose:    Blends between two graduated fill attributes.
09802                 This current calls the general fill blend function.
09803                 (See FillGeometryAttribute::Blend).
09804 
09805     Errors:     Out of memory.
09806     SeeAlso:    FillGeometryAttribute::Blend;
09807                 FillGeometryAttribute::BlendFillColours;
09808                 FillGeometryAttribute::BlendFillTransp;
09809                 FillGeometryAttribute::BlendControlPoints;
09810                 FlatFillAttribute::Blend
09811 
09812 ********************************************************************************************/
09813 
09814 BOOL GradTranspFillAttribute::Blend(BlendAttrParam* pBlendParam)
09815 {
09816     return FillGeometryAttribute::Blend(pBlendParam);
09817 }
09818 
09819 /********************************************************************************************
09820 
09821 >   BOOL StrokeTranspAttribute::Blend(BlendAttrParam* pBlendParam)
09822 
09823     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09824     Created:    28/11/94
09825     Returns:    TRUE - Blend went ok, the blended attr val is valid; FALSE if not.
09826     Purpose:    Blends between two fill attributes.
09827                 This is a general blend function for all fill attributes.
09828                 It will blend between any types of fill, but will always use the 'type'
09829                 of the first fill, taking control points, colours, and transparency
09830                 from the end fill if it can.
09831 
09832     Errors:     Out of memory.
09833     SeeAlso:    FillGeometryAttribute::BlendFillColours;
09834                 FillGeometryAttribute::BlendFillTransp;
09835                 FillGeometryAttribute::BlendControlPoints;
09836                 FlatFillAttribute::Blend;
09837                 GradFillAttribute::Blend
09838 
09839 ********************************************************************************************/
09840 
09841 BOOL StrokeTranspAttribute::Blend(BlendAttrParam* pBlendParam)
09842 {
09843     // First make a new object of the same type as this one
09844     CCRuntimeClass* ObjectType = GetRuntimeClass();
09845     FillGeometryAttribute* pNewAttr = (FillGeometryAttribute*)ObjectType->CreateObject();
09846 
09847     if (pNewAttr == NULL)
09848     {
09849         // Fail if we couldn't create the new fill
09850         pBlendParam->SetBlendedAttrVal(NULL);
09851         return FALSE;
09852     }
09853 
09854     // Make the new fill an exact copy of this one
09855     pNewAttr->SimpleCopy(this);
09856 
09857     // Now get the fill that we are blending to
09858     FillGeometryAttribute* OtherFill = 
09859                 (FillGeometryAttribute*)pBlendParam->GetOtherAttrVal();
09860 
09861     // and what point along the blend we are at
09862     double Ratio = pBlendParam->GetBlendRatio();
09863 
09864     // Look at the Start and Attribute maps to see if either end
09865     // is no colour
09866     CCAttrMap* pAttrMapStart = pBlendParam->GetStartAttrMap();
09867     CCAttrMap* pAttrMapEnd = pBlendParam->GetEndAttrMap();
09868 
09869     CCRuntimeClass     *pType;
09870     void               *pVal = NULL;
09871 
09872     // We're looking for Stroke Colour Attributes
09873     pType = CC_RUNTIME_CLASS(AttrStrokeColour);
09874 
09875     // Lookup the Start Line Colour
09876     pAttrMapStart->Lookup( pType, pVal );
09877     if (pVal == NULL)
09878         return FALSE;
09879 
09880     AttrStrokeColour * pStartColour = (AttrStrokeColour *)pVal;
09881     StrokeColourAttribute * pColourAttr = &(pStartColour->Value);
09882 
09883     BOOL StartIsNoColour = pColourAttr->Colour.IsTransparent();
09884 
09885     pVal = NULL;
09886 
09887     // Lookup the End Line Colour
09888     pAttrMapEnd->Lookup(pType,pVal);
09889     if (pVal == NULL)
09890         return FALSE;
09891 
09892     AttrStrokeColour * pEndColour = (AttrStrokeColour *)pVal;
09893     pColourAttr = &(pEndColour->Value);
09894 
09895     BOOL EndIsNoColour = pColourAttr->Colour.IsTransparent();
09896 
09897     // Blend the Start and End Transparencies
09898     UINT32 BlendTransp, BlendStartTransp, BlendEndTransp;
09899 
09900     // If either end if 'No Colour' then treat it as 100% transparent
09901     BlendStartTransp    = (StartIsNoColour && !EndIsNoColour) ? 255 : *GetStartTransp();
09902     BlendEndTransp      = (EndIsNoColour && !StartIsNoColour) ? 255 : *OtherFill->GetStartTransp();
09903 
09904     if (BlendFillTransp(&BlendStartTransp, &BlendEndTransp, &BlendTransp, Ratio, pBlendParam))
09905         pNewAttr->SetStartTransp(&BlendTransp);
09906 
09907     // Set the new fill as the blended attribute
09908     pBlendParam->SetBlendedAttrVal(pNewAttr);
09909     
09910     return TRUE;
09911 }
09912 
09913 /********************************************************************************************
09914 
09915 >   BOOL FillGeometryAttribute::BlendFillColours(DocColour* Start, DocColour* End, DocColour* Blend,
09916                                                  double& Ratio, BlendAttrParam* pBlendParam)
09917     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09918     Created:    28/11/94
09919     Returns:    TRUE - Blend went ok, the blended colour is valid; FALSE if not.
09920     Purpose:    Blends between two fill colours.
09921     SeeAlso:    FillGeometryAttribute::Blend;
09922                 FillGeometryAttribute::BlendFillTransp;
09923                 FillGeometryAttribute::BlendControlPoints;
09924                 FlatFillAttribute::Blend;
09925                 GradFillAttribute::Blend
09926 
09927 ********************************************************************************************/
09928 
09929 BOOL FillGeometryAttribute::BlendFillColours(DocColour* Start, DocColour* End, DocColour* Blend,
09930                                                 double& Ratio, BlendAttrParam* pBlendParam)
09931 {
09932     ERROR3IF(Blend == NULL || pBlendParam == NULL, "Illegal NULL param");
09933 
09934     if (Start == NULL)
09935         return FALSE;
09936 
09937     if (End == NULL)
09938     {
09939         *Blend = *Start;
09940         return TRUE;
09941     }
09942 
09943     ColourContext *BlendContext;
09944     ColourContext *OutputContext = NULL;
09945 
09946     // Find the ouptut ColourContext, if there is one available to us
09947     // This allows the blend to take advantage of the output context to do the best 
09948     // job it can of colour-separating tints
09949     if (pBlendParam->GetRenderRegion() != NULL)
09950     {
09951         ERROR3IF(pBlendParam->GetRenderRegion()->GetRenderView() == NULL, "No render view");
09952         if (pBlendParam->GetRenderRegion()->GetRenderView() != NULL)
09953             OutputContext = pBlendParam->GetRenderRegion()->GetRenderView()->GetColourContext(COLOURMODEL_RGBT);
09954     }
09955 
09956     switch (pBlendParam->GetColourBlend())
09957     {
09958         case COLOURBLEND_FADE:
09959             BlendContext = ColourManager::GetColourContext(COLOURMODEL_RGBT);
09960             Blend->Mix(Start, End, Ratio, BlendContext, FALSE, OutputContext);
09961             break;
09962 
09963         case COLOURBLEND_RAINBOW:
09964             BlendContext = ColourManager::GetColourContext(COLOURMODEL_HSVT);
09965             Blend->Mix(Start, End, Ratio, BlendContext, FALSE, OutputContext);
09966             break;
09967 
09968         case COLOURBLEND_ALTRAINBOW:
09969             BlendContext = ColourManager::GetColourContext(COLOURMODEL_HSVT);
09970             Blend->Mix(Start, End, Ratio, BlendContext, TRUE, OutputContext);
09971             break;
09972 
09973         default:
09974             ERROR3("Unknown colour blend type");
09975             return(FALSE);
09976     }
09977 
09978     return TRUE;
09979 }
09980 
09981 /********************************************************************************************
09982 
09983 >   BOOL FillGeometryAttribute::BlendFillTransp(UINT32* Start, UINT32* End, UINT32* Blend,
09984                                                 double& Ratio, BlendAttrParam* pBlendParam)
09985     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
09986     Created:    28/11/94
09987     Returns:    TRUE - Blend went ok, the blended transparency is valid; FALSE if not.
09988     Purpose:    Blends between two fill transparencies.
09989     SeeAlso:    FillGeometryAttribute::Blend;
09990                 FillGeometryAttribute::BlendFillColours;
09991                 FillGeometryAttribute::BlendControlPoints;
09992                 FlatFillAttribute::Blend;
09993                 GradFillAttribute::Blend
09994 
09995 ********************************************************************************************/
09996 
09997 BOOL FillGeometryAttribute::BlendFillTransp(UINT32* Start, UINT32* End, UINT32* Blend,
09998                                             double& Ratio, BlendAttrParam* pBlendParam)
09999 {
10000     if (Start == NULL)
10001         return FALSE;
10002 
10003     if (End == NULL)
10004     {
10005         *Blend = *Start;
10006         return TRUE;
10007     }
10008 
10009     INT32 dt = *End - *Start;
10010     *Blend = UINT32(double(*Start) + (double(dt) * Ratio));
10011     
10012     return TRUE;
10013 }
10014 
10015 /********************************************************************************************
10016 
10017 >   BOOL FillGeometryAttribute::BlendControlPoints(DocCoord* Start, DocCoord* End, DocCoord* Blend,
10018                                                     double& Ratio, BlendAttrParam* pBlendParam)
10019     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
10020     Created:    28/11/94
10021     Returns:    TRUE - Blend went ok, the blended point is valid; FALSE if not.
10022     Purpose:    Blends between two fill control point.
10023     SeeAlso:    FillGeometryAttribute::Blend;
10024                 FillGeometryAttribute::BlendFillColours;
10025                 FillGeometryAttribute::BlendFillTransp;
10026                 FlatFillAttribute::Blend;
10027                 GradFillAttribute::Blend
10028 
10029 ********************************************************************************************/
10030 
10031 BOOL FillGeometryAttribute::BlendControlPoints(DocCoord* Start, DocCoord* End, DocCoord* Blend,
10032                                                 double& Ratio, BlendAttrParam* pBlendParam, BOOL swapOrder)
10033 {
10034     if (Start == NULL)
10035     {   
10036         return FALSE;
10037     }
10038 
10039     if (End == NULL)
10040     {
10041         NodeRenderableBounded* pStartNode = NULL;
10042         NodeRenderableBounded* pEndNode = NULL;
10043 
10044         double origRatio = Ratio;
10045 
10046         if (!swapOrder)
10047         {
10048             if ((NodeRenderableBounded*) pBlendParam->GetStartAttrMap ())
10049             {
10050                 pStartNode = (NodeRenderableBounded*) pBlendParam->GetStartAttrMap ()->attrMapCreator;
10051             }
10052 
10053             if ((NodeRenderableBounded*) pBlendParam->GetEndAttrMap ())
10054             {
10055                 pEndNode = (NodeRenderableBounded*) pBlendParam->GetEndAttrMap ()->attrMapCreator;
10056             }
10057         }
10058         else
10059         {
10060             Ratio = 1 - Ratio;
10061             
10062             if ((NodeRenderableBounded*) pBlendParam->GetEndAttrMap ())
10063             {
10064                 pStartNode = (NodeRenderableBounded*) pBlendParam->GetEndAttrMap ()->attrMapCreator;
10065             }
10066  
10067             if ((NodeRenderableBounded*) pBlendParam->GetStartAttrMap ())
10068             {
10069                 pEndNode = (NodeRenderableBounded*) pBlendParam->GetStartAttrMap ()->attrMapCreator;
10070             }
10071         }
10072 
10073 //      ERROR3IF (((pStartNode == NULL) && (pEndNode == NULL)), "Somethings wrong!");   // this should NOT be so
10074         
10075         if (!pEndNode)
10076         {
10077             *Blend = *Start;
10078             if (swapOrder)
10079             {
10080                 Ratio = origRatio;
10081             }
10082             return TRUE;
10083         }
10084         else
10085         {
10086             // we are blending from something to nothing
10087             // previously will just made *Blend equal to *start and returned TRUE.
10088             // this causes problems when blending (e.g.) a linear transparency to a flat fill
10089             // (i.e.  all intermediate blend steps have EXACTLY the same fill geometry as the start)
10090             // this has now been changed.  In a case such as this, we create a temporary estimated 'fill
10091             // handle' point - and blend to that ....  This solution is NOT rotation independant (owing to
10092             // limitations of bounding boxs, but at least what we render on-screen is of a higher quality.
10093 
10094             if (pStartNode)
10095             {
10096                 DocRect rectStart (pStartNode->GetBoundingRect (TRUE));
10097                 DocRect rectEnd (pEndNode->GetBoundingRect (TRUE));
10098 
10099                 INT32 dx = static_cast<INT32> ( (rectEnd.Centre ().x - rectStart.Centre ().x) * Ratio );
10100                 INT32 dy = static_cast<INT32> ( (rectEnd.Centre ().y - rectStart.Centre ().y) * Ratio );
10101         
10102                 *Blend = DocCoord((*Start).x + dx, (*Start).y + dy);
10103 
10104                 if (swapOrder)
10105                 {
10106                     Ratio = origRatio;
10107                 }
10108 
10109                 return TRUE;
10110             }
10111             else
10112             {
10113                 if (swapOrder)
10114                 {
10115                     Ratio = origRatio;
10116                 }
10117                 return (FALSE);
10118             }
10119         }
10120     }
10121 
10122     // process as normal ....
10123 
10124     INT32 dx = INT32(double((*End).x - (*Start).x) * Ratio);
10125     INT32 dy = INT32(double((*End).y - (*Start).y) * Ratio);
10126     
10127     *Blend = DocCoord((*Start).x + dx, (*Start).y + dy);
10128 
10129     return TRUE;
10130 }
10131 
10132 
10133 /********************************************************************************************
10134 
10135 >   BOOL FillGeometryAttribute::CheckForGreyscaleBitmapBlend(KernelBitmap* pBitmap, 
10136                                                              DocColour* StartCol, DocColour* EndCol)
10137 
10138     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
10139     Created:    23/1/95
10140     Returns:    TRUE if colours where set.
10141     Purpose:    Checks for a blend using a Greyscale bitmap, and set the Start and End Cols
10142                 provided to suitable default Black and White colours.
10143 
10144 ********************************************************************************************/
10145 
10146 BOOL FillGeometryAttribute::CheckForGreyscaleBitmapBlend(KernelBitmap* pBitmap, 
10147                                                          DocColour* StartCol, DocColour* EndCol)
10148 {
10149     PORTNOTETRACE("other","FillGeometryAttribute::CheckForGreyscaleBitmapBlend - do nothing");
10150 #ifndef EXCLUDE_FROM_XARALX
10151 #ifndef WEBSTER
10152     if (pBitmap != NULL)
10153     {
10154         if (BfxALU::IsGreyscaleBitmap(pBitmap)) // WEBSTER-Martin-14/01/97 we prob do need this
10155         {
10156             // The bitmap is Greyscale, with NULL start and end colours,
10157             // so we will use Black and White colours in the blend
10158         
10159             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
10160                                                 _R(IDS_BLACKNAME), StartCol);
10161 
10162             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
10163                                                 _R(IDS_WHITENAME), EndCol);
10164 
10165             return TRUE;
10166         }
10167     }
10168 #endif //WEBSTER */
10169 #endif
10170     return FALSE;
10171 }

Generated on Sat Nov 10 03:45:16 2007 for Camelot by  doxygen 1.4.4