CorelEPSFilter Class Reference

A base class filter that implements the core functionality required for a Corel EPS import filter. Other filters are derived from this - this class is never instantiated as it is incomplete. More...

#include <coreleps.h>

Inheritance diagram for CorelEPSFilter:

EPSFilter VectorFilter Filter ListItem CCObject SimpleCCObject Corel3EPSFilter Corel4EPSFilter List of all members.

Public Member Functions

 CorelEPSFilter ()
 Constructor for an CorelEPSFilter object. The object should be initialised before use.
BOOL Init ()
 Initialise an CorelEPSFilter object.
char * GetEPSCommand (EPSCommand Cmd)
 Given an EPS token, return the string representation of it; mainly for debugging purposes.

Protected Member Functions

virtual void LookUpToken ()
 Compare the current token against the Corel keywords to see if it is one of them.
virtual BOOL ProcessToken ()
 Processes EPS tokens that are not part of the standard Illustrator set. i.e. this is the function that handles all the Corel EPS operators.
BOOL DecodeCorelGradFill ()
 Convert the preposterous Corel format of graduated fill information into something that resembles sanity, and install it as the current fill. The graduated fill information is assumed to be in the CorelEPSFilter::GradFillInfo structure.
BOOL DecodeLinearGradFill ()
 Convert the Corel grad values (padding, angle of fill etc) into a Camelot style grad fill - i.e. start and end points, like Camelot. This function copes with all styles of Corel linear graduated fills.
BOOL DecodeRadialGradFill ()
 Convert the Corel grad values (padding, centre of fill etc) into a Camelot style radial fill - i.e. start and end points, like ArtWorks. The calculations may seem strange. They are - but that's how Corel define their grad fills.
BOOL DecodeConicalGradFill ()
 Convert the Corel grad values (padding, centre of fill etc) into a Camelot style radial fill - i.e. start and end points, like ArtWorks.
BOOL AddAttributes (NodeRenderableBounded *pNode, BOOL Stroked, BOOL Filled)
 Used as a veneer to EPSFilter::AddAttributes. It checks to see if the current fill style is a graduated fill - if it is, then it calls CorelEPSFilter::DecodeCorelGradFill, which converts the Corel form of the grad fill to the Camelot form. This must be done for each object, as the grad fill is stored relative to the object's bounding box in Corel EPS files.

Protected Attributes

CorelEPSFilter::CCAPI GradFillInfo
BOOL GradFill
DocColour StartColour
DocColour EndColour

Static Protected Attributes

static CommandMap CorelCommands []

Private Member Functions

 CC_DECLARE_DYNAMIC (CorelEPSFilter)

Classes

struct  CCAPI

Detailed Description

A base class filter that implements the core functionality required for a Corel EPS import filter. Other filters are derived from this - this class is never instantiated as it is incomplete.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/03/94
See also:
Corel3EPSFilter; Corel4EPSFilter; EPSFilter

Definition at line 119 of file coreleps.h.


Constructor & Destructor Documentation

CorelEPSFilter::CorelEPSFilter  ) 
 

Constructor for an CorelEPSFilter object. The object should be initialised before use.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/10/93
See also:
EPSFilter::Init

Definition at line 208 of file coreleps.cpp.

00209 {
00210     // Set up filter description.
00211     FilterID = FILTERID_NONE;
00212 
00213 #ifndef STANDALONE
00214     Flags.CanImport = TRUE;
00215     Flags.CanExport = FALSE;
00216 #else
00217     Flags.CanImport = FALSE;
00218     Flags.CanExport = FALSE;
00219 #endif
00220 
00221     // Corel EPS does not store layer information
00222     SupportsLayers = FALSE;
00223 }


Member Function Documentation

BOOL CorelEPSFilter::AddAttributes NodeRenderableBounded pNode,
BOOL  Stroked,
BOOL  Filled
[protected, virtual]
 

Used as a veneer to EPSFilter::AddAttributes. It checks to see if the current fill style is a graduated fill - if it is, then it calls CorelEPSFilter::DecodeCorelGradFill, which converts the Corel form of the grad fill to the Camelot form. This must be done for each object, as the grad fill is stored relative to the object's bounding box in Corel EPS files.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/04/94
Parameters:
pNode - the bounded renderable node to add atributes to. [INPUTS] Stroked - TRUE if the object to add attributes to should be stroked, FALSE if not. Stroked - TRUE if the object to add attributes to should be filled, FALSE if not.
Returns:
TRUE if the attributes were added ok; FALSE if not.

Errors: Out of memory.

See also:
EPSFilter::AddAttributes; CorelEPSFilter::DeocdeCorelGradFill

Reimplemented from EPSFilter.

Definition at line 1093 of file coreleps.cpp.

01094 {
01095     // Check to see if we need to set up a Corel graduated fill attribute
01096     if (GradFill)
01097     {
01098         GradFill = FALSE;
01099         // Try to set up the grad fill for this object.
01100         if (!DecodeCorelGradFill())                                    
01101             return FALSE;
01102     }
01103 
01104     // Call the base class version
01105     return EPSFilter::AddAttributes(pNode, Stroked, Filled);
01106 }

CorelEPSFilter::CC_DECLARE_DYNAMIC CorelEPSFilter   )  [private]
 

BOOL CorelEPSFilter::DecodeConicalGradFill  )  [protected]
 

Convert the Corel grad values (padding, centre of fill etc) into a Camelot style radial fill - i.e. start and end points, like ArtWorks.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/04/94
Returns:
TRUE if grad fill converted without problems; FALSE if not.

Errors: Out of memory.

See also:
CorelEPSFilter::DecodeCorelGradFill; CorelEPSFilter::DecodeLinearGradFill

Definition at line 1016 of file coreleps.cpp.

01017 {
01018     // modified by Ben to get the start and end points right
01019 
01020     // The desired start and end points of the grad fill 'arrow'.
01021     DocCoord Start, End;
01022 
01023     // First, get the bounding box.
01024     DocRect BBox; 
01025     CDRFilter::GetCorelBBox(pPath, &BBox);
01026 
01027     // Calculate width and height
01028     MILLIPOINT Width = BBox.Width();
01029     MILLIPOINT Height = BBox.Height();
01030 
01031     // Start point is the centre given by Corel.
01032     // This centre is percentage offsets from the centre of the object, i.e. (0,0) is
01033     // the centre of the bounding box.
01034     Start.x = BBox.lo.x + (Width  / 2);
01035     Start.y = BBox.lo.y + (Height / 2);
01036     Start.x += ((GradFillInfo.RotateX * Width) / 100);
01037     Start.y += ((GradFillInfo.RotateY * Height) / 100);
01038 
01039     // End point is start point + radius but takes into account the angle
01040     double Radius = Width / 2;
01041     // angle is * 10, and needs to be in radians
01042     double Theta = (((double)(GradFillInfo.Angle)) / 360.0) * (2 * PI);
01043 
01044     // make the angle go anti-clockwise
01045     Theta = 0 - Theta;
01046 
01047     // rotate by PI / 2
01048     Theta -= PI / 2;
01049     
01050     // angle can be negative, ensure it's positive
01051     while(Theta < 0)
01052         Theta += (2 * PI);
01053 
01054     // calculate the triangle
01055     double dx, dy;
01056 
01057     dx = Radius * sin(Theta);
01058     dy = Radius * cos(Theta);
01059 
01060     End.x = Start.x + (INT32)dx;
01061     End.y = Start.y + (INT32)dy;
01062 
01063     // Seems that we need to swap start and end colours...
01064 
01065     // Set the fill type according to these calculations.
01066     return SetConicalFill(EndColour, StartColour, Start, End);  
01067 }

BOOL CorelEPSFilter::DecodeCorelGradFill  )  [protected]
 

Convert the preposterous Corel format of graduated fill information into something that resembles sanity, and install it as the current fill. The graduated fill information is assumed to be in the CorelEPSFilter::GradFillInfo structure.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/04/94
Returns:
TRUE if grad fill converted without problems; FALSE if not.

Definition at line 702 of file coreleps.cpp.

00703 {
00704     switch (GradFillInfo.FillType)
00705     {
00706         case 0:
00707             return DecodeLinearGradFill();
00708 
00709         case 1:
00710         case 3:     // square - radial is closest approximation
00711             return DecodeRadialGradFill();
00712 
00713         case 2:
00714             return DecodeConicalGradFill();
00715     }
00716 
00717     // Can't handle any other kinds of fills - ignore them.
00718     return TRUE;
00719 }

BOOL CorelEPSFilter::DecodeLinearGradFill  )  [protected]
 

Convert the Corel grad values (padding, angle of fill etc) into a Camelot style grad fill - i.e. start and end points, like Camelot. This function copes with all styles of Corel linear graduated fills.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/04/94
Returns:
TRUE if grad fill converted without problems; FALSE if not.

Errors: Out of memory.

See also:
CorelEPSFilter::DecodeCorelGradFill; CorelEPSFilter::DecodeRadialGradFill

Definition at line 737 of file coreleps.cpp.

00738 {
00739     // NB. this function is (hopefully!) over-complex and will be simplified.
00740     // However, it's like this atm so I can get my head around the weird maths 
00741 
00742     // The desired start and end points of the grad fill 'arrow'.
00743     DocCoord Start, End;
00744 
00745     // First, get the bounding box.
00746     DocRect BBox; 
00747     CDRFilter::GetCorelBBox(pPath, &BBox);
00748 
00749     // Calculate width and height
00750     MILLIPOINT Width = BBox.Width();
00751     MILLIPOINT Height = BBox.Height();
00752 
00753     // Find centre of box
00754     DocCoord Centre;
00755     Centre.x = BBox.lo.x + (Width / 2);
00756     Centre.y = BBox.lo.y + (Height / 2);
00757 
00758     // Find total area of BBox
00759     double TotalArea = (double) Width * (double) Height;
00760 
00761     // Cope with angles > 180
00762     BOOL Mirror = FALSE;
00763     INT32 Angle = GradFillInfo.Angle;
00764     
00765     if (Angle >= 180)
00766     {
00767         Angle -= 180;
00768         Mirror = TRUE;
00769     }
00770     else if (Angle < 0)
00771     {
00772         Angle += 180;
00773         Mirror = TRUE;
00774     }
00775 
00776     Angle += 90;
00777 
00778     if (Angle >= 180)
00779     {
00780         Angle -= 180;
00781     }
00782 
00783     // Calculate tan of the angle - convert angle to radians first.
00784     double Radians = (((double) Angle) / 180.0) * PI;
00785     double TanTheta;
00786     if (Angle == 90)
00787     {
00788         // Special case for horizontal grad fill arrow.
00789 
00790         // Make 0% padding first
00791         Start.x = BBox.lo.x;
00792         Start.y = Centre.y;
00793         End.x = BBox.hi.x;
00794         End.y = Centre.y;
00795 
00796         // Find out width of padding
00797         INT32 Padding = (Width * GradFillInfo.EdgePad) / 100;
00798         Start.x += Padding;
00799         End.x -= Padding;
00800     }
00801     else if (Angle == 0)
00802     {
00803         // Special case for vertical grad fill arrow.
00804 
00805         // Make 0% padding first
00806         Start.x = Centre.x;
00807         Start.y = BBox.lo.y;
00808         End.x = Centre.x;
00809         End.y = BBox.hi.y;
00810 
00811         // Find out width of padding
00812         INT32 Padding = (Height * GradFillInfo.EdgePad) / 100;
00813         Start.y += Padding;
00814         End.y -= Padding;
00815     }
00816     else
00817     {
00818         TanTheta = tan(Radians);
00819 
00820         // Find out what the maximum padding is that we can achieve using just triangles:
00821 
00822         // Find the maximum triangle width
00823         MILLIPOINT TriWidth = (MILLIPOINT) ((double) Height / TanTheta);
00824 
00825         // Limit it to sensible value
00826         if (TriWidth < 0)
00827             TriWidth = -TriWidth;
00828         if (TriWidth > Width)
00829             TriWidth = Width;
00830 
00831         // Find the maximum triangle width
00832         MILLIPOINT TriHeight = (MILLIPOINT) ((double) Width * TanTheta);
00833 
00834         // Limit it to sensible value
00835         if (TriHeight < 0)
00836             TriHeight = -TriHeight;
00837         if (TriHeight > Height)
00838             TriHeight = Height;
00839 
00840         // The 'c' values of the y = mx+c equation.
00841         MILLIPOINT StartC, EndC;
00842 
00843         // Work out the maximum percentage/edge padding this gives us
00844         // (50 because it's 100 / 2 because we want area of triangle, not rectangle).
00845         double Percentage = (50.0 * (double) TriWidth * (double) TriHeight) / TotalArea;
00846 
00847         INT32 Diff = 0;
00848 
00849         // Is this enough?
00850         if (((INT32) Percentage) >= GradFillInfo.EdgePad)
00851         {
00852             // Yes - calculate exactly how big the triangle needs to be.
00853             TriHeight = (MILLIPOINT) sqrt(ABS(((double) GradFillInfo.EdgePad * TotalArea * TanTheta) / 100.0));
00854 
00855             TriWidth = (MILLIPOINT) ((double) TriHeight / TanTheta);
00856             if (TriWidth < 0)
00857                 TriWidth = -TriWidth;
00858 
00859             ENSURE(TriWidth < Width, "Error in Corel Grad fill decoding logic");
00860         }
00861         else
00862         {
00863             // How much percentage do we need to add with each rectangle?
00864             Percentage = (GradFillInfo.EdgePad - Percentage) / 2;
00865 
00866             // Handle the rectangle stuff.
00867             if (TriWidth == Width)
00868             {
00869                 // Need to add rectangles to the top and bottom.
00870                 Diff = (MILLIPOINT) ((Percentage * Height) / 100.0);
00871             }
00872             else
00873             {
00874                 // Need to add rectangles to left and right
00875                 Diff = (MILLIPOINT) ((Percentage * Width) / 100.0);
00876                 Diff = (MILLIPOINT) (Diff / tan(PI - Radians));
00877                 Diff = ABS(Diff);
00878             }
00879         }
00880 
00881         // Work out the C value for the start line (c = y - mx)
00882         // (m = tan(angle) )
00883         if (Angle == 90)
00884         {
00885             //ENSURE(FALSE, "90 degree angle found!");
00886         }
00887         else if (Angle < 90)
00888         {
00889             StartC = (MILLIPOINT) (BBox.lo.y - ((BBox.hi.x - TriWidth) * TanTheta));
00890             EndC = (MILLIPOINT) (BBox.hi.y - ((BBox.lo.x + TriWidth) * TanTheta));
00891         }
00892         else
00893         {
00894             StartC = (MILLIPOINT) (BBox.lo.y - ((BBox.lo.x + TriWidth) * TanTheta));
00895             EndC = (MILLIPOINT) (BBox.hi.y - ((BBox.hi.x - TriWidth) * TanTheta));
00896         }
00897 
00898         // Add on difference for rectangles, if any.
00899         StartC += Diff;
00900         EndC -= Diff;
00901 
00902 
00903         // Work out m and c for the grad fill line.
00904         // We know m is -1/m of the triangle's hypotenuse.
00905         // c = roy - (rox/m)
00906         double FillM = -1.00 / TanTheta;
00907         MILLIPOINT FillC = (MILLIPOINT) (Centre.y - (Centre.x * FillM));
00908 
00909         // Work out intersections:  x = (c2 - c1) / (2m)
00910 
00911         Start.x = (MILLIPOINT) ( (FillC - StartC) / (TanTheta + (1.00 / TanTheta)) );
00912         Start.y = (MILLIPOINT) ((FillM * Start.x) + FillC);
00913 
00914         End.x = (MILLIPOINT) ( (FillC - EndC) / (TanTheta + (1.00 / TanTheta)) );
00915         End.y = (MILLIPOINT) ((FillM * End.x) + FillC);
00916     }
00917 
00918     if (Mirror)
00919     {
00920         // Swap the grid fill end-points over.
00921         DocCoord Tmp = Start;
00922         Start = End;
00923         End = Tmp;
00924     }
00925 
00926     // Set the fill type according to these calculations.
00927     return SetLinearFill(StartColour, EndColour, Start, End);   
00928 }

BOOL CorelEPSFilter::DecodeRadialGradFill  )  [protected]
 

Convert the Corel grad values (padding, centre of fill etc) into a Camelot style radial fill - i.e. start and end points, like ArtWorks. The calculations may seem strange. They are - but that's how Corel define their grad fills.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/04/95
Returns:
TRUE if grad fill converted without problems; FALSE if not.

Errors: Out of memory.

See also:
CorelEPSFilter::DecodeCorelGradFill; CorelEPSFilter::DecodeLinearGradFill

Definition at line 947 of file coreleps.cpp.

00948 {
00949     // The desired start and end points of the grad fill 'arrow'.
00950     DocCoord Start, End;
00951 
00952     // First, get the bounding box.
00953     DocRect BBox; 
00954     CDRFilter::GetCorelBBox(pPath, &BBox);
00955 
00956     // Calculate width and height
00957     MILLIPOINT Width = BBox.Width();
00958     MILLIPOINT Height = BBox.Height();
00959 
00960     // caluculate the source area
00961     // first, what's the diagonal length
00962     double dWidth = Width;
00963     double dHeight = Height;
00964     INT32 Diagonal = (INT32)sqrt(dWidth*dWidth + dHeight*dHeight);
00965 
00966     // and from that calculate area of the box containing the bit of the
00967     // bit of the circle in the bbox
00968     INT32 Edge = (Diagonal * (100 - (GradFillInfo.EdgePad * 2))) / 100;
00969 
00970     // Start point is the centre given by Corel.
00971     // This centre is percentage offsets from the centre of the object, i.e. (0,0) is
00972     // the centre of the bounding box.
00973     DocCoord Centre = DocCoord(BBox.lo.x + (Width / 2), BBox.lo.y + (Height / 2));
00974     INT32 OffX = (GradFillInfo.RotateX * Width) / 100;
00975     INT32 OffY = (GradFillInfo.RotateY * Height) / 100;
00976     Start.x = Centre.x + OffX;
00977     Start.y = Centre.y + OffY;
00978 
00979     // Find required radius of circle.
00980     double Radius = Edge / 2;
00981 
00982     // how far away is the centre of the fill from the centre of the bbox?
00983     double dOffX = OffX;
00984     double dOffY = OffY;
00985     double Dist = (INT32)sqrt(dOffX*dOffX + dOffY*dOffY);
00986 
00987     // and increase the radius by a bodge factor
00988     double BodgeFactor = 1 + (Dist / (double)(Diagonal / 2));
00989     Radius *= BodgeFactor;
00990     
00991     // End point is start point + radius
00992     End.x = Start.x + ((MILLIPOINT) Radius);
00993     End.y = Start.y;
00994 
00995     // Seems that we need to swap start and end colours...
00996 
00997     // Set the fill type according to these calculations.
00998     return SetRadialFill(EndColour, StartColour, Start, End);   
00999 }

char * CorelEPSFilter::GetEPSCommand EPSCommand  Cmd  ) 
 

Given an EPS token, return the string representation of it; mainly for debugging purposes.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/02/94
Parameters:
Cmd - the EPS token, e.g. EPSC_cd_c [INPUTS]
Returns:
Pointer to the string representation of the token, e.g. "@c"

Reimplemented from EPSFilter.

Reimplemented in Corel3EPSFilter, and Corel4EPSFilter.

Definition at line 671 of file coreleps.cpp.

00672 {
00673     INT32 i = 0;
00674     while (CorelCommands[i].Cmd != EPSC_Invalid)
00675     {
00676         if (CorelCommands[i].Cmd == Cmd)
00677             return CorelCommands[i].CmdStr;
00678 
00679         // Try next command
00680         i++;
00681     }
00682 
00683     // Couldn't find it - default to base class method
00684     return EPSFilter::GetEPSCommand(Cmd);
00685 }

BOOL CorelEPSFilter::Init void   )  [virtual]
 

Initialise an CorelEPSFilter object.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/02/94
Returns:
TRUE if the filter was initialised ok, FALSE otherwise.

Errors: Will fail if not enough memory to initialise the EPS stack.

See also:
EPSStack

Reimplemented from EPSFilter.

Reimplemented in Corel3EPSFilter, and Corel4EPSFilter.

Definition at line 238 of file coreleps.cpp.

00239 {
00240     // All ok
00241     return TRUE;
00242 }

void CorelEPSFilter::LookUpToken  )  [protected, virtual]
 

Compare the current token against the Corel keywords to see if it is one of them.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/02/94
See also:
EPSFilter::LookUpToken

Reimplemented from EPSFilter.

Reimplemented in Corel3EPSFilter, and Corel4EPSFilter.

Definition at line 256 of file coreleps.cpp.

00257 {
00258     // Not interested in comments
00259     if (Token == EPSC_Comment)
00260         return;
00261 
00262     // Check to see if it is a keyword - cycle through the array of keyword names and
00263     // compare against our token (could use a hash table?)
00264     INT32 i = 0;
00265     while (CorelCommands[i].Cmd != EPSC_Invalid)
00266     {
00267         if (camStrcmp(TokenBuf, CorelCommands[i].CmdStr) == 0)
00268         {
00269             // Found the token - set the token variable and return success
00270             Token = CorelCommands[i].Cmd;
00271             return;
00272         }
00273         // Try next command
00274         i++;
00275     }
00276 
00277     // Did not find this token - pass on to base class.
00278     EPSFilter::LookUpToken();
00279 }

BOOL CorelEPSFilter::ProcessToken  )  [protected, virtual]
 

Processes EPS tokens that are not part of the standard Illustrator set. i.e. this is the function that handles all the Corel EPS operators.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/02/94
Returns:
TRUE if token understood and processed ok, FALSE if not.

Errors: Syntax error in EPS, Out of memory.

See also:
EPSFilter::ProcessToken

Reimplemented from EPSFilter.

Reimplemented in Corel3EPSFilter, and Corel4EPSFilter.

Definition at line 295 of file coreleps.cpp.

00296 {
00297     // Variables used to extract operands from the stack
00298     DocCoord    Coords[3];
00299     INT32       Long;
00300     FIXEDPOINT  FixedPoint;
00301     PColourCMYK Col;
00302     DocColour   DocCol;
00303     String_64   ColName;
00304     FIXEDPOINT  TintVal;
00305 
00306     // Decode the command, and execute it...
00307     switch (Token)
00308     {
00309         case EPSC_S:
00310         case EPSC_b:
00311         case EPSC_B:
00312         case EPSC_f:
00313         case EPSC_F:
00314         case EPSC_s:
00315             if (ThePathType == PATH_DISCARD)
00316             {
00317                 // Discard this path, but try to use the next one.
00318                 ThePathType = PATH_NORMAL;
00319                 break;
00320             }
00321             
00322             if (ThePathType == PATH_DISCARD_STICKY)
00323                 // Keep discarding paths until explicitly told not to.
00324                 break;
00325 
00326             ENSURE((ThePathType == PATH_NORMAL) || 
00327                    (ThePathType == PATH_RECT) || 
00328                    (ThePathType == PATH_ELLIPSE), "No path in stroke!");
00329                         
00330             // If no path being constructed, probably just some strange masking going on
00331             // that we can't cope with yet, so ignore it.
00332             if (pPath == NULL)
00333                 break;
00334 
00335             // Terminate path - always have to do this with Corel EPS, as it doesn't
00336             // do it itself.
00337             if ((Token == EPSC_s) || (Token == EPSC_b) || (Token == EPSC_f))
00338             {
00339                 if (!pPath->InkPath.CloseSubPath())
00340                     // Not enough dynamic heap to insert the final element of the path
00341                     goto NoMemory;
00342             }
00343 
00344             // Make the path filled or not, depending on the EPS token.
00345             // NB. The IsFilled flag is set here too - this is an area in which
00346             //     Corel EPS is different to AI/AW/Camelot EPS.
00347             if ((Token == EPSC_b) || 
00348                 (Token == EPSC_B) || 
00349                 (Token == EPSC_F) || 
00350                 (Token == EPSC_f))
00351             {
00352                 pPath->InkPath.IsFilled = TRUE;
00353                 SetPathFilled(TRUE);
00354             }
00355             else
00356             {
00357                 pPath->InkPath.IsFilled = FALSE;
00358                 SetPathFilled(FALSE);
00359             }
00360 
00361             if (!EPSFlags.ComplexPath)
00362             {
00363                 // Not a complex path, so we terminate properly.
00364                 pPath->InvalidateBoundingRect();
00365                             
00366                 // Add the attributes, if we haven't done so for this path
00367                 if (EPSFlags.NoAttributes)
00368                 {
00369                     if (!AddAttributes(pPath, (Token != EPSC_f) && (Token != EPSC_F), pPath->InkPath.IsFilled))
00370                         goto NoMemory;
00371                     EPSFlags.NoAttributes = FALSE;
00372                 }
00373                 
00374                 // Add this path into the tree
00375                 if (!AddNewNode(pPath))
00376                     goto NoMemory;
00377 
00378                 // We've finished building this path - set to NULL so the other routines
00379                 // know that we're not building a path any more.
00380                 pPath = NULL;
00381                 pInkPath = NULL;
00382             }
00383             else
00384                 EPSFlags.StrokeComplexPath = (Token != EPSC_f) && (Token != EPSC_F);
00385 
00386             // Handle the next path normally
00387             ThePathType = PATH_NORMAL;
00388             break;
00389 
00390         case EPSC_cd_0sv:
00391         case EPSC_cd_0sm:
00392         case EPSC_cd_0rs:
00393         case EPSC_cd_0rax:
00394             // Ignore these commands - not needed
00395             break;
00396 
00397         case EPSC_cd_0E:
00398             // Bounding box of object - ignore it; we do it ourselves
00399             if (!Stack.Discard(4))
00400                 goto EPSError;
00401             break;
00402 
00403         case EPSC_cd_0B:
00404         case EPSC_cd_a:
00405         case EPSC_cd_r:
00406             // We don't need these commands - it seems safe to ignore them.
00407             // I think they're something to do with text handling, so when we do text
00408             // imoport, we'll need to process them properly.
00409             break;
00410 
00411         case EPSC_cd_0G:
00412         case EPSC_cd_0g:
00413             // Check the flag on the stack
00414             if (!Stack.Pop(&Long))
00415                 goto EPSError;
00416             if (Long == 1)
00417             {
00418                 // Discard the 3 top values from the stack
00419                 if (!Stack.Discard(3))
00420                     goto EPSError;
00421             }
00422             break;
00423 
00424         case EPSC_cd_0J:
00425         case EPSC_cd_0j:
00426             // Save/restore not needed - ignore
00427             break;
00428 
00429         case EPSC_cd_0w:
00430             // NOT IMPLEMENTED IN FULL
00431             // Set current line width to 1 (defined in points)
00432             if (!Stack.Discard(2))
00433                 goto EPSError;
00434                 
00435             if (Stack.Pop(&FixedPoint))
00436             {
00437                 // Scale line width from points to millipoints, and remember for future
00438                 // objects.
00439                 if (!SetLineWidth((MILLIPOINT) (FixedPoint * EPSScaleFactor) / FixedPointScale))
00440                     goto NoMemory;
00441 
00442                 // Check the flag
00443                 if (Stack.Pop(&Long))
00444                 {
00445                     if (Long == 1)
00446                     {
00447                         if (!Stack.DiscardArray())
00448                             goto EPSError;
00449                     }
00450                 }
00451                 else
00452                     goto EPSError;
00453             }
00454             else    
00455                 goto EPSError;
00456             break;
00457 
00458         case EPSC_cd_0c:
00459             // Close the current path  
00460             if (pPath == NULL)
00461                 // No path to close!
00462                 goto EPSError;
00463 
00464             if (!pPath->InkPath.CloseSubPath())
00465                 // Not enough dynamic heap to insert the final element of the path
00466                 goto NoMemory;
00467             break;
00468 
00469         case EPSC_cd_0t:
00470             // Display text - ignore for now; discard (x, y, string)
00471             if (!Stack.Discard(3))
00472                 goto EPSError;
00473             break;
00474                 
00475         case EPSC_cd_0tm:
00476             {
00477                 // Set text matrix - use this to update the stack's transform matrix, as
00478                 // otherwise pathified text will not be imported correctly.
00479                 EPSCommand Cmd;
00480                 Stack.PopCmd(&Cmd);
00481                 if (Cmd != EPSC_ArrayEnd)
00482                 {
00483                     if (IsUserName("Tim"))
00484                         TRACE( _T("@tm: Expected ArrayEnd, found '%s'\n"), GetEPSCommand(Cmd));
00485                     goto EPSError;
00486                 }
00487 
00488                 // Extract the six array values from the stack.
00489                 double M[6];
00490                 INT32 i = 5;
00491                 for (i = 5; i >= 0; i--)
00492                 {
00493                     if (!Stack.Pop(&M[i]))
00494                         goto EPSError;
00495                 }
00496 
00497                 Stack.PopCmd(&Cmd);
00498                 if (Cmd != EPSC_ArrayStart)
00499                 {
00500                     if (IsUserName("Tim"))
00501                         TRACE( _T("@tm: Expected ArrayStart, found '%s'\n"), GetEPSCommand(Cmd));
00502                     goto EPSError;
00503                 }
00504 
00505                 // Convert the abcd values into FIXED16s, cos that's what we use.
00506                 FIXED16 F16[4];
00507                 for (i = 0; i < 4; i++)
00508                 {
00509                     F16[i] = FIXED16(M[i]);
00510                 }
00511 
00512                 // Convert the Tx and Ty to MILLIPOINTS, cos that's what we use.
00513                 INT32 L1 = (INT32) (M[4] * 1000.0);
00514                 INT32 L2 = (INT32) (M[5] * 1000.0);
00515 
00516                 // Construct the matrix and tell the EPS stack to use it for future 
00517                 // coordinates.
00518                 Matrix TextMatrix(F16[0], F16[1], F16[2], F16[3], L1, L2);
00519                 Stack.SetXformMatrix(TextMatrix);
00520 
00521                 break;
00522             }
00523                 
00524         case EPSC_cd_x:
00525             // Set current fill colour (CMYK)
00526             GradFill = FALSE;
00527             if (Stack.PopColour(&Col, TINT_COREL, &TintVal, &ColName))
00528             {
00529                 GetEPSColour(&DocCol, &Col, TINT_COREL, TintVal, &ColName);
00530 
00531                 // Remember this fill colour for future objects
00532                 if (!SetFillColour(DocCol))
00533                     goto NoMemory;
00534             }
00535             else
00536                 // Invalid colour operands
00537                 goto EPSError;
00538             break;
00539             
00540         case EPSC_cd_X:
00541             // Set current line colour (CMYK)
00542             if (Stack.PopColour(&Col, TINT_COREL, &TintVal, &ColName))
00543             {
00544                 GetEPSColour(&DocCol, &Col, TINT_COREL, TintVal, &ColName);
00545 
00546                 // Remember this line colour for future objects
00547                 if (!SetLineColour(DocCol))
00548                     goto NoMemory;
00549             }
00550             else    
00551                 // Invalid colour operands
00552                 goto EPSError;
00553             break;
00554 
00555         case EPSC_cd_e:
00556             // Set text fill mode - ignore
00557             break;
00558 
00559         case EPSC_cd_z:
00560             // Get and scale font - ignore; discard font name and scale
00561             if (!Stack.Discard(2))
00562                 goto EPSError;
00563             break;
00564                 
00565         case EPSC_cd_Z:
00566             // Change font encosing vector - ignore; discard font names and encoding vector.
00567             if (!Stack.Discard(3) || !Stack.DiscardArray())
00568                 goto EPSError;
00569             break;
00570                 
00571         case EPSC_cd_T:
00572             // Stop using text matrix for transformations.
00573             Stack.SetNoXformMatrix();
00574             break;
00575 
00576         // MoveTo
00577         case EPSC_cd_m:
00578             // Get the co-ordinate from the stack
00579             if (Stack.PopCoordPair(&Coords[0]))
00580             {
00581                 if (pPath == NULL)
00582                 {
00583                     ERROR3IF(pInkPath != NULL,"Already got a path");
00584                     if (pInkPath != NULL)
00585                         goto EPSError;
00586 
00587                     // Create a new NodePath object
00588                     pPath = new NodePath;
00589                     
00590                     // No attributes on the path yet
00591                     EPSFlags.NoAttributes = TRUE;
00592                     
00593                     if ((pPath == NULL) || (!pPath->SetUpPath()))
00594                         // Not enough memory to initialise path
00595                         goto NoMemory;
00596                     
00597                     // Position tag at start of path.
00598                     pPath->InkPath.FindStartOfPath();
00599                     // Point inkpath pointer at the nodepath's path object.
00600                     pInkPath = &pPath->InkPath;
00601                 }
00602                 
00603                 // Insert a moveto into the path
00604                 if (!pPath->InkPath.InsertMoveTo(Coords[0]))
00605                     // Not enough dynamic heap to insert the moveto command
00606                     goto NoMemory;
00607             }
00608             else
00609                 // Invalid number/type of coordinate operands
00610                 goto EPSError;
00611             break;
00612 
00613         case EPSC_matrix:
00614             // NOT IMPLEMENTED IN FULL
00615             // Push dummy argument on
00616             Stack.Push((INT32) 0);
00617             break;
00618 
00619         case EPSC_currentmatrix:
00620             // NOT IMPLEMENTED IN FULL
00621             // Ignore this command
00622             break;
00623 
00624         case EPSC_def:
00625             // Pretend to do a 'def' - discard name and defn from stack
00626             if (!Stack.Discard(2))
00627                 goto EPSError;
00628             break;
00629 
00630         case EPSC_begin:
00631             // Pretend to do a 'begin' - discard dictionary
00632             if (!Stack.Discard())
00633                 goto EPSError;
00634             break;
00635 
00636         default:
00637             // Token not understood - pass onto base class.
00638             return EPSFilter::ProcessToken();
00639     }
00640 
00641 
00642     // No errors encountered while parsing this token and its operands.
00643     return TRUE;
00644     
00645     
00646     // Error handlers:
00647     
00648 EPSError:
00649     HandleEPSError();
00650     return FALSE;
00651 
00652 NoMemory:
00653     HandleNoMemory();
00654     return FALSE;
00655 }


Member Data Documentation

CommandMap CorelEPSFilter::CorelCommands [static, protected]
 

Definition at line 139 of file coreleps.h.

DocColour CorelEPSFilter::EndColour [protected]
 

Definition at line 155 of file coreleps.h.

BOOL CorelEPSFilter::GradFill [protected]
 

Definition at line 152 of file coreleps.h.

struct CorelEPSFilter::CCAPI CorelEPSFilter::GradFillInfo [protected]
 

DocColour CorelEPSFilter::StartColour [protected]
 

Definition at line 155 of file coreleps.h.


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