#include <coreleps.h>
Inheritance diagram for CorelEPSFilter:
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 |
Definition at line 119 of file coreleps.h.
|
Constructor for an CorelEPSFilter object. The object should be initialised before use.
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 }
|
|
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.
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 }
|
|
|
|
Convert the Corel grad values (padding, centre of fill etc) into a Camelot style radial fill - i.e. start and end points, like ArtWorks.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Given an EPS token, return the string representation of it; mainly for debugging purposes.
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 }
|
|
Initialise an CorelEPSFilter object.
Reimplemented from EPSFilter. Reimplemented in Corel3EPSFilter, and Corel4EPSFilter. Definition at line 238 of file coreleps.cpp. 00239 { 00240 // All ok 00241 return TRUE; 00242 }
|
|
Compare the current token against the Corel keywords to see if it is one of them.
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 }
|
|
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.
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 }
|
|
Definition at line 139 of file coreleps.h. |
|
Definition at line 155 of file coreleps.h. |
|
Definition at line 152 of file coreleps.h. |
|
|
|
Definition at line 155 of file coreleps.h. |