#include <aw_eps.h>
Inheritance diagram for ArtWorksEPSFilter:
Public Member Functions | |
ArtWorksEPSFilter () | |
Constructor for an ArtWorksEPSFilter object. The object should be initialised before use. | |
BOOL | Init () |
Initialise an ArtWorksEPSFilter object. | |
BOOL | PrepareToExport (CCLexFile *, Spread *pSpread) |
Prepare to import EPS data using this filter. This sets up the filter to a sensible state for reading. | |
TCHAR * | GetEPSCommand (EPSCommand Cmd) |
Given an EPS token, return the string representation of it; mainly for debugging purposes. | |
virtual BOOL | NeedsPrintComponents (void) |
Informs the print components code that no data should be written. | |
virtual BitmapFilterSupport | GetBitmapSupportLevel () |
Determine how well this filter supports bitmaps when exporting. | |
Protected Member Functions | |
virtual void | LookUpToken () |
Compare the current token against the ArtWorks keywords to see if it is one of them. | |
virtual BOOL | ProcessToken () |
Processes EPS tokens that are not part of the standard Illustrator set, or which need to be handled differently to the standard Illustrator meanings. i.e. this is the function that handles all the ArtWorks EPS operators. | |
INT32 | EPSHeaderIsOk (ADDR pFileHeader, UINT32 HeaderSize) |
Checks to see if the EPS comment headers specify that this is an ArtWorks generated EPS file, as required. | |
BOOL | ProcessBlend () |
Reads in all the elements of a blend structure in the EPS file. | |
BOOL | ProcessBlender () |
Reads in all the elements of a blender structure in the EPS file. | |
BOOL | StartBlend () |
Used when a blend structure needs to be created - after this is called, all new nodes added with AddNewNode() will be added as children of this new blend, until EndBlend is called. | |
BOOL | StartBlender () |
Used when a blender structure needs to be created - after this is called, all new paths will be discarded, until EndBlender is called. | |
BOOL | EndBlend () |
Used when a blend has finished being constructed and we want to return to normal node positioning. The blend is added to the document when this function is called (although that depending on the current filter mode, i.e. whether this is a new or existing layer, it may not be added directly to the documnent tree straight away - it may be deferred until the next layer is found, or the import has ended). | |
BOOL | EndBlender () |
Used when a blender has finished being constructed. Paths are not longer discarded. | |
BOOL | ProcessEnvelope () |
Reads in all the elements of an envelope structure in the ArtWorksEPS file and builds the camelot envelope tree. | |
BOOL | ProcessPerspective () |
Reads in all the elements of an perspective structure in the EPS file. | |
BOOL | StartMould (MouldSpace mSpace) |
Used when an mould structure needs to be created - after this is called, all new nodes added with AddNewNode() will be added as children of this new mould, until EndMould is called. | |
BOOL | EndMould () |
Used when a envelope has finished being constructed and we want to return to normal node positioning. | |
BOOL | ProcessMould () |
Processes tokens inside a mould object. Tokens specific to mould objects are processed along with some overridding of default tokens such as groups. | |
BOOL | ProcessMouldShape () |
Reads in all the elements of a mould geometry held in the EPS file. The description of the geometry for this particular file type is that of a path. Depending on the geometry type (perspective or envelope) we will obviously expect a slightly different path. The rules are, that currently perspective geometry is described as {m,l,l,l,l} and envelope geometry is {m,c,c,c,c}. Internally we are not restricted to these but ArtworksEPS certainly is. Input Stack = coord, coord. | |
BOOL | ProcessMangledObjs () |
On finding a 'apc' token in the input stream, this function is executed. It will process all further tokens in the stream until a path termination has been found. A path terminator is considered any of { s,S,b,B,f,F,h,H } Its purpose is strictly defined. It must place the next set of attributes and single path as children of the last object imported rather than the default action which would be to stick them in as siblings of the object. | |
BOOL | ConvertArtMould (NodeMould *) |
Right here comes the difficult bit. What we have now is a really interresting structure. We should have a complete tree beneath the mould group node containing invisible source objects and visible moulded shapes. So if we were to render this tree, it would look sensible. Now we need to disassemble this tree by placing all the moulded objects and their attributes inside our moulder object. This we will do by copying the entire tree and deleting the right bits. (Isn't it yuk but there you go, its the only sensible and simple way of doing it, without massively duplicating bits of code. | |
BOOL | ConvertMouldStyles (Node *pNode) |
Scan through all moulded objects, copying their fill and stroke styles to the original objects (which are currently their parents). | |
void | DeleteAllMangled (Node *pNode) |
Delete all nodes with their mangled bits set at and below pNode. | |
BOOL | DeleteAllNoneMangled (Node *pNode) |
Delete all renderable parents of mangled objects from pNode onwards. This really is a specialised function and should be used with care. It scans through the tree, hunting for mangled objects. When one is found it will attempt to promote the node to become a sibling of its parent and delete the parent. It will only do so if the parent is renderable. We know or are assuming this is a confined and sensible action. It is only so having loaded an ArtWorksEPS envelope or perspective object. | |
BOOL | PromoteMangled (Node *pNode) |
Promote all mangled child nodes to siblings of their parents. | |
BOOL | HandleMouldedFill () |
On finding a 'axm' token in the input stream, this function is executed. It will build a graduated fill structure and set it as the current fill style to be applied to future objects. The function has been split off from the main structure for one very important reason. Fills applied to moulds work in a random way. Imagine the senario, you have a rectangle, and you envelope it. You then apply a linear grad fill to it. If this gets exported as AWEPS what you get are two objects, one moulded and one rectangle. Now you also get a moulded and none moulded fill style represented by ax and axm. Unfortunately although ax stands for 'standard fill style' and axm is used as an override describing the coordinates of a moulded fill (hence the m) the coordinates of both fills are reversed. DONT ASK ME WHY, ASK THE AUTHOR OF AWEPS! So we have to perform some brain dead processing here to get the right attributes applied to the right objects. | |
Static Protected Attributes | |
static CommandMap | ArtWorksCommands [] |
Private Member Functions | |
CC_DECLARE_DYNAMIC (ArtWorksEPSFilter) | |
Private Attributes | |
DocRect | MouldRect |
INT32 | LastFillType |
GradEndCol | LastStartColour |
GradEndCol | LastEndColour |
Definition at line 130 of file aw_eps.h.
|
Constructor for an ArtWorksEPSFilter object. The object should be initialised before use.
Definition at line 223 of file aw_eps.cpp. 00224 { 00225 // Set up filter descriptions. 00226 FilterNameID = _R(IDT_AWEPS_FILTERNAME); 00227 FilterInfoID = _R(IDT_AWEPS_FILTERINFO); 00228 ImportMsgID = _R(IDT_IMPORTMSG_ARTWORKS); 00229 00230 FilterID = FILTERID_ARTWORKS_EPS; 00231 00232 #ifndef STANDALONE 00233 Flags.CanImport = TRUE; 00234 //WEBSTER-Martin-27/01/97 00235 #ifdef WEBSTER 00236 Flags.CanExport = FALSE; 00237 #else 00238 Flags.CanExport = TRUE; 00239 #endif //WEBSTER 00240 #else 00241 Flags.CanImport = FALSE; 00242 Flags.CanExport = FALSE; 00243 #endif 00244 00245 LastFillType = 0; 00246 }
|
|
|
|
Right here comes the difficult bit. What we have now is a really interresting structure. We should have a complete tree beneath the mould group node containing invisible source objects and visible moulded shapes. So if we were to render this tree, it would look sensible. Now we need to disassemble this tree by placing all the moulded objects and their attributes inside our moulder object. This we will do by copying the entire tree and deleting the right bits. (Isn't it yuk but there you go, its the only sensible and simple way of doing it, without massively duplicating bits of code.
Definition at line 2082 of file aw_eps.cpp. 02084 { 02085 ERROR2IF(pNodeMould==NULL, FALSE, "NULL mould pointer passed to ConvertArtMould()"); 02086 02087 NodeMouldGroup* pNodeMGroup = pNodeMould->FindMouldGroup(); 02088 if (pNodeMGroup==NULL) 02089 return FALSE; 02090 02091 NodeMoulder* pMoulder = pNodeMould->FindFirstMoulder(); 02092 if (pMoulder==NULL) 02093 return FALSE; 02094 02095 Node *pNode; 02096 // Stage 1 02097 // Copy all objects from the mould group to this new moulder object 02098 02099 pNode = pNodeMGroup->FindFirstChild(); 02100 while (pNode) 02101 { 02102 if (!pNode->CopyNode(pMoulder,LASTCHILD)) 02103 { 02104 pMoulder->CascadeDelete(); 02105 return FALSE; 02106 } 02107 pNode=pNode->FindNext(); 02108 } 02109 02110 // Stage2 02111 // Scan through deleting all mangled objects in the source tree 02112 pNode=pNodeMGroup->FindFirstChild(); 02113 DeleteAllMangled(pNode); 02114 02115 //Stage 3 02116 //Scan through deleting all none mangled objects in the destination tree 02117 //but leaving the mangled versions! 02118 pNode=pMoulder->FindFirstChild(); 02119 DeleteAllNoneMangled(pNode); 02120 02121 return TRUE; 02122 }
|
|
Scan through all moulded objects, copying their fill and stroke styles to the original objects (which are currently their parents).
Definition at line 2018 of file aw_eps.cpp. 02019 { 02020 Node *qNode, *rNode; 02021 BOOL IsFilled = FALSE, IsStroked = FALSE; 02022 02023 while (pNode) 02024 { 02025 qNode=pNode; 02026 pNode=pNode->FindNext(); 02027 02028 // if its mangled delete it otherwise scan its kids 02029 if (qNode->IsMangled()) 02030 { 02031 rNode = qNode->FindParent(); 02032 if (rNode) 02033 { 02034 // this should be polymorphic but there's no virtual func to 02035 // do it so I'll have to be explicit. 02036 if (IS_A(qNode, NodePath)) 02037 { 02038 IsFilled = ((NodePath*)qNode)->InkPath.IsFilled; 02039 IsStroked = ((NodePath*)qNode)->InkPath.IsStroked; 02040 02041 if (rNode->IsKindOf(CC_RUNTIME_CLASS(NodePath))) 02042 { 02043 ((NodePath*)rNode)->InkPath.IsFilled = IsFilled; 02044 ((NodePath*)rNode)->InkPath.IsStroked = IsStroked; 02045 } 02046 else if (rNode->IsKindOf(CC_RUNTIME_CLASS(NodeSimpleShape))) 02047 { 02048 ((NodePath*)rNode)->InkPath.IsFilled = IsFilled; 02049 ((NodePath*)rNode)->InkPath.IsStroked = IsStroked; 02050 } 02051 } 02052 } 02053 } 02054 else 02055 ConvertMouldStyles(qNode->FindFirstChild()); 02056 } 02057 return TRUE; 02058 }
|
|
Delete all nodes with their mangled bits set at and below pNode.
Definition at line 2139 of file aw_eps.cpp. 02140 { 02141 Node *qNode; 02142 02143 while (pNode) 02144 { 02145 qNode=pNode; 02146 pNode=pNode->FindNext(); 02147 02148 // if its mangled delete it otherwise scan its kids 02149 if (qNode->IsMangled()) 02150 { 02151 qNode->CascadeDelete(); 02152 delete qNode; 02153 } 02154 else 02155 DeleteAllMangled(qNode->FindFirstChild()); 02156 } 02157 }
|
|
Delete all renderable parents of mangled objects from pNode onwards. This really is a specialised function and should be used with care. It scans through the tree, hunting for mangled objects. When one is found it will attempt to promote the node to become a sibling of its parent and delete the parent. It will only do so if the parent is renderable. We know or are assuming this is a confined and sensible action. It is only so having loaded an ArtWorksEPS envelope or perspective object.
Definition at line 2178 of file aw_eps.cpp. 02179 { 02180 Node* qNode; 02181 while (pNode) 02182 { 02183 qNode=pNode; 02184 pNode=pNode->FindNext(); 02185 if (!PromoteMangled(qNode)) 02186 DeleteAllNoneMangled(qNode->FindFirstChild()); 02187 } 02188 return TRUE; 02189 }
|
|
Used when a blend has finished being constructed and we want to return to normal node positioning. The blend is added to the document when this function is called (although that depending on the current filter mode, i.e. whether this is a new or existing layer, it may not be added directly to the documnent tree straight away - it may be deferred until the next layer is found, or the import has ended).
Reimplemented in CamelotEPSFilter. Definition at line 1119 of file aw_eps.cpp. 01120 { 01121 // Sanity check 01122 ENSURE(pNode->IsKindOf(CC_RUNTIME_CLASS(NodeBlend)), "No blend in ArtWorksEPSFilter::EndBlend"); 01123 01124 // Keep the blend ptr and find the first child of the node before we reset pNode. 01125 Node* pBlend = pNode; 01126 Node* pChildNode = pNode->FindFirstChild(); 01127 01128 // Get the parent of the blend node, and use that to add new objects to 01129 pNode = pBlend->FindParent(); 01130 ERROR2IF(pNode==NULL, FALSE, "Blend has no parent in EndBlend()"); 01131 01132 // Initialise all the child blender nodes 01133 UINT32 BlenderCount=0; 01134 while (pChildNode != NULL) 01135 { 01136 if (IS_A(pChildNode,NodeBlender)) 01137 { 01138 NodeBlender* pNodeBlender = (NodeBlender*)pChildNode; 01139 INT32 PathIndexStart = pNodeBlender->GetPathIndexStart(); 01140 INT32 PathIndexEnd = pNodeBlender->GetPathIndexEnd(); 01141 01142 // Convert the AW path indexes into Camelot path indexes 01143 if (!pNodeBlender->ConvertAWPathIndexesToCamelot(&PathIndexStart,&PathIndexEnd)) 01144 { 01145 ERROR2(FALSE,"Unable to convert artworks path indexes in EndBlend()"); 01146 } 01147 01148 // Init the blender to blend the prev and next ink nodes together 01149 if (!pNodeBlender->Initialise(NULL,NULL,PathIndexStart,PathIndexEnd,ImportInfo.pOp,NULL,TRUE)) 01150 { 01151 ERROR2(FALSE,"Unable to initialise a node blender in EndBlend()"); 01152 } 01153 01154 BlenderCount++; 01155 } 01156 pChildNode = pChildNode->FindNext(); 01157 } 01158 01159 if (BlenderCount == 0) 01160 { 01161 ERROR3("Imported Blend node doesn't contain any blender nodes"); 01162 if (!ImportInfo.pOp->DoHideNode(pBlend, TRUE)) 01163 return FALSE; 01164 } 01165 01166 return TRUE; 01167 }
|
|
Used when a blender has finished being constructed. Paths are not longer discarded.
Reimplemented in CamelotEPSFilter. Definition at line 1301 of file aw_eps.cpp. 01302 { 01303 ThePathType = PATH_NORMAL; 01304 return TRUE; 01305 }
|
|
Used when a envelope has finished being constructed and we want to return to normal node positioning.
Reimplemented in CamelotEPSFilter. Definition at line 1520 of file aw_eps.cpp. 01521 { 01522 // Sanity check 01523 ERROR3IF(!pNode->IsKindOf(CC_RUNTIME_CLASS(NodeMouldGroup)), "No mouldgroup in ArtWorksEPSFilter::EndMould"); 01524 // NodeMouldGroup* pNodeMGroup = (NodeMouldGroup*)pNode; 01525 pNode = pNode->FindParent(); 01526 ERROR3IF(!pNode->IsKindOf(CC_RUNTIME_CLASS(NodeMould)), "No MouldParent in ArtWorksEPSFilter::EndMould"); 01527 NodeMould* pNodeMould = (NodeMould*)pNode; 01528 01529 NodeMoulder* pMoulder = pNodeMould->CreateNewMoulder(NULL); 01530 if (!pMoulder) 01531 { 01532 HandleNoMemory(); 01533 return FALSE; 01534 } 01535 01536 // Add it into the tree as the last child of the mould 01537 if (!AddNewNode(pMoulder)) 01538 { 01539 HandleNoMemory(); 01540 return FALSE; 01541 } 01542 01543 // Right, now we need to scan through all moulded objects and copy their fill and 01544 // stroke styles to the originals. We need to do this because the original objects 01545 // within the file are terminated by h and H functions. These describe closed and open 01546 // (none filled,none stroked) paths ie invisible paths. Hence to create the correct 01547 // original styles we need to take the definitions from the destination objects 01548 // instead. This means when we edit the imported mould the drawing doesn't suddenly 01549 // take on random fill and stroke styles. 01550 01551 // Right here comes the difficult bit. What we have now is a really interresting 01552 // structure. We should have a complete tree beneath the mould group node. This tree 01553 // contains invisible source objects and visible moulded shapes. So if we we're to 01554 // render this tree, it would look sensible. Now we need to disassemble this tree 01555 // by placing all the moulded objects and their attributes inside our moulder object. 01556 // This we will do by copying the entire tree and deleting the right bits. (Isn't it 01557 // yuk but there you go, its the only sensible and simple way of doing it, without 01558 // massively duplicating bits of code. 01559 01560 // go and convert the artworks tree 01561 if (!ConvertArtMould(pNodeMould)) 01562 { 01563 HandleNoMemory(); 01564 return FALSE; 01565 } 01566 01567 // and finally move pNode up one level 01568 pNode = pNode->FindParent(); 01569 ERROR3IF(pNode==NULL, "No parent of envelope in ArtWorksEPSFilter::EndMould"); 01570 01571 return TRUE; 01572 }
|
|
Checks to see if the EPS comment headers specify that this is an ArtWorks generated EPS file, as required.
Reimplemented from EPSFilter. Reimplemented in CamelotEPSFilter, and CamelotNativeEPSFilter. Definition at line 289 of file aw_eps.cpp. 00290 { 00291 // this function is not Unicode 00292 00293 // Check the first line in EPS file 00294 if (strncmp((char *) pFileHeader, "%!PS-Adobe-2.0 EPSF-1.2", 23) != 0) 00295 { 00296 // Incorrect version of EPS header line - we don't want this 00297 return 0; 00298 } 00299 00300 // !PS-Adobe line is ok - check creator line... 00301 std::istringstream HeaderFile((char *) pFileHeader, ios_base::in /*, HeaderSize*/); 00302 char Buffer[200]; 00303 00304 UINT32 Lines = 0; 00305 while ((Lines < 20) && !HeaderFile.eof()) 00306 { 00307 HeaderFile.getline(Buffer, 200); 00308 Lines++; 00309 00310 // Return TRUE if this file was created by ArtWorks 00311 if (strncmp(Buffer, "%%Creator: ArtWorks", 19) == 0) 00312 { 00313 // ArtWorks is the creator - but has it exported it in an alien format? 00314 // Return 10 if it hasn't, 1 if it has. 00315 if (strstr(Buffer, "exported") == NULL) 00316 return 10; 00317 else 00318 // 5 because it *might* be "ArtWorks (exported by Mr. Blobby)", and 00319 // we don't want to let the user not load this at all... 00320 return 5; 00321 } 00322 00323 // If we find the compression token then stop the search as we don't want to start 00324 // looking in the compressed data! 00325 if (strncmp(Buffer, "%%Compression:", 14)==0) 00326 break; 00327 } 00328 00329 // Didn't find a suitable Creator line, but we did find an EPS line, so indicate 00330 // that we're interested, but not sure. 00331 return 5; 00332 }
|
|
Determine how well this filter supports bitmaps when exporting.
Reimplemented from Filter. Reimplemented in CamelotNativeEPSFilter. Definition at line 2235 of file aw_eps.cpp. 02236 { 02237 // ArtWorks EPS has simple bitmap support 02238 return SimpleBitmapSupport; 02239 }
|
|
Given an EPS token, return the string representation of it; mainly for debugging purposes.
Reimplemented from EPSFilter. Reimplemented in CamelotEPSFilter. Definition at line 971 of file aw_eps.cpp. 00972 { 00973 INT32 i = 0; 00974 while (ArtWorksCommands[i].Cmd != EPSC_Invalid) 00975 { 00976 if (ArtWorksCommands[i].Cmd == Cmd) 00977 return ArtWorksCommands[i].CmdStr; 00978 00979 // Try next command 00980 i++; 00981 } 00982 00983 // Couldn't find it - default to base class method 00984 return EPSFilter::GetEPSCommand(Cmd); 00985 }
|
|
On finding a 'axm' token in the input stream, this function is executed. It will build a graduated fill structure and set it as the current fill style to be applied to future objects. The function has been split off from the main structure for one very important reason. Fills applied to moulds work in a random way. Imagine the senario, you have a rectangle, and you envelope it. You then apply a linear grad fill to it. If this gets exported as AWEPS what you get are two objects, one moulded and one rectangle. Now you also get a moulded and none moulded fill style represented by ax and axm. Unfortunately although ax stands for 'standard fill style' and axm is used as an override describing the coordinates of a moulded fill (hence the m) the coordinates of both fills are reversed. DONT ASK ME WHY, ASK THE AUTHOR OF AWEPS! So we have to perform some brain dead processing here to get the right attributes applied to the right objects.
Definition at line 1949 of file aw_eps.cpp. 01950 { 01951 01952 BOOL ok; 01953 01954 DocCoord StartPoint, EndPoint; 01955 DocColour StartColour, EndColour; 01956 01957 // Get start and end positions for grad-fills 01958 if (!Stack.PopCoordPair(&EndPoint) || !Stack.PopCoordPair(&StartPoint)) 01959 return FALSE; 01960 01961 // read the last definitions of set colours 01962 if (LastFillType>0) 01963 { 01964 GetEPSColour(&StartColour, 01965 &LastStartColour.Col, 01966 LastStartColour.Tint, 01967 LastStartColour.TintVal, 01968 &LastStartColour.ColName); 01969 01970 GetEPSColour(&EndColour, 01971 &LastEndColour.Col, 01972 LastEndColour.Tint, 01973 LastEndColour.TintVal, 01974 &LastEndColour.ColName); 01975 } 01976 01977 switch (LastFillType) 01978 { 01979 // Decode ArtWorks EPS grad fill codes 01980 case 1: 01981 // Check for silly grad fills first... 01982 if (StartPoint==EndPoint) 01983 ok = SetFillColour(StartColour); 01984 else 01985 ok = SetLinearFill(StartColour, EndColour, StartPoint, EndPoint); 01986 break; 01987 01988 case 2: 01989 // Check for silly grad fills first... 01990 if (StartPoint==EndPoint) 01991 ok=SetFillColour(EndColour); 01992 else 01993 ok=SetRadialFill(StartColour, EndColour, StartPoint, EndPoint); 01994 break; 01995 01996 default: 01997 // if there's no fill applied previously then this is rampant so ignore it. 01998 ok=Stack.Discard(4); 01999 } 02000 02001 return ok; 02002 }
|
|
Initialise an ArtWorksEPSFilter object.
Reimplemented from EPSFilter. Reimplemented in CamelotEPSFilter, and CamelotNativeEPSFilter. Definition at line 262 of file aw_eps.cpp. 00263 { 00264 // Get the OILFilter object 00265 pOILFilter = new ArtWorksEPSOILFilter(this); 00266 if (pOILFilter == NULL) 00267 return FALSE; 00268 00269 // Load the description strings 00270 FilterName.Load(FilterNameID); 00271 FilterInfo.Load(FilterInfoID); 00272 00273 // All ok 00274 return TRUE; 00275 }
|
|
Compare the current token against the ArtWorks keywords to see if it is one of them.
Reimplemented from EPSFilter. Reimplemented in CamelotEPSFilter, and CamelotNativeEPSFilter. Definition at line 413 of file aw_eps.cpp. 00414 { 00415 // Not interested in comments 00416 if (Token == EPSC_Comment) 00417 return; 00418 00419 // Check to see if it is a keyword - cycle through the array of keyword names and 00420 // compare against our token (could use a hash table?) 00421 INT32 i = 0; 00422 while (ArtWorksCommands[i].Cmd != EPSC_Invalid) 00423 { 00424 if (camStrcmp(TokenBuf, ArtWorksCommands[i].CmdStr) == 0) 00425 { 00426 // Found the token - set the token variable and return success 00427 Token = ArtWorksCommands[i].Cmd; 00428 return; 00429 } 00430 // Try next command 00431 i++; 00432 } 00433 00434 // Did not find this token - pass on to base class. 00435 EPSFilter::LookUpToken(); 00436 }
|
|
Informs the print components code that no data should be written.
Reimplemented from EPSFilter. Definition at line 998 of file aw_eps.cpp. 00999 { 01000 // We don't want print components! 01001 return FALSE; 01002 }
|
|
Prepare to import EPS data using this filter. This sets up the filter to a sensible state for reading.
Reimplemented from EPSFilter. Reimplemented in CamelotEPSFilter, and CamelotNativeEPSFilter. Definition at line 351 of file aw_eps.cpp. 00352 { 00353 #ifdef DO_EXPORT 00354 // Created the 'file' DC for rendering and try to open the specified file. 00355 ExportDCPtr = new EPSExportDC(this); 00356 if (ExportDCPtr == NULL) return FALSE; 00357 00358 // Tell it about the file 00359 if (!ExportDCPtr->Init(pFile)) return FALSE; 00360 00361 // Get the position of the first page, and use this to set the origin. 00362 Page *pPage = pSpread->FindFirstPageInSpread(); 00363 ENSURE(pPage != NULL, "Spread has no pages"); 00364 ERRORIF(pPage == NULL, _R(IDT_DOC_BADSTRUCTURE), FALSE); 00365 00366 // Use bottom left of page as origin 00367 DocRect PageRect = pPage->GetPageRect(); 00368 ExportDCPtr->SetOrigin(PageRect.lo); 00369 00370 // Create a new render region to export to: 00371 00372 // Don't care about clip regions when exporting - create a null region. 00373 DocRect NullClipRect; 00374 NullClipRect.MakeEmpty(); 00375 00376 if (IS_A(this, ArtWorksEPSFilter)) 00377 { 00378 // Don't use rendering matrix when exporting EPS as it uses fractional coordinates. 00379 Matrix Identity; 00380 00381 // Don't use view scale; set to 1 00382 FIXED16 Scale(1); 00383 00384 // Create the region 00385 ExportRegion = new ArtWorksEPSRenderRegion(NullClipRect, Identity, Scale); 00386 if (ExportRegion == NULL) 00387 return FALSE; 00388 00389 // Attach to the right device. 00390 ExportRegion->AttachDevice(DocView::GetSelected(), ExportDCPtr->GetDC(), pSpread); 00391 } 00392 00393 // All ok 00394 return TRUE; 00395 #else 00396 return FALSE; 00397 #endif 00398 };
|
|
Reads in all the elements of a blend structure in the EPS file.
Reimplemented in CamelotEPSFilter. Definition at line 1016 of file aw_eps.cpp. 01017 { 01018 if (!StartBlend()) 01019 return FALSE; 01020 01021 // Keep processing tokens until we find the end of the blend 01022 do 01023 { 01024 GetToken(); 01025 01026 // Look for the end of the blend token... 01027 if (Token == EPSC_aebd) 01028 { 01029 return EndBlend(); 01030 } 01031 } 01032 // Otherwise keep going until an error or eof is encountered 01033 while (HandleToken() && (!EPSFile->eof())); 01034 01035 if (EPSFile->eof()) 01036 { 01037 // Didn't find end of blend - syntax error; deal with it 01038 HandleEPSError(); 01039 } 01040 01041 // If we're here, something went wrong 01042 return FALSE; 01043 }
|
|
Reads in all the elements of a blender structure in the EPS file.
Reimplemented in CamelotEPSFilter. Definition at line 1182 of file aw_eps.cpp. 01183 { 01184 if (!StartBlender()) 01185 return FALSE; 01186 01187 // Keep processing tokens until we find the end of the blender 01188 do 01189 { 01190 GetToken(); 01191 01192 // Look for the end of the blender token... 01193 if (Token == EPSC_aebr) 01194 { 01195 return EndBlender(); 01196 } 01197 } 01198 // Otherwise keep going until an error or eof is encountered 01199 while (HandleToken() && (!EPSFile->eof())); 01200 01201 if (EPSFile->eof()) 01202 { 01203 // Didn't find end of blender - syntax error; deal with it 01204 HandleEPSError(); 01205 } 01206 01207 // If we're here, something went wrong 01208 return FALSE; 01209 }
|
|
Reads in all the elements of an envelope structure in the ArtWorksEPS file and builds the camelot envelope tree.
line col fill col start env envelope shape fill col invisible path (Sset) mangled path (Dset) fill col invisible path (Sset) mangled path (Dset) end env and this is saved as such in its EPS structure. Now Camelots structure is slightly different. It creates a source tree for Sset and a destination tree for Dset. Hence we need to disassemble the AW structure into two trees with the correct attributes in each. How do we do this? Complexity level 2. We could do this while importing, keeping two trees on the go, importing the correct bits into the correct tree. However this has many problems associated with it. Globally applied atts will need to be created in both trees. Groups too. We would have to intercept far more than the envelope tokens during import to do it. - no chance. So the only way to do it is to import the structure as is, creating an Artworks envelope inside Camelot. This will be structured as follows Env | > EnvShape => MouldGroup => Moulder | > { Sset + Dset objects } Having done this, we will convert this into Env | > EnvShape => MouldGroup => Moulder | | > Sset > Dset So long as we can tell the difference between Sset and Dset objects, which we can (all Dset objs are primary children of an Sset obj and Dset objects never contain Sset objs as children) we can use object move technology to build the correct moulder. Attributes will move (via inheritance) correctly with objects. Reimplemented in CamelotEPSFilter. Definition at line 1390 of file aw_eps.cpp. 01391 { 01392 // NOT IMPLEMENTED 01393 if (!StartMould(MOULDSPACE_ENVELOPE)) 01394 return FALSE; 01395 01396 if (ProcessMould()) 01397 // If we've completed then all is well 01398 return EndMould(); 01399 01400 if (EPSFile->eof()) 01401 { 01402 // Didn't find end of envelope - syntax error; deal with it 01403 HandleEPSError(); 01404 } 01405 01406 // if made it here all is not well 01407 return FALSE; 01408 }
|
|
On finding a 'apc' token in the input stream, this function is executed. It will process all further tokens in the stream until a path termination has been found. A path terminator is considered any of { s,S,b,B,f,F,h,H } Its purpose is strictly defined. It must place the next set of attributes and single path as children of the last object imported rather than the default action which would be to stick them in as siblings of the object.
Definition at line 1866 of file aw_eps.cpp. 01867 { 01868 // Set the new position of pNode, our insert indicator 01869 Node *pOldPos = pNode; 01870 pNode=pNode->FindLastChild(); 01871 if (pNode==NULL) 01872 { 01873 pNode=pOldPos; 01874 return FALSE; 01875 } 01876 01877 BOOL ok = TRUE, end = FALSE; 01878 01879 // The next path we create should be mangled 01880 ThePathType = PATH_MANGLED; 01881 01882 while ((!end) && (!EPSFile->eof()) && (ok)) 01883 { 01884 GetToken(); 01885 01886 switch (Token) 01887 { 01888 case EPSC_axm: 01889 // ignore axm in this context 01890 // See notes on func HandleMouldedFill below 01891 ok = Stack.Discard(4); 01892 break; 01893 01894 case EPSC_s: case EPSC_f: case EPSC_b: case EPSC_h: 01895 case EPSC_S: case EPSC_F: case EPSC_B: case EPSC_H: 01896 // We've finished so set term flag 01897 end = TRUE; 01898 ok = HandleToken(); 01899 break; 01900 01901 default: 01902 // try to handle whatever token it was. 01903 ok = HandleToken(); 01904 break; 01905 } 01906 } 01907 01908 // Set the path back to something sensible 01909 ThePathType=PATH_NORMAL; 01910 pNode=pOldPos; 01911 01912 if (ok && !(EPSFile->eof())) 01913 return TRUE; 01914 01915 // Arrgh didn't find an end-of-path token - syntax error; deal with it 01916 HandleEPSError(); 01917 return FALSE; 01918 }
|
|
Processes tokens inside a mould object. Tokens specific to mould objects are processed along with some overridding of default tokens such as groups.
Reimplemented in CamelotEPSFilter. Definition at line 1589 of file aw_eps.cpp. 01590 { 01591 // Keep processing tokens until we find the end of the envelope 01592 while (!EPSFile->eof()) 01593 { 01594 GetToken(); 01595 01596 // Look for the end of the envelope token... 01597 switch (Token) 01598 { 01599 case EPSC_aeev: 01600 case EPSC_aepr: 01601 // if we've found the envelope/perspective end then 01602 // all is well. 01603 return TRUE; 01604 break; 01605 01606 case EPSC_apc: 01607 // Create next object as a child 01608 if (!ProcessMangledObjs()) 01609 return FALSE; 01610 break; 01611 01612 case EPSC_u: 01613 // NOT IMPLEMENTED INSIDE MOULDS 01614 break; 01615 01616 case EPSC_U: 01617 // NOT IMPLEMENTED INSIDE MOULDS 01618 break; 01619 01620 case EPSC_aof: 01621 // don't need this token 01622 if (!Stack.Discard(2)) 01623 { 01624 HandleEPSError(); 01625 return FALSE; 01626 } 01627 break; 01628 01629 case EPSC_h: 01630 Token = EPSC_b; 01631 if (!HandleToken()) 01632 return FALSE; 01633 break; 01634 01635 case EPSC_H: 01636 Token = EPSC_B; 01637 if (!HandleToken()) 01638 return FALSE; 01639 break; 01640 01641 default: 01642 // try to handle whatever token this is. 01643 if (!HandleToken()) 01644 return FALSE; 01645 break; 01646 } 01647 } 01648 01649 HandleEPSError(); 01650 return FALSE; 01651 }
|
|
Reads in all the elements of a mould geometry held in the EPS file. The description of the geometry for this particular file type is that of a path. Depending on the geometry type (perspective or envelope) we will obviously expect a slightly different path. The rules are, that currently perspective geometry is described as {m,l,l,l,l} and envelope geometry is {m,c,c,c,c}. Internally we are not restricted to these but ArtworksEPS certainly is. Input Stack = coord, coord.
Reimplemented in CamelotEPSFilter. Definition at line 1677 of file aw_eps.cpp. 01678 { 01679 // We really should be inside a mould object at this stage 01680 if (!IS_A(pNode,NodeMould)) 01681 { 01682 ERROR3("Mould shape found outside a mould object"); 01683 return FALSE; 01684 } 01685 01686 NodeMould* pNodeMould = (NodeMould*)pNode; 01687 01688 // Create a path object to read the mould geometry into 01689 Path TempPath; 01690 if (!TempPath.Initialise(24,12)) 01691 { 01692 HandleNoMemory(); 01693 return FALSE; 01694 } 01695 01696 // Set the current used slots to none 01697 INT32 numt = 0; 01698 DocCoord Ta,Tb,Tc; 01699 PathFlags flags; 01700 flags.IsSelected = FALSE; 01701 01702 // ok, pop off the move stacked coordinate 01703 BOOL ok = Stack.PopCoordPair(&Ta); 01704 if (!ok) 01705 { 01706 HandleEPSError(); 01707 return FALSE; 01708 } 01709 01710 // Add this first element as a move to 01711 if (!TempPath.AddMoveTo(Ta, &flags)) 01712 { 01713 HandleNoMemory(); 01714 return FALSE; 01715 } 01716 01717 // increase the number of tokens read 01718 numt++; 01719 BOOL done = FALSE; 01720 01721 // Keep processing tokens until we find the end of the mould path 01722 while (!done && (!EPSFile->eof())) 01723 { 01724 GetToken(); 01725 01726 // {m,c,c,c,c,c,c,c,c,e} is current maximum 01727 // if more complex, then illegal 01728 if ((numt++)>60) 01729 { 01730 HandleEPSError(); 01731 return FALSE; 01732 } 01733 01734 switch (Token) 01735 { 01736 case EPSC_aml: 01737 // lineto (x,y) found 01738 ok = Stack.PopCoordPair(&Ta); 01739 if (ok) ok = TempPath.AddLineTo(Ta, &flags); 01740 break; 01741 01742 case EPSC_amc: 01743 // curveto (x0,y0,x1,y1,x2,y2) found 01744 ok = Stack.PopCoordPair(&Tc); 01745 if (ok) ok = Stack.PopCoordPair(&Tb); 01746 if (ok) ok = Stack.PopCoordPair(&Ta); 01747 if (ok) ok = TempPath.AddCurveTo(Ta,Tb,Tc,&flags); 01748 break; 01749 01750 case EPSC_amcp: 01751 // found a close path. That should be it for path elements 01752 ok = TempPath.CloseSubPath(); 01753 break; 01754 01755 case EPSC_amep: 01756 // end path drawfile parameter completes the path 01757 // it contains a single 'length' parameter which seems 01758 // to be zero always 01759 ok = Stack.Discard(); 01760 done = TRUE; 01761 break; 01762 01763 default: 01764 // try to handle whatever token this is. 01765 ok = HandleToken(); 01766 break; 01767 } 01768 01769 if (!ok) 01770 { 01771 HandleNoMemory(); 01772 return FALSE; 01773 } 01774 } 01775 01776 // We have read the path so now lets try and build the geometry 01777 // check the shape we've been given is fine and lovely 01778 UINT32 errID; 01779 if (!pNodeMould->GetGeometry()->Validate(&TempPath,errID)) 01780 { 01781 // ok the path we read is invalid so lets try to build a valid one 01782 Path* pPath = NULL; 01783 INT32 Corners[4] = {0, 3, 6, 9}; 01784 01785 if (!pNodeMould->GetGeometry()->MakeValidFrom(&pPath, &TempPath, Corners)) 01786 { 01787 ERROR2(FALSE,"Unable to rectify invalid mould path in ProcessMouldShape()"); 01788 } 01789 01790 if (!TempPath.CloneFrom(*pPath)) 01791 { 01792 delete pPath; 01793 HandleNoMemory(); 01794 return FALSE; 01795 } 01796 01797 delete pPath; 01798 } 01799 01800 // Build and if necessary fit the geometry 01801 NodeMouldPath* pNodeMPath = pNodeMould->CreateNewMouldShape(&TempPath,NULL,NULL); 01802 if (pNodeMPath==NULL) 01803 { 01804 HandleNoMemory(); 01805 return FALSE; 01806 } 01807 01808 // set the geometry using this new mould shape 01809 if (!pNodeMould->GetGeometry()->Define(&(pNodeMPath->InkPath), &MouldRect)) 01810 { 01811 HandleNoMemory(); 01812 return FALSE; 01813 } 01814 01815 // having created the shape bung it in the tree. 01816 if (!AddNewNode(pNodeMPath)) 01817 { 01818 delete pNodeMPath; 01819 HandleNoMemory(); 01820 return FALSE; 01821 } 01822 01823 // Create a mould group object 01824 NodeMouldGroup* pMouldGroup = pNodeMould->CreateNewMouldGroup(NULL); 01825 if (pMouldGroup==NULL) 01826 { 01827 HandleNoMemory(); 01828 return FALSE; 01829 } 01830 01831 if (!AddNewNode(pMouldGroup)) 01832 { 01833 delete pMouldGroup; 01834 HandleNoMemory(); 01835 return FALSE; 01836 } 01837 01838 // finally leave the insert pointer on the MouldGroup object 01839 pNode = pMouldGroup; 01840 01841 return TRUE; 01842 01843 }
|
|
Reads in all the elements of an perspective structure in the EPS file.
Reimplemented in CamelotEPSFilter. Definition at line 1424 of file aw_eps.cpp. 01425 { 01426 // NOT IMPLEMENTED 01427 if (!StartMould(MOULDSPACE_PERSPECTIVE)) 01428 return FALSE; 01429 01430 // If we've completed then all is well 01431 if (ProcessMould()) 01432 return EndMould(); 01433 01434 if (EPSFile->eof()) 01435 { 01436 // Didn't find end of perspective - syntax error; deal with it 01437 HandleEPSError(); 01438 } 01439 01440 // if made it here all is not well 01441 return FALSE; 01442 }
|
|
Processes EPS tokens that are not part of the standard Illustrator set, or which need to be handled differently to the standard Illustrator meanings. i.e. this is the function that handles all the ArtWorks EPS operators.
Reimplemented from EPSFilter. Reimplemented in CamelotEPSFilter, and CamelotNativeEPSFilter. Definition at line 453 of file aw_eps.cpp. 00454 { 00455 // Variables used to extract operands from the stack 00456 DocCoord Coords[3]; 00457 String_64 ColName; 00458 PColourCMYK Col; 00459 TintType Tint = TINT_NONE; 00460 FIXEDPOINT TintVal; 00461 INT32 Long; 00462 DocCoord StartPoint, 00463 EndPoint; 00464 PathFlags Flags; 00465 00466 // Decode the command, and execute it... 00467 switch (Token) 00468 { 00469 // LineTo - overridden to overcome ArtWorks EPS incompatibility with AI EPS. 00470 case EPSC_l: 00471 if (ThePathType == PATH_DISCARD || ThePathType == PATH_DISCARD_STICKY) 00472 { 00473 if (!Stack.PopCoordPair(&Coords[0])) 00474 goto EPSError; 00475 break; 00476 } 00477 00478 if (pInkPath == NULL) 00479 // Paths must start with a moveto 00480 goto EPSError; 00481 00482 // Get the co-ordinate from the stack 00483 if (Stack.PopCoordPair(&Coords[0])) 00484 { 00485 // ArtWorks doesn't save smoothing bit of the point, so default to 00486 // no smoothing (it's the logical default). 00487 Flags.IsSmooth = FALSE; 00488 00489 if (!pInkPath->InsertLineTo(Coords[0], &Flags)) 00490 // Not enough dynamic heap to insert the lineto command 00491 goto NoMemory; 00492 } 00493 else 00494 // Invalid number/type of coordinate operands 00495 goto EPSError; 00496 break; 00497 00498 // Curveto - overridden to overcome ArtWorks EPS incompatibility with AI EPS. 00499 case EPSC_c: 00500 if (ThePathType == PATH_DISCARD || ThePathType == PATH_DISCARD_STICKY) 00501 { 00502 if (!Stack.PopCoordPair(&Coords[2]) || 00503 !Stack.PopCoordPair(&Coords[1]) || 00504 !Stack.PopCoordPair(&Coords[0])) 00505 goto EPSError; 00506 00507 break; 00508 } 00509 00510 if (pInkPath == NULL) 00511 // Paths must start with a moveto 00512 goto EPSError; 00513 00514 // Get the co-ordinate from the stack 00515 if (Stack.PopCoordPair(&Coords[2]) && 00516 Stack.PopCoordPair(&Coords[1]) && 00517 Stack.PopCoordPair(&Coords[0])) 00518 { 00519 // ArtWorks doesn't save smoothing bit of the point, so default to 00520 // no smoothing (it's the logical default). 00521 Flags.IsSmooth = FALSE; 00522 00523 if (!pInkPath->InsertCurveTo(Coords[0], Coords[1], Coords[2], &Flags)) 00524 // Not enough dynamic heap to insert the curveto command 00525 goto NoMemory; 00526 } 00527 else 00528 // Invalid number/type of coordinate operands 00529 goto EPSError; 00530 break; 00531 00532 case EPSC_aoa: 00533 // NOT IMPLEMENTED 00534 if (!Stack.Discard()) 00535 goto EPSError; 00536 break; 00537 00538 case EPSC_aafs: 00539 // NOT IMPLEMENTED 00540 if (!Stack.Discard(3)) 00541 goto EPSError; 00542 break; 00543 00544 00545 // Path related procedures 00546 case EPSC_ar: 00547 // ArtWorks rectangle 00548 ThePathType = PATH_RECT; 00549 break; 00550 00551 case EPSC_arr: 00552 // NOT IMPLEMENTED 00553 if (!Stack.Discard(7)) 00554 goto EPSError; 00555 break; 00556 00557 case EPSC_ae: 00558 { 00559 // ArtWorks ellipse 00560 ThePathType = PATH_ELLIPSE; 00561 00562 // Read in parallelogram bounding box. 00563 if (!Stack.PopCoordPair(&ShapeBBox[0]) || 00564 !Stack.PopCoordPair(&ShapeBBox[1]) || 00565 !Stack.PopCoordPair(&ShapeBBox[2])) 00566 goto EPSError; 00567 00568 // Fill in the 4th co-ordinate 00569 ShapeBBox[3].x = ShapeBBox[0].x + (ShapeBBox[2].x - ShapeBBox[1].x); 00570 ShapeBBox[3].y = ShapeBBox[0].y + (ShapeBBox[2].y - ShapeBBox[1].y); 00571 00572 break; 00573 } 00574 00575 case EPSC_apl: 00576 // NOT IMPLEMENTED 00577 if (!Stack.Discard()) 00578 goto EPSError; 00579 break; 00580 00581 case EPSC_apc: 00582 // NOT IMPLEMENTED 00583 break; 00584 00585 case EPSC_aof: 00586 // NOT IMPLEMENTED 00587 if (!Stack.Discard(2)) 00588 goto EPSError; 00589 break; 00590 00591 00592 // Text related procedures 00593 case EPSC_asto: 00594 // NOT IMPLEMENTED 00595 break; 00596 00597 case EPSC_aeto: 00598 // NOT IMPLEMENTED 00599 break; 00600 00601 case EPSC_aco: 00602 // NOT IMPLEMENTED 00603 if (!Stack.Discard(2)) 00604 goto EPSError; 00605 break; 00606 00607 case EPSC_atc: 00608 // NOT IMPLEMENTED 00609 if (!Stack.Discard()) 00610 goto EPSError; 00611 break; 00612 00613 case EPSC_atph: 00614 // NOT IMPLEMENTED 00615 if (!Stack.Discard()) 00616 goto EPSError; 00617 break; 00618 00619 case EPSC_atof: 00620 // NOT IMPLEMENTED 00621 if (!Stack.Discard(2)) 00622 goto EPSError; 00623 break; 00624 00625 00626 // Blend related procedures 00627 case EPSC_asbd: 00628 return ProcessBlend(); 00629 00630 case EPSC_aebd: 00631 goto EPSError; 00632 00633 case EPSC_asbr: 00634 return ProcessBlender(); 00635 00636 case EPSC_aebr: 00637 goto EPSError; 00638 00639 00640 // Mould related procedures 00641 case EPSC_asev: 00642 return ProcessEnvelope(); 00643 00644 case EPSC_aeev: 00645 goto EPSError; 00646 00647 case EPSC_aspr: 00648 return ProcessPerspective(); 00649 00650 case EPSC_aepr: 00651 goto EPSError; 00652 00653 case EPSC_amm: 00654 return ProcessMouldShape(); 00655 00656 case EPSC_aml: 00657 case EPSC_amc: 00658 case EPSC_amcp: 00659 case EPSC_amep: 00660 // all these tokens are mould path related and are 00661 // delt with inside ProcessMouldShape(). If they are found 00662 // on their own elsewhere then we obviously have an error 00663 goto EPSError; 00664 00665 00666 // Group related procedures 00667 00668 case EPSC_anu: 00669 // Discard the name - we don't do named groups. 00670 if (!Stack.Discard()) 00671 goto EPSError; 00672 00673 // Process as a normal EPS group. 00674 GroupNesting++; 00675 return ProcessGroup(); 00676 00677 // Linear/radial fills 00678 case EPSC_ax: 00679 // Colours are described using a name and tint as well as CMYK. 00680 Tint = TINT_ILLUSTRATOR; 00681 case EPSC_az: 00682 { 00683 DocColour StartColour, EndColour; 00684 DocCoord StartPoint, EndPoint; 00685 00686 // Get start and end positions for grad-fills 00687 if (!Stack.PopCoordPair(&EndPoint) || !Stack.PopCoordPair(&StartPoint)) 00688 goto EPSError; 00689 00690 // Get start and end colours for grad-fills 00691 if (!Stack.PopColour(&Col, Tint, &TintVal, &ColName)) 00692 // Invalid colour operands 00693 goto EPSError; 00694 00695 // Keep hold of this colour definition 00696 LastEndColour.Col = Col; 00697 LastEndColour.Tint = Tint; 00698 LastEndColour.TintVal = TintVal; 00699 LastEndColour.ColName = ColName; 00700 00701 GetEPSColour(&EndColour, &Col, Tint, TintVal, &ColName); 00702 00703 if (!Stack.PopColour(&Col, Tint, &TintVal, &ColName)) 00704 // Invalid colour operands 00705 goto EPSError; 00706 00707 // Keep hold of this colour definition 00708 LastStartColour.Col = Col; 00709 LastStartColour.Tint = Tint; 00710 LastStartColour.TintVal = TintVal; 00711 LastStartColour.ColName = ColName; 00712 00713 GetEPSColour(&StartColour, &Col, Tint, TintVal, &ColName); 00714 00715 // Get fill type 00716 if (!Stack.Pop(&Long)) 00717 goto EPSError; 00718 00719 // Also save the last fill style 00720 LastFillType = Long; 00721 00722 switch (Long) 00723 { 00724 // Decode ArtWorks EPS grad fill codes 00725 case 1: 00726 // Check for silly grad fills first... 00727 if (StartPoint == EndPoint) 00728 { 00729 // Zero length grad fill line! 00730 // Just set a flat fill using the first colour, cos that is 00731 // how Arc GDraw renders such fills. 00732 if (!SetFillColour(StartColour)) 00733 goto NoMemory; 00734 } 00735 else 00736 { 00737 if (!SetLinearFill(StartColour, EndColour, StartPoint, EndPoint)) 00738 goto NoMemory; 00739 } 00740 break; 00741 00742 case 2: 00743 // Check for silly grad fills first... 00744 if (StartPoint == EndPoint) 00745 { 00746 // Zero length grad fill line! 00747 // Just set a flat fill using the second colour, cos that is 00748 // how Arc GDraw renders such fills. 00749 // 00750 // NB. This is different to linear fills above, which use the first 00751 // colour - that is how the GDraw cookie crumbles, cos that's 00752 // the kind of guys we are! :-) 00753 if (!SetFillColour(EndColour)) 00754 goto NoMemory; 00755 } 00756 else 00757 { 00758 if (!SetRadialFill(StartColour, EndColour, StartPoint, EndPoint)) 00759 goto NoMemory; 00760 } 00761 break; 00762 00763 default: 00764 ENSURE(FALSE, "Unknown fill type found!"); 00765 break; // Don't know this fill type 00766 } 00767 break; 00768 } 00769 00770 case EPSC_axm: 00771 { 00772 // ignore axm in this context 00773 if (!HandleMouldedFill()) 00774 goto EPSError; 00775 break; 00776 } 00777 00778 case EPSC_axop: 00779 // NOT IMPLEMENTED 00780 if (!Stack.Discard(4)) 00781 goto EPSError; 00782 break; 00783 00784 00785 // Others(!) 00786 case EPSC_awr: 00787 if (!Stack.Pop(&Long)) 00788 goto EPSError; 00789 // Decode winding rule 00790 ENSURE((Long == 0) || (Long == 1), "Bad winding rule found in Artworks EPS"); 00791 if (Long == 0) 00792 { 00793 if (!SetWindingRule(NonZeroWinding)) 00794 goto NoMemory; 00795 } 00796 else if (Long == 1) 00797 { 00798 if (!SetWindingRule(EvenOddWinding)) 00799 goto NoMemory; 00800 } 00801 break; 00802 00803 case EPSC_asc: 00804 // NOT IMPLEMENTED 00805 if (!Stack.Discard(3)) 00806 goto EPSError; 00807 break; 00808 00809 case EPSC_aec: 00810 // NOT IMPLEMENTED 00811 if (!Stack.Discard(3)) 00812 goto EPSError; 00813 break; 00814 00815 case EPSC_aca: 00816 // NOT IMPLEMENTED 00817 break; 00818 00819 case EPSC_asah: 00820 // NOT IMPLEMENTED 00821 if (!Stack.Discard(3)) 00822 goto EPSError; 00823 break; 00824 00825 case EPSC_aeah: 00826 // NOT IMPLEMENTED 00827 if (!Stack.Discard(3)) 00828 goto EPSError; 00829 break; 00830 00831 case EPSC_asat: 00832 // NOT IMPLEMENTED 00833 if (!Stack.Discard(6)) 00834 goto EPSError; 00835 break; 00836 00837 case EPSC_aeat: 00838 // NOT IMPLEMENTED 00839 if (!Stack.Discard(6)) 00840 goto EPSError; 00841 break; 00842 00843 // Procedures that define a text object 00844 case EPSC_atp: 00845 // NOT IMPLEMENTED 00846 if (!Stack.Discard(2)) 00847 goto EPSError; 00848 break; 00849 00850 case EPSC_atf: 00851 // NOT IMPLEMENTED 00852 if (!Stack.Discard()) 00853 goto EPSError; 00854 break; 00855 00856 case EPSC_atxy: 00857 // NOT IMPLEMENTED 00858 if (!Stack.Discard(2)) 00859 goto EPSError; 00860 break; 00861 00862 case EPSC_atrk: 00863 // NOT IMPLEMENTED 00864 if (!Stack.Discard(4)) 00865 goto EPSError; 00866 break; 00867 00868 case EPSC_akrn: 00869 // NOT IMPLEMENTED 00870 if (!Stack.Discard(2)) 00871 goto EPSError; 00872 break; 00873 00874 00875 // Layer procedure 00876 case EPSC_alyr: 00877 { 00878 String_256 LayerName; 00879 INT32 Visible; 00880 INT32 Locked; 00881 INT32 Foreground; 00882 INT32 Printable; 00883 00884 // We ignore the layer type and print over-ride flag (for now) 00885 if (!Stack.Pop(&Locked) || 00886 !Stack.Pop(&Printable) || 00887 !Stack.Pop(&Visible) || 00888 !Stack.Pop(&Foreground) || 00889 !Stack.Pop(&LayerName)) 00890 goto EPSError; 00891 00892 if (Filter::ImportWithLayers) 00893 { 00894 // We are importing layers, so put all new nodes on this layer. 00895 UseLayer(LayerName); 00896 00897 // Try to set the visible/locked flags on this layer, but only if 00898 // we created a new one (i.e. don't change the flags of existing layers. 00899 if (EPSFlags.AddToNewLayer) 00900 { 00901 // Here we force layers to be printable if they are in the foreground - just in case 00902 // This will have to change if the UI allows Printable & Foreground to be specified 00903 // independantly. 00904 Printable = Foreground; 00905 00906 // Visible flag 00907 pLayer->SetVisible(!(Visible == 0)); 00908 00909 // Locked flag 00910 pLayer->SetLocked(!(Locked == 0)); 00911 00912 // Printable flag 00913 pLayer->SetPrintable(!(Printable == 0)); 00914 00915 // Background flag 00916 pLayer->SetBackground(Foreground == 0); 00917 } 00918 } 00919 break; 00920 } 00921 00922 00923 // Sprite procedure 00924 case EPSC_ass: 00925 // NOT IMPLEMENTED 00926 ERROR2RAW("EPS reader cannot handle Acorn sprites - Dream On!"); 00927 goto EPSError; 00928 break; 00929 00930 case EPSC_aes: 00931 // NOT IMPLEMENTED 00932 ERROR2RAW("EPS reader cannot handle Acorn sprites! - Dream On!"); 00933 goto EPSError; 00934 break; 00935 00936 default: 00937 // Token not understood - pass on to base class 00938 return EPSFilter::ProcessToken(); 00939 } 00940 00941 00942 // No errors encountered while parsing this token and its operands. 00943 return TRUE; 00944 00945 00946 // Error handlers: 00947 00948 EPSError: 00949 HandleEPSError(); 00950 return FALSE; 00951 00952 NoMemory: 00953 HandleNoMemory(); 00954 return FALSE; 00955 }
|
|
Promote all mangled child nodes to siblings of their parents.
Definition at line 2203 of file aw_eps.cpp. 02204 { 02205 Node* sNode; 02206 sNode=rNode->FindFirstChild(); 02207 while (sNode) 02208 { 02209 if (sNode->IsMangled()) 02210 { 02211 sNode->SetMangled(FALSE); 02212 sNode->MoveNode(rNode,NEXT); 02213 rNode->CascadeDelete(); 02214 delete rNode; 02215 return TRUE; 02216 } 02217 sNode=sNode->FindNext(); 02218 } 02219 return FALSE; 02220 }
|
|
Used when a blend structure needs to be created - after this is called, all new nodes added with AddNewNode() will be added as children of this new blend, until EndBlend is called.
Reimplemented in CamelotEPSFilter. Definition at line 1061 of file aw_eps.cpp. 01062 { 01063 INT32 NumBlendShapes,Version,Expanded; 01064 01065 // Read in the params 01066 BOOL ok = Stack.Pop(&NumBlendShapes); 01067 if (ok) ok = Stack.Pop(&Expanded); 01068 if (ok) ok = Stack.Pop(&Version); 01069 if (!ok) 01070 { 01071 HandleEPSError(); 01072 return FALSE; 01073 } 01074 01075 // If the version isn;t one we know, go b-b-b-bang! 01076 ERROR1IF(Version != 1,FALSE,_R(IDT_EPS_BADSYNTAX)); 01077 01078 // Make a new blend node for this blend 01079 NodeBlend *pBlend = new NodeBlend; 01080 if (pBlend==NULL) 01081 { 01082 HandleNoMemory(); 01083 return FALSE; 01084 } 01085 01086 // Add it into the tree 01087 if (!AddNewNode(pBlend)) 01088 { 01089 HandleNoMemory(); 01090 return FALSE; 01091 } 01092 01093 // Make sure new objects are added as children of the node 01094 pNode = pBlend; 01095 01096 // All ok 01097 return TRUE; 01098 }
|
|
Used when a blender structure needs to be created - after this is called, all new paths will be discarded, until EndBlender is called.
Reimplemented in CamelotEPSFilter. Definition at line 1226 of file aw_eps.cpp. 01227 { 01228 UINT32 NumBlendSteps; 01229 INT32 Expanded,OneToOne,Complex; 01230 INT32 PathIndexStart,PathIndexEnd; 01231 01232 // Get the blender params 01233 BOOL ok = Stack.Pop(&PathIndexEnd); 01234 if (ok) ok = Stack.Pop(&PathIndexStart); 01235 if (ok) ok = Stack.Pop(&NumBlendSteps); 01236 if (ok) ok = Stack.Pop(&OneToOne); 01237 if (ok) ok = Stack.Pop(&Complex); 01238 if (ok) ok = Stack.Pop(&Expanded); 01239 if (!ok) 01240 { 01241 HandleEPSError(); 01242 return FALSE; 01243 } 01244 01245 // Make a new blender node for this blender 01246 NodeBlender *pNodeBlender = new NodeBlender; 01247 if (pNodeBlender == NULL) 01248 { 01249 HandleNoMemory(); 01250 return FALSE; 01251 } 01252 01253 // Add it into the tree 01254 if (!AddNewNode(pNodeBlender)) 01255 { 01256 delete pNodeBlender; 01257 HandleNoMemory(); 01258 return FALSE; 01259 } 01260 01261 // If both indexes are -ve, don't change the start points of the paths when blending 01262 if (PathIndexEnd < 0 && PathIndexEnd < 0) 01263 PathIndexStart = PathIndexEnd = 0; 01264 01265 // Set the AW path indexes to be used when we get an "aebd" (end blend) token 01266 pNodeBlender->SetPathIndexStart(PathIndexStart); 01267 pNodeBlender->SetPathIndexEnd (PathIndexEnd); 01268 01269 // Some of these flags are stored in the parent blend node in Camelot - so set them! 01270 if (!IS_A(pNode,NodeBlend)) 01271 { 01272 ERROR2(FALSE,"Found a blender token without finding a blend"); 01273 } 01274 01275 NodeBlend* pNodeBlend = (NodeBlend*)pNode; 01276 pNodeBlend->SetNumBlendSteps(NumBlendSteps-1); 01277 pNodeBlend->SetOneToOne(OneToOne); 01278 01279 // Discard all paths between this and the aebr tokens 01280 ThePathType = PATH_DISCARD_STICKY; 01281 01282 // All ok 01283 return TRUE; 01284 }
|
|
Used when an mould structure needs to be created - after this is called, all new nodes added with AddNewNode() will be added as children of this new mould, until EndMould is called.
Reimplemented in CamelotEPSFilter. Definition at line 1464 of file aw_eps.cpp. 01465 { 01466 // Read in the bounding box of the original objects 01467 if (!Stack.PopCoordPair(&MouldRect.hi) || 01468 !Stack.PopCoordPair(&MouldRect.lo)) 01469 { 01470 HandleEPSError(); 01471 return FALSE; 01472 } 01473 01474 // create a mould parent and insert it in the tree 01475 NodeMould* pMouldParent = new NodeMould; 01476 if (pMouldParent==NULL) 01477 { 01478 HandleNoMemory(); 01479 return FALSE; 01480 } 01481 01482 // give the parent mould object a shape and mould space to work with and stick it 01483 // in the tree 01484 if (!pMouldParent->CreateGeometry(mSpace)) 01485 { 01486 delete pMouldParent; 01487 HandleNoMemory(); 01488 return FALSE; 01489 } 01490 01491 if (!AddNewNode(pMouldParent)) 01492 { 01493 HandleNoMemory(); 01494 return FALSE; 01495 } 01496 01497 // Make sure new objects are added as children of the mould 01498 pNode = pMouldParent; 01499 01500 // All ok 01501 return TRUE; 01502 }
|
|
|
|
|
|
|
|
|
|
|