MetaFileFilter Class Reference

Encapsulates a filter for importing Windows MetaFiles (16-bit only at the moment). More...

#include <metafilt.h>

Inheritance diagram for MetaFileFilter:

VectorFilter Filter ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 MetaFileFilter ()
 MetaFile filter constructor - this initialises the default attributes.
 ~MetaFileFilter ()
 Destructor for the metafile filter. Does nothing at present.
BOOL Init ()
 Initialise the filter.
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 baseclass version return FALSE and hence assume that the filters that need to will override this function to return TRUE.
INT32 HowCompatible (PathName &Filename, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize)
 Find out how compatible a file is with this import filter, i.e. does it look like a metafile? It evaluates the header structure, and checks the file extension.
BOOL DoImport (SelOperation *Op, CCLexFile *, Document *DestDoc, BOOL AutoChosen, ImportPosition *Pos=NULL, KernelBitmap **ppImportedBitmap=NULL, DocCoord *pPosTranslate=NULL, String_256 *URL=NULL)
BOOL DoExport (Operation *, CCLexFile *, PathName *, Document *, BOOL)
BOOL DoExport (Operation *, CCLexFile *pFile, Document *pDoc, METAFILEPICT *pMetaInfo)
void SetLogicalFont (LOGFONT_16 *pNewFont)
 Makes a note of the selected font ready for when it is used.

Protected Member Functions

BOOL PrepareToImport ()
 Sets up the MetaFile filter so it can read in a metafile.
void CleanUpAfterImport ()
 Delete dynamic objects used in the import process.
BOOL MetaFileHeaderIsOk (METAHEADER *pHeader)
 Evaluate a metafile header structure, to see if it looks like a real metafile. This is done as part of the auto-recognition process.
virtual BOOL OpenAndIterateMetafile (CCLexFile *pDiskFile)
 Virtual fn which opens and enumerates the metafile. This can be overriden for other metafile-based readers (e.g. AldusFormatfilter).
HMETAFILE GetMetaFileHandle (LPSTR Filename, METADATA *)
 Given a filename, obtain a handle to the metafile, and provide basic info about the metafile. (Based on code written by Andy for MetaView).
INT32 DecodeMetafileRecord (METARECORD *pMetaRec)
BOOL DecodePolygon (METARECORD *pRec, BOOL FillPolygon)
 Given a Metafile record for a polygon, decode it and convert it into a Camelot path. This function is used to decode the Polygon and PolyLine records in a metafile. The only difference between the two is that polygons are filled and polylines are not, hence the FillPolygon flag that gets passed in.
BOOL DecodePolyPolygon (METARECORD *)
 Given a Metafile record for a 'poly-polygon', decode it and convert it into a Camelot path.
BOOL DecodeLineTo (METARECORD *pMetaRec)
 Decodes the metafile LineTo function and updates the current position.
BOOL DecodeRectangle (METARECORD *pMetaRec)
 Decodes the metafile rectangle command. We insert a Path into the tree of the correct size.
BOOL DecodeEllipse (METARECORD *pMetaRec)
 Decodes the metafile ellipse function.
BOOL DecodeTextStory (METARECORD *pMetaRec)
 Decodes the TextOut function and makes a text story.
BOOL DecodeExtTextStory (METARECORD *pMetaRec)
 Decodes the ExtTextOut function.
BOOL DecodeStretchDIB (METARECORD *)
 Decodes the StretchDIB record from a metafile and makes a NodeBitmap object out of it.
BOOL DecodeDIBStretchBlt (METARECORD *pMetaRec)
 Decodes the StretchBlt function in a Metafile. It builds a NodeBitmap and adds it to the tree.
BOOL DecodeBitBlt (METARECORD *pMetaRec)
 Decodes the bitmap from the metafile and creates a NodeBitmap in the tree of the correct size etc.
BOOL DecodeStretchBlt (METARECORD *pMetaRec)
 Decodes the bitmap from the metafile and creates a NodeBitmap in the tree of the correct size etc.
BOOL DecodeDIBToDevice (METARECORD *pMetaRec)
 Decodes the bitmap from the metafile and creates a NodeBitmap in the tree of the correct size etc.
BOOL DecodeDIBBitBlt (METARECORD *pMetaRec)
 Decodes the bitmap from the metafile and creates a NodeBitmap in the tree of the correct size etc.
KernelBitmapCreateBitmap (BITMAPINFO *pBitmapStart)
 This function expects to find the BITMAPINFO structure at the address passed in, immediatly followed by the Bitmap Bits (ie that actual bitmap data). This function will try to extract the bitmap info and the bitmap bits. It will also try to allocate memory to put a copy of the bitmap info into, and a seperate block of memory to put the bits in. It is assumed that the pointer passed in was found from inside a metafile so the memory is not owned by us. We need to make a copy so that we can keep the bitmap after the metafile is closed and thrown away by windows.
NodeBitmapBuildNodeBitmap (KernelBitmap *pBitmap, const DocRect &Position)
 This function creates a NodeBitmap and attaches the Kernel bitmap to it. When it creates the Node, it attaches it to the correct place in the sub tree that we are building.
void TransformCoord (DocCoord *C)
void ScaleCoord (DocCoord *C)
BOOL AddAttributes (Node *pNewNode)
 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.
virtual BOOL PrepareToExport (CCLexFile *, Spread *pSpread)
virtual void CleanUpAfterExport ()
virtual BOOL WriteToFile (HMETAFILE, METAFILEHEADER *)

Static Protected Member Functions

static INT32 CALLBACK DecodeMetaFile (HDC hdc, HANDLETABLE FAR *pHandleTable, METARECORD FAR *pMetaRec, INT32 cObj, LPARAM lParam)
 Callback function for decoding metafiles. This is called by the SDK function EnumMetaFile, and decodes each record that it is passed into the relevant Camelot object.

Protected Attributes

HMETAFILE MetaFile
HDC MetaFileDC
LOGFONT SelectedFont
INT32 CurrentMappingMode
DocCoord MetaFileOrigin
BOOL FlipYCoords
BOOL IsYExtentNegative
INT32 YShift
LayerpLayer
NodepNode
CImportInfo ImportInfo
DocColour TextColour
HandleTableHandles
friend HandleTable
INT32 FileSize
INT32 BytesRead
INT32 LastProgressUpdate
BOOL Placeable
MILLIPOINT ScaleFactor
INT32 Dpi
DocCoord CurrentPoint
BOOL AllUnderstood
CCLexFileOutputFile
CDC ReferenceDC
CMetaFileDC MetafileDC
RenderRegionExportRegion
DocRect ExportClipRect
MetafileViewpMetaView

Private Member Functions

 CC_DECLARE_MEMDUMP (MetaFileFilter)
void AddNodeToMetaFileGroup (NodeRenderableBounded *pNode)
 Inserts a new node into the group the meta file is being imported into.

Private Attributes

NodepLastInsertedNode
HFILE InFile

Friends

class MetaFileClipMap

Classes

struct  CImportInfo

Detailed Description

Encapsulates a filter for importing Windows MetaFiles (16-bit only at the moment).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/03/94
See also:
Filter

Definition at line 235 of file metafilt.h.


Constructor & Destructor Documentation

MetaFileFilter::MetaFileFilter  ) 
 

MetaFile filter constructor - this initialises the default attributes.

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

Definition at line 974 of file metafilt.cpp.

00975 {
00976     // Set up filter descriptions.
00977     FilterName.Load(_R(IDT_METAFILE_FILTERNAME));
00978     FilterInfo.Load(_R(IDT_METAFILE_FILTERINFO));
00979     FilterID = FILTERID_METAFILE;
00980 
00981     // We can import and export metafiles
00982     Flags.CanImport = TRUE ;
00983     Flags.CanExport = TRUE;
00984 
00985     OutputFile = NULL;
00986     ExportRegion = NULL;
00987     ExportMsgID = _R(IDT_EXPORTMSG_METAFILE1);
00988 
00989     // Default values
00990     FlipYCoords = FALSE;
00991     YShift = 0;
00992     IsYExtentNegative = FALSE;
00993     Dpi = 96;
00994 
00995     // Default to Black text
00996     TextColour = DocColour(0,0,0);
00997 
00998     // Set up the font
00999     SelectedFont.lfHeight = -96;
01000     SelectedFont.lfWidth = 0;
01001     SelectedFont.lfEscapement = 0;
01002     SelectedFont.lfOrientation = 0;
01003     SelectedFont.lfWeight = 0;
01004     SelectedFont.lfItalic = FALSE;
01005     SelectedFont.lfUnderline = FALSE;
01006     SelectedFont.lfStrikeOut = FALSE;
01007     SelectedFont.lfCharSet = 0;
01008     SelectedFont.lfOutPrecision = 3;
01009     SelectedFont.lfClipPrecision = 2;
01010     SelectedFont.lfQuality = 1;
01011     SelectedFont.lfPitchAndFamily = 18;
01012     
01013     camStrcpy(SelectedFont.lfFaceName, (TCHAR *)String_64(_R(IDS_METAFILT_FONT))/*"Times New Roman"*/);
01014 
01015     // Clear out the view
01016     pMetaView = NULL;
01017 };

MetaFileFilter::~MetaFileFilter  ) 
 

Destructor for the metafile filter. Does nothing at present.

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

Definition at line 1057 of file metafilt.cpp.

01058 {
01059 }


Member Function Documentation

BOOL MetaFileFilter::AddAttributes Node pNewNode  )  [protected]
 

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 3515 of file metafilt.cpp.

03516 {
03517     // If not filled, then set the ignore bit on the fill attribute.
03518     if (pNewNode->IS_KIND_OF(NodePath))
03519     {
03520         NodePath* pPath = (NodePath*) pNewNode;
03521         if (!pPath->InkPath.IsFilled)
03522             CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
03523     }
03524         
03525     // Add attributes to the path, if they are different from the default...
03526     BOOL Result = AttributeManager::ApplyBasedOnDefaults(pNewNode, CurrentAttrs);
03527 
03528     // Enable the fill attribute again
03529     CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
03530 
03531     // Return success or failure
03532     return Result;
03533 }

void MetaFileFilter::AddNodeToMetaFileGroup NodeRenderableBounded pNewNode  )  [inline, private]
 

Inserts a new node into the group the meta file is being imported into.

Author:
Jonathan_Payne (Xara Group Ltd) <camelotdev@xara.com>
Date:
06/11/2000
Parameters:
pNewNode [INPUTS]
Returns:
True if all is OK

Definition at line 1030 of file metafilt.cpp.

01031 {
01032     if (pLastInsertedNode)
01033         // The group we are adding to has some objects in it se we just need
01034         // to instert the new node as NEXT after pLastInsertedNode
01035         pNewNode->AttachNode(pLastInsertedNode, NEXT);
01036     else
01037         // pLastInsertedNode == 0 so this is the fist object to be inserted into the
01038         // group so the object is inserted as LASTCHILD of the group
01039         pNewNode->AttachNode(pNode, LASTCHILD);
01040 
01041     pNewNode->GetBoundingRect();
01042 
01043     // Update pLastInsertedNode pointer
01044     pLastInsertedNode = pNewNode;
01045 }

NodeBitmap * MetaFileFilter::BuildNodeBitmap KernelBitmap pBitmap,
const DocRect Position
[protected]
 

This function creates a NodeBitmap and attaches the Kernel bitmap to it. When it creates the Node, it attaches it to the correct place in the sub tree that we are building.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/5/95
Parameters:
pBitmap - the bitmap to put in the NodeBitmap [INPUTS] Position - the rect that the bitmap will fill.
Returns:
A pointer to a NodeBitmap, or NULL if there was a problem

Definition at line 2011 of file metafilt.cpp.

02012 {
02013     // Create a NodeBitmap to put it in
02014     NodeBitmap *pNodeBitmap = new NodeBitmap;
02015 
02016     if (pNodeBitmap==NULL)
02017         return NULL;
02018 
02019     // try and set up the bitmap
02020     if (!pNodeBitmap->SetUpPath(12,12))
02021     {
02022         // Destroy the unwanted nodes
02023         pNodeBitmap->CascadeDelete();
02024         delete pNodeBitmap;
02025         return NULL;
02026     }
02027 
02028     // Make the node bitmap use the bitmap we have found
02029     pNodeBitmap->GetBitmapRef()->Attach(pBitmap, GetDocument());
02030     if (pNodeBitmap->GetBitmap() != pBitmap)
02031     {
02032         // It didn't use the bitmap we gave it, so we can delete it
02033         delete pBitmap;
02034     }
02035 
02036     // And set this in our bitmap node
02037     pNodeBitmap->CreateShape(Position);
02038 
02039     // And apply the default Bitmap attributes
02040     pNodeBitmap->ApplyDefaultBitmapAttrs(NULL);
02041 
02042     // return the bitmap we have made
02043     AddNodeToMetaFileGroup(pNodeBitmap);
02044 
02045     return pNodeBitmap;
02046 }

MetaFileFilter::CC_DECLARE_MEMDUMP MetaFileFilter   )  [private]
 

void MetaFileFilter::CleanUpAfterExport  )  [protected, virtual]
 

Definition at line 3839 of file metafilt.cpp.

03840 {
03841     // Clean up the view
03842     if (pMetaView!=NULL)
03843     {
03844         delete pMetaView;
03845         pMetaView = NULL;
03846     }
03847 
03848     // Clean up the metafile DC
03849     if (MetafileDC.m_hDC)
03850     {
03851         MetafileDC.DeleteDC();
03852     }
03853 
03854     // and the attribute DC
03855     if (ReferenceDC.m_hDC)
03856     {
03857         ReferenceDC.DeleteDC();
03858     }
03859 
03860     // and make sure the file is closed
03861     if (OutputFile)
03862     {
03863         OutputFile->close();
03864         // *dont* delete OutputFile because it turns out to be a static object...
03865         OutputFile = NULL;
03866     }
03867 }

void MetaFileFilter::CleanUpAfterImport void   )  [protected]
 

Delete dynamic objects used in the import process.

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

Definition at line 1177 of file metafilt.cpp.

01178 {
01179     DeleteCurrentAttrs();
01180 
01181     // Release our handle to the metafile
01182     if (MetaFile != NULL)
01183     {
01184         if (!::DeleteMetaFile(MetaFile))
01185             ENSURE(FALSE, "Error occured while closing metafile");
01186         MetaFile = NULL;
01187     }
01188 
01189     // Release our handle to the metafile's DC
01190     if (MetaFileDC != NULL)
01191     {
01192         if (!::CloseMetaFile(MetaFileDC))
01193         {
01194             ENSURE(FALSE, "Error occured while closing metafile");
01195         }
01196         MetaFileDC = NULL;
01197     }
01198 
01199     // Get rid of our handle table
01200     delete Handles;
01201     Handles = NULL;
01202 }

KernelBitmap * MetaFileFilter::CreateBitmap BITMAPINFO pBitmapStart  )  [protected]
 

This function expects to find the BITMAPINFO structure at the address passed in, immediatly followed by the Bitmap Bits (ie that actual bitmap data). This function will try to extract the bitmap info and the bitmap bits. It will also try to allocate memory to put a copy of the bitmap info into, and a seperate block of memory to put the bits in. It is assumed that the pointer passed in was found from inside a metafile so the memory is not owned by us. We need to make a copy so that we can keep the bitmap after the metafile is closed and thrown away by windows.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/5/95
Parameters:
pBitmapStart - the start of the bitmap info. [INPUTS]
Returns:
A pointer to a KernelBitmap, or NULL if one could not be created

Errors: Error _R(IDS_OUT_OF_MEMORY) if there is not enough memory for the new bitmap

Definition at line 1949 of file metafilt.cpp.

01950 {
01951     // Find out about the bitmap header
01952     BITMAPINFOHEADER Header = pBitmapStart->bmiHeader;
01953     LPBYTE pData = NULL;
01954 
01955     // Allocate some ram for the bitmap
01956     LPBITMAPINFO pInfo = AllocDIB(Header.biWidth, Header.biHeight, Header.biBitCount, &pData);
01957 
01958     // See if it worked
01959     if ((pInfo==NULL) || (pData==NULL))
01960         return NULL;
01961 
01962     // work out if there is a palette etc and if so, how big it is.
01963     INT32 OldPalSize = Header.biClrUsed * sizeof(RGBQUAD);
01964     INT32 NewPalSize = pInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD);
01965     ERROR3IF(OldPalSize!=NewPalSize, "Palettes are of a different size");
01966 
01967     // Work out where the real bits start
01968     LPBYTE pBitsStart = (LPBYTE) pBitmapStart;
01969     pBitsStart += sizeof(BITMAPINFOHEADER) + OldPalSize;
01970 
01971     // copy the bits into our new bitmap
01972     memcpy(pData, pBitsStart, Header.biSizeImage);
01973 
01974     // Copy the palette
01975     memcpy(pInfo->bmiColors, pBitmapStart->bmiColors, NewPalSize);
01976 
01977     // Finally create the WinBitmap with all this in it
01978     WinBitmap* pWinBitmap = new WinBitmap(pInfo, pData);
01979 
01980     // Check for out of memory
01981     if (pWinBitmap==NULL)
01982         return NULL;
01983     
01984     // Create a new KernelBitmap to put the WinBitmap into
01985     KernelBitmap* pKernelBmp = new KernelBitmap(pWinBitmap, FALSE);
01986     if (pKernelBmp==NULL)
01987     {
01988         delete pWinBitmap;
01989         return NULL;
01990     }
01991 
01992     // return the bitmap
01993     return pKernelBmp;
01994 }

BOOL MetaFileFilter::DecodeBitBlt METARECORD *  pMetaRec  )  [protected]
 

Decodes the bitmap from the metafile and creates a NodeBitmap in the tree of the correct size etc.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/5/95
Parameters:
pMetaRec - the metafile records that holds the info about the bitmap [INPUTS]
Returns:
TRUE if the bitmap was decoded, FALSE if there was a problem

Definition at line 1740 of file metafilt.cpp.

01741 {
01742     TRACEUSER( "Jonathan", _T("Decoding Bit Blt\n"));
01743     AllUnderstood = FALSE;
01744     return TRUE;
01745 }

BOOL MetaFileFilter::DecodeDIBBitBlt METARECORD *  pMetaRec  )  [protected]
 

Decodes the bitmap from the metafile and creates a NodeBitmap in the tree of the correct size etc.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/5/95
Parameters:
pMetaRec - the metafile records that holds the info about the bitmap [INPUTS]
Returns:
TRUE if the bitmap was decoded, FALSE if there was a problem

Definition at line 1801 of file metafilt.cpp.

01802 {
01803     TRACEUSER( "Jonathan", _T("Decoding DIB Bit Blt\n"));
01804     AllUnderstood = FALSE;
01805     return TRUE;
01806 }

BOOL MetaFileFilter::DecodeDIBStretchBlt METARECORD *  pRec  )  [protected]
 

Decodes the StretchBlt function in a Metafile. It builds a NodeBitmap and adds it to the tree.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/5/95
Parameters:
pMetaRec - the 16bit metafile record [INPUTS]
Returns:
TRUE if all went well, FALSE if there was a problem

Definition at line 1821 of file metafilt.cpp.

01822 {
01823     TRACEUSER( "Jonathan", _T("Decoding DIBSTRETCHBLT\n"));
01824     AllUnderstood = FALSE;
01825 /*
01826     // Get the bitmap info block
01827     LPWORD pWords = (LPWORD) pRec->rdParm;
01828     
01829     // Step over the Rop field and all the src coord fields
01830     // There are 6 words worth of this in a StrecthBlt
01831     pWords+=6;
01832     
01833     // Read in all the coords for the bitmap
01834     INT16 DestYExt = (UINT16) *pWords++;
01835     INT16 DestXExt = (UINT16) *pWords++;
01836     INT16 DestY = (UINT16) *pWords++;
01837     INT16 DestX = (UINT16) *pWords++;
01838 
01839     // Get at the bitmap info structure, and the bitmap info header in that
01840     BITMAPINFO* pBmpInfo = (BITMAPINFO*) pWords;
01841     KernelBitmap* pBitmap = CreateBitmap(pBmpInfo);
01842 
01843     // There was an error, so send it up
01844     if (pBitmap==NULL)
01845         return FALSE;
01846 
01847     // First, set the rectangle to the right size for the bitmap...
01848     DocCoord Position((INT32)DestX, (INT32)DestY);
01849     DocCoord Size(Position.x + (INT32)DestXExt, Position.y + (INT32)DestYExt);
01850 
01851     // Get them in DocCoords
01852     TransformCoord(&Position);
01853     TransformCoord(&Size);
01854 
01855     // Build a rectangle
01856     DocRect BoundsRect;
01857     BoundsRect.lo.x = min(Position.x, Size.x);
01858     BoundsRect.lo.y = min(Position.y, Size.y);
01859     BoundsRect.hi.x = max(Position.x, Size.x);
01860     BoundsRect.hi.y = max(Position.y, Size.y);
01861                  Poly
01862     // Create a NodeBitmap to put it in
01863     NodeBitmap* pNodeBitmap = BuildNodeBitmap(pBitmap, BoundsRect);
01864 */
01865     // return Happy
01866     return TRUE;
01867 }

BOOL MetaFileFilter::DecodeDIBToDevice METARECORD *  pMetaRec  )  [protected]
 

Decodes the bitmap from the metafile and creates a NodeBitmap in the tree of the correct size etc.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/5/95
Parameters:
pMetaRec - the metafile records that holds the info about the bitmap [INPUTS]
Returns:
TRUE if the bitmap was decoded, FALSE if there was a problem

Definition at line 1781 of file metafilt.cpp.

01782 {
01783     TRACEUSER( "Jonathan", _T("Decoding Set DIB To Device\n"));
01784     AllUnderstood = FALSE;
01785     return TRUE;
01786 }

BOOL MetaFileFilter::DecodeEllipse METARECORD *  pMetaRec  )  [protected]
 

Decodes the metafile ellipse function.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/5/95
Parameters:
pMetaRec - the metafile record [INPUTS]
Returns:
TRUE if it decoded the ellipse ok, FALSE if not

Definition at line 2505 of file metafilt.cpp.

02506 {
02507     TRACEUSER( "Jonathan", _T("Decoding Ellipse\n"));
02508 
02509     // Create a new NodePath pbject
02510     NodeEllipse *pElip = new NodeEllipse;
02511     if (pElip==NULL)
02512         return FALSE;
02513 
02514     // try and set up the ellipse
02515     if (!pElip->SetUpPath(12,12))
02516     {
02517         // Couldn't initialise path - delete path (if created) and return error.
02518         pElip->CascadeDelete();
02519         delete pElip;
02520         return FALSE;
02521     }
02522 
02523     // Get pointer to the first coord
02524     INT16 *pCoord = (INT16 *) (pMetaRec->rdParm);
02525                 
02526     // Add the moveto to the path
02527     DocCoord TopRight((INT32) pCoord[1], (INT32) pCoord[2]);
02528     DocCoord BotLeft((INT32) pCoord[3], (INT32) pCoord[0]);
02529     TransformCoord(&TopRight);
02530     TransformCoord(&BotLeft);
02531 
02532     DocRect Rect(min(TopRight.x, BotLeft.x),
02533                  min(TopRight.y, BotLeft.y),
02534                  max(TopRight.x, BotLeft.x),
02535                  max(TopRight.y, BotLeft.y));
02536 
02537     // Create the ellipse
02538     pElip->CreateShape(Rect);
02539     pElip->InkPath.IsFilled = TRUE;
02540 
02541     // Add attributes
02542     BOOL retvalue = AddAttributes(pElip);
02543 
02544     AddNodeToMetaFileGroup(pElip);
02545 
02546     return retvalue;
02547 }

BOOL MetaFileFilter::DecodeExtTextStory METARECORD *  pMetaRec  )  [protected]
 

Decodes the ExtTextOut function.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/7/95
Parameters:
pMetaRec - the metafile record for the ExtTextOut [INPUTS]
Returns:
TRUE if all went well, FALSE if there was a problem

Definition at line 2768 of file metafilt.cpp.

02769 {
02770     // Get the info block
02771     LPWORD pWords = (LPWORD) pMetaRec->rdParm;
02772     
02773     // Get a coord to house the string
02774     DocCoord Position(0,0);
02775 
02776     // Get the coordinates
02777     Position.y = (INT16) *pWords++;
02778     Position.y -= SelectedFont.lfHeight;
02779     Position.x = (INT16) *pWords++;
02780 
02781     // transform the Coord
02782     TransformCoord(&Position);
02783 
02784     // Read in the number of chars in the string
02785     INT16 Count = (UINT16) *pWords++;
02786 
02787     // Read in the options flag
02788     INT16 Option = (UINT16) *pWords++;
02789     if (Option!=0)
02790     {
02791         // Read in the rectangle if its there
02792         pWords++;       // left
02793         pWords++;       // top
02794         pWords++;       // right
02795         pWords++;       // bottom
02796     }
02797 
02798     // Get a string
02799     char* pString = new char[Count+1];
02800     if (pString==NULL)
02801         return FALSE;
02802     
02803     // Copy the chars into our new string
02804     camStrncpy(pString, (char*)pWords, Count);
02805     pString[Count] = 0;
02806     TRACE( _T("%s\n"), pString);
02807 
02808     // Find the coords
02809     while (Count>0)
02810     {
02811         pWords++;
02812         Count-=2;
02813     }
02814 
02815     // Build the text story
02816     TextStory* pNewStory = TextStory::CreateFromChars(Position, pString, NULL, GetDocument(),
02817                                                       &SelectedFont, FALSE, &TextColour);
02818     // Clean up the string
02819     delete pString;
02820 
02821     // See if we have a new text story
02822     if (pNewStory==NULL)
02823         return FALSE;
02824 
02825     // Yes, put it in the tree
02826     AddNodeToMetaFileGroup(pNewStory);
02827 
02828     // Return
02829     return TRUE;
02830 }

BOOL MetaFileFilter::DecodeLineTo METARECORD *  pMetaRec  )  [protected]
 

Decodes the metafile LineTo function and updates the current position.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/9/95
Parameters:
pMetaRec - the metafile record [INPUTS]
Returns:
TRUE if it decoded the LineTo ok, FALSE if not

Definition at line 2415 of file metafilt.cpp.

02416 {
02417     // The current position should hold the coord for the last point drawn (eg, after a
02418     // moveto or a previous line to.
02419 
02420     // Create a new NodePath object to put the line it
02421     NodePath *pPath = new NodePath;
02422     if (pPath==NULL)
02423         return FALSE;
02424 
02425     // Try and set up the path
02426     if (!pPath->SetUpPath(2))
02427     {
02428         // Couldn't initialise path - delete path (if created) and return error.
02429         pPath->CascadeDelete();
02430         delete pPath;
02431         return FALSE;
02432     }
02433 
02434     // Position tag at start of path.
02435     pPath->InkPath.FindStartOfPath();
02436     pPath->InkPath.IsFilled = FALSE;
02437 
02438     // Insert a move to to the current point
02439     if (!pPath->InkPath.InsertMoveTo(CurrentPoint))
02440     {
02441         // Clean it up
02442         pPath->CascadeDelete();
02443         delete pPath;
02444         return FALSE;
02445     }
02446 
02447     // Decode the coord for the line to and update the current point
02448     CurrentPoint.y = (INT16) pMetaRec->rdParm[0];
02449     CurrentPoint.x = (INT16) pMetaRec->rdParm[1];
02450     TransformCoord(&CurrentPoint);
02451 
02452     // Insert a lineto to the new current point
02453     if (!pPath->InkPath.InsertLineTo(CurrentPoint))
02454     {
02455         // Clean it up
02456         pPath->CascadeDelete();
02457         delete pPath;
02458         return FALSE;
02459     }
02460 
02461     // Make sure that we have a vald path here...
02462     BOOL ChangesMade;
02463     if (!pPath->InkPath.EnsureValid(&ChangesMade))
02464     {
02465         // We could not fix this path, so scrap it
02466         TRACE( _T("dl Found a path that was so badly damaged we had to throw it away\n"));
02467         Error::ClearError();
02468         pPath->CascadeDelete();
02469         delete pPath;
02470         
02471         // This path had nothing useful in it, so just return
02472         return TRUE;
02473     }
02474 
02475     #ifdef _DEBUG
02476         // See if we had to make any changes to the path
02477         if (ChangesMade)
02478         {
02479             // yep, we sure did - tell Rik all about it
02480             TRACE( _T("We had to change this path as it was corrupt\n"));
02481         }
02482     #endif
02483 
02484     // Add attributes
02485     BOOL retvalue = AddAttributes(pPath);
02486 
02487     AddNodeToMetaFileGroup(pPath);
02488 
02489     return retvalue;
02490 }

INT32 CALLBACK MetaFileFilter::DecodeMetaFile HDC  hdc,
HANDLETABLE FAR *  pHandleTable,
METARECORD FAR *  pMetaRec,
INT32  cObj,
LPARAM  lParam
[static, protected]
 

Callback function for decoding metafiles. This is called by the SDK function EnumMetaFile, and decodes each record that it is passed into the relevant Camelot object.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/03/94
Parameters:
hdc - the DC of the metafile. [INPUTS] pHandleTable - pointer to the handle table that GDI maintains while enumerating a metafile (NB this is not the same thing as the Camelot 'HandleTable' class). pMetaRec - pointer to the metafile record to be decoded. cObj - number of objects that have handles in the handle table (ignored). lParam - user data; actually a pointer to the relevant MetaFileFilter object.
Returns:
1 => Keep enumerating the metafile 0 => An error occurred - stop enumerating the metafile now.

Errors: Out of memory; Syntax error/corruption in metafile (e.g. trying to select a non-existent object).

See also:
MetaFileFilter

Definition at line 1229 of file metafilt.cpp.

01231 {
01232     MetaFileFilter *Filter = (MetaFileFilter*)lParam;
01233     INT32 Result = Filter->DecodeMetafileRecord(pMetaRec);
01234 
01235     // If there was an error, return an error to the caller
01236     if (Result!=1)
01237         ERROR1(FALSE, _R(IDE_BADMETAFILE));
01238 
01239     // if there was no error, return asking for the next record
01240     return 1;
01241 }

INT32 MetaFileFilter::DecodeMetafileRecord METARECORD *  pMetaRec  )  [protected]
 

BOOL MetaFileFilter::DecodePolygon METARECORD *  pRec,
BOOL  FillPolygon
[protected]
 

Given a Metafile record for a polygon, decode it and convert it into a Camelot path. This function is used to decode the Polygon and PolyLine records in a metafile. The only difference between the two is that polygons are filled and polylines are not, hence the FillPolygon flag that gets passed in.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/03/94
Parameters:
pRec - the polygon record to decode. [INPUTS] FillPolygon - TRUE if the polygon should be filled with the current fill colour, FALSE if it should be just an outline
Returns:
TRUE if the polygon was decoded successfuly; FALSE otherwise.

Errors: Out of memory.

See also:
MetaFileFilter; MetaFileFilter::DecodeMetaFile

Definition at line 2255 of file metafilt.cpp.

02256 {
02257     DocRect BoundingRect;
02258     BOOL retvalue;
02259 
02260     // Get pointer to the polygon structure
02261     INT16 *pNumPoints;
02262     pNumPoints = (INT16 *) (pRec->rdParm);
02263 
02264     // Find out how many points there are
02265     UINT32 NumPoints;
02266     NumPoints = (UINT32) *pNumPoints;
02267 
02268     // Ignore anything with less than 2 points
02269     if (NumPoints < 2)
02270         return TRUE;
02271 
02272     // Create a new NodePath pbject
02273     NodePath *pPath = new NodePath;
02274     if (pPath==NULL)
02275         return FALSE;
02276 
02277     // Try and set it up
02278     if (!pPath->SetUpPath(NumPoints))
02279     {
02280         // Couldn't initialise path - delete path (if created) and return error.
02281         // Destroy any half-created paths
02282         if (pPath != NULL)
02283             pPath->CascadeDelete();
02284         
02285         // delete the unwanted path
02286         delete pPath;
02287 
02288         // Set the error for the caller of EnumMetaFile() to report
02289         return FALSE;
02290     }
02291 
02292     // Position tag at start of path.
02293     pPath->InkPath.FindStartOfPath();
02294 
02295     // Get pointer to the first coord
02296     POINT_16 *pCoord = (POINT_16 *) (pNumPoints + 1);
02297                 
02298     // Add the moveto to the path
02299     DocCoord Coord;
02300     Coord.x = pCoord->x;
02301     Coord.y = pCoord->y;
02302     TransformCoord(&Coord);
02303     if (!pPath->InkPath.InsertMoveTo(Coord))
02304         // Not enough dynamic heap to insert the moveto command
02305         goto NoMemory;
02306 
02307     // Move past the moveto command
02308     pCoord++;
02309     NumPoints--;
02310 
02311     while (NumPoints > 0)
02312     {
02313         Coord.x = pCoord->x;
02314         Coord.y = pCoord->y;
02315         TransformCoord(&Coord);
02316         if (!pPath->InkPath.InsertLineTo(Coord))
02317             // Not enough dynamic heap to insert the moveto command
02318             goto NoMemory;
02319 
02320         // Try next coordinate
02321         pCoord++;
02322         NumPoints--;
02323     }
02324 
02325     // Remember current point
02326     pCoord--;
02327     CurrentPoint.x = pCoord->x;
02328     CurrentPoint.y = pCoord->y;
02329 
02330     // Terminate path properly.
02331     if ((FillPolygon) && (!pPath->InkPath.CloseSubPath()))
02332         // Not enough dynamic heap to insert the closepath command
02333         goto NoMemory;
02334 
02335     // Make sure that we have a vald path here...
02336     BOOL ChangesMade;
02337     if (!pPath->InkPath.EnsureValid(&ChangesMade))
02338     {
02339         // We could not fix this path, so scrap it
02340         TRACE( _T("dp Found a path that was so badly damaged we had to throw it away\n"));
02341         Error::ClearError();
02342 
02343         // Destroy the path
02344         if (pPath != NULL)
02345             pPath->CascadeDelete();
02346 
02347         // delete the unwanted path
02348         delete pPath;
02349 
02350         // and return without error
02351         return TRUE;
02352     }
02353 
02354     #ifdef _DEBUG
02355         // See if we had to make any changes to the path
02356         if (ChangesMade)
02357         {
02358             // yep, we sure did - tell Rik all about it
02359             TRACE( _T("We had to change this path as it was corrupt\n"));
02360         }
02361     #endif
02362 
02363     if (FillPolygon)
02364     {
02365         // Find out what fill colour we have (safe to do this as we only have flat fills
02366         // in metafiles), and use this to set the 'filled' flag on the path.
02367         FlatFillAttribute *pAttr;
02368         pAttr = (FlatFillAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
02369         ENSURE(pAttr->IsKindOf(CC_RUNTIME_CLASS(FlatFillAttribute)),
02370                 "Bad fill type in metafile filter");
02371 
02372         pPath->InkPath.IsFilled = !(pAttr->Colour.IsTransparent());
02373     }
02374     else
02375     {
02376         // Make sure that the path is not filled
02377         pPath->InkPath.IsFilled = FALSE;
02378     }
02379 
02380     // Add attributes
02381     retvalue = AddAttributes(pPath);
02382 
02383     AddNodeToMetaFileGroup(pPath);
02384 
02385     return retvalue;
02386         
02387 NoMemory:
02388     // Error - Out of memory while decoding polygon
02389     
02390     // Destroy any half-created paths
02391     if (pPath != NULL)
02392         pPath->CascadeDelete();
02393         
02394     // delete the unwanted path
02395     delete pPath;
02396 
02397     // Set the error for the caller of EnumMetaFile() to report
02398     return FALSE;
02399 }

BOOL MetaFileFilter::DecodePolyPolygon METARECORD *  pRec  )  [protected]
 

Given a Metafile record for a 'poly-polygon', decode it and convert it into a Camelot path.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/03/94
Parameters:
pRec - the poly-polygon record to decode. [INPUTS]
Returns:
TRUE if the poly-polygon was decoded successfuly; FALSE otherwise.

Errors: Out of memory.

See also:
MetaFileFilter; MetaFileFilter::DecodeMetaFile

Definition at line 2064 of file metafilt.cpp.

02065 {
02066     BOOL retvalue;
02067 
02068     // Get friendly pointer to the polypolygon data.
02069     POLYPOLYGON_INFO16 *pPolyInfo = (POLYPOLYGON_INFO16 *) pRec->rdParm;
02070 
02071     // Used to read coordinates from the data structure
02072     DocCoord Coord;
02073 
02074     // Used to set the bound rectangle of the path.
02075     DocRect BoundingRect;
02076 
02077     // Find out how many polygons there are
02078     UINT32 NumPolys = (UINT32) pPolyInfo->PolyCount;
02079 
02080     // Find out how big this path is so we can give the path class a hint about how big
02081     // to make it's initial arrays.
02082  
02083     // Get pointer to start of polygon vertex counts
02084     INT16 *pVertCount = pPolyInfo->VertCounts;
02085  
02086     UINT32 NumSlots = 0;
02087  
02088     // Iterate through all the polygons to find the number of slots for this path.
02089     while (NumPolys > 0)
02090     {
02091         // Find out how many points there are
02092         NumSlots += (UINT32) *pVertCount;
02093  
02094         // Try next polygon
02095         pVertCount++;
02096         NumPolys--;
02097     }
02098 
02099     // Create a new NodePath object
02100     NodePath *pPath = new NodePath;
02101     if (pPath==NULL)
02102         return FALSE;
02103 
02104     // try and set up the path
02105     if (!pPath->SetUpPath(NumSlots))
02106     {
02107         // Couldn't initialise path - delete path (if created) and return error.
02108         // Destroy any half-created paths
02109         if (pPath != NULL)
02110             pPath->CascadeDelete();
02111         
02112         // delete the unwanted path
02113         delete pPath;
02114 
02115         // Set the error for the caller of EnumMetaFile() to report
02116         return FALSE;
02117     }
02118 
02119     // Position tag at start of path.
02120     pPath->InkPath.FindStartOfPath();
02121 
02122     // Reposition the vertex count pointer, and polygon count
02123     pVertCount = pPolyInfo->VertCounts;
02124     NumPolys = (UINT32) pPolyInfo->PolyCount;
02125 
02126     // Get pointer to start of polygon points
02127     POINT_16 *pCoord = (POINT_16 *) (pPolyInfo->VertCounts + NumPolys);
02128 
02129     // Iterate through all the polygons.
02130     while (NumPolys > 0)
02131     {
02132         // Find out how many points there are
02133         UINT32 NumPoints = (UINT32) *pVertCount;
02134 
02135         // Add the moveto to the path
02136         Coord.x = pCoord->x;
02137         Coord.y = pCoord->y;
02138         TransformCoord(&Coord);
02139         if (!pPath->InkPath.InsertMoveTo(Coord))
0214