#include <freeeps.h>
Inheritance diagram for FreeHandEPSFilter:
Public Member Functions | |
FreeHandEPSFilter () | |
Constructor for an FreeHandEPSFilter object. The object should be initialised before use. | |
BOOL | Init () |
Initialise an FreeHandEPSFilter object. | |
Protected Member Functions | |
BOOL | PrepareToImport () |
prepares to import a freehand EPS file | |
INT32 | EPSHeaderIsOk (ADDR pFileHeader, UINT32 HeaderSize) |
Checks to see if the EPS comment headers specify that this is an FreeHand 3.0 generated EPS file, as required. | |
void | LookUpToken () |
Compare the current token against the AI keywords to see if it is one of them. | |
BOOL | ProcessToken () |
Examines the current token and performs whatever actions are necessary to process its meaning. Operands are simply pushed onto the EPS stack, and keywords are either acted upon, or ignored if they describe something that Camelot does not yet support (in the latter case, the operands of the keyword, if any, are simply discarded from the stack). | |
void | CleanUpAfterImport (BOOL Successful) |
clears up after importing a FreeHand 3.0 EPS file | |
BOOL | ValidateGroup (Node *pGroup) |
validates a group created by the filter. As all objects have a group around then, this removes groups which only have one entry. | |
BOOL | MaskedGroupEnding () |
Restores the graphic state after a masked group ends. | |
virtual BOOL | AddNewNode (Node *pNewNode) |
checks to see if we're in complex path mode before passing on the node to the base class. If we are, it joins it to the last one and fiddles about with the attributes. | |
Private Member Functions | |
CC_DECLARE_DYNAMIC (FreeHandEPSFilter) | |
BOOL | PopColour (DocColour *Col) |
Pops a FreeHand colour off the stack. | |
BOOL | PopNamedColour (DocColour *Col) |
Pops a FreeHand named colour off the stack. | |
BOOL | DiscardFillSubType () |
discards a fill sub type from the stack ('{}' or '{logtaper}' or something) | |
BOOL | SaveCurrentFill () |
stores the current fill attribute | |
BOOL | RestoreCurrentFill () |
restores the current fill attribute from the stored one | |
BOOL | RemoveLastSubPathIfNotUnique (Path *pPath) |
Removes the last subpath from a path if an sub path with it's exact coords already exists. | |
Private Attributes | |
BOOL | HadhToken |
BOOL | DoingGradFill |
AttributeValue * | OldFill |
BOOL | InColours |
BOOL | InText |
ImportedColours * | pNewColours |
IndexedColour ** | ColourArray |
INT32 | ColourArrayEntries |
INT32 | ColourArraySize |
BOOL | ComplexPathMode |
BOOL | HadFirstOfComplexPath |
NodePath * | pLastPathSeen |
Static Private Attributes | |
static CommandMap | FHCommands [] |
Definition at line 121 of file freeeps.h.
|
Constructor for an FreeHandEPSFilter object. The object should be initialised before use.
Definition at line 213 of file freeeps.cpp. 00214 { 00215 // Set up filter descriptions. 00216 FilterNameID = _R(IDT_FREEHANDEPS_FILTERNAME); 00217 FilterInfoID = _R(IDT_FREEHANDEPS_FILTERINFO); 00218 ImportMsgID = _R(IDT_IMPORTMSG_FREEHANDEPS); 00219 00220 FilterID = FILTERID_FREEHAND_EPS; 00221 00222 Flags.CanImport = TRUE; 00223 Flags.CanExport = FALSE; 00224 00225 AdjustOrigin = FALSE; 00226 }
|
|
checks to see if we're in complex path mode before passing on the node to the base class. If we are, it joins it to the last one and fiddles about with the attributes.
Reimplemented from EPSFilter. Definition at line 1409 of file freeeps.cpp. 01410 { 01411 if(IS_A(pNewNode, NodePath)) 01412 pLastPathSeen = (NodePath *)pNewNode; 01413 01414 // check to see if we want to handle this 01415 if((ComplexPathMode == FALSE) || (pNewNode == 0) || (pNode == 0) || (!IS_A(pNewNode, NodePath))) 01416 return EPSFilter::AddNewNode(pNewNode); 01417 01418 // check to see if this is the first... 01419 if(HadFirstOfComplexPath == FALSE) 01420 { 01421 HadFirstOfComplexPath = TRUE; 01422 return EPSFilter::AddNewNode(pNewNode); 01423 } 01424 01425 // find the last child of the node 01426 Node *pLastChild = pNode->FindLastChild(); 01427 if(pLastChild == 0 || !IS_A(pLastChild, NodePath)) 01428 return EPSFilter::AddNewNode(pNewNode); 01429 01430 // we know that both of these things are NodePaths. 01431 Path *pTarget = &((NodePath *)pLastChild)->InkPath; 01432 Path *pAddition = &((NodePath *)pNewNode)->InkPath; 01433 01434 // work out the new flags for the target 01435 BOOL TargetFilled = pTarget->IsFilled; 01436 BOOL TargetStroked = pTarget->IsStroked; 01437 if(pAddition->IsFilled) TargetFilled = TRUE; 01438 if(pAddition->IsStroked) TargetStroked = TRUE; 01439 01440 // add this new path to the old one... 01441 if(!pTarget->MergeTwoPaths(*pAddition)) 01442 return FALSE; 01443 01444 // check that the thing we just added isn't already there 01445 if(!RemoveLastSubPathIfNotUnique(pTarget)) 01446 return FALSE; 01447 01448 // set it's flags 01449 pTarget->IsFilled = TargetFilled; 01450 pTarget->IsStroked = TargetStroked; 01451 01452 // vape it's attributes 01453 pLastChild->DeleteChildren(pLastChild->FindFirstChild()); 01454 01455 // apply some new ones 01456 SetPathFilled(TargetFilled); 01457 if(!AddAttributes((NodePath *)pLastChild, TargetStroked, TargetFilled)) 01458 return FALSE; 01459 01460 // hide the nice additional path 01461 //if(!ImportInfo.pOp->DoHideNode(pNewNode, TRUE)) 01462 // return FALSE; 01463 pNewNode->CascadeDelete(); 01464 delete pNewNode; 01465 01466 // set the last seen path bollox 01467 pLastPathSeen = (NodePath *)pLastChild; 01468 01469 // done! 01470 return TRUE; 01471 }
|
|
|
|
clears up after importing a FreeHand 3.0 EPS file
Reimplemented from EPSFilter. Definition at line 316 of file freeeps.cpp. 00317 { 00318 // ensure that there's no old fill hanging around 00319 if(OldFill != 0) 00320 delete OldFill; 00321 00322 OldFill = 0; 00323 00324 // add new colours if successful, destroy them if not 00325 if(Successful) 00326 { 00327 pNewColours->AddColoursToDocument(); 00328 } 00329 else 00330 { 00331 pNewColours->DestroyColours(); 00332 } 00333 00334 // delete the colour reference array 00335 if(ColourArray != 0) 00336 { 00337 CCFree(ColourArray); 00338 ColourArray = 0; 00339 } 00340 00341 // get rid of any stuff in the stack 00342 Stack.DeleteAll (); 00343 00344 EPSFilter::CleanUpAfterImport(Successful); 00345 }
|
|
discards a fill sub type from the stack ('{}' or '{logtaper}' or something)
Definition at line 1063 of file freeeps.cpp. 01064 { 01065 BOOL Done = FALSE; 01066 EPSType Type; 01067 while(Done == FALSE) 01068 { 01069 Type = Stack.GetType(); 01070 if(Type == EPSTYPE_NONE) 01071 { 01072 // not enough stuff on the stack 01073 return FALSE;; 01074 } 01075 else if(Type == EPSTYPE_STRING) 01076 { 01077 // string - is this the ending? 01078 String_64 Str; 01079 if(!Stack.Pop(&Str)) 01080 return FALSE; 01081 if(camStrcmp(Str, _T("{")) == 0) 01082 Done = TRUE; // found end of this bit 01083 } 01084 else 01085 { 01086 // just something unimportant - discard it 01087 if(!Stack.Discard()) 01088 return FALSE; 01089 } 01090 } 01091 01092 return TRUE; 01093 }
|
|
Checks to see if the EPS comment headers specify that this is an FreeHand 3.0 generated EPS file, as required.
Reimplemented from EPSFilter. Definition at line 360 of file freeeps.cpp. 00361 { 00362 // Check the first line in EPS file 00363 if (strncmp((char *) pFileHeader, "%!PS-Adobe", 10) != 0) 00364 { 00365 // Incorrect version of EPS header line - we don't want this 00366 return 0; 00367 } 00368 00369 // !PS-Adobe line is ok - check creator line... 00370 TCHAR *Buffer; 00371 CCMemTextFile HeaderFile((char *)pFileHeader, HeaderSize); 00372 if(HeaderFile.IsMemFileInited() == FALSE || HeaderFile.InitLexer() == FALSE) 00373 { 00374 HeaderFile.close(); 00375 return 0; 00376 } 00377 00378 00379 BOOL HaveCreatorString = FALSE; 00380 00381 UINT32 Lines = 0; 00382 while ((Lines < 20) && !HeaderFile.eof()) 00383 { 00384 HeaderFile.GetLineToken(); 00385 Buffer = (TCHAR *)HeaderFile.GetTokenBuf(); 00386 ERROR2IF(Buffer == 0, 0, "Returned buffer from lex file == 0"); 00387 Lines++; 00388 00389 // Return TRUE if this file was created by Illustrator, or has been exported in 00390 // Illustrator format. 00391 if (camStrncmp( (const TCHAR *)Buffer, _T("%%Creator: "), 11) == 0 && 00392 camStrstr( (const TCHAR*)Buffer, _T("FreeHand")) != 0) 00393 { 00394 // found a plausible creator string - but it could be any version 00395 // (3.0 for the Mac gives it's version number here, but the PC one doesn't) 00396 HaveCreatorString = TRUE; 00397 } 00398 00399 if (camStrncmp(Buffer, _T("%%DocumentProcSets: FreeHand_header 3 "), 38) == 0 && HaveCreatorString) 00400 { 00401 // I'll have that then. 00402 HeaderFile.close(); 00403 return 10; 00404 } 00405 00406 // If we find the compression token then stop the search as we don't want to start 00407 // looking in the compressed data! 00408 if (camStrncmp(Buffer, _T("%%Compression:"), 14)==0) 00409 break; 00410 } 00411 00412 HeaderFile.close(); 00413 00414 return 0; 00415 }
|
|
Initialise an FreeHandEPSFilter object.
Reimplemented from EPSFilter. Definition at line 241 of file freeeps.cpp. 00242 { 00243 // Get the OILFilter object 00244 pOILFilter = new FreeHandEPSOILFilter(this); 00245 if (pOILFilter == NULL) 00246 return FALSE; 00247 00248 // Load the description strings 00249 FilterName.Load(FilterNameID); 00250 FilterInfo.Load(FilterInfoID); 00251 00252 // All ok 00253 return TRUE; 00254 }
|
|
Compare the current token against the AI keywords to see if it is one of them.
Reimplemented from EPSFilter. Definition at line 431 of file freeeps.cpp. 00432 { 00433 // Check to see if it is a keyword - cycle through the array of keyword names and 00434 // compare against our token (could use a hash table?) 00435 INT32 i = 0; 00436 while (FHCommands[i].Cmd != EPSC_Invalid) 00437 { 00438 if (camStrcmp(TokenBuf, FHCommands[i].CmdStr) == 0) 00439 { 00440 // Found the token - set the token variable and return success 00441 Token = FHCommands[i].Cmd; 00442 return; 00443 } 00444 // Try next command 00445 i++; 00446 } 00447 00448 // Did not find this token - pass on to base class. 00449 EPSFilter::LookUpToken(); 00450 }
|
|
Restores the graphic state after a masked group ends.
Reimplemented from EPSFilter. Definition at line 1322 of file freeeps.cpp. 01323 { 01324 // make the path type normal 01325 if(ThePathType == PATH_DISCARD || ThePathType == PATH_DISCARD_STICKY) 01326 { 01327 ThePathType = PATH_NORMAL; 01328 } 01329 01330 return TRUE; 01331 }
|
|
Pops a FreeHand colour off the stack.
Definition at line 1109 of file freeeps.cpp. 01110 { 01111 // OK, we expect an array of four values in the order (of popping) K, Y, M, C 01112 01113 // check that we've got a array end 01114 EPSCommand Cmd; 01115 if(!Stack.PopCmd(&Cmd)) 01116 return FALSE; 01117 if(Cmd != EPSC_ArrayEnd) 01118 return FALSE; 01119 01120 // pop the colours 01121 double C, M, Y, K; 01122 if(!Stack.Pop(&K) || 01123 !Stack.Pop(&Y) || 01124 !Stack.Pop(&M) || 01125 !Stack.Pop(&C)) 01126 return FALSE; 01127 01128 // check that we've got a array start 01129 if(!Stack.PopCmd(&Cmd)) 01130 return FALSE; 01131 if(Cmd != EPSC_ArrayStart) 01132 return FALSE; 01133 01134 // knock up the colour... 01135 ColourCMYK Colour; 01136 01137 Colour.Cyan = C; 01138 Colour.Magenta = M; 01139 Colour.Yellow = Y; 01140 Colour.Key = K; 01141 01142 IndexedColour *NewCol = new IndexedColour(COLOURMODEL_CMYK, (ColourGeneric *)&Colour); 01143 01144 if(NewCol == 0) 01145 return FALSE; 01146 01147 pColours->GetColourList()->GetUnnamedColours()->AddTail(NewCol); 01148 01149 Col->MakeRefToIndexedColour(NewCol); 01150 01151 return TRUE; 01152 }
|
|
Pops a FreeHand named colour off the stack.
Definition at line 1168 of file freeeps.cpp. 01169 { 01170 // OK, we expect an array of two values in the order (of popping) random, index 01171 // and we can use the index to look up the indexed colour we should use in our 01172 // nice list in ColourArray. 01173 // 'random'? Maybe it's a tint or something? Which doesn't seem to be used. 01174 01175 // check that we've got a array end 01176 EPSCommand Cmd; 01177 if(!Stack.PopCmd(&Cmd)) 01178 return FALSE; 01179 if(Cmd != EPSC_ArrayEnd) 01180 return FALSE; 01181 01182 // pop the index 01183 double Random; 01184 INT32 Index; 01185 if(!Stack.Pop(&Index) || 01186 !Stack.Pop(&Random)) 01187 return FALSE; 01188 01189 // check that we've got a array start 01190 if(!Stack.PopCmd(&Cmd)) 01191 return FALSE; 01192 if(Cmd != EPSC_ArrayStart) 01193 return FALSE; 01194 01195 // check that the index is valid 01196 if(Index < 0 || Index >= ColourArrayEntries) 01197 return FALSE; 01198 01199 // knock up the colour... 01200 Col->MakeRefToIndexedColour(ColourArray[Index]); 01201 01202 return TRUE; 01203 }
|
|
prepares to import a freehand EPS file
Reimplemented from EPSFilter. Definition at line 268 of file freeeps.cpp. 00269 { 00270 if(!EPSFilter::PrepareToImport()) 00271 return FALSE; 00272 00273 // set some nice variables 00274 HadhToken = FALSE; 00275 DoingGradFill = FALSE; 00276 OldFill = 0; 00277 InColours = FALSE; 00278 InText = FALSE; 00279 ComplexPathMode = FALSE; 00280 pLastPathSeen = 0; 00281 00282 // set the clipping flags 00283 ClipRegion.SetClippingFlags(2); 00284 00285 // get an importedcolours object 00286 pNewColours = new ImportedColours(pColours, FALSE); 00287 if(pNewColours == 0 || !pNewColours->Init()) 00288 return FALSE; 00289 00290 // get a colour array 00291 ColourArray = (IndexedColour **)CCMalloc(FHEF_COLOURARRAY_INITIALSIZE * sizeof(IndexedColour *)); 00292 if(ColourArray == 0) 00293 { 00294 delete pNewColours; 00295 pNewColours = 0; 00296 return FALSE; 00297 } 00298 ColourArrayEntries = 0; 00299 ColourArraySize = FHEF_COLOURARRAY_INITIALSIZE; 00300 00301 return TRUE; 00302 }
|
|
Examines the current token and performs whatever actions are necessary to process its meaning. Operands are simply pushed onto the EPS stack, and keywords are either acted upon, or ignored if they describe something that Camelot does not yet support (in the latter case, the operands of the keyword, if any, are simply discarded from the stack).
Reimplemented from EPSFilter. Definition at line 477 of file freeeps.cpp. 00478 { 00479 // Decode the command, and execute it... 00480 switch (Token) 00481 { 00482 // state saving 00483 case EPSC_vms: 00484 if(!Import_gsave()) 00485 return FALSE; 00486 break; 00487 00488 case EPSC_vmr: 00489 if(!Import_grestore()) 00490 return FALSE; 00491 break; 00492 00493 case EPSC_vmrs: 00494 if(!Import_grestore()) 00495 return FALSE; 00496 if(!Import_gsave()) 00497 return FALSE; 00498 break; 00499 00500 // tokens to ignore 00501 case EPSC_FREEHAND_IGNOREDTOKEN: 00502 break; 00503 00504 // tokens which should be ignored and one entry discarded 00505 case EPSC_load: // the load part of a fill - discard the /clipper before it 00506 case EPSC_fhsetspreadallow: 00507 if(!Stack.Discard(1)) 00508 goto EPSError; 00509 break; 00510 00511 case EPSC_concat: 00512 if(!Stack.DiscardArray()) 00513 goto EPSError; 00514 break; 00515 00516 // complex paths... 00517 case EPSC_eomode: 00518 { 00519 INT32 ComplexStart; 00520 00521 if(!Stack.Pop(&ComplexStart)) 00522 goto EPSError; 00523 00524 // is this a start of a complex path? 00525 if(ComplexStart != TRUE) 00526 { 00527 ComplexPathMode = FALSE; 00528 } 00529 else 00530 { 00531 HadFirstOfComplexPath = FALSE; 00532 ComplexPathMode = TRUE; 00533 } 00534 } 00535 break; 00536 00537 case EPSC_true: 00538 Stack.Push((INT32)TRUE); 00539 break; 00540 00541 case EPSC_false: 00542 Stack.Push((INT32)FALSE); 00543 break; 00544 00545 case EPSC_u: 00546 HadFirstOfComplexPath = FALSE; 00547 return EPSFilter::ProcessToken(); 00548 break; 00549 00550 // colours 00551 case EPSC_Ka: 00552 case EPSC_ka: 00553 { 00554 DocColour Colour; 00555 00556 if(PopColour(&Colour)) 00557 { 00558 // Remember this colour for future objects 00559 if (Token == EPSC_ka) 00560 { 00561 if (!SetFillColour(Colour)) 00562 goto NoMemory; 00563 } 00564 else 00565 { 00566 if (!SetLineColour(Colour)) 00567 goto NoMemory; 00568 } 00569 } 00570 else 00571 // Invalid colour operands 00572 goto EPSError; 00573 } 00574 break; 00575 00576 case EPSC_Xa: 00577 case EPSC_xa: 00578 { 00579 DocColour Colour; 00580 00581 if(PopNamedColour(&Colour)) 00582 { 00583 // Remember this colour for future objects 00584 if (Token == EPSC_xa) 00585 { 00586 if (!SetFillColour(Colour)) 00587 goto NoMemory; 00588 } 00589 else 00590 { 00591 if (!SetLineColour(Colour)) 00592 goto NoMemory; 00593 } 00594 } 00595 else 00596 // Invalid colour operands 00597 goto EPSError; 00598 } 00599 break; 00600 00601 case EPSC_H: 00602 if(ComplexPathMode) 00603 { 00604 // in complex path mode - make this a filled one, not a discarded one 00605 Token = EPSC_S; 00606 } 00607 return EPSFilter::ProcessToken(); 00608 break; 00609 00610 case EPSC_h: 00611 if(ComplexPathMode) 00612 { 00613 // in complex path mode - modify and process 00614 Token = EPSC_s; 00615 return EPSFilter::ProcessToken(); 00616 break; 00617 } 00618 // the hidden path closing operator - a grad fill thingy will follow shortly maybe... 00619 // this will prevent it being processed now, although it may get processed later on. 00620 HadhToken = TRUE; 00621 break; 00622 00623 // for clipping masks, do some funky stuff 00624 case EPSC_q: 00625 // if there's a pending grad fill... 00626 if(DoingGradFill) 00627 { 00628 if(pPath != 0) 00629 { 00630 // right then, make a copy of the path... 00631 NodePath *pPathClone; 00632 00633 if(!pPath->NodeCopy((Node **)&pPathClone)) 00634 { 00635 goto NoMemory; 00636 } 00637 00638 // copy the flags 00639 EPSFlagsDefn EPSFlagsClone = EPSFlags; 00640 00641 // send a token to finish and fill the path... 00642 Token = (pInkPath->IsFilled)?EPSC_f:EPSC_s; 00643 if(!EPSFilter::ProcessToken()) 00644 return FALSE; 00645 00646 // restore the old fill 00647 if(!RestoreCurrentFill()) 00648 goto NoMemory; 00649 00650 // restore the copy of the path 00651 pPath = pPathClone; 00652 pInkPath = &pPath->InkPath; 00653 00654 // restore the flags 00655 EPSFlags = EPSFlagsClone; 00656 00657 // definately want to send an h 00658 HadhToken = TRUE; 00659 } 00660 00661 // done the grad fill 00662 DoingGradFill = FALSE; 00663 00664 // restore the old token 00665 Token = EPSC_q; 00666 } 00667 00668 // clipping started - have we got an h token to send? 00669 if(HadhToken) 00670 FHEF_SENDh 00671 00672 // process this 00673 return EPSFilter::ProcessToken(); 00674 break; 00675 00676 // for now, if there's no path, don't return a W 00677 case EPSC_W: 00678 if(pPath == 0) 00679 { 00680 // OK, now we want to get the last path we created, make a copy of it and then install it as the current one 00681 if(pLastPathSeen == 0) 00682 goto EPSError; 00683 00684 // make a copy of it 00685 NodePath *pClone; 00686 00687 if(!pLastPathSeen->NodeCopy((Node **)&pClone)) 00688 goto NoMemory; 00689 00690 // delete it's attributes 00691 pClone->DeleteChildren(pClone->FindFirstChild()); 00692 00693 // make it the current path 00694 pPath = pClone; 00695 pInkPath = &pPath->InkPath; 00696 ThePathType = PATH_NORMAL; 00697 EPSFlags.NoAttributes = TRUE; 00698 } 00699 if(pPath != 0) 00700 return EPSFilter::ProcessToken(); 00701 break; 00702 00703 // we may need to modify path closing things if we're doing a grad fill 00704 case EPSC_s: 00705 case EPSC_S: 00706 if(Token == EPSC_S) 00707 { 00708 // if we've had an h token but no grad fill, send the h now 00709 if(HadhToken) 00710 FHEF_SENDh 00711 00712 // if we've got a grad fill, modify the token we got 00713 if(DoingGradFill) 00714 Token = EPSC_b; 00715 } 00716 00717 // process the possily modified token normally 00718 HadhToken = FALSE; 00719 return EPSFilter::ProcessToken(); 00720 break; 00721 00722 // modify path closing for grad fills. 00723 case EPSC_n: 00724 if(DoingGradFill) 00725 { 00726 Token = EPSC_f; // we want to fill the thing 00727 HadhToken = FALSE; 00728 return EPSFilter::ProcessToken(); 00729 break; 00730 } 00731 HadhToken = FALSE; // ignore h's as this is another end path thingy... 00732 00733 if(pPath != 0) 00734 return EPSFilter::ProcessToken(); 00735 break; 00736 00737 // unset the had h token for other path closing things 00738 case EPSC_N: 00739 case EPSC_F: 00740 case EPSC_f: 00741 case EPSC_B: 00742 case EPSC_b: 00743 HadhToken = FALSE; 00744 return EPSFilter::ProcessToken(); 00745 break; 00746 00747 // interested in path element things to switch off grad fills 00748 case EPSC_m: 00749 if(InText) 00750 { 00751 // if we're doing some text, discard the moveto command 00752 if(!Stack.Discard(2)) 00753 goto EPSError; 00754 00755 break; 00756 } 00757 case EPSC_l: 00758 case EPSC_L: 00759 case EPSC_c: 00760 case EPSC_C: 00761 case EPSC_v: 00762 case EPSC_V: 00763 case EPSC_y: 00764 case EPSC_Y: 00765 // maybe we need an h token to be sent 00766 if(HadhToken) 00767 FHEF_SENDh 00768 00769 // stop grad fill 00770 if(DoingGradFill) 00771 { 00772 // turn the grad fill state off 00773 DoingGradFill = FALSE; 00774 00775 // restore the old fill type 00776 RestoreCurrentFill(); 00777 } 00778 return EPSFilter::ProcessToken(); 00779 break; 00780 00781 00782 case EPSC_recfill: 00783 { 00784 // get the colours 00785 DocColour StartColour, EndColour; 00786 00787 if(!PopColour(&EndColour) || 00788 !PopColour(&StartColour)) 00789 goto EPSError; 00790 00791 // discard the fill type thingy - we can only do colours 00792 if(!DiscardFillSubType()) 00793 goto EPSError; 00794 00795 // OK, now a few coords 00796 DocCoord Centre; 00797 double Angle; 00798 DocRect BBox; 00799 if(!Stack.PopCoordPair(&BBox.hi) || 00800 !Stack.PopCoordPair(&BBox.lo) || 00801 !Stack.Pop(&Angle) || 00802 !Stack.PopCoordPair(&Centre)) 00803 goto EPSError; 00804 00805 // munge the angle a little and get it into radians 00806 Angle += 225; 00807 Angle = (Angle * (2 * PI)) / 360; 00808 00809 // see if we can get a more accurate BBox 00810 if(pPath != 0) 00811 { 00812 BBox = pPath->GetBoundingRect(); 00813 Centre.x = BBox.lo.x + (BBox.Width() / 2); 00814 Centre.y = BBox.lo.y + (BBox.Height() / 2); 00815 } 00816 00817 // OK, we've got all the stuff we need to do some niceness on it 00818 BBox.Translate(0 - Centre.x, 0 - Centre.y); 00819 DocCoord StartPoint, EndPoint; 00820 00821 StartPoint.x = Centre.x + (INT32)(((double)BBox.lo.x * cos(Angle)) - ((double)BBox.lo.y * sin(Angle))); 00822 StartPoint.y = Centre.y + (INT32)(((double)BBox.lo.x * sin(Angle)) + ((double)BBox.lo.y * cos(Angle))); 00823 EndPoint.x = Centre.x + (INT32)(((double)BBox.hi.x * cos(Angle)) - ((double)BBox.hi.y * sin(Angle))); 00824 EndPoint.y = Centre.y + (INT32)(((double)BBox.hi.x * sin(Angle)) + ((double)BBox.hi.y * cos(Angle))); 00825 00826 // store current fill attribute 00827 SaveCurrentFill(); 00828 00829 // set the fill 00830 if(!SetLinearFill(StartColour, EndColour, StartPoint, EndPoint)) 00831 goto NoMemory; 00832 00833 // say we're doing a grad fill 00834 DoingGradFill = TRUE; 00835 HadhToken = FALSE; // absorb this 00836 } 00837 break; 00838 00839 case EPSC_radfill: 00840 { 00841 // get the colours 00842 DocColour StartColour, EndColour; 00843 00844 if(!PopColour(&StartColour) || 00845 !PopColour(&EndColour)) 00846 goto EPSError; 00847 00848 // get the radius and centre coordinate 00849 DocCoord Centre; 00850 INT32 Radius; 00851 if(!Stack.PopCoord(&Radius) || 00852 !Stack.PopCoordPair(&Centre)) 00853 goto EPSError; 00854 00855 // store current fill attribute 00856 SaveCurrentFill(); 00857 00858 // set the fill 00859 DocCoord EndPoint(Centre.x + Radius, Centre.y); 00860 if(!SetRadialFill(StartColour, EndColour, Centre, EndPoint)) 00861 goto NoMemory; 00862 00863 // say we're doing a grad fill 00864 DoingGradFill = TRUE; 00865 HadhToken = FALSE; 00866 } 00867 break; 00868 00869 case EPSC_BeginSetup: 00870 // there's probably a colour list or something in that there setup thingy - search for the spots token 00871 { 00872 BOOL Found = FALSE; 00873 00874 while(Found == FALSE) 00875 { 00876 if(!EPSFile->GetToken()) 00877 return FALSE; 00878 00879 if(EPSFile->GetTokenType() == TOKEN_NORMAL) 00880 { 00881 if(camStrcmp(TokenBuf, _T("spots")) == 0) 00882 { 00883 // check to see if the array is about to start 00884 if(!EPSFile->GetToken()) 00885 return FALSE; 00886 00887 if(TokenBuf[0] == '[') 00888 { 00889 TRACEUSER( "Ben", _T("Found spots\n")); 00890 Found = TRUE; 00891 } 00892 } 00893 } 00894 00895 if(camStrncmp(TokenBuf, _T("%%EndSetup"), 10) == 0) 00896 { 00897 TRACEUSER( "Ben", _T("Met end of setup without finding spots\n")); 00898 break; 00899 } 00900 00901 if(EPSFile->eof()) 00902 goto EPSError; 00903 } 00904 00905 if(Found == TRUE) 00906 { 00907 InColours = TRUE; 00908 } 00909 } 00910 break; 00911 00912 case EPSC_def: 00913 if(InColours) 00914 { 00915 // finished the colours... 00916 TRACEUSER( "Ben", _T("Finished spot colours\n")); 00917 // scan for the end of the setup section 00918 BOOL Found = FALSE; 00919 00920 while(Found == FALSE) 00921 { 00922 if(!EPSFile->GetToken()) 00923 return FALSE; 00924 00925 if(EPSFile->GetTokenType() == TOKEN_COMMENT) 00926 { 00927 if(camStrncmp(TokenBuf, _T("%%EndSetup"), 10) == 0) 00928 { 00929 TRACEUSER( "Ben", _T("Found end of setup\n")); 00930 Found = TRUE; 00931 } 00932 } 00933 00934 if(EPSFile->eof()) 00935 goto EPSError; 00936 } 00937 00938 // get the ] off the stack 00939 EPSCommand Ignored; 00940 Stack.PopCmd(&Ignored); 00941 00942 // empty it... 00943 Stack.DeleteAll (); 00944 InColours = FALSE; 00945 } 00946 else 00947 { 00948 // probably a font type thingy - empty the stack including commands 00949 Stack.DeleteAll (); 00950 } 00951 break; 00952 00953 case EPSC_newcmykcustomcolor: 00954 // OK, here's a named colour... add it to those known 00955 { 00956 // discard some random thingy 00957 if(!Stack.Discard()) 00958 goto EPSError; 00959 00960 // get the name 00961 String_64 ColourName; 00962 if(!Stack.Pop(&ColourName)) 00963 goto EPSError; 00964 00965 // get the components 00966 double C, M, Y, K; 00967 if(!Stack.Pop(&K) || 00968 !Stack.Pop(&Y) || 00969 !Stack.Pop(&M) || 00970 !Stack.Pop(&C)) 00971 goto EPSError; 00972 00973 // make the new colour 00974 ColourCMYK Colour; 00975 Colour.Cyan = C; 00976 Colour.Magenta = M; 00977 Colour.Yellow = Y; 00978 Colour.Key = K; 00979 00980 // add it 00981 if(!pNewColours->AddColour(&ColourName, &Colour)) 00982 goto NoMemory; 00983 00984 // add it to the list of colours 00985 // this is a bit of a bodge, but never mind. Shouldn't be that bad. 00986 IndexedColour *TheNewColour = pNewColours->GetColour(ColourName); 00987 00988 if(TheNewColour == 0) 00989 goto NoMemory; 00990 00991 // add it to the list of colours 00992 // enough space? 00993 if((ColourArrayEntries + 1) >= ColourArraySize) 00994 { 00995 TRACEUSER( "Ben", _T("Extening colour array\n")); 00996 IndexedColour **NewPtr = (IndexedColour **)CCRealloc(ColourArray, (ColourArraySize + FHEF_COLOURARRAY_CHUNK) * sizeof(IndexedColour *)); 00997 00998 if(NewPtr == 0) 00999 goto NoMemory; 01000 01001 ColourArray = NewPtr; 01002 ColourArraySize += FHEF_COLOURARRAY_CHUNK; 01003 } 01004 01005 // add 01006 ColourArray[ColourArrayEntries] = TheNewColour; 01007 ColourArrayEntries++; 01008 } 01009 break; 01010 01011 // ignore text stuff 01012 case EPSC_makesetfont: 01013 if(!Stack.DiscardArray()) 01014 goto EPSError; 01015 if(!Stack.Discard(1)) 01016 goto EPSError; 01017 InText = TRUE; 01018 break; 01019 01020 case EPSC_ts: 01021 if(!Stack.Discard(6)) 01022 goto EPSError; 01023 break; 01024 01025 case EPSC_stob: 01026 case EPSC_sts: 01027 Stack.DeleteAll (); 01028 InText = FALSE; 01029 break; 01030 01031 default: 01032 // Token not understood - pass on to base class 01033 return EPSFilter::ProcessToken(); 01034 } 01035 01036 01037 // No errors encountered while parsing this token and its operands. 01038 return TRUE; 01039 01040 01041 // Error handlers: 01042 EPSError: 01043 HandleEPSError(); 01044 return FALSE; 01045 01046 NoMemory: 01047 HandleNoMemory(); 01048 return FALSE; 01049 }
|
|
Removes the last subpath from a path if an sub path with it's exact coords already exists.
Definition at line 1346 of file freeeps.cpp. 01347 { 01348 // get coord arrays 01349 INT32 NCoords = pIPath->GetNumCoords(); 01350 DocCoord *Coords = pIPath->GetCoordArray(); 01351 PathVerb *Verbs = pIPath->GetVerbArray(); 01352 01353 // find the last moveto 01354 INT32 LastMoveTo = -1; 01355 INT32 c; 01356 01357 for(c = 0; c < NCoords; c++) 01358 { 01359 if((Verbs[c] & ~PT_CLOSEFIGURE) == PT_MOVETO) 01360 { 01361 LastMoveTo = c; 01362 } 01363 } 01364 01365 // check that there is a last moveto and it's not the first coord... 01366 if(LastMoveTo == -1 || LastMoveTo == 0) 01367 return TRUE; // nothing more to do 01368 01369 // go through the coords matching subpaths... 01370 for(c = 0; c < LastMoveTo; c++) 01371 { 01372 if((Verbs[c] & ~PT_CLOSEFIGURE) == PT_MOVETO) 01373 { 01374 // found a moveto... compare the subpaths 01375 INT32 n = 0; 01376 01377 while(((Verbs[c+n] & ~PT_CLOSEFIGURE) == (Verbs[LastMoveTo+n] & ~PT_CLOSEFIGURE)) && (Coords[c+n] == Coords[LastMoveTo+n])) 01378 { 01379 // this was ok... is the next a moveto and the subpath the right length? 01380 01381 if((LastMoveTo+n+1) == NCoords) 01382 { 01383 // yes, delete and return 01384 return pIPath->DeleteFromElement(LastMoveTo); 01385 } 01386 01387 n++; 01388 } 01389 } 01390 } 01391 01392 return TRUE; 01393 }
|
|
restores the current fill attribute from the stored one
Definition at line 1252 of file freeeps.cpp. 01253 { 01254 if(OldFill == 0) 01255 return TRUE; // no saved state 01256 01257 // delete the old attribute 01258 if(CurrentAttrs[ATTR_FILLGEOMETRY].pAttr != 0) 01259 delete CurrentAttrs[ATTR_FILLGEOMETRY].pAttr; 01260 01261 // make the current one the old one 01262 CurrentAttrs[ATTR_FILLGEOMETRY].pAttr = OldFill; 01263 01264 // mark this as used so it doesn't get deleted 01265 OldFill = 0; 01266 01267 return TRUE; 01268 }
|
|
stores the current fill attribute
Definition at line 1218 of file freeeps.cpp. 01219 { 01220 // get rid of any stored fill 01221 if(OldFill != 0) 01222 delete OldFill; 01223 01224 // create a copy of the current fill attribute 01225 CCRuntimeClass* ObjectType = CurrentAttrs[ATTR_FILLGEOMETRY].pAttr->GetRuntimeClass(); 01226 AttributeValue* AttrClone = (AttributeValue*)ObjectType->CreateObject(); 01227 01228 if(AttrClone == 0) 01229 return FALSE; 01230 01231 AttrClone->SimpleCopy(CurrentAttrs[ATTR_FILLGEOMETRY].pAttr); 01232 01233 // set the old fill pointer to the nice clone we've made 01234 OldFill = AttrClone; 01235 01236 return TRUE; 01237 }
|
|
validates a group created by the filter. As all objects have a group around then, this removes groups which only have one entry.
Reimplemented from EPSFilter. Definition at line 1282 of file freeeps.cpp. 01283 { 01284 ERROR2IF(pGroup == 0, FALSE, "Group passed to validateGroup is null"); 01285 01286 Node *pFirstChild = pGroup->FindFirstChild(); 01287 01288 ERROR2IF(pFirstChild == 0, FALSE, "Group without children passed to ValidateGroup - should have been deleted by EndGroup"); 01289 01290 if(pFirstChild->FindNext() == 0) 01291 { 01292 // there was only one object - delete this group. 01293 01294 // if pFirstNodeInRange is this node, set it to the child 01295 if(pFirstNodeInRange == pGroup) 01296 pFirstNodeInRange = pFirstChild; 01297 01298 // move the child to the parent of the group 01299 if (!ImportInfo.pOp->DoMoveNode(pFirstChild, pNode, LASTCHILD)) 01300 return FALSE; 01301 01302 // see EPSFilter::EndGroup for the reason why it's hidden rather than deleted 01303 if (!ImportInfo.pOp->DoHideNode(pGroup, TRUE)) 01304 return FALSE; 01305 01306 } 01307 01308 return TRUE; 01309 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|