#include <cdrfiltr.h>
Inheritance diagram for CDRArrowheadStore:
Public Member Functions | |
BOOL | AddChunkToStore (RIFFFile *RIFF) |
Stores arrowhead chunks for the CDRFilter class. | |
NodeRenderableBounded * | GetConvertedNode (DWORD Reference, INT32 *Distance, BOOL *NotPresent) |
Private Member Functions | |
CC_DECLARE_MEMDUMP (CDRArrowheadStore) |
Definition at line 243 of file cdrfiltr.h.
|
Stores arrowhead chunks for the CDRFilter class.
Reimplemented from CDRAttributeStore. Definition at line 849 of file cdroutl.cpp. 00850 { 00851 if(RIFF->GetObjType() != RIFFOBJECTTYPE_CHUNK) 00852 { 00853 ERROR2(FALSE, "CDRAttributeStore::AddChunkToStore called without a chunk in the RIFFFile"); 00854 } 00855 00856 // get a new item obect 00857 CDRArrowheadStoredItem *Item = new CDRArrowheadStoredItem; 00858 00859 if(Item == 0) 00860 return FALSE; 00861 00862 // get the data of the RIFF chunk 00863 if(!Item->Aquire(RIFF)) 00864 { 00865 delete Item; 00866 return FALSE; 00867 } 00868 00869 Item->Size = RIFF->GetObjSize(); 00870 00871 // and add the new item to the list 00872 AddTail(Item); 00873 00874 return TRUE; 00875 }
|
|
|
|
Definition at line 897 of file cdroutl.cpp. 00898 { 00899 // set up the not present thingy 00900 *NotPresent = FALSE; 00901 00902 // find the correct chunk 00903 CDRArrowheadStoredItem *Item; 00904 INT32 Size; 00905 00906 if(IsEmpty()) 00907 return 0; // no items in the list 00908 00909 Item = (CDRArrowheadStoredItem *)GetHead(); 00910 00911 // scan though the list looking for the reference 00912 while(Item != 0) 00913 { 00914 if(CDRDATA_DWORD(*((DWORD *)(Item->Block))) == Reference) 00915 { 00916 Size = Item->Size; 00917 break; 00918 } 00919 00920 Item = (CDRArrowheadStoredItem *)GetNext(Item); 00921 } 00922 00923 // did we find a chunk? 00924 if(Item == 0) 00925 { 00926 *NotPresent = TRUE; 00927 return 0; 00928 } 00929 00930 // locate the coordinates 00931 cdrfArrowhead *Arrow = (cdrfArrowhead *)Item->Block; 00932 cdrfCoord *Coords = (cdrfCoord *)(Item->Block + CDRDATA_WORD(Arrow->CoordsOffset) + cdrfARROWHEAD_COORDOFF_CORRECT); 00933 00934 // store the distance from the definitons 00935 *Distance = CDRDATA_SWORD(Arrow->Distance); 00936 00937 // check to see if a cached pointer is available 00938 if(Item->pNode != 0) 00939 return Item->pNode; 00940 00941 // OK, convert that arrowhead 00942 00943 // this is not particularly pleasant. We need to scan though the coords creating a path, 00944 // each sub path must be a seperate path unless the next subpath has the same closedness 00945 // as the previous one, in which case it's a sub path. 00946 // this is because closed sub paths have different attributes to open ones. It's a nasty 00947 // system, and rather overcomplicated, but never mind. 00948 00949 INT32 ThisType = GCN_LASTSUB_NONE; // the type of this subpath 00950 INT32 LastType = GCN_LASTSUB_NONE; // the type of the last subpath 00951 00952 NodePath *FirstPath = 0; // the first path in my set of paths 00953 NodePath *LastPath = 0; // the last path in my set of paths 00954 NodePath *ThisPath = 0; // the path I'm currently working on 00955 00956 // check that the first node type is a move to avoid stuffing up my next bit 00957 if((Arrow->NodeTypes[0] & cdrfPATHCOORDTYPE_MASK) != cdrfPATHCOORDTYPE_MOVE) 00958 { 00959 // for now, if the first element isn't a move, pretend that it doesn't exist 00960 *NotPresent = TRUE; 00961 return 0; 00962 } 00963 00964 INT32 CoordType; 00965 00966 INT32 l; 00967 00968 UINT32 Control1 = 0; // number of first control point 00969 UINT32 Control2 = 0; // of second 00970 DocCoord co, cn1, cn2; // coordinates 00971 PathFlags Flags; 00972 00973 INT32 NNodes = CDRDATA_WORD(Arrow->NNodes); 00974 BOOL NeedMoveTo = TRUE; 00975 00976 // convert all the coordinates 00977 for(l = 0; l < NNodes; l++) 00978 { 00979 CoordType = Arrow->NodeTypes[l] & cdrfPATHCOORDTYPE_MASK; 00980 00981 if(CoordType == cdrfPATHCOORDTYPE_MOVE || l == 0) 00982 { 00983 // start a new path! 00984 LastType = ThisType; 00985 00986 // first of all, what type of path is this? 00987 if((Arrow->NodeTypes[l] & cdrfPATHCOORDATTR_CLOSE) != 0) 00988 ThisType = GCN_LASTSUB_CLOSED; 00989 else 00990 ThisType = GCN_LASTSUB_OPEN; 00991 00992 // OK, do we need to start a new path? 00993 if(ThisType != LastType) 00994 { 00995 // yep, attach the last one we did 00996 if(ThisPath != 0) 00997 { 00998 // check that the path is OK 00999 if(!ThisPath->InkPath.EnsureValid()) 01000 { 01001 // no, it's completely knackered 01002 delete ThisPath; 01003 ThisPath = 0; 01004 } else { 01005 // finish off the path 01006 ThisPath->InvalidateBoundingRect(); 01007 01008 if(FirstPath == 0) 01009 FirstPath = ThisPath; 01010 01011 if(LastPath != 0) 01012 ThisPath->AttachNode(LastPath, NEXT); 01013 01014 LastPath = ThisPath; 01015 01016 ThisPath = 0; 01017 } 01018 } 01019 01020 // get a new path 01021 ThisPath = new NodePath; 01022 01023 if(ThisPath == 0) 01024 return 0; // no path created. A bit of a pity 01025 01026 // set it up ready for conversion 01027 if(!ThisPath->SetUpPath()) 01028 return 0; 01029 01030 ThisPath->InkPath.FindStartOfPath(); 01031 01032 // set whether it's filled or not 01033 if(ThisType == GCN_LASTSUB_CLOSED) 01034 { 01035 ThisPath->InkPath.IsFilled = TRUE; 01036 ThisPath->InkPath.IsStroked = FALSE; 01037 } else { 01038 ThisPath->InkPath.IsFilled = FALSE; 01039 ThisPath->InkPath.IsStroked = TRUE; 01040 } 01041 01042 } 01043 01044 } 01045 01046 co.x = CDRDATA_SWORD(Coords[l].X); 01047 co.y = CDRDATA_SWORD(Coords[l].Y); 01048 01049 // ensure we get all the move tos we need. 01050 if(NeedMoveTo && CoordType != cdrfPATHCOORDTYPE_MOVE) 01051 { 01052 if(!ThisPath->InkPath.InsertMoveTo(co)) 01053 return 0; 01054 } 01055 01056 NeedMoveTo = FALSE; 01057 01058 // convert the coordinates 01059 switch(CoordType) 01060 { 01061 case cdrfPATHCOORDTYPE_MOVE: 01062 // add a move to this path 01063 if(!ThisPath->InkPath.InsertMoveTo(co)) 01064 return 0; 01065 break; 01066 01067 case cdrfPATHCOORDTYPE_LINETO: 01068 // add a line to this coord to the path 01069 if(!ThisPath->InkPath.InsertLineTo(co)) 01070 return 0; 01071 break; 01072 01073 case cdrfPATHCOORDTYPE_CURVE: 01074 // check we have some control points for this curve 01075 // a control point cannot be the first coord, so it's OK to check against 0 01076 if(Control1 == 0 || Control2 == 0) 01077 { 01078 TRACEUSER( "Ben", _T("No control points for curve element\n")); 01079 return 0; 01080 } 01081 01082 // convert the control points 01083 cn1.x = CDRDATA_SWORD(Coords[Control1].X); 01084 cn1.y = CDRDATA_SWORD(Coords[Control1].Y); 01085 cn2.x = CDRDATA_SWORD(Coords[Control2].X); 01086 cn2.y = CDRDATA_SWORD(Coords[Control2].Y); 01087 01088 // create the curve 01089 Flags.IsSelected = FALSE; 01090 Flags.IsSmooth = Flags.IsRotate = ((Arrow->NodeTypes[l] & cdrfPATHCOORDATTR_SMOOTH) != 0)?TRUE:FALSE; 01091 Flags.IsEndPoint; 01092 01093 // insert it into the path 01094 if(!ThisPath->InkPath.InsertCurveTo(cn1, cn2, co, &Flags)) 01095 return 0; 01096 break; 01097 01098 case cdrfPATHCOORDTYPE_CONTROL: 01099 // shuffle the control points we've already got and add the new one 01100 Control1 = Control2; 01101 Control2 = l; 01102 break; 01103 01104 default: 01105 break; 01106 } 01107 01108 // is this a close subpath situtation? 01109 if((Arrow->NodeTypes[l] & cdrfPATHCOORDATTR_CLOSE) != 0) 01110 { 01111 // close the sub path 01112 if(CoordType != cdrfPATHCOORDTYPE_MOVE) 01113 { 01114 if(!ThisPath->InkPath.CloseSubPath()) 01115 return 0; 01116 01117 // check the next coord type 01118 NeedMoveTo = TRUE; 01119 } 01120 } 01121 } 01122 01123 // finish off the last path 01124 ThisPath->InvalidateBoundingRect(); 01125 01126 // finish off this path we're doing 01127 if(ThisPath != 0) 01128 { 01129 if(FirstPath == 0) 01130 FirstPath = ThisPath; 01131 01132 if(LastPath != 0) 01133 ThisPath->AttachNode(LastPath, NEXT); 01134 01135 LastPath = ThisPath; 01136 01137 ThisPath = 0; 01138 } 01139 01140 // make up a nice group if there's more than one path 01141 NodeRenderableBounded *ToInsert = 0; 01142 if(FirstPath == LastPath) 01143 { 01144 ToInsert = FirstPath; 01145 } else { 01146 ToInsert = new NodeGroup; 01147 01148 if(ToInsert == 0) 01149 return 0; 01150 01151 FirstPath->InsertChainSimple(ToInsert, FIRSTCHILD); 01152 } 01153 01154 Item->pNode = ToInsert; 01155 01156 return ToInsert; 01157 }
|