TraceControl Class Reference

Dialog for tracer. More...

#include <tracectl.h>

Inheritance diagram for TraceControl:

BitmapEffectBase ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 TraceControl ()
 Constructs the trace control object.
virtual ~TraceControl ()
 Destructor, does nothing.
virtual BOOL InitBitmap (KernelBitmap *theOriginal=NULL)
 Initialises trace control object to work on a given set of bitmaps.
virtual BOOL GetBitmaps (KernelBitmap **theOriginal=NULL, KernelBitmap **theProposed=NULL, KernelBitmap **theUndithered=NULL)
 Returns the current bitmap pointers.
virtual BOOL Trace (BOOL *Done)
 Spits out a single object into the trace output stream.
virtual BOOL SetPath (NodePath *pNodePath)
 Sets up the NP to use.
virtual NodeGetPaths ()
 Returns the current path.
virtual BOOL RemoveTree (BOOL DeleteIt=TRUE)
 Relinquishes control of the tree structure.
virtual BOOL GetParams (TraceMethod *pMethod=NULL, INT32 *pMinimumArea=NULL, double *pMaximumInitialAreaErrorThreshold=NULL, double *pMinimumInitialAreaErrorThreshold=NULL, double *pInitialAreaErrorRatio=NULL, double *pMinGradFillError=NULL, double *pGradFillErrorRatio=NULL, double *pMinPixelError=NULL, double *pMaxPixelError=NULL, double *pPixelErrorRatio=NULL, double *pQuantColours=NULL, double *pBlur=NULL, double *pSmooth=NULL)
 Gets the tracing parameters.
virtual BOOL SetParams (TraceMethod *pMethod=NULL, INT32 *pMinimumArea=NULL, double *pMaximumInitialAreaErrorThreshold=NULL, double *pMinimumInitialAreaErrorThreshold=NULL, double *pInitialAreaErrorRatio=NULL, double *pMinGradFillError=NULL, double *pGradFillErrorRatio=NULL, double *pMinPixelError=NULL, double *pMaxPixelError=NULL, double *pPixelErrorRatio=NULL, double *pQuantColours=NULL, double *pBlur=NULL, double *pSmooth=NULL)
 Sets the tracing parameters.
virtual BOOL GetProgress (INT32 *pPercent=NULL, INT32 *pNumPaths=NULL, INT32 *pNumCusps=NULL, INT32 *pNumPoints=NULL, BOOL *pProgressDone=NULL)
 Returning information for status line function.

Protected Member Functions

virtual BOOL MarkInitialArea ()
 Marks out intial area in temp bitmap.
virtual BOOL TracePath (BfxPixelOp *pBfxPixelOp)
 A NodePath is traced from the temporary bitmap.
virtual BOOL CalculateStatistics ()
 To determine the stats that help us find the optimum grad fill.
virtual BOOL FormGradFill ()
 Calculate the optimum grad fill from the stats available.
virtual BOOL PlotGradFill (BOOL ToProposed, BOOL UsePath=TRUE)
 Plots the grad fill on top of the proposed bitmap into the temp bitmap.
virtual BOOL CheckMinimumArea (BfxPixelOp *pBfxPixelOp)
 Determines whether atleast (MinimumArea) pixels are within the region.

Protected Attributes

KernelBitmappOriginal
KernelBitmappProposed
KernelBitmappUndithered
NodePathpCurrentPath
LinearFillAttributepFill
NodepTree
NodepJoinNode
TraceRegionpTraceRegion
BfxErrorRegionListpErrorRegionList
KernelStatisticspStats
BfxPixelOppThresholdPixelOp
BfxPixelOppColourThresholdPixelOp
BfxPixelOppPositivePixelOp
double InitialAreaErrorThreshold
double MaximumInitialAreaErrorThreshold
double MinimumInitialAreaErrorThreshold
double InitialAreaErrorRatio
double GradFillError
double NewGradFillError
double MinGradFillError
double GradFillErrorRatio
double PixelError
double MinPixelError
double MaxPixelError
double PixelErrorRatio
double QuantColours
double Blur
double Smooth
TraceMethod Method
INT32 Log2BPP
INT32 MinimumArea
INT32 TotalPasses
INT32 NumPasses
INT32 NumPaths
INT32 NumCusps
INT32 NumPoints
BOOL ProgressDone
BOOL HavePath
BOOL FirstShape
BOOL ShapeFreePass
BOOL FoundRegion
INT32 InitialX
INT32 InitialY
INT32 RegionArea
INT32 ScanPointX
INT32 ScanPointY
DWORD ScanPointColour
INT32 XSize
INT32 YSize
INT32 GFStartX
INT32 GFStartY
INT32 GFEndX
INT32 GFEndY
DWORD GFStartC
DWORD GFEndC

Private Member Functions

 CC_DECLARE_DYNCREATE (TraceControl)

Detailed Description

Dialog for tracer.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/12/94

Definition at line 136 of file tracectl.h.


Constructor & Destructor Documentation

TraceControl::TraceControl  ) 
 

Constructs the trace control object.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/12/94

Definition at line 172 of file tracectl.cpp.

00172                            : BitmapEffectBase()
00173 {
00174     pOriginal = NULL;
00175     pProposed = NULL;
00176     pUndithered = NULL;
00177     pCurrentPath = NULL;
00178     pFill = NULL;
00179     pTraceRegion = NULL;
00180     pStats = NULL;
00181     pErrorRegionList = NULL;
00182     pThresholdPixelOp = NULL;
00183     pColourThresholdPixelOp = NULL;
00184     pPositivePixelOp = NULL;
00185 
00186     pTree=NULL;
00187     pJoinNode=NULL;
00188 
00189 #ifdef _DEBUG
00190     for (INT32 i=0; i<NUM_TRACECTL_DEBUG_BITMAPS; i++) {pDebug[i]=NULL;DebugSwitch[i]=FALSE;DebugInvalid[i]=TRUE;}
00191 #endif
00192 
00193     MaximumInitialAreaErrorThreshold = 0.12;
00194     InitialAreaErrorThreshold = MaximumInitialAreaErrorThreshold;
00195     MinimumInitialAreaErrorThreshold = 0.06;
00196     InitialAreaErrorRatio = 0.5;
00197 
00198     GradFillError = 1.0;
00199     NewGradFillError = 0.0;
00200     MinGradFillError = 2.0/256.0;
00201     GradFillErrorRatio = 0.8;
00202 
00203     MinPixelError=0.45;
00204     MaxPixelError=2.0;
00205     PixelError=MaxPixelError;
00206     PixelErrorRatio=0.5;
00207     QuantColours=30;
00208 
00209     Blur=64.0;
00210     Smooth=0.0;
00211     Log2BPP=5;
00212     Method = TRACEMETHOD_TRUECOL;
00213 
00214     MinimumArea = 10;
00215 
00216     FoundRegion = FALSE;
00217     InitialX = 0 ;
00218     InitialY = 0;
00219 
00220     ScanPointX = 0;
00221     ScanPointY = 0;
00222 
00223     XSize = 0;
00224     YSize = 0;
00225 
00226     HavePath = FALSE;
00227 
00228     TotalPasses=0;
00229     NumPasses=0;
00230     NumPaths=0;
00231     NumCusps=0;
00232     NumPoints=0;
00233     ProgressDone=FALSE;
00234 
00235     InitBitmap();
00236 
00237     FirstShape = TRUE;
00238     ShapeFreePass = FALSE;
00239 }       

TraceControl::~TraceControl  )  [virtual]
 

Destructor, does nothing.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/12/94

Definition at line 253 of file tracectl.cpp.

00254 {
00255     InitBitmap(); // Free bitmaps if there are any
00256     RemoveTree();
00257     if (pTraceRegion) delete pTraceRegion;
00258     if (pCurrentPath) delete pCurrentPath;
00259     if (pFill) delete pFill;
00260     if (pStats) delete pStats;
00261     if (pErrorRegionList) delete pErrorRegionList;
00262     if (pThresholdPixelOp) delete pThresholdPixelOp;
00263     if (pColourThresholdPixelOp) delete pColourThresholdPixelOp;
00264     if (pPositivePixelOp) delete pPositivePixelOp;
00265 
00266 
00267 #ifdef _DEBUG
00268     for (INT32 i=0; i<NUM_TRACECTL_DEBUG_BITMAPS; i++) if (pDebug[i]) delete pDebug[i];
00269 #endif
00270 } 


Member Function Documentation

BOOL TraceControl::CalculateStatistics  )  [protected, virtual]
 

To determine the stats that help us find the optimum grad fill.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
None [INPUTS]
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: Many possible Scope: Public

See also:
-
GDraw is called to plot the trace path in a way such that we obtain various useful stats.

Definition at line 1318 of file tracectl.cpp.

01319 {
01320 #if TRACEUSESTATS
01321     if (!pStats) if ((pStats = /*assign*/ new KernelStatistics) == NULL) return FALSE;
01322 
01323     ERROR3IF ((!pUndithered) || (!pProposed), "CalculateStatistics() missing some bitmaps");
01324     ERROR2IF ((!pCurrentPath), FALSE, "CalculateStatistics() called without path to grad fill"); 
01325     
01326     if (!(ALU->SetA(pUndithered))) return FALSE;
01327 
01328     //TRACEUSER( "Alex", _T("Calc stats\n"));
01329 
01330     return (ALU->GetStatistics(&(pCurrentPath->InkPath), pStats));
01331 #else
01332     return TRUE;
01333 #endif
01334 }

TraceControl::CC_DECLARE_DYNCREATE TraceControl   )  [private]
 

BOOL TraceControl::CheckMinimumArea BfxPixelOp pBfxPixelOp  )  [protected, virtual]
 

Determines whether atleast (MinimumArea) pixels are within the region.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
pBfxPixelOp = pointer to the pixel op to use [INPUTS]
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: None yet Scope: Public

See also:
TraceControl::FloodSearch
FoundRegion is set according the the result. The search starts at InitialX/InitialY

This call *must* be done immediately (yes, immediately) after the cache is cleared. If not you lose all your caching. Har har.

Definition at line 1028 of file tracectl.cpp.

01029 {
01030     return pBfxPixelOp->CheckMinimumArea(MinimumArea, InitialX, InitialY, &FoundRegion);
01031 }

BOOL TraceControl::FormGradFill  )  [protected, virtual]
 

Calculate the optimum grad fill from the stats available.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
None [INPUTS]
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: Many possible Scope: Public

See also:
-
We do some cunning processing and end up with a grad fill attribute. We use the statistics from CalculateStatistics above.

Definition at line 1355 of file tracectl.cpp.

01356 {
01357     GFStartX = 0;
01358     GFStartY = 0;
01359     GFEndX = XSize;
01360     GFEndY = YSize;
01361 
01362 #if TRACEUSESTATS
01363     ERROR3IF((!pStats), "How come we got here without a statistics block then?!");
01364     INT32 R = (INT32)(pStats->R * 255.0);
01365     INT32 G = (INT32)(pStats->G * 255.0);
01366     INT32 B = (INT32)(pStats->B * 255.0);
01367 #if 0
01368 UINT32 pval = (UINT32)(pStats->Pixel);
01369 R = (pval/*>>0*/) & 0xFF; // Bitmaps are TRGB, colourrefs are TBGR
01370 G = (pval>>8) & 0xFF;
01371 B = (pval>>16) & 0xFF;
01372 #endif
01373 
01374     if (R<0) R=0;
01375     if (G<0) G=0;
01376     if (B<0) B=0;
01377     if (R>255) R=255;
01378     if (G>255) G=255;
01379     if (B>255) B=255;
01380 
01381     GFStartC = GFEndC = (DWORD)(R | (G<<8) | (B<<16));
01382 
01383     //TRACEUSER( "Alex", _T("Trying colour R=%d G=%d B=%d N=%d\n"),R,G,B,pStats->N);
01384 
01385     return TRUE;
01386 
01387 #else
01388 
01389     GFStartC = GFEndC = (DWORD)(pPositivePixelOp->ReadOriginalPixel(InitialX, InitialY)) &0x00FFFFFF;
01390     return TRUE;
01391 
01392 #endif
01393 }

BOOL TraceControl::GetBitmaps KernelBitmap **  theOriginal = NULL,
KernelBitmap **  theProposed = NULL,
KernelBitmap **  theUndithered = NULL
[virtual]
 

Returns the current bitmap pointers.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
None [INPUTS]
theOriginal = pointer to a place to store a pointer to the original to trace [OUTPUTS] we'll be using. May be NULL if no record required of this. theProposed = pointer to a place to store a pointer to the proposed image we'll be using. May be NULL if no record required of this. theTemp = pointer to a place to store a pointer to the temp image we'll be using. May be NULL if no record required of this.
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: None yet Scope: Public

See also:
-
None the bitmap pointers may be NULL if not initialised yet (for instance if no tracing has yet been done).

Definition at line 557 of file tracectl.cpp.

00559 {
00560 
00561     if (theOriginal) *theOriginal = pOriginal;
00562     if (theProposed) *theProposed = pProposed;
00563     if (theUndithered) *theUndithered = pUndithered;
00564     return TRUE;
00565 }

BOOL TraceControl::GetParams TraceMethod pMethod = NULL,
INT32 *  pMinimumArea = NULL,
double *  pMaximumInitialAreaErrorThreshold = NULL,
double *  pMinimumInitialAreaErrorThreshold = NULL,
double *  pInitialAreaErrorRatio = NULL,
double *  pMinGradFillError = NULL,
double *  pGradFillErrorRatio = NULL,
double *  pMinPixelError = NULL,
double *  pMaxPixelError = NULL,
double *  pPixelErrorRatio = NULL,
double *  pQuantColours = NULL,
double *  pBlur = NULL,
double *  pSmooth = NULL
[virtual]
 

Gets the tracing parameters.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
None [INPUTS]
double values of parameters to read. May be set to NULL to not read them [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: mainly memory. Scope: Public

See also:
-

Definition at line 302 of file tracectl.cpp.

00317 {
00318     if (pMethod)                            *pMethod                            =Method;
00319     if (pMinimumArea)                       *pMinimumArea                       =MinimumArea;
00320     if (pMaximumInitialAreaErrorThreshold)  *pMaximumInitialAreaErrorThreshold  =MaximumInitialAreaErrorThreshold;
00321     if (pMinimumInitialAreaErrorThreshold)  *pMinimumInitialAreaErrorThreshold  =MinimumInitialAreaErrorThreshold;
00322     if (pInitialAreaErrorRatio)             *pInitialAreaErrorRatio             =InitialAreaErrorRatio;
00323     if (pMinGradFillError)                  *pMinGradFillError                  =MinGradFillError;
00324     if (pGradFillErrorRatio)                *pGradFillErrorRatio                =GradFillErrorRatio;
00325     if (pMinPixelError)                     *pMinPixelError                     =MinPixelError;
00326     if (pMaxPixelError)                     *pMaxPixelError                     =MaxPixelError;
00327     if (pPixelErrorRatio)                   *pPixelErrorRatio                   =PixelErrorRatio;
00328     if (pQuantColours)                      *pQuantColours                      =QuantColours;
00329     if (pBlur)                              *pBlur                              =Blur;
00330     if (pSmooth)                            *pSmooth                            =Smooth;
00331     return TRUE;
00332 }

Node * TraceControl::GetPaths void   )  [virtual]
 

Returns the current path.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
None [INPUTS]
None [OUTPUTS]
Returns:
^CurrentPath or NULL if none

Errors: None yet Scope: Public

See also:
-

Definition at line 1075 of file tracectl.cpp.

01076 {
01077     return pTree;
01078 }

BOOL TraceControl::GetProgress INT32 *  pPercent = NULL,
INT32 *  pNumPaths = NULL,
INT32 *  pNumCusps = NULL,
INT32 *  pNumPoints = NULL,
BOOL *  pProgressDone = NULL
[virtual]
 

Returning information for status line function.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
Pointers to things to fill in [INPUTS]
*pPercent = percentage of way through trace [OUTPUTS] pNumPaths = number of paths pNumCusps = number of cusps pNumPoints = number of points pProgressDone = TRUE if complete else false
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: None yet Scope: Public

See also:
None
The pointers may be NULL if you're not interested in getting them filled in

Definition at line 985 of file tracectl.cpp.

00990 {
00991     if (pProgressDone) *pProgressDone = ProgressDone && pOriginal;
00992     if (pPercent)
00993     {
00994         INT32 percent=ProgressDone?100:(INT32)(1.0+100.0*(
00995             ((double)ScanPointY/(double)(YSize?YSize:1)+(double)NumPasses)/(double)(TotalPasses?TotalPasses:1) ));
00996         if ((percent<0 ) || (!pOriginal) || (!ProgressDone && ScanPointX==0 && ScanPointY==0 && NumPasses==0)) percent=0;
00997         if (percent>100) percent=100;
00998         *pPercent=percent;
00999     }
01000     if (pNumPaths) *pNumPaths=NumPaths;
01001     if (pNumCusps) *pNumCusps=NumCusps;
01002     if (pNumPoints) *pNumPoints=NumPoints;
01003     return TRUE;
01004 }

BOOL TraceControl::InitBitmap KernelBitmap theOriginal = NULL  )  [virtual]
 

Initialises trace control object to work on a given set of bitmaps.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
theOriginal = pointer to the bitmap to use as the original to trace [INPUTS] or NULL to cancel use of bitmap
theProposed = pointer to a place to store a pointer to the proposed image [OUTPUTS] we'll be using. May be NULL if no record required of this. theTemp = pointer to a place to store a pointer to the temp image we'll be using. May be NULL if no record required of this.
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: mainly memory. Scope: Public

See also:
-
Also, if we don't have a traceregion or a grad fill we claim these.

Definition at line 423 of file tracectl.cpp.

00424 {
00425 #ifdef _DEBUG
00426     for (INT32 i=0; i<NUM_TRACECTL_DEBUG_BITMAPS; i++) if (pDebug[i]) {delete pDebug[i];pDebug[i]=NULL;DebugInvalid[i]=TRUE;}
00427 #endif
00428 
00429     if (pErrorRegionList)
00430     {
00431         // We don't want this around
00432         delete pErrorRegionList;
00433         pErrorRegionList = NULL;
00434     }
00435 
00436     if (pThresholdPixelOp) delete pThresholdPixelOp;
00437     if (pColourThresholdPixelOp) delete pColourThresholdPixelOp;
00438     if (pPositivePixelOp) delete pPositivePixelOp;
00439     pThresholdPixelOp = NULL;
00440     pColourThresholdPixelOp = NULL;
00441     pPositivePixelOp = NULL;
00442 
00443     XSize = 0;
00444     YSize = 0;
00445 
00446     if (!pTraceRegion) if ((pTraceRegion /*assign*/ = new TraceRegion) == NULL) return FALSE;
00447     if (!pFill) if ((pFill /*assign*/ = new LinearFillAttribute) == NULL) return FALSE;
00448 
00449     if (!theOriginal) // They've asked us not to use this bitmap after all
00450     {
00451         // if we have a proposed copy, delete it
00452         if (pProposed) delete pProposed;
00453         if (pUndithered) delete pUndithered;
00454 
00455         pProposed = NULL;
00456         pUndithered = NULL;
00457 
00458         // record no original
00459         pOriginal = NULL;
00460         return TRUE;    // We succeeded
00461     }
00462     // if we have a proposed copy, delete it
00463     if (pProposed) delete pProposed;
00464     if (pUndithered) delete pUndithered;
00465 
00466     if (!RemoveTree(TRUE)) return FALSE;
00467     ProgressDone=0;
00468 
00469     pProposed = NULL;
00470     pUndithered = NULL;
00471 
00472     // Make up some pixel ops - if any memory allocs fail pOriginal will be NULL still
00473     if (Method == TRACEMETHOD_TRUECOL)
00474     {
00475         if ((pThresholdPixelOp = /*assign*/ new BfxThresholdPixelOp) ==NULL) return FALSE;
00476         if ((pColourThresholdPixelOp = /*assign*/ new BfxColourThresholdPixelOp) ==NULL) return FALSE;
00477         if ((pPositivePixelOp = /*assign*/ new /*BfxPositivePixelOp*/BfxColourThresholdPixelOp) ==NULL) return FALSE;
00478     }
00479     else
00480     {
00481         if ((pThresholdPixelOp = /*assign*/ new BfxThresholdPixelOpPseudo) ==NULL) return FALSE;
00482         if ((pColourThresholdPixelOp = /*assign*/ new BfxColourThresholdPixelOpPseudo) ==NULL) return FALSE;
00483         if ((pPositivePixelOp = /*assign*/ new /*BfxPositivePixelOp*/BfxColourThresholdPixelOpPseudo) ==NULL) return FALSE;
00484     }
00485 
00486 
00487     // Record for us
00488     pOriginal = theOriginal;
00489 
00490     FirstShape = TRUE;
00491 
00492     return TRUE; 
00493 }

BOOL TraceControl::MarkInitialArea  )  [protected, virtual]
 

Marks out intial area in temp bitmap.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
None [INPUTS]
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: Many possible Scope: Public

See also:
-
We find the next error region in the error region list and ensure that this is marked as REGION_PIXEL in the temporary bitmap. We do this by copying from the top byte of the Proposed bitmap if there are more regions on the list, otherwise we generate a new set of error regions in the following manner:

The temporary bitmap is marked such that all those points whose squared errors exceed InitialAreaError^2 are set and all others cleared. Then BuildErrorList is called to build up the error list (well that's a surprise).

Note we don't actually need the path for this as we can assume that the whole path is set, which is fair enough as the initial area will only be required when we haven't got a path.

Definition at line 1108 of file tracectl.cpp.

01109 {
01110     ERROR3IF (HavePath, "MarkInitialArea() called when a path was set up. Wierd...");
01111     ERROR3IF ((!pUndithered) || (!pProposed), "MarkInitialArea() missing some bitmaps");
01112 
01113     BOOL FirstCall = FALSE;
01114 
01115     if (!pErrorRegionList)
01116     {
01117         if ((pErrorRegionList = /*assign*/ new BfxErrorRegionList) == NULL) return FALSE;
01118         if (!pErrorRegionList->Init(1000))
01119         {
01120             delete pErrorRegionList;
01121             pErrorRegionList = NULL;
01122             return FALSE;
01123         }
01124         FirstCall = TRUE;
01125     }
01126 
01127     // What the main loop does: (just in case you were wondering)
01128     //
01129     // Tries to find something on the error region list
01130     // If it's now empty:
01131     //  tries the next scan point.
01132     //  (If the next scanpoint is off the end of the bitmap, resets it and tries again using a lower threshold,
01133     //   if it still can't find one, we're done)
01134     //  Marks regions of approximately that colour which form the new error region list (sorted by size)
01135     // Takes the next error region
01136     // Repeats until the next error region is greater or equal to 2 pixels in size.
01137     do
01138     {
01139 
01140         pErrorRegionList->Next(); // Move on to next one (doens't move if EOL)
01141         while (!pErrorRegionList->GetCurrent(&InitialX,&InitialY,&RegionArea)) // at end of list
01142         {
01143             // Go back to start
01144             pErrorRegionList->ResetRead();
01145 
01146             if (TRUE || ShapeFreePass || !pErrorRegionList->GetCurrent(&InitialX,&InitialY,&RegionArea)) // if no items on new list
01147             {
01148 //              double AError = 0.0;
01149 //              double BError = 0.0;
01150 //              INT32 TotalPixels = 0;
01151 //              INT32 MarkedPixels = 0;
01152 
01153                 INT32 theErrorThreshold = (INT32)(0.5+3.0*DoubleSquare(InitialAreaErrorThreshold * 255.0));
01154                 
01155 
01156                 // Find the next ScanPoint
01157                 BOOL FoundScanPoint=FALSE;
01158                 
01159                 do
01160                 {
01161                     // Don't look for one if we haven't done the very first area mark yet
01162                     if (!FirstCall)
01163                     {
01164                         theErrorThreshold = (INT32)(0.5+3.0*DoubleSquare(InitialAreaErrorThreshold * 255.0));
01165                         if (!(ALU->SetB(pProposed) && ALU->SetT(pUndithered))) return FALSE;
01166                         if (!(ALU->ScanThreshold(theErrorThreshold, &ScanPointX, &ScanPointY, NULL, &FoundScanPoint, TRUE))) return FALSE;
01167                     }
01168                                         
01169                     // If we haven't done the first area mark yet, or didn't find a point, we need to mark the area
01170                     if (FirstCall || !FoundScanPoint)
01171                     {
01172                         // Reset ScanPoint
01173                         ScanPointX=0;
01174                         ScanPointY=0;
01175                         
01176                         // Only on noninitial calls do we need to reduce the threshold
01177                         if (!FirstCall)
01178                         {
01179                             NumPasses++;
01180                             if (InitialAreaErrorThreshold-1E-10<=MinimumInitialAreaErrorThreshold)
01181                             {
01182                                 FoundRegion = FALSE; // We haven't & can't find an error region - so all done!
01183                                 ProgressDone=TRUE;
01184                                 return TRUE;         // OK though
01185                             }
01186                             InitialAreaErrorThreshold *= InitialAreaErrorRatio;
01187                         }
01188                         
01189                         // We're certainly not an initial call now
01190                         FirstCall=FALSE;
01191 
01192                         // Calculate new error threshold
01193                         if (InitialAreaErrorThreshold<=MinimumInitialAreaErrorThreshold)
01194                             InitialAreaErrorThreshold=MinimumInitialAreaErrorThreshold;
01195                         TRACEUSER( "Alex", _T("> Reducing InitialAreaErrorThreshold to %f\n"),InitialAreaErrorThreshold);
01196 
01197                     }               
01198                 } while (!FoundScanPoint);
01199 
01200                 // OK, we've found a ScanPoint to start off with. Hurrah. Now we take it's colour and build an ErrorRegion
01201                 // List based on that colour
01202 
01203                 // Clear the bit off, we don't want to deal with this pixel again unless it is remarked at a lower
01204                 // threshold. Note that if we actuially plot over this pixel, We later clear this bit for anything
01205                 // positively affected
01206                 //pUndithered->PlotPixel(ScanPointX,ScanPointY, pUndithered->ReadPixel(ScanPointX, ScanPointY) & ~BIT_THRESHOLD);
01207 
01208 
01209 
01210                 // Obtain the pixels colour
01211                 ScanPointColour =pPositivePixelOp->ReadOriginalPixel(ScanPointX, ScanPointY) & 0x00FFFFFF;              
01212 
01213 
01214                 // Now mark on thresholded error. What this means is we're marking all the pixels of a similar colour
01215                 // to the one which we've just found which are 'wrong' in the proposed bitmap as well. We'll use this
01216                 // as the first basis of our trace. We hope the area is large enough to give us a good approximation to
01217                 // a grad fill. This will hopefully extend over a larger area on the first refinement if (say) we've
01218                 // picked a grad filled band.
01219                 if (!pColourThresholdPixelOp->ClearCachedArea()) return FALSE;
01220                 if (!pColourThresholdPixelOp->SetAuxilliaryBitmaps(NULL, pProposed, pUndithered, theErrorThreshold, ScanPointColour))
01221                     return FALSE;
01222                 
01223                 // For the time being just insert the area we are using
01224                 InitialX=ScanPointX; InitialY=ScanPointY;
01225 
01226                 ScanPointX++;
01227                 if (ScanPointX>=XSize) {ScanPointX=0;ScanPointY++;} // we deliberately let this overrun
01228 
01229                 // Check minimum area & set FoundRegion
01230                 if (!CheckMinimumArea(pColourThresholdPixelOp)) return FALSE;
01231                 RegionArea = MinimumArea + 1; // Bodge
01232 
01233                 if (!pColourThresholdPixelOp->IsInRegion(InitialX, InitialY))
01234                 {
01235                     FoundRegion=FALSE;
01236 //                  ERROR3IF(IsUserName("Alex"),"ScanThreshold lied");
01237                 }
01238 
01239                 if (!pErrorRegionList->Empty()) return FALSE;
01240                 if ((FoundRegion) && (RegionArea>=MinimumArea)) if (!(pErrorRegionList->Insert(InitialX, InitialY, RegionArea))) return FALSE;
01241                 if (!(pErrorRegionList->Sort() && pErrorRegionList->ResetRead())) return FALSE; 
01242                 
01243             }
01244             // Mark begining of (as yet) shape free pass
01245             ShapeFreePass = TRUE;
01246         }
01247 
01248         // We've got one
01249         FoundRegion = TRUE;
01250 
01251     } while // validation - Loop if it's NOT (valid region area, AND this pixel set AND any adjacent pixel set)
01252         (!( (RegionArea>MinimumArea) &&
01253             (pColourThresholdPixelOp->IsInRegion(InitialX, InitialY)) &&
01254             ( // an adjacent pixel is set
01255                 pColourThresholdPixelOp->IsInRegion(InitialX-1, InitialY  ) ||
01256                 pColourThresholdPixelOp->IsInRegion(InitialX+1, InitialY  ) ||
01257                 pColourThresholdPixelOp->IsInRegion(InitialX,   InitialY-1) ||
01258                 pColourThresholdPixelOp->IsInRegion(InitialX-1, InitialY-1) ||
01259                 pColourThresholdPixelOp->IsInRegion(InitialX-1, InitialY-1) ||
01260                 pColourThresholdPixelOp->IsInRegion(InitialX,   InitialY+1) ||
01261                 pColourThresholdPixelOp->IsInRegion(InitialX-1, InitialY+1) ||
01262                 pColourThresholdPixelOp->IsInRegion(InitialX-1, InitialY+1) )
01263         ));
01264 
01265     return (pErrorRegionList->MarkUsed());
01266 }

BOOL TraceControl::PlotGradFill BOOL  ToProposed,
BOOL  UsePath = TRUE
[protected, virtual]
 

Plots the grad fill on top of the proposed bitmap into the temp bitmap.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
ToProposed set if to plot to Proposed rather than temp [INPUTS] UsePath = TRUE to plot path, FALSE to plot whole area
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: Many possible Scope: Public

See also:
-
Pretty much a straight GDraw call or two.

Definition at line 1414 of file tracectl.cpp.

01415 {
01416     ERROR3IF ((!pUndithered) || (!pProposed) || (!ToProposed && !pUndithered), "PlotGradFill() missing some bitmaps");
01417     if (UsePath) ERROR2IF ((!pCurrentPath), FALSE, "PlotGradFill() called without path to grad fill"); 
01418 
01419     if (ToProposed)
01420     {
01421         if (!(ALU->SetA(pProposed))) return FALSE;
01422     }
01423     else
01424     {
01425         if (!(ALU->SetA(pUndithered) && ALU->SetB(pProposed) && ALU->ByteCopyBA())) return FALSE;
01426     }
01427 
01428     return (ALU->GradFillPath(UsePath?&(pCurrentPath->InkPath):NULL, GFStartC, GFEndC,
01429                               GFStartX, GFStartY, GFEndX, GFEndY, FALSE, TRUE));
01430 }

BOOL TraceControl::RemoveTree BOOL  DeleteIt = TRUE  )  [virtual]
 

Relinquishes control of the tree structure.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
DeleteIt = TRUE to delete the tree, FALSE to merely disclaim responsibility for it [INPUTS]
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: mainly memory. Scope: Public

See also:
-
This call would be called with TRUE to delete the tree for instance on destruction of the object or if the trace was cancelled, but with FALSE if the tree was inserted into a doc.

This call does nothing if the tree isn't there

Definition at line 516 of file tracectl.cpp.

00517 {
00518     if (!DeleteIt) {pTree = NULL; pJoinNode=NULL; return TRUE;}
00519 
00520     if (pTree)
00521     {
00522         Node * pFirstChild = pTree->FindFirstChild();
00523         if (pFirstChild) pTree->DeleteChildren(pFirstChild);
00524         delete pTree;
00525         pTree = NULL;
00526         pJoinNode = NULL;
00527     }
00528     return TRUE;
00529 }

BOOL TraceControl::SetParams TraceMethod pMethod = NULL,
INT32 *  pMinimumArea = NULL,
double *  pMaximumInitialAreaErrorThreshold = NULL,
double *  pMinimumInitialAreaErrorThreshold = NULL,
double *  pInitialAreaErrorRatio = NULL,
double *  pMinGradFillError = NULL,
double *  pGradFillErrorRatio = NULL,
double *  pMinPixelError = NULL,
double *  pMaxPixelError = NULL,
double *  pPixelErrorRatio = NULL,
double *  pQuantColours = NULL,
double *  pBlur = NULL,
double *  pSmooth = NULL
[virtual]
 

Sets the tracing parameters.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
^double values of parameters to set. May be set to NULL to not change them [INPUTS]
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: mainly memory. Scope: Public

See also:
-
This call can only run after InitBitmaps() as some of the parameters live in the TraceRegion (yes, this is a bit messy)

Definition at line 367 of file tracectl.cpp.

00382 {
00383     ERROR2IF((!pTraceRegion), FALSE, "SetParams() called without prior call to InitBitmaps()");
00384     if (pMethod)                            Method                              =*pMethod;
00385     if (pMinimumArea)                       MinimumArea                         =*pMinimumArea;
00386     if (pMaximumInitialAreaErrorThreshold)  MaximumInitialAreaErrorThreshold    =*pMaximumInitialAreaErrorThreshold;
00387     if (pMinimumInitialAreaErrorThreshold)  MinimumInitialAreaErrorThreshold    =*pMinimumInitialAreaErrorThreshold;
00388     if (pInitialAreaErrorRatio)             InitialAreaErrorRatio               =*pInitialAreaErrorRatio;
00389     if (pMinGradFillError)                  MinGradFillError                    =*pMinGradFillError;
00390     if (pGradFillErrorRatio)                GradFillErrorRatio                  =*pGradFillErrorRatio;
00391     if (pMinPixelError)                     MinPixelError                       =*pMinPixelError;
00392     if (pMaxPixelError)                     MaxPixelError                       =*pMaxPixelError;
00393     if (pPixelErrorRatio)                   PixelErrorRatio                     =*pPixelErrorRatio;
00394     if (pQuantColours)                      QuantColours                        =*pQuantColours;
00395     if (pBlur)                              Blur                                =*pBlur;
00396     if (pSmooth)                            Smooth                              =*pSmooth;
00397     return TRUE;
00398 }

BOOL TraceControl::SetPath NodePath pNodePath  )  [virtual]
 

Sets up the NP to use.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
pNodePath = pointer to the NP to use or NULL for whole image [INPUTS]
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: None yet Scope: Public

See also:
-
It is the callers responsibility to deal with the old NP (in terms of memory management) if this call is used.

Definition at line 1052 of file tracectl.cpp.

01053 {
01054     pCurrentPath = pNodePath;
01055     if (!pCurrentPath) HavePath = FALSE;
01056     return TRUE;
01057 }

BOOL TraceControl::Trace BOOL *  Done  )  [virtual]
 

Spits out a single object into the trace output stream.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
None [INPUTS]
Done - pointer to BOOL to indicate completion [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: Many possible Scope: Public

See also:
-
This is the central routine that actually orchestrates tracing of a single object. Note that a return of FALSE indicates an error condition (and tracing should be abandonned). Successful completion is indicated by the setting of the Done flag. It is guaranteed that (a) the Done flag will be either cleared or set (unless you are silly enough to pass a Null pointer in 0 in which case you wouldn't be able to check it anyway), and (b) the Done flag will be clear if an error condition occurs. Thus Done ALWAYS indicates successful completion.

Definition at line 590 of file tracectl.cpp.

00591 {
00592     // First set done flag to false after checking it exists. This way all
00593     // exits will be clean.
00594     ERROR2IF(!Done, FALSE, "Don't call TraceControl::Trace with a NULL Done ptr");
00595     *Done = FALSE;
00596 
00597     ERROR2IF((!pOriginal), FALSE, "Don't call TraceControl::Trace without calling InitBitmaps() first");
00598 
00599     // Welcome to control algorithm No.2. Hopefully this one won't turn out exponential.
00600     //
00601     // Minor introduction to state storage:
00602     //
00603     // Various things about the state of tracing are stored across path generation. These are:
00604     //      InitialAreaErrorThreshold - this decreases monotonically throughout the trace
00605     //      ErrorRegionList - (see MarkInitialArea()) and it's information in top byte of ProposedImage
00606     //
00607     // No, OK it wasn't exponential, merely square. Now I allege we have an O(n) algorithm or at least
00608     // an O(n^(3/2)) one. Welcome to algorithm no. 3 and the world of the BfxPixelOp.
00609 
00610     // Do some stuff on the first call
00611     if (FirstShape)
00612     {
00613         if (!RemoveTree(TRUE)) return FALSE;
00614 
00615         if ((pTree = /*assign*/ new NodeGroup) ==NULL ) return FALSE;
00616         if ((pJoinNode = /*assign*/ new AttrStrokeColour(pTree, FIRSTCHILD)) == NULL) return FALSE;
00617         DocColour TheColour(COLOUR_NONE);
00618         ((AttrStrokeColour *)pJoinNode)->SetStartColour(&TheColour);
00619         NodePath * pRect;
00620         AttrFillGeometry * pRectCol;
00621         if (!(((pRect = /*assign*/ new NodePath(pJoinNode, NEXT))!=NULL) && pRect->SetUpPath(32, 32))) return FALSE;
00622         if (!(((pRectCol = /*assign*/ new AttrFlatColourFill(pRect, FIRSTCHILD))!=NULL))) return FALSE;
00623         pJoinNode=pRect;
00624     
00625         TRACEUSER( "Alex", _T("> Removing dither\n"));
00626         if (pProposed) delete pProposed;
00627         if (pUndithered) delete pUndithered;
00628 
00629         pProposed = NULL;
00630         pUndithered = NULL;
00631 
00632         ERROR2IF(!ALU, FALSE, "OK, where's the ALU gone?");
00633 
00634         if (!ALU->SetB(pOriginal)) return FALSE;
00635         INT32 NumColours = (INT32)(17.5+(255.0-17.0)*QuantColours);
00636         if (Method==TRACEMETHOD_GREYSCALE) NumColours = (INT32)(2.5+(255.0-2.0)*QuantColours);
00637         if (!ALU->RemoveDither(&pUndithered, (INT32)(Blur*2.55+0.5), NumColours, Method)) return FALSE;
00638         ERROR2IF(!pUndithered, FALSE, "How come remove dither failed to generate a KB without generating an error");
00639 
00640         EndSlowJob();
00641         String_64 ProcessMessage(_R(IDS_TRACEDLG_TRACING));
00642         BeginSlowJob(100, FALSE, &ProcessMessage);
00643 
00644         // Now we should go and claim proposed bitmap the size of the undithered one
00645         if ((pProposed = /*assign*/ ALU->NewBitmap(pUndithered,0,0/*,32*/)) == NULL)
00646         {
00647             delete pUndithered;
00648             pUndithered = NULL;
00649             return FALSE;
00650         }
00651 
00652         ALU->SetA(pProposed);
00653         ALU->ZeroA(0xFF);
00654 
00655         if (!ALU->GetSize(pUndithered, &XSize, &YSize)) return FALSE;
00656 
00657         if (!(
00658             pThresholdPixelOp->SetBitmap(pUndithered, BIT_CACHEV_THRESHOLD, BIT_CACHES_THRESHOLD, FALSE) &&
00659             pColourThresholdPixelOp->SetBitmap(pUndithered, BIT_CACHEV_COLOURTHRESHOLD, BIT_CACHES_COLOURTHRESHOLD, FALSE) &&
00660             pPositivePixelOp->SetBitmap(pUndithered, BIT_CACHEV_POSITIVE, BIT_CACHES_POSITIVE, FALSE) &&
00661 
00662             TRUE)) return FALSE;
00663 
00664         TRACEUSER( "Alex", _T("> First shape, here we go\n"));
00665         FirstShape = FALSE;
00666         ShapeFreePass = FALSE;
00667         InitialAreaErrorThreshold = MaximumInitialAreaErrorThreshold;
00668         GradFillError = 1.0;
00669         NewGradFillError = 0.0;
00670         if (!(
00671             pThresholdPixelOp->ClearEntireCache() &&
00672             pColourThresholdPixelOp->ClearEntireCache() &&
00673             pPositivePixelOp->ClearEntireCache() &&
00674             TRUE)) return FALSE;
00675         
00676         // set aux bitmaps up so we can start reading colours
00677         if (!pPositivePixelOp->SetAuxilliaryBitmaps(NULL, pProposed, pUndithered, 0, 0))
00678             return FALSE;
00679 
00680 
00681 #ifdef _DEBUG
00682         for (INT32 i=0; i<NUM_TRACECTL_DEBUG_BITMAPS; i++) if (pDebug[i]) {delete pDebug[i];pDebug[i]=NULL;DebugInvalid[i]=TRUE;}
00683 #endif
00684         SetDebugBitmap(0, pUndithered);
00685 
00686         TotalPasses=0;
00687         NumPasses=0;
00688         NumPaths=0;
00689         NumCusps=0;
00690         NumPoints=0;
00691         ProgressDone=0;
00692 
00693         double iaet=InitialAreaErrorThreshold;
00694         while (TRUE)
00695         {
00696 
00697             // This is the same loop we use
00698             if (iaet<=MinimumInitialAreaErrorThreshold)
00699                 iaet=MinimumInitialAreaErrorThreshold;
00700             TotalPasses++;
00701 
00702             if (iaet-1E-10<=MinimumInitialAreaErrorThreshold)
00703                 break;
00704             iaet *= InitialAreaErrorRatio;
00705         }
00706 
00707 
00708         // build a path
00709         pRect->InkPath.FindStartOfPath();
00710 
00711         // Start at bottom left corner
00712         pRect->InkPath.InsertMoveTo(DocCoord(0,0));
00713         pRect->InkPath.InsertLineTo(DocCoord(0,YSize<<8));
00714         pRect->InkPath.InsertLineTo(DocCoord(XSize<<8,YSize<<8));
00715         pRect->InkPath.InsertLineTo(DocCoord(XSize<<8,0));
00716         pRect->InkPath.InsertLineTo(DocCoord(0,0));
00717 
00718         // Close the path properly
00719         pRect->InkPath.CloseSubPath();
00720         pRect->InkPath.IsFilled = TRUE; // What lovely encapsulation & abstraction...
00721 
00722         // And give it a vaguely appropriate colour
00723         GFStartC = GFEndC = (DWORD)(pPositivePixelOp->ReadOriginalPixel(0, 0)) &0x00FFFFFF;
00724         INT32 R = 0;
00725         INT32 G = 0;
00726         INT32 B = 0;
00727         pPositivePixelOp->TranslateToRGB(GFStartC, pUndithered, &R, &G, &B);
00728         DocColour RectColour( R, G, B );
00729         GFStartX = 0;
00730         GFStartY = 0;
00731         GFEndX = XSize;
00732         GFEndY = YSize;
00733         pRectCol->SetStartColour(&RectColour);
00734         return PlotGradFill(TRUE, FALSE);
00735         // And next time do some more interesting shapes as FirstShape is FALSE
00736     }
00737 
00738     // Set proposed path to whole bitmap
00739     HavePath = FALSE;
00740 
00741     // There are two embedded exits from the main region finding loop - when we've found a beneficial region we
00742     // want to stick in the tree, and when we have decided the trace is complete.   
00743     while (TRUE)
00744     {
00745         ERROR1IF(KeyPress::IsEscapePressed(), FALSE, _R(IDS_ABORT));
00746 
00747         // Get the next error area out.
00748         // Occasionally (when there are no regions left in the error region list), this will result in a 
00749         // complete pass through the bitmap determining threshold error (and a recalculation of the threshold)
00750         // and the building up of a new error list. At the end we know that the temp bitmap is marked with
00751         // REGION_PIXEL
00752         if (!MarkInitialArea()) return FALSE;
00753 
00754         if (!FoundRegion)
00755         {
00756             // Wow! We've found *no* regions whose errors are greater than the Minimum threshold
00757             // error specified. This means (amazingly) we've done the trace!
00758             *Done = TRUE;
00759             return TRUE;
00760         }
00761 
00762         //TRACEUSER( "Alex", _T("Found Initial region at %d, %d, colour %x\n"),InitialX, InitialY, ScanPointColour);
00763 
00764 
00765         // We do a number of passes to refine the area. These consist of tracing the current region, finding the best
00766         // grad fill for it, and finding the region that grad fill positiviely affects. We must do at least two
00767         // passes.
00768         INT32 Passes = 0;
00769         BOOL UseColourThresholdPixelOp = TRUE;
00770         do
00771         {
00772             // InitialX & InitialY are set up. Our next step is to trace the region. We trace at first with
00773             // the minimum accuracy (i.e. the max PixelError) and reduce the accuracy until we have got a path
00774             // that works. Works means it has at least n% of the pixels of the original region.
00775             PixelError = MaxPixelError;
00776             BOOL RegionTraceable = FALSE;
00777             while ((PixelError>=MinPixelError) && !RegionTraceable)     
00778             {
00779                 if (!(
00780                     pTraceRegion->SetParams(&PixelError) &&
00781                     TracePath(UseColourThresholdPixelOp?pColourThresholdPixelOp:pPositivePixelOp) &&
00782                                                     // Trace region to path
00783                     CalculateStatistics() &&        // Calculate grad fill stats
00784                     TRUE)) return FALSE;
00785                 if (PixelError>MinPixelError)
00786                 {
00787                     PixelError *= PixelErrorRatio;
00788                     if (PixelError<MinPixelError) PixelError=MinPixelError;
00789                 } else PixelError=0.0; // Ensures loop terminates
00790                 RegionTraceable = (!pStats) || (pStats->N > 2); // Grrr with all these fancy pixel ops we can't get the area
00791                                                    // as it's not calculated yet. Oh well.
00792                 //( ((double)(pStats->N))/((double)RegionArea)>PixelAccuracyRatio );
00793             }
00794 
00795             UseColourThresholdPixelOp = FALSE;
00796 
00797             if (RegionTraceable)
00798             {
00799                 HavePath = TRUE;
00800 
00801                 // We have to plot the things twice at the moment to do the error calc until we've performed
00802                 // more GDraw mungery
00803                 if (!(
00804                     FormGradFill() &&               // Determine best grad fill
00805 //                  PlotGradFill(FALSE, FALSE) &&   // Plot proposed + grad fill to temp
00806                     TRUE)) return FALSE;
00807 /*
00808 We'll have to do this another way (like just do it on the cached area)
00809 
00810                 if (FoundRegion && (NewGradFillError >= GradFillError))
00811                 {
00812                     TRACEUSER( "Alex", _T("> This region doesn't reduce the error!\n"));
00813                     FoundRegion=FALSE; // We've gone seriously awry!
00814                 }
00815 */
00816                 INT32 theErrorThreshold = (INT32)(0.5+3.0*DoubleSquare(InitialAreaErrorThreshold * 255.0));
00817                 if (!pPositivePixelOp->ClearCachedArea()) return FALSE;
00818                 // This is a bodge until we have a way to calculate the true grad fill colour
00819                 if (!pPositivePixelOp->SetAuxilliaryBitmaps(NULL, pProposed, pUndithered, theErrorThreshold,
00820                         GFStartC /*pPositivePixelOp->ReadOriginalPixel(InitialX, InitialY) &0x00FFFFFF */))
00821                     return FALSE;
00822 
00823                 // BODGE! We start in the middle and look around for somewhere helpful
00824                 FoundRegion = pPositivePixelOp->IsInRegion(InitialX, InitialY);
00825                 INT32 xadj;
00826                 INT32 yadj;
00827                 if (!FoundRegion) for (yadj=-1; (yadj<=1) && !FoundRegion; yadj++) 
00828                     for (xadj=-1; (xadj<=1) && !FoundRegion; xadj++)
00829                     if (pPositivePixelOp->IsInRegion(InitialX+xadj, InitialY+yadj))
00830                     {
00831                         FoundRegion=TRUE;
00832                         InitialX+=xadj;
00833                         InitialY+=yadj; // break done by setting FoundRegion as we can't do 2 level break
00834                     }
00835                         
00836                 // OK OK so this clears out the cache. We've lost a maximum of 9 pixels.
00837                 if (FoundRegion) if (!CheckMinimumArea(pPositivePixelOp)) return FALSE;
00838                 // Sets FoundRegion
00839                 RegionArea = MinimumArea + 1; // Bodge
00840 
00841                 // If we marked any points as OK
00842                 if (FoundRegion)
00843                 {
00844                     // Is the current path & grad fill good enough for us?
00845                     // We must have done at least one top to bottom and one top to here pass. If we have
00846                     // done the maximum number of passes that's OK too. Other than that, we continue refining
00847                     // if the rate of decent of error is looking good.
00848                     if (TRUE /*don't refine while we're not doing grad fills*/
00849                         || (Passes>=/*MaxRefinementPasses*/1) || ((Passes != 0) && !(FALSE /* some other loop criterion*/)))
00850                     {
00851                         
00852                         if (!PlotGradFill(TRUE, TRUE)) return FALSE;
00853                         if ((Smooth>3.0) && pCurrentPath)
00854                         {
00855 //                          if (!pCurrentPath->InkPath.Smooth(Smooth*(256.0*65536.0/100.0))) return FALSE;
00856 
00857                             INT32 orignumcoords = pCurrentPath->InkPath.GetNumCoords();
00858 
00859                             // create a path and quantise to it
00860                             Path QuantPath;
00861                             INT32 startpoints=((orignumcoords>24)?orignumcoords:24)*5;
00862                             QuantPath.Initialise(startpoints,(startpoints>2400)?2400:startpoints);
00863 
00864                             // quantise original path to QuantPath
00865                             //pCurrentPath->InkPath.Quantise(64.0, &QuantPath);
00866 
00867                             double coordsmooth = Smooth*10.24; /* Smooth/100.0*4.0*256.0; */
00868                             
00869                             ProcessFlags QuantFlags(TRUE,FALSE,TRUE);
00870                             pCurrentPath->InkPath.CreateFlatPath(QuantFlags, coordsmooth, &QuantPath);
00871 
00872                             // create and fit a smooth curve to the data points.
00873                             
00874                             // Full range up to 4 pixels out
00875                             CurveFitObject Smoothed(&QuantPath, coordsmooth*coordsmooth);
00876 
00877                             if (Smoothed.Initialise(&QuantPath,QuantPath.GetNumCoords()))
00878                             {
00879                                 Smoothed.FitCurve();
00880                                 QuantPath.CloseSubPath();
00881                                 QuantPath.IsFilled=TRUE;
00882 
00883                                 // now that we've smoothed the curve lets check on the number
00884                                 // of coordinates we've generated. If its more, then we should
00885                                 // leave the original path as it was. If its less then replace
00886                                 if (QuantPath.GetNumCoords()<orignumcoords)
00887                                     if (!pCurrentPath->InkPath.CloneFrom(QuantPath)) return FALSE;
00888         
00889                             }
00890                         }
00891 
00892                         ShapeFreePass=FALSE;
00893                         //if (pErrorRegionList) pErrorRegionList->Empty(); // This is a bodge to ensure reevaluation
00894                         GradFillError = NewGradFillError;
00895 
00896                         if (pCurrentPath) NumPoints+=pCurrentPath->InkPath.GetNumCoords()/3;
00897                         NumPaths++;
00898                         //TRACEUSER( "Alex", _T("> Inserting path covering %d points after %d refinement(s)\n\n"),pStats->N, Passes);
00899 
00900                         INT32 R = 0;
00901                         INT32 G = 0;
00902                         INT32 B = 0;
00903                         pPositivePixelOp->TranslateToRGB(GFStartC, pUndithered, &R, &G, &B);
00904                         DocColour TheColour( R, G, B );
00905 
00906                         AttrFillGeometry * pFillGeometry = new AttrFlatColourFill;
00907                         if (!pFillGeometry) return FALSE; //new sets error
00908                         
00909                         pFillGeometry->SetStartColour(&TheColour);
00910                         pFillGeometry->AttachNode(pCurrentPath, FIRSTCHILD);
00911 
00912                         // The first node has to be attached under pTree, the rest to the right
00913                         if (pJoinNode)
00914                         {
00915                             pCurrentPath->AttachNode(pJoinNode, NEXT);
00916                         }
00917                         else
00918                         {
00919                             pCurrentPath->AttachNode(pTree, FIRSTCHILD);
00920                         }
00921 
00922                         pJoinNode = pCurrentPath;
00923                         pCurrentPath = NULL;
00924 
00925                         return TRUE;
00926                     }
00927 
00928                     // We do a refinement
00929                 }
00930             }
00931             else
00932             {
00933                 FoundRegion = FALSE;                // OK, so technically we found a region, but as we can't find
00934                                                     // a path that encloses it, we might as well pretend we haven't...
00935             }
00936 
00937             Passes++;
00938         } while (FoundRegion);          // repeat refinement if pur region hasn't disappeared - else try next one
00939         TRACEUSER( "Alex", _T("< Rejecting malformed error region\n"));
00940         HavePath = FALSE;
00941     }
00942 
00943     
00944     // We should never get here
00945     ERROR3("OK, How come a while(TRUE) terminated? Has someone inserted a break or what?");
00946     return FALSE;
00947 }

BOOL TraceControl::TracePath BfxPixelOp pBfxPixelOp  )  [protected, virtual]
 

A NodePath is traced from the temporary bitmap.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/1/95
Parameters:
None [INPUTS]
None [OUTPUTS]
Returns:
TRUE on success, FALSE (& error set) on failure

Errors: Many possible Scope: Public

See also:
-
The marked pixels from the temporary bitmap which are connected to Initial{X,Y} are turned into a NodePath which is then stored in CurrentPath.

Definition at line 1288 of file tracectl.cpp.

01289 {
01290     if (!pCurrentPath)
01291         if (!(((pCurrentPath = /*assign*/ new NodePath)!=NULL) && pCurrentPath->SetUpPath(32, 32))) return FALSE;
01292     ERROR3IF ((!pUndithered) || (!pProposed) || (!pBfxPixelOp), "TracePath() missing some bitmaps");
01293 
01294     return( pTraceRegion->UseBitmap(pUndithered) &&
01295             pTraceRegion->UsePath(&(pCurrentPath->InkPath)) &&
01296             pTraceRegion->Trace(InitialX, InitialY, pBfxPixelOp) &&
01297             TRUE );
01298 }


Member Data Documentation

double TraceControl::Blur [protected]
 

Definition at line 255 of file tracectl.h.

BOOL TraceControl::FirstShape [protected]
 

Definition at line 272 of file tracectl.h.

BOOL TraceControl::FoundRegion [protected]
 

Definition at line 275 of file tracectl.h.

DWORD TraceControl::GFEndC [protected]
 

Definition at line 292 of file tracectl.h.

INT32 TraceControl::GFEndX [protected]
 

Definition at line 289 of file tracectl.h.

INT32 TraceControl::GFEndY [protected]
 

Definition at line 290 of file tracectl.h.

DWORD TraceControl::GFStartC [protected]
 

Definition at line 291 of file tracectl.h.

INT32 TraceControl::GFStartX [protected]
 

Definition at line 287 of file tracectl.h.

INT32 TraceControl::GFStartY [protected]
 

Definition at line 288 of file tracectl.h.

double TraceControl::GradFillError [protected]
 

Definition at line 244 of file tracectl.h.

double TraceControl::GradFillErrorRatio [protected]
 

Definition at line 247 of file tracectl.h.

BOOL TraceControl::HavePath [protected]
 

Definition at line 271 of file tracectl.h.

double TraceControl::InitialAreaErrorRatio [protected]
 

Definition at line 242 of file tracectl.h.

double TraceControl::InitialAreaErrorThreshold [protected]
 

Definition at line 239 of file tracectl.h.

INT32 TraceControl::InitialX [protected]
 

Definition at line 276 of file tracectl.h.

INT32 TraceControl::InitialY [protected]
 

Definition at line 277 of file tracectl.h.

INT32 TraceControl::Log2BPP [protected]
 

Definition at line 259 of file tracectl.h.

double TraceControl::MaximumInitialAreaErrorThreshold [protected]
 

Definition at line 240 of file tracectl.h.

double TraceControl::MaxPixelError [protected]
 

Definition at line 251 of file tracectl.h.

TraceMethod TraceControl::Method [protected]
 

Definition at line 258 of file tracectl.h.

double TraceControl::MinGradFillError [protected]
 

Definition at line 246 of file tracectl.h.

INT32 TraceControl::MinimumArea [protected]
 

Definition at line 261 of file tracectl.h.

double TraceControl::MinimumInitialAreaErrorThreshold [protected]
 

Definition at line 241 of file tracectl.h.

double TraceControl::MinPixelError [protected]
 

Definition at line 250 of file tracectl.h.

double TraceControl::NewGradFillError [protected]
 

Definition at line 245 of file tracectl.h.

INT32 TraceControl::NumCusps [protected]
 

Definition at line 267 of file tracectl.h.

INT32 TraceControl::NumPasses [protected]
 

Definition at line 265 of file tracectl.h.

INT32 TraceControl::NumPaths [protected]
 

Definition at line 266 of file tracectl.h.

INT32 TraceControl::NumPoints [protected]
 

Definition at line 268 of file tracectl.h.

BfxPixelOp* TraceControl::pColourThresholdPixelOp [protected]
 

Definition at line 236 of file tracectl.h.

NodePath* TraceControl::pCurrentPath [protected]
 

Definition at line 224 of file tracectl.h.

BfxErrorRegionList* TraceControl::pErrorRegionList [protected]
 

Definition at line 231 of file tracectl.h.

LinearFillAttribute* TraceControl::pFill [protected]
 

Definition at line 225 of file tracectl.h.

double TraceControl::PixelError [protected]
 

Definition at line 249 of file tracectl.h.

double TraceControl::PixelErrorRatio [protected]
 

Definition at line 252 of file tracectl.h.

Node* TraceControl::pJoinNode [protected]
 

Definition at line 228 of file tracectl.h.

KernelBitmap* TraceControl::pOriginal [protected]
 

Definition at line 212 of file tracectl.h.

BfxPixelOp* TraceControl::pPositivePixelOp [protected]
 

Definition at line 237 of file tracectl.h.

KernelBitmap* TraceControl::pProposed [protected]
 

Definition at line 213 of file tracectl.h.

BOOL TraceControl::ProgressDone [protected]
 

Definition at line 269 of file tracectl.h.

KernelStatistics* TraceControl::pStats [protected]
 

Definition at line 233 of file tracectl.h.

BfxPixelOp* TraceControl::pThresholdPixelOp [protected]
 

Definition at line 235 of file tracectl.h.

TraceRegion* TraceControl::pTraceRegion [protected]
 

Definition at line 230 of file tracectl.h.

Node* TraceControl::pTree [protected]
 

Definition at line 227 of file tracectl.h.

KernelBitmap* TraceControl::pUndithered [protected]
 

Definition at line 214 of file tracectl.h.

double TraceControl::QuantColours [protected]
 

Definition at line 253 of file tracectl.h.

INT32 TraceControl::RegionArea [protected]
 

Definition at line 278 of file tracectl.h.

DWORD TraceControl::ScanPointColour [protected]
 

Definition at line 282 of file tracectl.h.

INT32 TraceControl::ScanPointX [protected]
 

Definition at line 280 of file tracectl.h.

INT32 TraceControl::ScanPointY [protected]
 

Definition at line 281 of file tracectl.h.

BOOL TraceControl::ShapeFreePass [protected]
 

Definition at line 273 of file tracectl.h.

double TraceControl::Smooth [protected]
 

Definition at line 256 of file tracectl.h.

INT32 TraceControl::TotalPasses [protected]
 

Definition at line 264 of file tracectl.h.

INT32 TraceControl::XSize [protected]
 

Definition at line 284 of file tracectl.h.

INT32 TraceControl::YSize [protected]
 

Definition at line 285 of file tracectl.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 04:02:02 2007 for Camelot by  doxygen 1.4.4