#include <tracectl.h>
Inheritance diagram for TraceControl:
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 Node * | GetPaths () |
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 | |
KernelBitmap * | pOriginal |
KernelBitmap * | pProposed |
KernelBitmap * | pUndithered |
NodePath * | pCurrentPath |
LinearFillAttribute * | pFill |
Node * | pTree |
Node * | pJoinNode |
TraceRegion * | pTraceRegion |
BfxErrorRegionList * | pErrorRegionList |
KernelStatistics * | pStats |
BfxPixelOp * | pThresholdPixelOp |
BfxPixelOp * | pColourThresholdPixelOp |
BfxPixelOp * | pPositivePixelOp |
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) |
Definition at line 136 of file tracectl.h.
|
Constructs the trace control object.
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 }
|
|
Destructor, does nothing.
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 }
|
|
To determine the stats that help us find the optimum grad fill.
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 }
|
|
|
|
Determines whether atleast (MinimumArea) pixels are within the region.
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 }
|
|
Calculate the optimum grad fill from the stats available.
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 }
|
|
Returns the current bitmap pointers.
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 }
|
|
Gets the tracing parameters.
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 }
|
|
Returns the current path.
Definition at line 1075 of file tracectl.cpp. 01076 { 01077 return pTree; 01078 }
|
|
Returning information for status line function.
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 }
|
|
Initialises trace control object to work on a given set of bitmaps.
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 }
|
|
Marks out intial area in temp bitmap.
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 }
|
|
Plots the grad fill on top of the proposed bitmap into the temp bitmap.
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 }
|
|
Relinquishes control of the tree structure.
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 }
|
|
Sets the tracing parameters.
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 }
|
|
Sets up the NP to use.
Definition at line 1052 of file tracectl.cpp. 01053 { 01054 pCurrentPath = pNodePath; 01055 if (!pCurrentPath) HavePath = FALSE; 01056 return TRUE; 01057 }
|
|
Spits out a single object into the trace output stream.
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 }
|
|
A NodePath is traced from the temporary bitmap.
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 }
|
|
Definition at line 255 of file tracectl.h. |
|
Definition at line 272 of file tracectl.h. |
|
Definition at line 275 of file tracectl.h. |
|
Definition at line 292 of file tracectl.h. |
|
Definition at line 289 of file tracectl.h. |
|
Definition at line 290 of file tracectl.h. |
|
Definition at line 291 of file tracectl.h. |
|
Definition at line 287 of file tracectl.h. |
|
Definition at line 288 of file tracectl.h. |
|
Definition at line 244 of file tracectl.h. |
|
Definition at line 247 of file tracectl.h. |
|
Definition at line 271 of file tracectl.h. |
|
Definition at line 242 of file tracectl.h. |
|
Definition at line 239 of file tracectl.h. |
|
Definition at line 276 of file tracectl.h. |
|
Definition at line 277 of file tracectl.h. |
|
Definition at line 259 of file tracectl.h. |
|
Definition at line 240 of file tracectl.h. |
|
Definition at line 251 of file tracectl.h. |
|
Definition at line 258 of file tracectl.h. |
|
Definition at line 246 of file tracectl.h. |
|
Definition at line 261 of file tracectl.h. |
|
Definition at line 241 of file tracectl.h. |
|
Definition at line 250 of file tracectl.h. |
|
Definition at line 245 of file tracectl.h. |
|
Definition at line 267 of file tracectl.h. |
|
Definition at line 265 of file tracectl.h. |
|
Definition at line 266 of file tracectl.h. |
|
Definition at line 268 of file tracectl.h. |
|
Definition at line 236 of file tracectl.h. |
|
Definition at line 224 of file tracectl.h. |
|
Definition at line 231 of file tracectl.h. |
|
Definition at line 225 of file tracectl.h. |
|
Definition at line 249 of file tracectl.h. |
|
Definition at line 252 of file tracectl.h. |
|
Definition at line 228 of file tracectl.h. |
|
Definition at line 212 of file tracectl.h. |
|
Definition at line 237 of file tracectl.h. |
|
Definition at line 213 of file tracectl.h. |
|
Definition at line 269 of file tracectl.h. |
|
Definition at line 233 of file tracectl.h. |
|
Definition at line 235 of file tracectl.h. |
|
Definition at line 230 of file tracectl.h. |
|
Definition at line 227 of file tracectl.h. |
|
Definition at line 214 of file tracectl.h. |
|
Definition at line 253 of file tracectl.h. |
|
Definition at line 278 of file tracectl.h. |
|
Definition at line 282 of file tracectl.h. |
|
Definition at line 280 of file tracectl.h. |
|
Definition at line 281 of file tracectl.h. |
|
Definition at line 273 of file tracectl.h. |
|
Definition at line 256 of file tracectl.h. |
|
Definition at line 264 of file tracectl.h. |
|
Definition at line 284 of file tracectl.h. |
|
Definition at line 285 of file tracectl.h. |