AcornDrawFilter Class Reference

Encapsulates an RISC OS Draw input filter system. More...

#include <drawfltr.h>

Inheritance diagram for AcornDrawFilter:

VectorFilter Filter ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 AcornDrawFilter ()
 Filter constructor - this initialises the default attributes and the input buffer.
 ~AcornDrawFilter ()
 Destructor for the filter - this deallocates the input buffer.
BOOL Init ()
 Initialise the filter (attaches a DrawOILFilter object).
virtual BOOL IsDefaultDocRequired (const TCHAR *pcszPathName)
 Works out if opening a file of this type requires a default document to be loaded. If the file format supplies the document then return FALSE otherwise return TRUE. An example would be opening a bitmap file. This has no document defined in the file format and so we need to laod the default document before importing the bitmap into this file. In this version we return TRUE as either this format has no page size or nobody has implemented it yet.
INT32 HowCompatible (PathName &Filename, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize)
 Analyse a file to see if it is an Acorn Draw file - at present this is done by checking to see if the first four bytes are "Draw".
BOOL DoImport (SelOperation *Op, CCLexFile *, Document *DestDoc, BOOL AutoChosen, ImportPosition *Pos=NULL, KernelBitmap **ppImportedBitmap=NULL, DocCoord *pPosTranslate=NULL, String_256 *=NULL)
 Import the named Acorn draw file into the specified document. As yet, only path and group objects are handled. Tagged objects are handled correctly, so, e.g. TableMate files can be loaded by Camelot (although the results are not very interesting). Currently, the data is always positioned on the first page of the first spread in the first chapter. If the read is successful, the End() function of the 'Op' operation is called, otherwise it is not called.
BOOL DoExport (Operation *, CCLexFile *, PathName *, Document *, BOOL)
 None; this is a dummy function as we don't export in Acorn Draw format (yet).

Private Member Functions

 CC_DECLARE_DYNAMIC (AcornDrawFilter)
BOOL PrepareToImport ()
 Sets up the Draw filter so it can read in a Draw file.
void CleanUpAfterImport ()
 Delete dynamic objects used in the import process.
void TransformCoord (DocCoord &C)
BOOL ReadFileHeader ()
 Read the header block of an Acorn Draw file.
BOOL ReadObjectHeader ()
 This function reads in the header of a Draw object from the input file, and stores the result in the ObjectHeader member variable. Using the data in the header it then sets up the HeaderSize and DataSize member variables correctly. It is not ok just to use sizeof(ObjectHeader) as this is not always accurate because some objects in Draw files has stupid headers which are smaller than the standard size, so we have to compensate for this. In such cases we also have to rewind the file so we are in the correct position to read in the data following the header.
BOOL ReadObjectData ()
 Read in the data for a Draw object. The data is stored in the buffer pointed to by the member variable DataBuf. If the buffer is not big enough, it is automagically expanded.
BOOL ProcessObject ()
 Routes the object data to the appropriate function to be processed, according to the tag in the object's header data. If the object is not understood, then the data is simply discarded.
BOOL ProcessPath ()
 Read in the data for a Draw path object, and convert it to an equivalent Camelot NodePath object, and add it to the node pointed to by the pNode member variable.
BOOL ProcessGroup ()
BOOL ProcessTaggedObject ()
 Read in and process a tagged object from a Draw file. A tagged object is a normal object with some arbitrary data following it. This function can handle the tagged object being a group which itself contains tagged objects, and so on.
BOOL SkipObject ()
 Skips past the data for this object, usually because the object is not supported by this filter and/or Camelot.
BOOL AddAttributes (NodePath *pPath, DrawPathHeader *pHeader)
 Add attributes to the path object specified. The attributes are optimised so that if they are the same as the document's default attributes, they are not applied. The attributes applied are line and fill colour, and line style.

Private Attributes

CCLexFileDrawFile
BOOL eof
LayerpLayer
PagepPage
NodepNode
BOOL ComplexPath
BOOL NoAttributes
DocCoord Origin
DrawFileHeader FileHeader
DrawObjectHeader ObjectHeader
ADDR DataBuf
UINT32 DataBufSize
UINT32 HeaderSize
UINT32 DataSize
INT32 BytesRead
INT32 LastProgressUpdate

Detailed Description

Encapsulates an RISC OS Draw input filter system.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/10/93

Definition at line 194 of file drawfltr.h.


Constructor & Destructor Documentation

AcornDrawFilter::AcornDrawFilter  ) 
 

Filter constructor - this initialises the default attributes and the input buffer.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93

Definition at line 305 of file drawfltr.cpp.

00306 {
00307     // Set up filter descriptions.
00308     FilterName.Load(_R(IDT_DRAW_FILTERNAME));
00309     FilterInfo.Load(_R(IDT_DRAW_FILTERINFO));
00310     FilterID = FILTERID_ACORN_DRAW;
00311 
00312 #ifndef STANDALONE
00313     Flags.CanImport = TRUE;
00314     Flags.CanExport = FALSE;
00315 #else
00316     Flags.CanImport = FALSE;
00317     Flags.CanExport = FALSE;
00318 #endif
00319 
00320 #if 0
00321     // No attributes yet
00322     DefLineWidthAttr = NULL;
00323     DefLineColAttr = NULL;
00324     DefFillColAttr = NULL;
00325 #endif
00326 
00327     // No buffer yet
00328     DataBuf = NULL;
00329     DataBufSize = 0;
00330 };

AcornDrawFilter::~AcornDrawFilter  ) 
 

Destructor for the filter - this deallocates the input buffer.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93

Definition at line 343 of file drawfltr.cpp.

00344 {
00345     // Clean up our input buffer
00346     CCFree(DataBuf);
00347 }


Member Function Documentation

BOOL AcornDrawFilter::AddAttributes NodePath pPath,
DrawPathHeader pHeader
[private]
 

Add attributes to the path object specified. The attributes are optimised so that if they are the same as the document's default attributes, they are not applied. The attributes applied are line and fill colour, and line style.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Parameters:
pPath - pointer to the NodePath object to add attributes to. [INPUTS] pHeader - pointer to the Draw file object header which describes the path attributes.
Returns:
TRUE if the attributes were added ok, FALSE if not.

Errors: Fails (returns FALSE) if not enough memory to add attributes. Scope: Private

Definition at line 1160 of file drawfltr.cpp.

01161 {
01162     // Add attributes to the path, if they are different from the default...
01163 
01164     // First set the current attributes.
01165 
01166     // Fill colour
01167     if (pHeader->FillColour.Data.ColourValue == DRAW_TRANSPARENT)
01168     {
01169         pPath->InkPath.IsFilled = FALSE;
01170     }
01171     else
01172     {
01173         pPath->InkPath.IsFilled = TRUE;
01174 
01175         DocColour FillColour(pHeader->FillColour.Data.Component.Red, 
01176                              pHeader->FillColour.Data.Component.Green,
01177                              pHeader->FillColour.Data.Component.Blue);
01178         
01179         if (!SetFillColour(FillColour))
01180             return FALSE;
01181     }
01182 
01183     // Line colour
01184     if (pHeader->LineColour.Data.ColourValue == DRAW_TRANSPARENT)
01185     {
01186         if (!SetLineColour(DocColour(COLOUR_TRANS)))
01187             return FALSE;
01188     }
01189     else
01190     {
01191         DocColour LineColour(pHeader->LineColour.Data.Component.Red, 
01192                              pHeader->LineColour.Data.Component.Green,
01193                              pHeader->LineColour.Data.Component.Blue);
01194 
01195         if (!SetLineColour(LineColour))
01196             return FALSE;
01197     }
01198                 
01199     // Line width
01200 
01201     // Convert from Draw units (1/640 of a point) to Camelot units (millipoints_
01202     // Hence it involves multiplying by 1000/640, which equates to 25/16.
01203     pHeader->LineWidth *= 25;
01204     pHeader->LineWidth /= 16;
01205 
01206     if (!SetLineWidth(pHeader->LineWidth))
01207         return FALSE;
01208 
01209     // Now add attributes if they are different from the defaults.
01210 
01211     // If not filled, then set the ignore bit on the fill attribute.
01212     if (!pPath->InkPath.IsFilled)
01213         CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
01214 
01215     // Add attributes to the path, if they are different from the default...
01216     BOOL Result = AttributeManager::ApplyBasedOnDefaults(pPath, CurrentAttrs);
01217 
01218     // Enable the fill attribute again
01219     CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
01220 
01221     // Return success or failure
01222     return Result;
01223 }

AcornDrawFilter::CC_DECLARE_DYNAMIC AcornDrawFilter   )  [private]
 

void AcornDrawFilter::CleanUpAfterImport void   )  [private]
 

Delete dynamic objects used in the import process.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/02/94
See also:
AcornDrawFilter::PrepareToImport; AcornDrawFilter::DoImport

Definition at line 478 of file drawfltr.cpp.

00479 {
00480     DeleteCurrentAttrs();
00481     DrawFile = NULL;
00482     CCFree(DataBuf);
00483     DataBuf = NULL;
00484     DataBufSize = 0;
00485 }

BOOL AcornDrawFilter::DoExport Operation ,
CCLexFile ,
PathName ,
Document ,
BOOL 
[virtual]
 

None; this is a dummy function as we don't export in Acorn Draw format (yet).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
As base class version. [INPUTS]
Returns:
FALSE.
See also:
Filter::DoExport; Filter

Reimplemented from Filter.

Definition at line 1238 of file drawfltr.cpp.

01239 {
01240     // We don't export in Draw format
01241     return FALSE;
01242 }

BOOL AcornDrawFilter::DoImport SelOperation Op,
CCLexFile pFile,
Document DestDoc,
BOOL  AutoChosen,
ImportPosition Pos = NULL,
KernelBitmap **  ppImportedBitmap = NULL,
DocCoord pPosTranslate = NULL,
String_256 URL = NULL
[virtual]
 

Import the named Acorn draw file into the specified document. As yet, only path and group objects are handled. Tagged objects are handled correctly, so, e.g. TableMate files can be loaded by Camelot (although the results are not very interesting). Currently, the data is always positioned on the first page of the first spread in the first chapter. If the read is successful, the End() function of the 'Op' operation is called, otherwise it is not called.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Parameters:
Op - pointer to the operation that this read process is associated with. [INPUTS] pFile - The file that we are trying to import DestDoc - pointer to the document to insert the Draw file data into. AutoChosen - Pos - ppImportedBitmap - this is used mainly in the bitfltr.cpp for the HTML import filter. HTMLFilter::DoImport() needs a pointer to a kernel bitmap to set the background bitmap up into Camelot. pPosTranslate - This is used too by the HTMLFilter in order to do a formatting. URL - original URL of the imported file
Returns:
TRUE if the read was successful, FALSE if not.

Errors: Unable to open file, corrupted document tree found.

Reimplemented from Filter.

Definition at line 519 of file drawfltr.cpp.

00522 {
00523     // Let's get ready
00524     if (!PrepareToImport())
00525         return FALSE;
00526 
00527     // Make sure that there is a layer to put the bitmap onto
00528     if (!MakeSureLayerExists(DestDoc))
00529         // There is no layer and one could not be made, so we will have to fail
00530         return FALSE;
00531 
00532     // Find the layer on the first page of this document...
00533     pLayer = GetActiveLayer(DestDoc);
00534     ENSURE(pLayer != NULL, "Spread has no active layer"); 
00535     
00536     // pNode is where new objects will go - they all go into a group so the user
00537     // can easily drag the imported Draw file around.  They can then ungroup it afterwards
00538     // if they want.
00539     NodeGroup *pDrawGroup = new NodeGroup;
00540     ERRORIF(pDrawGroup == NULL, _R(IDT_DRAW_NOMEMORY), FALSE);
00541     pNode = pDrawGroup;
00542         
00543     Spread *pSpread;
00544 
00545     if (Pos == NULL)
00546     {
00547         // For now, position Draw objects on 1st page of spread 1
00548 PORTNOTE("spread", "Multi-spread warning!")
00549         pSpread = GetFirstSpread(DestDoc);
00550         pPage = (Page *) pSpread->FindFirstPageInSpread();
00551         ENSURE(pPage->IsKindOf(CC_RUNTIME_CLASS(Page)),
00552                "AcornDrawFilter::Read(): Could not find first Page");
00553         
00554         // Use bottom left of page as origin
00555         DocRect PageRect = pPage->GetPageRect();
00556         Origin = PageRect.lo;
00557     }
00558     else
00559     {
00560         pSpread = Pos->pSpread;
00561         Origin = Pos->Position;
00562     }
00563     
00564     // No complex path initially
00565     ComplexPath = FALSE;
00566 
00567     // Make a note of the disk file
00568     DrawFile = pFile;
00569 
00570     // Disable exceptions and error reporting for this file - we'll do it ourselves
00571     DrawFile->SetReportErrors(FALSE);
00572     DrawFile->SetThrowExceptions(FALSE);
00573 
00574     // Find out the size of the file, in bytes.
00575     INT32 filesize = DrawFile->Size();
00576         
00577     // Initialise
00578     eof = FALSE;
00579         
00580     // Set the progress indicator, this next bit might take a while.
00581     String_64 ImportMessage(_R(IDT_IMPORTMSG_ACORNDRAW));
00582     ImportMessage = GetImportProgressString(pFile, _R(IDT_IMPORTMSG_ACORNDRAW));
00583     BeginSlowJob(filesize, TRUE, &ImportMessage);
00584 
00585     BytesRead = 0;
00586     LastProgressUpdate = 0;
00587 
00588     // Find out details on the file
00589     ReadFileHeader();
00590 
00591     // Check that this is an Acorn Draw file...the first four characters in the file
00592     // should be "Draw".  If we've been chosen automatically, then don't bother as we've
00593     // already checked this.
00594     if (DrawFile->eof() || (!AutoChosen && (camStrncmp(FileHeader.Ident, "Draw", 4) != 0)))
00595     {
00596         // Could not find the ident header - close the file, and return error.
00597         EndSlowJob();
00598         CleanUpAfterImport();
00599         ERROR(_R(IDT_DRAW_NOTADRAWFILE), FALSE);
00600     }
00601     
00602     // Remember file errors
00603     BOOL Error = FALSE;
00604 
00605     // Process each object in the file
00606     do 
00607     {
00608         // Read and process each object
00609         if (ReadObjectHeader())
00610         {
00611             // Header read ok so there is another object to process
00612             if (!ProcessObject())
00613                 // Unable to process object - set error flag
00614                 Error = TRUE;
00615         }
00616     }
00617     while ((BytesRead < filesize) && !Error);
00618     
00619     // All work has been completed . . .
00620     EndSlowJob();
00621     
00622     // All done
00623     BOOL Failed = Error && (BytesRead < filesize);
00624 
00625     // Free up dynamic objects used for import
00626     CleanUpAfterImport();
00627 
00628     // If the load failed for any reason, delete the subtree we have created; otherwise
00629     // graft it into the tree.
00630     if (Failed)
00631     {
00632         // Failed - delete the sub-tree we just created, free the buffer, and return error.
00633         pDrawGroup->CascadeDelete();
00634         delete pDrawGroup;
00635         return FALSE;
00636     }
00637     else
00638     {
00639         // It worked - add the node into the tree
00640         
00641         // Remember current bounding rectangle of the group
00642         DocRect BoundsRect = pDrawGroup->GetBoundingRect(TRUE);
00643         
00644         if (Pos != NULL)
00645         {
00646             // It should be centred on the given position...
00647             DocCoord Centre;
00648             Centre.x = (BoundsRect.lo.x + BoundsRect.hi.x) / 2;
00649             Centre.y = (BoundsRect.lo.y + BoundsRect.hi.y) / 2;
00650 
00651             Trans2DMatrix Xlate(Pos->Position.x - Centre.x, Pos->Position.y - Centre.y);
00652             pDrawGroup->Transform(Xlate);
00653         }
00654                 
00655         // Insert the node and invalidate its region
00656         if (!Op->DoInsertNewNode(pDrawGroup, pSpread, TRUE))
00657         {
00658             // It didn't work - delete the sub-tree we just created
00659             pDrawGroup->CascadeDelete();
00660             delete pDrawGroup;
00661             pDrawGroup = NULL;
00662         }
00663     
00664     }
00665 
00666     // All ok
00667     return TRUE;
00668 }

INT32 AcornDrawFilter::HowCompatible PathName Filename,
ADDR  HeaderStart,
UINT32  HeaderSize,
UINT32  FileSize
[virtual]
 

Analyse a file to see if it is an Acorn Draw file - at present this is done by checking to see if the first four bytes are "Draw".

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/03/94
Parameters:
Filename - name of the file. [INPUTS] HeaderStart - Address of the first few bytes of the file. HeaderSize - the number of bytes in the header pointed to by FileStart. FileSize - the size of the whole file, in bytes.
Returns:
Compatibility: 0 => Not a Draw file; 10 => It is a Draw file
See also:
AcornDrawFilter

Reimplemented from Filter.

Definition at line 419 of file drawfltr.cpp.

00422 {
00423 PORTNOTE("byteorder", "TODO: Check byte ordering")
00424     if (camStrncmp((char *) HeaderStart, "Draw", 4) == 0)
00425     {
00426         // It's a Draw file.
00427         return 10;
00428     }
00429     
00430     // It's not a Draw file.
00431     return 0;
00432 }

BOOL AcornDrawFilter::Init void   )  [virtual]
 

Initialise the filter (attaches a DrawOILFilter object).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Returns:
Always TRUE at the moment.
See also:
DrawOILFilter

Implements Filter.

Definition at line 362 of file drawfltr.cpp.

00363 {
00364     // Get the OILFilter object
00365     pOILFilter = new DrawOILFilter(this);
00366     if (pOILFilter == NULL)
00367         return FALSE;
00368 
00369     // All ok
00370     return TRUE;
00371 }

BOOL AcornDrawFilter::IsDefaultDocRequired const TCHAR pcszPathName  )  [virtual]
 

Works out if opening a file of this type requires a default document to be loaded. If the file format supplies the document then return FALSE otherwise return TRUE. An example would be opening a bitmap file. This has no document defined in the file format and so we need to laod the default document before importing the bitmap into this file. In this version we return TRUE as either this format has no page size or nobody has implemented it yet.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/10/95
Parameters:
pcszPathName pointer to the pathname to check [INPUTS]
Returns:
TRUE if the filter requires a default document, FALSE if not.
See also:
Filter; Filter::IsDefaultDocRequired; CCamDoc::OnOpenDocument;

FilterFamily::DoImport; Filter::DoImport;

Reimplemented from Filter.

Definition at line 393 of file drawfltr.cpp.

00394 {
00395     // No need to check the pathname, just return TRUE as all currently known bitmap filters
00396     // will require the default document.
00397     return TRUE;
00398 }   

BOOL AcornDrawFilter::PrepareToImport  )  [private]
 

Sets up the Draw filter so it can read in a Draw file.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/02/94
Returns:
TRUE if it succeeds, FALSE if not.

Definition at line 446 of file drawfltr.cpp.

00447 {
00448     // Get a default set of attributes for ink objects.
00449     if (!SetUpCurrentAttrs())
00450         return FALSE;
00451 
00452     // Shouldn't have a data buffer at this point
00453     ENSURE(DataBuf == NULL, "DataBuf is non-NULL in PrepareToImport()");
00454 
00455     // No objects read yet
00456     HeaderSize = 0;
00457     DataSize = 0;
00458 
00459     // Get a Diskfile object
00460     DrawFile = NULL;
00461 
00462     // Ok so far
00463     return TRUE;
00464 }

BOOL AcornDrawFilter::ProcessGroup  )  [private]
 

Definition at line 956 of file drawfltr.cpp.

00957 {
00958     // Remembers file read errors
00959     BOOL Error = FALSE;
00960 
00961     // Skip past the group name
00962     DrawFile->seekIn(DRAW_GROUPNAMESIZE, ios::cur);
00963     BytesRead += DRAW_GROUPNAMESIZE;
00964 
00965     // Create a group node, and make pNode point to it, so that all objects in the group
00966     // are attached to it.
00967     NodeGroup *pGroup = new NodeGroup(pNode, LASTCHILD);
00968     if (pGroup == NULL)
00969     {
00970         // Not enough heap to create group
00971         ERROR(_R(IDT_DRAW_NOMEMORY), FALSE);
00972     }
00973 
00974     Node *pOldNode = pNode;
00975     pNode = pGroup;
00976 
00977     // Work out where the end of the group is
00978     FilePos EndPos = DrawFile->tellIn();
00979     DataSize -= DRAW_GROUPNAMESIZE;
00980     EndPos += DataSize;
00981 
00982     // Read (and process) each object in the group, until the end of group or end of file
00983     // is found.
00984     do 
00985     {
00986         // Read in and process the next object
00987         if (!(ReadObjectHeader() && ProcessObject()))
00988             Error = TRUE;
00989 
00990     } while (!DrawFile->eof() && (DrawFile->tellIn() < EndPos));
00991 
00992         
00993     // Restore the node pointer to the parent of this group
00994     pNode = pOldNode;
00995 
00996     // If EOF found, then the group was truncated, so return error.
00997     // Also return error if object reading failed in any way.
00998     if (Error)
00999         // Error has already been set
01000         return FALSE;
01001 
01002     if (DrawFile->eof())
01003         ERROR1(FALSE, _R(IDT_DRAW_BADSYNTAX));
01004         
01005     // Must have worked
01006     return TRUE;
01007 }

BOOL AcornDrawFilter::ProcessObject void   )  [private]
 

Routes the object data to the appropriate function to be processed, according to the tag in the object's header data. If the object is not understood, then the data is simply discarded.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/11/93
Returns:
TRUE if the object was processed with no errors, FALSE if not.

Errors: -

See also:
AcornDrawFilter::ProcessPath; AcornDrawFilter::ProcessGroup; AcornDrawFilter::ProcessTaggedObject; AcornDrawFilter::SkipObject Scope: Private

Definition at line 771 of file drawfltr.cpp.

00772 {
00773     if (BytesRead > (LastProgressUpdate + 2048))
00774     {
00775         LastProgressUpdate = BytesRead;
00776         if (!ContinueSlowJob(BytesRead))
00777             return FALSE;
00778     }
00779 
00780     switch (ObjectHeader.Type)
00781     {
00782         case DRAWOBJECT_PATH:       return ProcessPath();
00783         case DRAWOBJECT_GROUP:      return ProcessGroup();
00784         case DRAWOBJECT_TAGGED:     return ProcessTaggedObject();
00785         default:                    return SkipObject();
00786     }
00787 }

BOOL AcornDrawFilter::ProcessPath  )  [private]
 

Read in the data for a Draw path object, and convert it to an equivalent Camelot NodePath object, and add it to the node pointed to by the pNode member variable.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Returns:
TRUE if the path object is read and converted ok, FALSE if not.

Errors: File reading error, out of memory.

See also:
AcornDrawFilter::ProcessObject Scope: Private

Definition at line 805 of file drawfltr.cpp.

00806 {
00807     // Attempt to read the data for this object
00808     if (!ReadObjectData())
00809         return FALSE;
00810 
00811     // Construct the path and add it to our group node...
00812 
00813     // Create a new NodePath pbject
00814     NodePath *pPath = new NodePath(pNode, LASTCHILD);
00815     if ((pPath == NULL) || (!pPath->SetUpPath()))
00816     {
00817         // Couldn't initialise path - delete path (if created) and return error.
00818         delete pPath;
00819         ERROR(_R(IDT_DRAW_NOMEMORY), FALSE);
00820     }
00821 
00822     // Position tag at start of path.
00823     pPath->InkPath.FindStartOfPath();
00824 
00825     // Examine path header info
00826     DrawPathHeader *pHeader = (DrawPathHeader *) DataBuf;
00827 
00828     // Find first path element
00829     DrawPathElement *pElement = (DrawPathElement *) (pHeader + 1);
00830 
00831     // Skip dash pattern if present
00832     if (pHeader->Style.Data.DashPresent)
00833     {
00834         DashPatternHeader *pDashPattern = (DashPatternHeader *) pElement;
00835         pElement = (DrawPathElement *) 
00836          ( ((ADDR) pElement) + sizeof(DashPatternHeader) + (4 * pDashPattern->NumElements) );
00837     }
00838 
00839     // Process path elements until no more data is left.
00840     UINT32 BytesUsed = 0;
00841 
00842     INT32 Tag = (pElement->Tag) & 0xFF;
00843 
00844     while (Tag != DRAWTAG_ENDOFPATH)
00845     {
00846         switch (Tag)
00847         {
00848             case DRAWTAG_MOVETO:
00849                 BytesUsed = SIZEOF_MOVETO;
00850 
00851                 TransformCoord(pElement->Coords[0]);
00852 
00853                 // Insert a moveto into the path
00854                 if (!pPath->InkPath.InsertMoveTo(pElement->Coords[0]))
00855                     // Not enough dynamic heap to insert the moveto command
00856                     goto NoMemory;
00857                 break;
00858 
00859             case DRAWTAG_LINETO:
00860                 BytesUsed = SIZEOF_LINETO;
00861 
00862                 TransformCoord(pElement->Coords[0]);
00863 
00864                 // Insert a lineto into the path
00865                 if (!pPath->InkPath.InsertLineTo(pElement->Coords[0]))
00866                     // Not enough dynamic heap to insert the lineto command
00867                     goto NoMemory;
00868                 break;
00869 
00870             case DRAWTAG_CURVETO:
00871                 BytesUsed = SIZEOF_CURVETO;
00872 
00873                 TransformCoord(pElement->Coords[0]);
00874                 TransformCoord(pElement->Coords[1]);
00875                 TransformCoord(pElement->Coords[2]);
00876 
00877                 // Insert a curveto into the path
00878                 if (!pPath->InkPath.InsertCurveTo(pElement->Coords[0], 
00879                                                   pElement->Coords[1], pElement->Coords[2]))
00880                     // Not enough dynamic heap to insert the curveto command
00881                     goto NoMemory;
00882                 break;
00883 
00884             case DRAWTAG_CLOSESUBPATH:
00885                 BytesUsed = SIZEOF_CLOSESUBPATH;
00886 
00887                 // Terminate sub-path
00888                 if (!pPath->InkPath.CloseSubPath())
00889                     // Not enough dynamic heap to insert the final element of the path
00890                     goto NoMemory;
00891                             
00892                 break;
00893 
00894             default:
00895                 // Don't understand this element!
00896                 ERROR1(FALSE, _R(IDT_DRAW_BADSYNTAX));
00897         }
00898 
00899         // Move pointer onto next path element
00900         pElement = (DrawPathElement *) (((ADDR) pElement) + BytesUsed);
00901 
00902         Tag = (pElement->Tag) & 0xFF;
00903     }
00904 
00905     // check that the path is OK
00906     if(!pPath->InkPath.EnsureValid())
00907     {
00908         // no, it's completely knackered
00909         pPath->UnlinkNodeFromTree();
00910         delete pPath;
00911         // don't error about it.
00912         return TRUE;
00913     }
00914 
00915     // Use the path header to set the attributes on this path
00916     AddAttributes(pPath, pHeader);
00917 
00918     // Terminate path properly.
00919     pPath->InvalidateBoundingRect();
00920                 
00921     // All ok
00922     return TRUE;
00923 
00924 NoMemory:
00925     // Error - Out of memory while reading Draw file
00926     
00927     // Destroy any half-created paths
00928     if (pPath != NULL)
00929     {
00930         pPath->CascadeDelete();
00931         delete pPath;
00932     }   
00933     // Set the error for the caller to report
00934     ERROR(_R(IDT_DRAW_NOMEMORY), FALSE);
00935 }

BOOL AcornDrawFilter::ProcessTaggedObject  )  [private]
 

Read in and process a tagged object from a Draw file. A tagged object is a normal object with some arbitrary data following it. This function can handle the tagged object being a group which itself contains tagged objects, and so on.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/11/93
Returns:
TRUE if the tagged object is read and process ok, FALSE if not.

Errors: Out of memory, error processing the tagged object.

See also:
AcornDrawFilter::ProcessObject; AcornDrawFilter::ReadObjectHeader Scope: Private

Definition at line 1028 of file drawfltr.cpp.

01029 {
01030     // Remembers file read errors
01031     BOOL Error = FALSE;
01032 
01033     // Skip past the object tag
01034     DrawFile->seekIn(DRAW_TAGSIZE, ios::cur);
01035     BytesRead += DRAW_TAGSIZE;
01036 
01037     // Work out where the end of the tagged object is
01038     FilePos EndPos = DrawFile->tellIn();
01039     DataSize -= DRAW_TAGSIZE;
01040     EndPos += DataSize;
01041 
01042     // Read (and process) the object
01043     if (!(ReadObjectHeader() && ProcessObject()))
01044         // Something went wrong so return error
01045         return FALSE;
01046 
01047     // Skip the word-aligned data following the object
01048     DrawFile->seekIn(EndPos);
01049     BytesRead = EndPos;
01050 
01051     // All ok
01052     return TRUE;
01053 }

BOOL AcornDrawFilter::ReadFileHeader  )  [private]
 

Read the header block of an Acorn Draw file.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Returns:
TRUE if the read is successful, FALSE if an error was encountered.
See also:
AcornDrawFilter::ReadObjectHeader Scope: Private

Definition at line 683 of file drawfltr.cpp.

00684 {
00685     DrawFile->read(&FileHeader, sizeof(FileHeader));
00686     BytesRead += sizeof(FileHeader);
00687     return TRUE;
00688 }

BOOL AcornDrawFilter::ReadObjectData  )  [private]
 

Read in the data for a Draw object. The data is stored in the buffer pointed to by the member variable DataBuf. If the buffer is not big enough, it is automagically expanded.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Returns:
TRUE if the data was read ok, FALSE if not.

Errors: Out of memory.

See also:
AcornDrawFilter::ReadObjectHeader Scope: Private

Definition at line 1104 of file drawfltr.cpp.

01105 {
01106     // Obtain a buffer to read the data into, if we haven't got one already
01107     if (DataSize > DataBufSize)
01108     {
01109         // Buffer is not big enough - try to expand it.
01110         // Don't overwrite DataBuf pointer unless we know the realloc succeeds, otherwise
01111         // we won't be able to free the old buffer if it fails.
01112         ADDR NewBuf = (ADDR) CCRealloc(DataBuf, DataSize);
01113 
01114         // Failed to expand buffer - return error.
01115         ERRORIF(NewBuf == NULL, _R(IDT_DRAW_NOMEMORY), FALSE);
01116 
01117         // Buffer was expanded ok - update the buffer pointer/size variables.
01118         DataBufSize = DataSize;
01119         DataBuf = NewBuf;
01120     }
01121 
01122     // To get this far, we must have a buffer big enough to hold the object, so read it in...
01123     // NB we check that we read the correct number of bytes.
01124     FilePos BeforePos = DrawFile->tell();
01125     DrawFile->read(DataBuf, DataSize);
01126     BytesRead += DataSize;
01127     FilePos AfterPos = DrawFile->tell();
01128 
01129     if ((UINT32) (AfterPos-BeforePos) != DataSize)
01130     {
01131         ERROR3_PF(("Bytes read - actual: %d, planned: %d", (AfterPos-BeforePos), DataSize));
01132         // If EOF found, then an error has occured
01133         ERROR1(FALSE, _R(IDT_DRAW_BADSYNTAX));
01134     }
01135 
01136     // Ok if we got here.
01137     return TRUE;
01138 }

BOOL AcornDrawFilter::ReadObjectHeader  )  [private]
 

This function reads in the header of a Draw object from the input file, and stores the result in the ObjectHeader member variable. Using the data in the header it then sets up the HeaderSize and DataSize member variables correctly. It is not ok just to use sizeof(ObjectHeader) as this is not always accurate because some objects in Draw files has stupid headers which are smaller than the standard size, so we have to compensate for this. In such cases we also have to rewind the file so we are in the correct position to read in the data following the header.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Returns:
TRUE if the header was read ok, FALSE if not.

Errors: If the EOF is found.

See also:
AcornDrawFilter::ReadObjectData; AcornDrawFilter::ReadFileHeader Scope: Private

Definition at line 711 of file drawfltr.cpp.

00712 {
00713     // Set default header size
00714     FilePos BeforePos = DrawFile->tell();
00715 
00716     HeaderSize = sizeof(ObjectHeader);
00717 
00718     DrawFile->read(&ObjectHeader, sizeof(ObjectHeader));
00719 
00720     BytesRead += sizeof(ObjectHeader);
00721 
00722     FilePos AfterPos = DrawFile->tell();
00723 
00724     if ((UINT32) (AfterPos-BeforePos) != sizeof(ObjectHeader))
00725     {
00726         ERROR3_PF(("Header bytes read - actual: %d, planned: %d", (AfterPos-BeforePos), sizeof(ObjectHeader)));
00727         // If EOF found, then an error has occured
00728         ERROR1(FALSE, _R(IDT_DRAW_BADSYNTAX));
00729     }
00730 
00731     // Check for silly objects that don't have a bounding box, and move the input pointer
00732     // back to cope with this.
00733     switch (ObjectHeader.Type)
00734     {
00735         case DRAWOBJECT_FONTTABLE:
00736             // Move back over the bounding box fields (which don't really exist)
00737             FilePos Pos = DrawFile->tellIn();
00738 
00739             // Bounding box fields take up 16 bytes in Acorn Draw files.
00740             DrawFile->seekIn(Pos - 16);
00741             BytesRead -= 16;
00742 
00743             // Adjust header size
00744             HeaderSize -= 16;
00745             break;
00746     }
00747 
00748     DataSize = ObjectHeader.Size - HeaderSize;
00749 
00750     // If eof not found, then no error
00751     return TRUE;
00752 }

BOOL AcornDrawFilter::SkipObject  )  [private]
 

Skips past the data for this object, usually because the object is not supported by this filter and/or Camelot.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Returns:
TRUE always at present.
See also:
AcornDrawFilter::ProcessObject Scope: Private

Definition at line 1069 of file drawfltr.cpp.

01070 {
01071     if (IsUserName("Tim"))
01072     {
01073         TRACE( _T("Skipping unsupported object (type %d, size %d)\n"),
01074                 ObjectHeader.Type, 
01075                 ObjectHeader.Size);
01076     }
01077 
01078     // Skip the number of bytes specified in the current object's header
01079     FilePos Pos = DrawFile->tellIn();
01080     Pos += DataSize;
01081     DrawFile->seekIn(Pos);
01082     BytesRead = Pos;
01083 
01084     // No error checking yet
01085     return TRUE;
01086 }

void AcornDrawFilter::TransformCoord DocCoord C  )  [inline, private]
 

Definition at line 246 of file drawfltr.h.

00247         {   C.x *= 25; C.x /= 16; C.x += Origin.x;
00248             C.y *= 25; C.y /= 16; C.y += Origin.y; };


Member Data Documentation

INT32 AcornDrawFilter::BytesRead [private]
 

Definition at line 270 of file drawfltr.h.

BOOL AcornDrawFilter::ComplexPath [private]
 

Definition at line 236 of file drawfltr.h.

ADDR AcornDrawFilter::DataBuf [private]
 

Definition at line 253 of file drawfltr.h.

UINT32 AcornDrawFilter::DataBufSize [private]
 

Definition at line 254 of file drawfltr.h.

UINT32 AcornDrawFilter::DataSize [private]
 

Definition at line 256 of file drawfltr.h.

CCLexFile* AcornDrawFilter::DrawFile [private]
 

Definition at line 221 of file drawfltr.h.

BOOL AcornDrawFilter::eof [private]
 

Definition at line 224 of file drawfltr.h.

DrawFileHeader AcornDrawFilter::FileHeader [private]
 

Definition at line 248 of file drawfltr.h.

UINT32 AcornDrawFilter::HeaderSize [private]
 

Definition at line 255 of file drawfltr.h.

INT32 AcornDrawFilter::LastProgressUpdate [private]
 

Definition at line 271 of file drawfltr.h.

BOOL AcornDrawFilter::NoAttributes [private]
 

Definition at line 239 of file drawfltr.h.

DrawObjectHeader AcornDrawFilter::ObjectHeader [private]
 

Definition at line 252 of file drawfltr.h.

DocCoord AcornDrawFilter::Origin [private]
 

Definition at line 242 of file drawfltr.h.

Layer* AcornDrawFilter::pLayer [private]
 

Definition at line 227 of file drawfltr.h.

Node* AcornDrawFilter::pNode [private]
 

Definition at line 233 of file drawfltr.h.

Page* AcornDrawFilter::pPage [private]
 

Definition at line 230 of file drawfltr.h.


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