#include <strkcomp.h>
Inheritance diagram for StrokeComponent:
Public Member Functions | |
StrokeComponent () | |
Constructor. | |
virtual | ~StrokeComponent () |
Destructor. | |
virtual BOOL | StartImport (BaseCamelotFilter *pFilter) |
Called before we start to import a file. | |
virtual BOOL | EndImport (BaseCamelotFilter *pFilter, BOOL Success) |
Called on completion of an import. | |
virtual BOOL | StartExport (BaseCamelotFilter *pFilter) |
Called before an export is started. | |
virtual BOOL | EndExport (BaseCamelotFilter *pFilter, BOOL Success) |
Called on completion of file export. | |
Static Public Member Functions | |
static StrokeHandle | AddNewStroke (StrokeDefinition *pStroke) |
Adds the given stroke to the global stroke list. | |
static StrokeDefinition * | FindStroke (StrokeHandle Handle) |
Find a stroke, given its unique identity handle. | |
static BOOL | StartImportStroke (CamelotRecordHandler *pHandler, CXaraFileRecord *pRecord) |
To import a vector stroke definition. | |
static BOOL | EndImportStroke (CamelotRecordHandler *pHandler) |
To import a vector stroke definition. | |
static StrokeHandle | FindImportedStroke (UINT32 ImportedHandle) |
To match up a handle from the currently importing file to the real internal StrokeHandle of the imported StrokeDefinition. | |
static BOOL | ExportStroke (BaseCamelotFilter *pFilter, StrokeHandle Handle) |
To export a vector stroke definition. | |
Static Protected Member Functions | |
static void | DeleteStrokeList (void) |
Static deinitialisation function, called on shutdown. Clears out the global stroke list. Must be called when all users of the stroke system (documents) have already been deleted. | |
Static Private Member Functions | |
static BOOL | ExpandArray (void) |
(Internal method) Expands the storage structure of the stroke list to allow more entries to be used. Called automatically by AddNewStroke as necessary. | |
Static Private Attributes | |
static StrokeDefinition ** | pStrokeList = NULL |
static UINT32 | CurrentSize = 0 |
static UINT32 | Used = 0 |
static UINT32 | ImportHandle = 0 |
static UINT32 | ImportFlags = 0 |
static UINT32 | ImportData1 = 0 |
static UINT32 | ImportData2 = 0 |
static InsertTreeContext * | pImportPreviousContext = NULL |
static Node * | pImportNewBrush = NULL |
static String_32 | ImportedName |
Friends | |
class | StrokeComponentClass |
class | StrokeDefinition |
Definition at line 266 of file strkcomp.h.
|
Constructor.
Definition at line 487 of file strkcomp.cpp.
|
|
Destructor.
Definition at line 504 of file strkcomp.cpp.
|
|
Adds the given stroke to the global stroke list.
YOU MUST NOT use the pStroke pointer after this call! If the call fails, or if the stroke is merged with an existing one, the object you passed in will be IMMEDIATELY DELETED! If you wish to use the stroke after Adding it, you must call FindStroke with the returned stroke handle! Technical: Strokes are recorded in an array of StrokeDefinition pointers. The StrokeHandle is just an index into this array, for fast lookup. When deleted, the array-entry is set NULL and never re-used, so that any handles floating around can be safely used (much better than getting IndexedColour deleted when in use errors, eh? ;-). New entries are thus always appended to the list. Definition at line 576 of file strkcomp.cpp. 00577 { 00578 // ****!!!!TODO - if we're multi-threadig, this probably needs to be a critical section 00579 // because the list is global 00580 00581 ERROR3IF(pStroke == NULL, "Illegal NULL param"); 00582 00583 // --- First, check if we can merge the given stroke with one already in the list 00584 for (UINT32 i = 0; i < Used; i++) 00585 { 00586 if (pStrokeList[i] != NULL && !pStroke->IsDifferent(pStrokeList[i])) 00587 { 00588 // The stroke is the same as one we already have in our stroke list, so we 00589 // delete the copy that was passed in, and return the existing ones handle 00590 // We copy the import handle value over, though, so that we don't "lose" 00591 // merged strokes during import! 00592 pStrokeList[i]->SetIOStore(pStroke->ReadIOStore()); 00593 delete pStroke; 00594 return((StrokeHandle) i); 00595 } 00596 } 00597 00598 // --- Next, check if we have enough room in our stroke array to add a new entry to the end 00599 if (Used >= CurrentSize) 00600 { 00601 if (!ExpandArray()) 00602 { 00603 delete pStroke; 00604 return(StrokeHandle_NoStroke); 00605 } 00606 } 00607 00608 // --- OK, we have a totally new stroke, so add it to the end of the list 00609 StrokeHandle NewHandle = (StrokeHandle) Used; 00610 pStrokeList[Used] = pStroke; 00611 Used++; 00612 00613 // --- Now, make sure the stroke gallery display updates to show the new stroke 00614 // ****!!!!TODO - should notify the stroke gallery (broadcast a msg) so that it updates 00615 // I'll use a nasty bodgy direct call to the line gallery instead... eeek! 00616 { 00617 PathProcessorStrokeVector *pProcessor = new PathProcessorStrokeVector; 00618 if (pProcessor != NULL) 00619 { 00620 pProcessor->SetStrokeDefinition(NewHandle); 00621 00622 PORTNOTE("other","Removed LineGallery usage") 00623 #ifndef EXCLUDE_FROM_XARALX 00624 StrokeTypeAttrValue *pStrokeAttr = new StrokeTypeAttrValue(pProcessor); 00625 if (pStrokeAttr != NULL) 00626 LineGallery::AddNewStrokeItem(pStrokeAttr); 00627 else 00628 delete pProcessor; 00629 #endif 00630 } 00631 } 00632 00633 // --- And return the new handle 00634 return(NewHandle); 00635 }
|
|
Static deinitialisation function, called on shutdown. Clears out the global stroke list. Must be called when all users of the stroke system (documents) have already been deleted.
Definition at line 523 of file strkcomp.cpp. 00524 { 00525 if (pStrokeList != NULL) 00526 { 00527 for (UINT32 i = 0; i < Used; i++) 00528 { 00529 if (pStrokeList[i] != NULL) 00530 delete pStrokeList[i]; 00531 00532 pStrokeList[i] = NULL; 00533 } 00534 00535 CCFree(pStrokeList); 00536 pStrokeList = NULL; 00537 } 00538 }
|
|
Called on completion of file export.
Reimplemented from DocComponent. Definition at line 806 of file strkcomp.cpp. 00807 { 00808 BOOL ok = TRUE; 00809 TRACEUSER( "Diccon", _T("End Export Stroke Component\n")); 00810 #if !defined(EXCLUDE_FROM_RALPH) 00811 if (pFilter == NULL) 00812 { 00813 ERROR3("StrokeComponent::EndExport filter is null!"); 00814 return(ok); 00815 } 00816 00817 if (!Success) // If we failed to export, then return immediately 00818 return(ok); 00819 00820 #endif 00821 return(ok); 00822 }
|
|
Called on completion of an import.
Reimplemented from DocComponent. Definition at line 731 of file strkcomp.cpp. 00732 { 00733 return TRUE; 00734 }
|
|
To import a vector stroke definition.
Definition at line 1028 of file strkcomp.cpp. 01029 { 01030 ERROR3IF(pImportPreviousContext == NULL, "EndImportStroke - something hasn't gone too well"); 01031 01032 // Restore the previous import context node 01033 pHandler->RestoreInsertContext(pImportPreviousContext); 01034 pImportPreviousContext = NULL; 01035 01036 // --- Now, convert all IndexedColours (which are document-dependent) into standalone DocColours 01037 // This wouldn't be necessary, except that the DocColours we saved have magically been turned 01038 // back into local Indexedcolours by the export/import process. 01039 // BLOCK 01040 { 01041 Node *pCurNode = pImportNewBrush->FindFirstDepthFirst(); 01042 Node *pNextNode; 01043 01044 while (pCurNode !=NULL) 01045 { 01046 // We may be about to chop this node out of the tree, so get the next node now 01047 pNextNode = pCurNode->FindNextDepthFirst(pImportNewBrush); 01048 01049 // Use to scan the colour fields of the attribute. 01050 if (pCurNode->IsAnAttribute()) 01051 { 01052 01053 PORTNOTE("colourmanager","Removed ColourManager usage") 01054 #ifndef EXCLUDE_FROM_XARALX 01055 UINT32 Context = 0; 01056 NodeAttribute *pNodeAttr = (NodeAttribute *) pCurNode; 01057 // Get the next colour field from the attribute 01058 DocColour *pColour = pNodeAttr->EnumerateColourFields(Context++); 01059 01060 while (pColour != NULL) 01061 { 01062 // For each colour field, make sure the colour is a local DocColour so that 01063 // the sub-tree is entirely stand-alone 01064 if (pColour->FindParentIndexedColour() != NULL) 01065 { 01066 ColourGeneric ColDef; 01067 ColourContext *cc = ColourManager::GetColourContext(pColour->GetColourModel()); 01068 ERROR3IF(cc == NULL, "Can't find colour context?!"); 01069 01070 // Get the IndexedColour definition as a standalone colour definition 01071 cc->ConvertColour(pColour->FindParentIndexedColour(), &ColDef); 01072 01073 // Make the DocColour into a simple standalone "lookalike" of the parent colour 01074 *pColour = DocColour(pColour->GetColourModel(), &ColDef); 01075 } 01076 01077 pColour = pNodeAttr->EnumerateColourFields(Context++); 01078 } 01079 #endif 01080 } 01081 pCurNode = pNextNode; 01082 } 01083 } 01084 01085 // Create a new stroke definition from the imported brush 01086 // Read the imported data from ImportFlags, ImportData1, ImportData2 01087 // (Currently, we only handle the Repeating, Optimal Repeating and Number of Repeating flags) 01088 BOOL Repeating = ((ImportFlags & 0x100) != 0); 01089 01090 INT32 Repeats = 0; 01091 01092 // If repeating a certain number of times, get the number of times, else assume 0 - optimal 01093 if((ImportFlags & 0xff) == 2) 01094 Repeats = (INT32)ImportData1; 01095 01096 StrokeDefinition *pNewStroke = new StrokeDefinition(pImportNewBrush, Repeating, Repeats); 01097 if (pNewStroke == NULL) 01098 return(FALSE); 01099 01100 pNewStroke->SetOverrideFill((ImportFlags & 0x400) != 0); 01101 pNewStroke->SetOverrideTrans((ImportFlags & 0x800) != 0); 01102 01103 // Remember the handle used for the stroke in the file with the stroke so that 01104 // we can map any incoming handles into the real handles we are using internally. 01105 pNewStroke->SetIOStore(ImportHandle & 0x00ffffff); 01106 01107 // And set the stroke's name, if any was supplied 01108 if (!ImportedName.IsEmpty()) 01109 pNewStroke->SetStrokeName(&ImportedName); 01110 01111 // And add/merge this stroke into our global list 01112 AddNewStroke(pNewStroke); 01113 return(TRUE); 01114 }
|
|
(Internal method) Expands the storage structure of the stroke list to allow more entries to be used. Called automatically by AddNewStroke as necessary.
Definition at line 1172 of file strkcomp.cpp. 01173 { 01174 // ****!!!!TODO - if we're multi-threading, this probably needs to be a critical section 01175 // because the list is global 01176 01177 const INT32 AllocSize = CurrentSize + 64; 01178 01179 if (pStrokeList == NULL) 01180 { 01181 pStrokeList = (StrokeDefinition **) CCMalloc(AllocSize * sizeof(StrokeDefinition *)); 01182 if (pStrokeList == NULL) 01183 return(FALSE); 01184 } 01185 else 01186 { 01187 // We have an array - we must make it larger 01188 StrokeDefinition **pNewBuf = (StrokeDefinition **) 01189 CCRealloc(pStrokeList, AllocSize * sizeof(StrokeDefinition *)); 01190 if (pNewBuf == NULL) 01191 return(FALSE); 01192 01193 pStrokeList = pNewBuf; 01194 } 01195 01196 // Success. Initalise all the new pointers to NULL 01197 for (UINT32 i = Used; i < CurrentSize; i++) 01198 pStrokeList[i] = NULL; 01199 01200 // Update the current size value, and return success 01201 CurrentSize = AllocSize; 01202 return(TRUE); 01203 }
|
|
To export a vector stroke definition.
When saving your reference to the stroke, save out the stroke's Handle as it's unique ID word. Definition at line 855 of file strkcomp.cpp. 00856 { 00857 ERROR3IF(pFilter == NULL, "Illegal NULL params"); 00858 TRACEUSER( "Diccon", _T("Exporting Stroke\n")); 00859 // Find the stroke, and baulk if it's all gone wrong 00860 StrokeDefinition *pStroke = FindStroke(Handle); 00861 if (pStroke == NULL) 00862 { 00863 ERROR3("Attempt to save a deleted or non-existent stroke"); 00864 return(FALSE); 00865 } 00866 00867 // Check if the definition has already been saved, in which case we don't need to do anything more 00868 if (pStroke->ReadIOStore()) 00869 return(TRUE); 00870 00871 // We've got a stroke definition now, so let's chuck it out to the file 00872 BOOL ok = TRUE; 00873 CXaraFileRecord Rec(TAG_STROKEDEFINITION, TAG_STROKEDEFINITION_SIZE); 00874 if (ok) ok = Rec.Init(); 00875 00876 if (ok) ok = Rec.WriteUINT32(Handle); 00877 00878 UINT32 Flags = 0x200; // All vector strokes include a name (Named flag == 0x200) 00879 if (ok) 00880 { 00881 // Write the flags out. 00882 if (pStroke->IsRepeating()) // Repeating flag = 0x100 00883 Flags |= 0x100; 00884 00885 if (pStroke->OverrideFill()) // Fill override flag = 0x400 00886 Flags |= 0x400; 00887 00888 if (pStroke->OverrideTrans()) // Transparency override flag = 0x800 00889 Flags |= 0x800; 00890 00891 ok = Rec.WriteUINT32(Flags); 00892 } 00893 if (ok) 00894 { 00895 INT32 NumRepeats = 0; 00896 if(pStroke->IsRepeating()) 00897 { 00898 // Write the flags out. 00899 NumRepeats = pStroke->NumRepeats(); 00900 00901 if(NumRepeats == 0) 00902 Flags |= 1; 00903 else 00904 Flags |= 2; 00905 } 00906 00907 // Write Data1 - this contains the number of times the brush should repeat down the stroke 00908 ok = Rec.WriteUINT32(NumRepeats); 00909 } 00910 00911 if (ok) ok = Rec.WriteUINT32(0); // Write Data2 - for now, this is always 0 00912 00913 if (ok && ((Flags & 0x200) != 0)) // Write the (optional) name field 00914 ok = Rec.WriteUnicode((TCHAR *)*(pStroke->GetStrokeName())); 00915 00916 if (ok) pFilter->Write(&Rec); // And write out the record 00917 00918 // Now, follow the definition record with the brush subtree 00919 if (ok) 00920 { 00921 Node *pNode = pStroke->GetStrokeTree(); // Find the root Spread 00922 if (pNode != NULL) 00923 pNode = pNode->FindFirstChild(); // Find the Layer 00924 if (pNode != NULL) 00925 pNode = pNode->FindFirstChild(); // Find the NodeGroup 00926 00927 if (pNode == NULL) 00928 ok = FALSE; 00929 00930 ERROR3IF(pNode == NULL || !pNode->IsCompound(), "Vector brush not in the format I expected"); 00931 00932 // Write out the clipart subtree. We have to encapsulate it in DOWN and UP 00933 // records ourselves 00934 CXaraFileRecord DownRec(TAG_DOWN, 0); 00935 if (ok) pFilter->Write(&DownRec); 00936 00937 ok = pFilter->WriteNodes(pNode); 00938 00939 CXaraFileRecord UpRec(TAG_UP, 0); 00940 if (ok) pFilter->Write(&UpRec); 00941 } 00942 00943 // Finally, mark this stroke as having been written out so we don't do it again 00944 if (ok) pStroke->SetIOStore(TRUE); 00945 00946 return(ok); 00947 }
|
|
To match up a handle from the currently importing file to the real internal StrokeHandle of the imported StrokeDefinition.
Definition at line 1136 of file strkcomp.cpp. 01137 { 01138 ImportedHandle &= 0x00ffffff; // Only the bottom 24 bits are relevant 01139 for (UINT32 Index = 0; Index < Used; Index++) 01140 { 01141 if (pStrokeList[Index] != NULL && pStrokeList[Index]->ReadIOStore() == ImportedHandle) 01142 return((StrokeHandle)Index); 01143 } 01144 01145 return(StrokeHandle_NoStroke); 01146 }
|
|
Find a stroke, given its unique identity handle.
Definition at line 657 of file strkcomp.cpp. 00658 { 00659 if (Handle == StrokeHandle_NoStroke) 00660 return(NULL); 00661 00662 if (Handle >= Used) 00663 { 00664 ERROR3("Out of range stroke handle"); 00665 return(NULL); 00666 } 00667 00668 return(pStrokeList[Handle]); 00669 }
|
|
Called before an export is started.
Reimplemented from DocComponent. Definition at line 753 of file strkcomp.cpp. 00754 { 00755 #if !defined(EXCLUDE_FROM_RALPH) 00756 if (pFilter == NULL) 00757 { 00758 ERROR3("StrokeComponent::StartExport filter is null!"); 00759 return(TRUE); 00760 } 00761 TRACEUSER( "Diccon", _T("Start Export Stroke Component\n")); 00762 // ****!!!!TODO - if we're multi-threadig, this probably needs to be a critical section 00763 // because the list is global 00764 00765 // Flag all strokes as not having been saved. When we save one, we set its flag so that 00766 // we don't try to save it a second time. 00767 if (pStrokeList != NULL) 00768 { 00769 for (UINT32 Index = 0; Index < Used; Index++) 00770 { 00771 if (pStrokeList[Index] != NULL) 00772 pStrokeList[Index]->SetIOStore(FALSE); 00773 } 00774 00775 // Write out an atomic tag definition in front of the vector stroke definition. 00776 // ****!!!!TODO - This should really only be done just before we export the first 00777 // STROKEDEFINITION tag, but it is not properly supported by the export system as yet. 00778 BOOL ok = TRUE; 00779 CXaraFileRecord Rec(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE); 00780 if (ok) ok = Rec.Init(); 00781 if (ok) ok = Rec.WriteUINT32(TAG_STROKEDEFINITION); 00782 if (ok) pFilter->Write(&Rec); // And write out the record 00783 } 00784 #endif 00785 return(TRUE); 00786 }
|
|
Called before we start to import a file.
Reimplemented from DocComponent. Definition at line 689 of file strkcomp.cpp. 00690 { 00691 if (pFilter == NULL) 00692 { 00693 ERROR3("StrokeComponent::StartImport filter is null!"); 00694 return(TRUE); 00695 } 00696 00697 // Set the IOStore in all the strokes to 0xffffffff. During import, this entry is used 00698 // to map imported handles to the real handles they have been assigned. 00699 if (pStrokeList != NULL) 00700 { 00701 for (UINT32 Index = 0; Index < Used; Index++) 00702 { 00703 if (pStrokeList[Index] != NULL) 00704 pStrokeList[Index]->SetIOStore(0xffffffff); 00705 } 00706 } 00707 00708 return(TRUE); 00709 }
|
|
To import a vector stroke definition.
Definition at line 966 of file strkcomp.cpp. 00967 { 00968 ImportHandle = 0xffffffff; 00969 ImportFlags = 0; 00970 ImportData1 = 0; 00971 ImportData2 = 0; 00972 pImportPreviousContext = NULL; 00973 pImportNewBrush = NULL; 00974 00975 String_256 TempName; // Load the name into a nice large safe buffer 00976 00977 // Import the data from the record 00978 if (!pRecord->ReadUINT32(&ImportHandle) || !pRecord->ReadUINT32(&ImportFlags) || 00979 !pRecord->ReadUINT32(&ImportData1) || !pRecord->ReadUINT32(&ImportData2)) 00980 { 00981 return(FALSE); 00982 } 00983 00984 // If there is a name to be imported, read it as well 00985 if ((ImportFlags & 0x200) != 0 && !pRecord->ReadUnicode(&TempName)) 00986 return(FALSE); 00987 00988 // We remember the imported flags and suchlike, which we will use in EndImportStroke. 00989 TempName.Left((StringBase *)&ImportedName, 31); 00990 00991 // Create a spread and set up the import system to import the brush into it 00992 // If this fails, then it'll just find somewhere "sensible" to import into 00993 pImportNewBrush = new Spread; 00994 if (pImportNewBrush == NULL) 00995 return(FALSE); 00996 00997 Layer *pBrushLayer = new Layer(pImportNewBrush, FIRSTCHILD, String_256(TEXT("Jason did this"))); 00998 if (pBrushLayer == NULL) 00999 { 01000 delete pImportNewBrush; 01001 pImportNewBrush = NULL; 01002 return(FALSE); 01003 } 01004 01005 // Now, remember where we were importing into, and point the importer at our brush tree 01006 pImportPreviousContext = pHandler->GetInsertContext(); 01007 pHandler->SetInsertContextNode(pBrushLayer); 01008 return(TRUE); 01009 }
|
|
Definition at line 268 of file strkcomp.h. |
|
Definition at line 269 of file strkcomp.h. |
|
Definition at line 313 of file strkcomp.h. |
|
Definition at line 319 of file strkcomp.h. |
|
Definition at line 320 of file strkcomp.h. |
|
Definition at line 323 of file strkcomp.h. |
|
Definition at line 318 of file strkcomp.h. |
|
Definition at line 317 of file strkcomp.h. |
|
Definition at line 322 of file strkcomp.h. |
|
Definition at line 321 of file strkcomp.h. |
|
Definition at line 312 of file strkcomp.h. |
|
Definition at line 314 of file strkcomp.h. |