BevelHelpers Class Reference

#include <ppbevel.h>

Inheritance diagram for BevelHelpers:

CCObject SimpleCCObject List of all members.

Static Public Member Functions

static void ShrinkPath (Path *pSrcPath, double amountX, double amountY, Path *pRetnPath, BOOL bTest=TRUE)
 Shrinks the path very slightly so that antialiasing doesn't bleed out of the bevel.
static BOOL IsPathToBeReversed (Path *pPath)
 Indicates that the path is around the wrong way for bevelling i.e. the normals will be facing outwards, not inwards Notes: The path must have no sub-paths.
static void EliminateMultiplePoints (Path *pPath)
 Eliminates multiple points in the path Path must be flat !

Detailed Description

Definition at line 177 of file ppbevel.h.


Member Function Documentation

void BevelHelpers::EliminateMultiplePoints Path pPath  )  [static]
 

Eliminates multiple points in the path Path must be flat !

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/99
See also:
-

Definition at line 642 of file ppbevel.cpp.

00643 {   
00644     Path NewPath;
00645     NewPath.Initialise();
00646 
00647     // flatten the path
00648     pPath->Flatten(200, &NewPath);
00649     pPath->CloneFrom(NewPath);
00650     pPath->IsFilled = TRUE;
00651     pPath->IsStroked = FALSE;
00652 
00653     NewPath.ClearPath();
00654     NewPath.IsFilled = TRUE;
00655     NewPath.IsStroked = FALSE;
00656 
00657     DocCoord dc1(0,0);
00658     DocCoord dc2;
00659 
00660     INT32 StartIndex = 0;
00661 
00662     for (INT32 i = 0 ; i < pPath->GetNumCoords(); i++)
00663     {
00664         dc2 = pPath->GetCoordArray()[i];
00665 
00666         // ensure that dc1 is different to dc2 on first index
00667         if (i == 0)
00668         {
00669             dc1.x = dc2.x - 1000;
00670         }
00671         
00672         if (dc2.x != dc1.x ||
00673             dc2.y != dc1.y ||
00674             pPath->GetVerbArray()[i] == PT_MOVETO)
00675         {
00676             if (pPath->GetVerbArray()[i] == PT_MOVETO)
00677             {
00678                 /*
00679                 if (i > 0)
00680                 {
00681                     // make sure we close the path
00682                     if (NewPath.GetCoordArray()[i - 1].x != NewPath.GetCoordArray()[StartIndex].x ||
00683                         NewPath.GetCoordArray()[i - 1].y != NewPath.GetCoordArray()[StartIndex].y)
00684                     {
00685                         NewPath.AddLineTo(NewPath.GetCoordArray()[StartIndex]);
00686                     }
00687                 }
00688                 */
00689 
00690                 NewPath.AddMoveTo(dc2);
00691                 StartIndex = i;
00692             }
00693             else
00694             {
00695                 NewPath.AddLineTo(dc2);
00696             }
00697         }
00698 
00699         dc1 = dc2;
00700     }
00701 
00702     // make sure we close the path
00703     /*
00704     if (NewPath.GetCoordArray()[i - 1].x != NewPath.GetCoordArray()[StartIndex].x ||
00705         NewPath.GetCoordArray()[i - 1].y != NewPath.GetCoordArray()[StartIndex].y)
00706     {
00707         NewPath.AddLineTo(NewPath.GetCoordArray()[StartIndex]);
00708     }
00709     */
00710 
00711     pPath->ClearPath();
00712     pPath->CloneFrom(NewPath);
00713 }

BOOL BevelHelpers::IsPathToBeReversed Path pPath  )  [static]
 

Indicates that the path is around the wrong way for bevelling i.e. the normals will be facing outwards, not inwards Notes: The path must have no sub-paths.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/10/98
See also:
-

Definition at line 581 of file ppbevel.cpp.

00582 {
00583     NormCoord ncBefore;
00584     NormCoord ncAfter;
00585     NormCoord ncBefore90;
00586 
00587     double TotalDot = 0;
00588     double dot1 = 0;
00589     double dot2 = 0;
00590 
00591     DocRect Bounds = pPath->GetBoundingRect();
00592     DocCoord Centre ;
00593     Centre.x = Bounds.lo.x + (Bounds.Width() / 2);
00594     Centre.y = Bounds.lo.y + (Bounds.Height() / 2);
00595 
00596     UINT32 Count = 0;
00597     
00598     for (INT32 i = 0; i < pPath->GetNumCoords()-1; i++)
00599     {
00600         if (i > 0 && pPath->GetVerbArray()[i] == PT_MOVETO)
00601             break;
00602 
00603         Count ++;
00604         
00605         // get the points before & after
00606         ncBefore.x = pPath->GetCoordArray()[i].x - Centre.x;
00607         ncBefore.y = pPath->GetCoordArray()[i].y - Centre.y;
00608         
00609         ncAfter.x = pPath->GetCoordArray()[i+1].x - Centre.x;
00610         ncAfter.y = pPath->GetCoordArray()[i+1].y - Centre.y;
00611 
00612         ncBefore.Normalise();
00613         ncAfter.Normalise();
00614 
00615         ncBefore90.y = -ncBefore.x;
00616         ncBefore90.x =  ncBefore.y;
00617 
00618         dot1 = ncBefore90.x * ncAfter.x + ncBefore90.y * ncAfter.y;
00619         dot2 = ncBefore.x * ncAfter.x + ncBefore.y * ncAfter.y;
00620 
00621         TotalDot += dot1;
00622     }
00623 
00624     TotalDot /= (double)Count;
00625 
00626     TRACEUSER( "DavidM", _T("Total %f\n"), TotalDot);
00627 
00628     return (TotalDot < -0.05);
00629 }

void BevelHelpers::ShrinkPath Path pSrcPath,
double  amountX,
double  amountY,
Path pRetnPath,
BOOL  bTest = TRUE
[static]
 

Shrinks the path very slightly so that antialiasing doesn't bleed out of the bevel.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/10/98
See also:
-

Definition at line 262 of file ppbevel.cpp.

00264 {
00265     if (!pSrcPath || !pRetnPath)
00266         return;
00267 
00268     if (pSrcPath->GetNumCoords() < 3)
00269     {
00270         pRetnPath->CloneFrom(*pSrcPath);
00271         return;
00272     }
00273     
00274     if (amountX == 0 || amountY == 0)
00275         return;
00276 
00277     pRetnPath->ClearPath();
00278     pRetnPath->CloneFrom(*pSrcPath);
00279 
00280     DocCoord dcBefore;
00281     DocCoord dcThis;
00282     DocCoord dcAfter;
00283     DocCoord dcTest;
00284 
00285     DocRect testRect;
00286     DocRect thisRect;
00287 
00288     NormCoord ncBefore;
00289     NormCoord ncAfter;
00290     NormCoord ncAverage;
00291 
00292     double dt = 0;
00293 //  double dot = 0;
00294 
00295     INT32 IStart = 0;
00296     INT32 IEnd = 0;
00297 
00298     double BeforeLen = 0;
00299     double AfterLen  = 0;
00300     double LenAverage = 0;
00301 
00302     BOOL bOK = FALSE;
00303 
00304     // first, calculate the normal list
00305     NormCoord *pNormList = new NormCoord[pSrcPath->GetNumCoords()];
00306     
00307     for (INT32 i = 0 ; i < pSrcPath->GetNumCoords(); i++)
00308     {
00309         // get the points before & after
00310         IStart = i - 1;
00311         IEnd = i + 1;
00312         
00313         if (i == pSrcPath->GetNumCoords() - 1)
00314         {
00315             IEnd = i;
00316             pSrcPath->FindStartOfSubPath(&IEnd);
00317             IEnd ++;
00318         }
00319         else if (pSrcPath->GetVerbArray()[i] == PT_MOVETO)
00320         {
00321             // find the end of the sub-path
00322             IStart = i;
00323             pSrcPath->FindEndElOfSubPath(&IStart);
00324             IStart -= 1;
00325         }
00326         else if (pSrcPath->GetVerbArray()[i+1] == PT_MOVETO)
00327         {
00328             IEnd = i;
00329             pSrcPath->FindStartOfSubPath(&IEnd);
00330             IEnd ++;
00331         }
00332         
00333         dcBefore = pSrcPath->GetCoordArray()[IStart];
00334         dcThis = pSrcPath->GetCoordArray()[i];
00335         dcAfter = pSrcPath->GetCoordArray()[IEnd];
00336 
00337         ncBefore.x = dcThis.x - dcBefore.x;
00338         ncBefore.y = dcThis.y - dcBefore.y;
00339         BeforeLen = 1/ncBefore.GetLength();
00340 
00341         if (BeforeLen > 0)
00342         {
00343             ncBefore.x *= BeforeLen;
00344             ncBefore.y *= BeforeLen;
00345         }
00346 
00347         ncAfter.x = dcAfter.x - dcThis.x;
00348         ncAfter.y = dcAfter.y - dcThis.y;
00349         AfterLen = 1/ncAfter.GetLength();
00350 
00351         if (AfterLen > 0)
00352         {
00353             ncAfter.x *= AfterLen;
00354             ncAfter.y *= AfterLen;
00355         }
00356         
00357         ncAverage.x = ncBefore.x + ncAfter.x;
00358         ncAverage.y = ncBefore.y + ncAfter.y;
00359         
00360         LenAverage = 1/ncAverage.GetLength();
00361 
00362         // do the normal
00363         if (LenAverage > 0)
00364         {
00365             ncAverage.x *= LenAverage;
00366             ncAverage.y *= LenAverage;
00367         
00368             // rotate by 90 degrees
00369             dt = ncAverage.x;
00370             ncAverage.x = -ncAverage.y;
00371             ncAverage.y = dt;
00372 
00373             pNormList[i] = ncAverage;
00374         }
00375     }                      
00376 
00377     INT32 AbsAmountX = abs((INT32)(amountX));
00378     INT32 AbsAmountY = abs((INT32)(amountY));
00379     INT32 NextIndex = 0;
00380 
00381     DocCoord intersection;
00382     double p = 0;
00383     double q = 0;
00384     
00385     BOOL bDoTest = FALSE;
00386 
00387     // now, run through the list again calculating bounding rects
00388     for (INT32 i = 0 ; i < pSrcPath->GetNumCoords(); i++)
00389     {
00390         dcThis = pSrcPath->GetCoordArray()[i];
00391         
00392         // only do this on single sub-paths (quicker !)
00393         /*
00394         if (pSrcPath->GetVerbArray()[i] == PT_MOVETO)
00395         {
00396             IStart = i;
00397             IEnd = i;
00398             pSrcPath->FindEndElOfSubPath(&IEnd);
00399         }
00400         */
00401 
00402         IStart = 0;
00403         IEnd = pSrcPath->GetNumCoords();
00404         
00405         // is sub path in list ?
00406         bOK = TRUE;
00407 
00408         IStart = 0;
00409         IEnd = pSrcPath->GetNumCoords();
00410 
00411         thisRect.lo.x = dcThis.x - AbsAmountX;
00412         thisRect.lo.y = dcThis.y - AbsAmountY;
00413         thisRect.hi.x = dcThis.x + AbsAmountX;
00414         thisRect.hi.y = dcThis.y + AbsAmountY;
00415         
00416         for (INT32 j = IStart; j <= IEnd && bOK; j++)
00417         {
00418             // get the line segment to test         
00419             dcTest = pSrcPath->GetCoordArray()[j];
00420             
00421             bDoTest = TRUE;
00422 
00423             if (i == IStart)
00424             {
00425                 if (j == IEnd || j == i || j == i+1)
00426                 {
00427                     bDoTest = FALSE;
00428                 }
00429             }
00430             else if (i == IEnd)
00431             {
00432                 if (j == IEnd - 1 || j == i || j == IStart)
00433                 {
00434                     bDoTest = FALSE;
00435                 }
00436             }
00437             else if (j == i - 1 || j == i || j == i+1)
00438             {
00439                 bDoTest = FALSE;
00440             }
00441             
00442             if (bDoTest)
00443             {
00444                 NextIndex = j + 1;
00445                 
00446                 if (NextIndex == IEnd)
00447                 {
00448                     NextIndex = IStart;
00449                 }
00450                 
00451                 dcAfter = pSrcPath->GetCoordArray()[NextIndex];
00452                 
00453                 // do the bounding rect
00454                 if (dcTest.x < dcAfter.x)
00455                 {
00456                     testRect.lo.x = dcTest.x;
00457                     testRect.hi.x = dcAfter.x;
00458                 }
00459                 else
00460                 {
00461                     testRect.lo.x = dcAfter.x;
00462                     testRect.hi.x = dcTest.x;
00463                 }
00464                 
00465                 if (dcTest.y < dcAfter.y)
00466                 {
00467                     testRect.lo.y = dcTest.y;
00468                     testRect.hi.y = dcAfter.y;
00469                 }
00470                 else
00471                 {
00472                     testRect.lo.y = dcAfter.y;
00473                     testRect.hi.y = dcTest.y;
00474                 }
00475                 
00476                 if (testRect.IsIntersectedWith(thisRect))
00477                 {
00478                     // check if when we move the point the point changes sides from
00479                     // one side of the line segment to the other
00480                     ncAverage.x = dcTest.x - dcAfter.x;
00481                     ncAverage.y = dcTest.y - dcAfter.y;
00482                     
00483                     if (CCreateBevelTrapezoids::CalculateIntersection(&dcThis, &(pNormList[i]),
00484                         &dcAfter, &ncAverage, 
00485                         &intersection, &p, &q))
00486                     {
00487                         if (intersection.x > testRect.lo.x && intersection.x < testRect.hi.x &&
00488                             intersection.y > testRect.lo.y && intersection.y < testRect.hi.y)
00489                         {
00490                             // get the length of the line
00491                             ncAverage.x = dcThis.x - intersection.x;
00492                             ncAverage.y = dcThis.y - intersection.y;
00493 
00494                             q = ncAverage.GetLength();
00495 
00496                             if (q > 0)
00497                             {
00498                                 if (q < fabs(amountX*2))
00499                                 {
00500                                     bOK = FALSE;
00501                                 }
00502                             }
00503 
00504                         }
00505                     }
00506                 }           
00507             }
00508         }
00509 
00510         if (bOK)
00511         {
00512             dcThis.x = (INT32)((((double)dcThis.x) - (pNormList[i].x * amountX)));
00513             dcThis.y = (INT32)((((double)dcThis.y) - (pNormList[i].y * amountY)));
00514                     
00515             pRetnPath->GetCoordArray()[i] = dcThis;
00516         }       
00517     }
00518 
00519     delete [] pNormList;
00520     pNormList = NULL;
00521 
00522     /*
00523     Path StrokedPath;
00524     StrokedPath.Initialise();
00525 
00526     pSrcPath->StrokePathToPath((INT32)(amountX*2),
00527                               LineCapButt,
00528                               MitreJoin,
00529                               NULL,
00530                               &StrokedPath,
00531                               BEVEL_FLATNESS/5,
00532                               TRUE);
00533     
00534     // need to flatten this
00535     ProcessFlatten Flatten(BEVEL_FLATNESS/5);
00536 
00537     Path FlatPath;
00538     FlatPath.Initialise();
00539 
00540     pRetnPath->ClearPath(FALSE);
00541     pRetnPath->Initialise();
00542     
00543     ProcessFlags pf(TRUE, FALSE, FALSE);
00544     Flatten.FlattenPath(pf, &StrokedPath, &FlatPath);
00545 
00546     if (!bAdd)
00547     {
00548         FlatPath.ClipPathToPath(pSrcPath, 
00549             pRetnPath,
00550             1 | CLIPPING_SOURCE_WINDING,
00551             0, BEVEL_FLATNESS/5, BEVEL_FLATNESS/5);
00552     }
00553     else
00554     {
00555         FlatPath.ClipPathToPath(pSrcPath, 
00556             pRetnPath,
00557             7 | CLIPPING_SOURCE_WINDING,
00558             0, BEVEL_FLATNESS/5, BEVEL_FLATNESS/5);
00559     }
00560     */
00561 
00562 
00563     pRetnPath->IsFilled = TRUE;
00564     pRetnPath->IsStroked = FALSE;
00565 
00566 }


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