CDRArrowheadStore Class Reference

A storage object for arrowheads from a CDR file import. More...

#include <cdrfiltr.h>

Inheritance diagram for CDRArrowheadStore:

CDRAttributeStore List CCObject SimpleCCObject List of all members.

Public Member Functions

BOOL AddChunkToStore (RIFFFile *RIFF)
 Stores arrowhead chunks for the CDRFilter class.
NodeRenderableBoundedGetConvertedNode (DWORD Reference, INT32 *Distance, BOOL *NotPresent)

Private Member Functions

 CC_DECLARE_MEMDUMP (CDRArrowheadStore)

Detailed Description

A storage object for arrowheads from a CDR file import.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
22 03 95

Definition at line 243 of file cdrfiltr.h.


Member Function Documentation

BOOL CDRArrowheadStore::AddChunkToStore RIFFFile RIFF  )  [virtual]
 

Stores arrowhead chunks for the CDRFilter class.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
22 03 95
Parameters:
A RIFFFile object [INPUTS]
Returns:
error flag
See also:
CDRFilter, CDRAttributeStore

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 }

CDRArrowheadStore::CC_DECLARE_MEMDUMP CDRArrowheadStore   )  [private]
 

NodeRenderableBounded * CDRArrowheadStore::GetConvertedNode DWORD  Reference,
INT32 *  Distance,
BOOL *  NotPresent
 

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 }


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:52:15 2007 for Camelot by  doxygen 1.4.4