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 =