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))
02140             // Not enough dynamic heap to insert the moveto command
02141             goto NoMemory;
02142 
02143         // Move past the moveto command
02144         pCoord++;
02145         NumPoints--;
02146 
02147         while (NumPoints > 0)
02148         {
02149             Coord.x = pCoord->x;
02150             Coord.y = pCoord->y;
02151             TransformCoord(&Coord);
02152             if (!pPath->InkPath.InsertLineTo(Coord))
02153                 // Not enough dynamic heap to insert the moveto command
02154                 goto NoMemory;
02155 
02156             // Try next coordinate
02157             pCoord++;
02158             NumPoints--;
02159         }
02160 
02161         // Try next polygon
02162         pVertCount++;
02163         NumPolys--;
02164     }
02165 
02166     // Remember current point
02167     pCoord--;
02168     CurrentPoint.x = pCoord->x;
02169     CurrentPoint.y = pCoord->y;
02170 
02171     // Terminate path properly.
02172     if (!pPath->InkPath.CloseSubPath())
02173         // Not enough dynamic heap to insert the closepath command
02174         goto NoMemory;
02175 
02176     // Make sure that we have a vald path here...
02177     BOOL ChangesMade;
02178     if (!pPath->InkPath.EnsureValid(&ChangesMade))
02179     {
02180         // We could not fix this path, so scrap it
02181         TRACE( _T("dpp Found a path that was so badly damaged we had to throw it away\n"));
02182         Error::ClearError();
02183 
02184         // Destroy the path
02185         if (pPath != NULL)
02186             pPath->CascadeDelete();
02187 
02188         // delete the unwanted path
02189         delete pPath;
02190 
02191         // and return without error
02192         return TRUE;
02193     }
02194 
02195     #ifdef _DEBUG
02196         // See if we had to make any changes to the path
02197         if (ChangesMade)
02198         {
02199             // yep, we sure did - tell Rik all about it
02200             TRACE( _T("We had to change this path as it was corrupt\n"));
02201         }
02202     #endif
02203 
02204     // Find out what fill colour we have (safe to do this as we only have flat fills
02205     // in metafiles), and use this to set the 'filled' flag on the path.
02206     FlatFillAttribute *pAttr;
02207     pAttr = (FlatFillAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
02208     ENSURE(pAttr->IsKindOf(CC_RUNTIME_CLASS(FlatFillAttribute)),
02209             "Bad fill type in metafile filter");
02210 
02211     pPath->InkPath.IsFilled = !(pAttr->Colour.IsTransparent());
02212 
02213     // Add attributes
02214     retvalue = AddAttributes(pPath);
02215 
02216     AddNodeToMetaFileGroup(pPath);
02217 
02218     return retvalue;
02219 
02220 NoMemory:
02221     // Error - Out of memory while reading metafile
02222     
02223     // Destroy any half-created paths
02224     if (pPath != NULL)
02225         pPath->CascadeDelete();
02226         
02227     // delete the unwanted path
02228     delete pPath;
02229 
02230     // Set the error for the caller of EnumMetaFile() to report
02231     return FALSE;
02232 }

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

Decodes the metafile rectangle command. We insert a Path into the tree of the correct size.

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

Definition at line 2563 of file metafilt.cpp.

02564 {
02565     BOOL retvalue;
02566     TRACEUSER( "Jonathan", _T("Decoding Rectangle\n"));
02567 
02568     // Create a new NodePath pbject
02569     NodePath *pPath = new NodePath;
02570     if (pPath==NULL)
02571         return FALSE;
02572 
02573     // try and set up the path
02574     if (!pPath->SetUpPath(12,12))
02575     {
02576         // Destroy any half-created paths
02577         if (pPath != NULL)
02578             pPath->CascadeDelete();
02579         
02580         // delete the unwanted path
02581         delete pPath;
02582 
02583         // Set the error for the caller of EnumMetaFile() to report
02584         return FALSE;
02585     }
02586 
02587     // Position tag at start of path.
02588     pPath->InkPath.FindStartOfPath();
02589 
02590     // Get pointer to the first coord
02591     INT16 *pCoord = (INT16 *) (pMetaRec->rdParm);
02592                 
02593     // Add the moveto to the path
02594     DocCoord TopRight((INT32) pCoord[1], (INT32) pCoord[2]);
02595     DocCoord BotLeft((INT32) pCoord[3], (INT32) pCoord[0]);
02596     TransformCoord(&TopRight);
02597     TransformCoord(&BotLeft);
02598 
02599     DocRect Rect(min(TopRight.x, BotLeft.x),
02600                  min(TopRight.y, BotLeft.y),
02601                  max(TopRight.x, BotLeft.x),
02602                  max(TopRight.y, BotLeft.y));
02603 
02604     // Insert the move to
02605     DocCoord Coord;
02606     Coord.x = Rect.lo.x;
02607     Coord.y = Rect.lo.y;
02608     if (!pPath->InkPath.InsertMoveTo(Coord))
02609         // Not enough dynamic heap to insert the moveto command
02610         goto NoMemory;
02611 
02612     // Insert each of the line sections
02613     Coord.y = Rect.hi.y;
02614     if (!pPath->InkPath.InsertLineTo(Coord))
02615         // Not enough dynamic heap to insert the moveto command
02616         goto NoMemory;
02617 
02618     Coord.x = Rect.hi.x;
02619     if (!pPath->InkPath.InsertLineTo(Coord))
02620         // Not enough dynamic heap to insert the moveto command
02621         goto NoMemory;
02622 
02623     Coord.y = Rect.lo.y;
02624     if (!pPath->InkPath.InsertLineTo(Coord))
02625         // Not enough dynamic heap to insert the moveto command
02626         goto NoMemory;
02627 
02628     Coord.x = Rect.lo.x;
02629     if (!pPath->InkPath.InsertLineTo(Coord))
02630         // Not enough dynamic heap to insert the moveto command
02631         goto NoMemory;
02632 
02633     // Terminate path properly.
02634     if (!pPath->InkPath.CloseSubPath())
02635         // Not enough dynamic heap to insert the closepath command
02636         goto NoMemory;
02637 
02638     // Make sure that we have a vald path here...
02639     BOOL ChangesMade;
02640     if (!pPath->InkPath.EnsureValid(&ChangesMade))
02641     {
02642         // We could not fix this path, so scrap it
02643         TRACE( _T("Found a path that was so badly damaged we had to throw it away\n"));
02644         Error::ClearError();
02645 
02646         // Destroy the path
02647         if (pPath != NULL)
02648             pPath->CascadeDelete();
02649 
02650         // delete the unwanted path
02651         delete pPath;
02652 
02653         // and return without error
02654         return TRUE;
02655     }
02656 
02657     #ifdef _DEBUG
02658         // See if we had to make any changes to the path
02659         if (ChangesMade)
02660         {
02661             // yep, we sure did - tell Rik all about it
02662             TRACE( _T("We had to change this path as it was corrupt\n"));
02663         }
02664     #endif
02665 
02666     // Make sure that the path is not filled
02667     pPath->InkPath.IsFilled = TRUE;
02668 
02669     // Add attributes
02670     retvalue = AddAttributes(pPath);
02671 
02672     AddNodeToMetaFileGroup(pPath);
02673 
02674     return retvalue;
02675 
02676 NoMemory:
02677     // Error - Out of memory while decoding polygon
02678     // Destroy any half-created paths
02679     if (pPath != NULL)
02680         pPath->CascadeDelete();
02681 
02682     // delete the unwanted path
02683     delete pPath;
02684         
02685     // Set the error for the caller of EnumMetaFile() to report
02686     return FALSE;
02687 }

BOOL MetaFileFilter::DecodeStretchBlt 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 1761 of file metafilt.cpp.

01762 {
01763     TRACEUSER( "Jonathan", _T("Decoding Stretch Blt\n"));
01764     AllUnderstood = FALSE;
01765     return TRUE;
01766 }

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

Decodes the StretchDIB record from a metafile and makes a NodeBitmap object out of it.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/5/95
Parameters:
pRec - the Metafile record [INPUTS]
Returns:
TRUE if it decoded the record ok, FALSE if there was a problem

Definition at line 1882 of file metafilt.cpp.

01883 {
01884     TRACEUSER( "Jonathan", _T("Decoding Stretch DIB\n"));
01885 
01886     // Get the bitmap info block
01887     LPWORD pWords = (LPWORD) pRec->rdParm;
01888     
01889     // Step over the Rop field and all the src coord fields
01890     // there are 7 words worth in a StretchDIBits function
01891     pWords+=7;
01892     
01893     // Read in all the coords for the bitmap
01894     INT16 DestYExt = (UINT16) *pWords++;
01895     INT16 DestXExt = (UINT16) *pWords++;
01896     INT16 DestY = (UINT16) *pWords++;
01897     INT16 DestX = (UINT16) *pWords++;
01898 
01899     // Get at the bitmap info structure, and the bitmap info header in that
01900     BITMAPINFO* pBmpInfo = (BITMAPINFO*) pWords;
01901     KernelBitmap* pBitmap = CreateBitmap(pBmpInfo);
01902 
01903     // There was an error, so send it up
01904     if (pBitmap==NULL)
01905         return FALSE;
01906 
01907     // First, set the rectangle to the right size for the bitmap...
01908     DocCoord Position((INT32)DestX, (INT32)DestY);
01909     DocCoord Size(Position.x + (INT32)DestXExt, Position.y + (INT32)DestYExt);
01910 
01911     // Get them in DocCoords
01912     TransformCoord(&Position);
01913     TransformCoord(&Size);
01914 
01915     // Build a rectangle
01916     DocRect BoundsRect;
01917     BoundsRect.lo.x = min(Position.x, Size.x);
01918     BoundsRect.lo.y = min(Position.y, Size.y);
01919     BoundsRect.hi.x = max(Position.x, Size.x);
01920     BoundsRect.hi.y = max(Position.y, Size.y);
01921 
01922     // Create a NodeBitmap to put it in
01923     NodeBitmap* pNodeBitmap = BuildNodeBitmap(pBitmap, BoundsRect);
01924 
01925     // return Happy
01926     return TRUE;
01927 }

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

Decodes the TextOut function and makes a text story.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/5/95
Parameters:
pMetaRec - the record to decode [INPUTS]
Returns:
TRUE if it worked, FALSE if there was a problem

Definition at line 2701 of file metafilt.cpp.

02702 {
02703     // Get the bitmap info block
02704     LPWORD pWords = (LPWORD) pMetaRec->rdParm;
02705     
02706     // Read in the number of chars in the string
02707     INT16 Count = (UINT16) *pWords++;
02708 
02709     // Get a string
02710     char* pString = new char[Count+1];
02711     if (pString==NULL)
02712         return FALSE;
02713     
02714     // Copy the chars into our new string
02715     camStrncpy(pString, (char*)pWords, Count);
02716     pString[Count] = 0;
02717     TRACE( _T("- %s\n"), pString);
02718 
02719     // Find the coords
02720     while (Count>0)
02721     {
02722         pWords++;
02723         Count-=2;
02724     }
02725 
02726     // Get a coord to house the string
02727     DocCoord Position(0,0);
02728 
02729     // Get the coordinates
02730     Position.y = (INT16) *pWords++;
02731     Position.x = (INT16) *pWords++;
02732 
02733     // transform them
02734     TransformCoord(&Position);
02735 
02736     // Build the text story
02737     TRACEUSER( "Jonathan", _T("Text Story : %s\n"), pString);
02738     TextStory* pNewStory = TextStory::CreateFromChars(Position, pString, NULL, GetDocument(),
02739                                                       &SelectedFont, FALSE, &TextColour);
02740     // Clean up the string
02741     delete pString;
02742 
02743     // See if we have a new text story
02744     if (pNewStory==NULL)
02745         return FALSE;
02746 
02747     // Yes, put it in the tree
02748     AddNodeToMetaFileGroup(pNewStory);
02749 
02750     // Return
02751     return TRUE;
02752 }

BOOL MetaFileFilter::DoExport Operation ,
CCLexFile pFile,
Document pDoc,
METAFILEPICT *  pMetaInfo
 

Definition at line 3668 of file metafilt.cpp.

03669 {
03670     // Get pointer to the spread to export.
03671     Spread *pSpread = GetFirstSpread(pDoc);
03672     ExportClipRect.MakeEmpty();
03673 
03674     // Set up device context and render region for this export.
03675     // This will show a progress hourglass for the objects being rendered
03676     if (!PrepareToExport(NULL, pSpread))
03677     {
03678         CleanUpAfterExport();
03679         return FALSE;
03680     }
03681 
03682     // put out some sensible stuff on the front
03683     MetafileDC.SetMapMode(pMetaView->GetMetafileMapMode());
03684     pMetaInfo->mm = pMetaView->GetMetafileMapMode();
03685 
03686     // Export the data to the file
03687     BOOL ok = ExportRender(ExportRegion);
03688     HMETAFILE hMetafile = NULL;
03689 
03690     if (ok)
03691     {
03692         // get a metafile handle from the metafile DC
03693         hMetafile = MetafileDC.Close();
03694         if (hMetafile==NULL)
03695         {
03696             ERROR1RAW(_R(IDE_MF_NOCLOSE));
03697             ok = FALSE;
03698         }
03699     }
03700 
03701     // If at this point, something has gone wrong, tidy up
03702     if (!ok)
03703     {
03704         // Get rid of the metafile
03705         if (hMetafile)
03706             DeleteMetaFile(hMetafile);
03707 
03708         // Tidy up and fail
03709         CleanUpAfterExport();
03710         return FALSE;
03711     }
03712 
03713     // Put up a progress display/hourglass
03714     String_64 ProgressString(_R(IDT_EXPORTMSG_METAFILE2));
03715     ProgressString = GetExportProgressString(pFile, _R(IDT_EXPORTMSG_METAFILE2));
03716     BeginSlowJob(100, FALSE, &ProgressString);
03717 
03718     // Fill in the info about the metafile that we know
03719     // make it bigger as the coords we use are smaller than most.
03720     FIXED16 PixelSize;
03721     pMetaView->GetPixelSize(&PixelSize, &PixelSize);
03722     INT32 Size = PixelSize.MakeLong();
03723     pMetaInfo->xExt = ExportClipRect.Width() / Size;
03724     pMetaInfo->yExt = ExportClipRect.Height() / Size;
03725     pMetaInfo->hMF = hMetafile;
03726 
03727     // All done - deallocate dynamic objects, stop the progress display/hourglass
03728     // and return success. (Also closes file).
03729     CleanUpAfterExport();
03730     EndSlowJob();       
03731 
03732     return ok;
03733 }

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

Reimplemented from Filter.

Definition at line 3550 of file metafilt.cpp.

03552 {
03553     // Used to open the file up before starting DoExport. But this meant a cancel on the export
03554     // options dialog had filled the file, if it was already present. So now up up here if
03555     // not open already. In the PreviewBitmap case the file will already be open.
03556     if (!pFile->isOpen())
03557     {
03558         if (pFile->IsKindOf(CC_RUNTIME_CLASS(CCDiskFile)))
03559         {
03560             BOOL ok = OpenExportFile((CCDiskFile*) pFile, pPath);
03561             if (!ok) return FALSE;
03562         }
03563         else
03564         {
03565             TRACEUSER( "JustinF", _T("Tried to open non-CCDiskFile in MetaFileFilter::DoExport\n"));
03566             return FALSE;
03567         }
03568     }
03569 
03570     // Get pointer to the spread to export.
03571     Spread* pSpread = GetFirstSpread(pDoc);
03572     ExportClipRect.MakeEmpty();
03573 
03574     // Set up device context and render region for this export.
03575     // This will show a progress hourglass for the objects being rendered
03576     if (!PrepareToExport(pFile, pSpread))
03577     {
03578         CleanUpAfterExport();
03579         return FALSE;
03580     }
03581 
03582     // put out some sensible stuff on the front
03583     MetafileDC.SetMapMode(pMetaView->GetMetafileMapMode());
03584 
03585     // Export the data to the file
03586     BOOL ok = ExportRender(ExportRegion);
03587     HMETAFILE hMetafile = NULL;
03588 
03589     // If there have been no errors so far, find out about the metafile
03590     if (ok)
03591     {
03592         // get a metafile handle from the metafile DC
03593         hMetafile = MetafileDC.Close();
03594         if (hMetafile == NULL)
03595         {
03596             ERROR1RAW( _R(IDE_MF_NOCLOSE) );
03597             ok = FALSE;
03598         }
03599     }
03600 
03601     // and clean up
03602     if (!ok)
03603     {
03604         if (hMetafile) DeleteMetaFile(hMetafile);
03605         CleanUpAfterExport();
03606         return FALSE;
03607     }
03608 
03609     // Put up a progress display/hourglass
03610     // (0 - 100, FALSE => no delay, show it NOW!, use the filters export message)
03611     String_64 ProgressString(_R(IDT_EXPORTMSG_METAFILE2));
03612     ProgressString = GetExportProgressString(pFile, _R(IDT_EXPORTMSG_METAFILE2));
03613     BeginSlowJob(100, FALSE, &ProgressString);
03614 
03615     // build standard placeable metafile header
03616     METAFILEHEADER Header;
03617     Header.key      = METAFILEHEADERKEY;
03618     Header.hmf      = 0;
03619     Header.inch     = pMetaView->GetMetafileDPI();
03620     Header.reserved = 0L;
03621     Header.checksum = 0;
03622 
03623     // And fill in the details about the Bounding rect
03624     FIXED16 PixelSize;
03625     pMetaView->GetPixelSize(&PixelSize, &PixelSize);
03626     INT32 Size = PixelSize.MakeLong();
03627     Header.bbox.left   = (short) (ExportClipRect.lo.x / Size);
03628     Header.bbox.top    = (short) (ExportClipRect.lo.y / Size);
03629     Header.bbox.right  = (short) (ExportClipRect.hi.x / Size);
03630     Header.bbox.bottom = (short) (ExportClipRect.hi.y / Size);
03631 
03632     // calculate checksum as Word checks this
03633     LPWORD p = (LPWORD) &Header;
03634     INT32 i = 10;
03635     while (i--)
03636     {
03637         // Just OR together all the WORDs in the Header
03638         Header.checksum ^= *p++;
03639     }
03640 
03641     // actually write to the file
03642     ok = WriteToFile( hMetafile, &Header );
03643     DeleteMetaFile( hMetafile );
03644 
03645     // All done - deallocate dynamic objects, stop the progress display/hourglass
03646     // and return success. (Also closes file).
03647     CleanUpAfterExport();
03648     EndSlowJob();       
03649 
03650     // return, saying if it worked or not
03651     return ok;
03652 }

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

Reimplemented from Filter.

Definition at line 1376 of file metafilt.cpp.

01379 {
01380     // Set up value for each import
01381     InFile = 0;
01382     
01383     // We need to know which document later on
01384     TheDocument = DestDoc;
01385 
01386     // Let's get ready
01387     if (!PrepareToImport())
01388         return FALSE;
01389 
01390     // Make sure that there is a layer to put the bitmap onto
01391     if (!MakeSureLayerExists(DestDoc))
01392         // There is no layer and one could not be made, so we will have to fail
01393         return FALSE;
01394 
01395     // Find the layer on the first page of this document...
01396     pLayer = GetActiveLayer(DestDoc);
01397     ENSURE(pLayer != NULL, "Spread has no active layer"); 
01398 
01399     NodeGroup* pGroup = new NodeGroup;
01400     if (!pGroup)
01401         return FALSE;
01402     pNode = pGroup;
01403 
01404     // Put the group in the tree
01405     AttachNodeDirection dir;
01406 
01407     Node *pInsertPoint = pLayer->FindLastChild();
01408     if (pInsertPoint)
01409     {
01410         if (pInsertPoint->IsAnInsertionNode())
01411             dir = PREV;
01412         else
01413             dir = NEXT;
01414     }
01415     else
01416     {
01417         pInsertPoint = pLayer;
01418         dir = LASTCHILD;
01419     }
01420 
01421     Op->DoInsertNewNode(pGroup,         // Node to insert
01422                         pInsertPoint,   // Context
01423                         dir,            // AttachDirection
01424                         TRUE,           // InvalidateRegion
01425                         TRUE,           // ClearSelection
01426                         TRUE,           // SelectNewObject
01427                         FALSE);         // NormaliseAttributes
01428 
01429 
01430     // Set last inserted node to zero so the next node is inserted as a child of pGroup
01431     pLastInsertedNode = 0;
01432 
01433     ImportInfo.pOp = Op;
01434 
01435     if (pPos == NULL)
01436     {       
01437         ImportInfo.Pos.pSpread = GetFirstSpread(DestDoc);
01438         DocCoord centre = ImportInfo.Pos.pSpread->FindFirstPageInSpread()->GetPageRect().Centre();
01439         ImportInfo.Pos.Position.x = centre.x;
01440         ImportInfo.Pos.Position.y = centre.y;
01441     }
01442     else
01443         ImportInfo.Pos      = *pPos;
01444 
01445     // now read the file etc using virtual function so does different things on different
01446     // sub-classes
01447     AllUnderstood = TRUE;
01448     BOOL Worked = OpenAndIterateMetafile( pDiskFile );
01449 
01450     CleanUpAfterImport();
01451 
01452     if (InFile)
01453     {
01454         _lclose(InFile);
01455         InFile = 0;
01456     }
01457 
01458     if (!Worked)
01459     {
01460 //      pGroup->CascadeDelete();
01461 //      delete pGroup;
01462         return FALSE;
01463     }
01464 
01465     // Get the final group under the mouse cursor (or coords
01466     // set above if this is not a drag'n'drop)
01467     pGroup->InvalidateBoundingRect();
01468 
01469     DocCoord GroupCentre = pGroup->GetBoundingRect().Centre();
01470     DocCoord GroupTrans;
01471 
01472     GroupTrans.x = ImportInfo.Pos.Position.x - GroupCentre.x;
01473     GroupTrans.y = ImportInfo.Pos.Position.y - GroupCentre.y;
01474     
01475     Trans2DMatrix trans(GroupTrans.x, GroupTrans.y);
01476     pGroup->Transform(trans);
01477 
01478     pGroup->InvalidateBoundingRect();
01479     Op->DoInvalidateNodeRegion(pGroup, FALSE, FALSE, FALSE);
01480 
01481     // Post import
01482     if ((TheDocument!=NULL) && (pNode!=NULL))
01483         TheDocument->PostImport();
01484 
01485     // If it worked, but there was something we did not understand, explain to the user
01486     if ((Worked) && (!AllUnderstood))
01487     {
01488         Error::SetError(_R(IDS_MEATFILE_WARN), 0);
01489         InformWarning();
01490         Error::ClearError();
01491     }
01492 
01493     return Worked;
01494 }

HMETAFILE MetaFileFilter::GetMetaFileHandle LPSTR  Filename,
METADATA pMetaData
[protected]
 

Given a filename, obtain a handle to the metafile, and provide basic info about the metafile. (Based on code written by Andy for MetaView).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/03/94
Parameters:
Filename - name of the file to attempt to load as a metafile. [INPUTS]
pMetaData - various data about the metafile, if it was loaded successfully. [OUTPUTS]
Returns:
Handle to the loaded metafile, or NULL if an error occured.

Errors: Unable to open file; Unable to read enough data from file; Header looks invalid; Out of memory.

See also:
METADATA

Definition at line 1590 of file metafilt.cpp.

01591 {
01592     OFSTRUCT OpenBuf;
01593 
01594     // Try to open the file
01595     OpenBuf.cBytes = sizeof(OpenBuf);
01596     InFile = OpenFile(Filename, &OpenBuf, OF_READ);
01597 
01598     // Did it work ok?
01599     if (InFile == HFILE_ERROR)
01600         return NULL;
01601 
01602     // Read in the first dword of the file to see if this is a placeable metafile
01603     INT32 BytesRead = _lread(InFile, &pMetaData->Header, sizeof(DWORD));
01604 
01605     if (BytesRead != sizeof(DWORD))
01606     {
01607         // Unable to read from the file - return error.
01608         _lclose(InFile);
01609         InFile = 0;
01610         return NULL;
01611     }
01612 
01613     METAHEADER MetaHeader;
01614 
01615     // Is this a placeable metafile?
01616     if (pMetaData->Header.key != METAFILEHEADERKEY)
01617     {
01618 
01619         // Not placable - if it looks OK, let the system read it
01620         // Go to the start of the file, read the header in, and close the file.
01621         _llseek(InFile, 0L, 0);
01622         _lread(InFile, &MetaHeader, sizeof(MetaHeader));
01623         _lclose(InFile);
01624         InFile = 0;
01625 
01626         if (!MetaFileHeaderIsOk(&MetaHeader))
01627             // Can't handle this file - return ERROR
01628             return NULL;
01629 
01630         // Looks ok - get the system to try and read it
01631         pMetaData->Placeable = FALSE;
01632         return ::GetMetaFile(Filename);
01633     }
01634 
01635     // Read the placeable header in.
01636     BytesRead = _lread(InFile, (LPVOID) &(pMetaData->Header.hmf), sizeof(METAFILEHEADER)-sizeof(DWORD));
01637 
01638     // Did it work?
01639     if (BytesRead!=(sizeof(METAFILEHEADER)-sizeof(DWORD)))
01640     {
01641         // No - return error
01642         _lclose(InFile);
01643         InFile = 0;
01644         return NULL;
01645     }
01646 
01647     // Read standard metafile header in.
01648     BytesRead = _lread(InFile, (LPSTR) &MetaHeader, sizeof(METAHEADER));
01649 
01650     // Did it work?
01651     if (BytesRead != sizeof(METAHEADER))
01652     {
01653         // No - return error.
01654         _lclose(InFile);
01655         InFile = 0;
01656         return NULL;
01657     }
01658 
01659     // Allocate memory for the metafile bits.
01660     GLOBALHANDLE MemHandle = GlobalAlloc(GHND, (MetaHeader.mtSize * 2L));
01661 
01662     if (MemHandle == NULL)
01663     {
01664         // Didn't get the memory - return error
01665         _lclose(InFile);
01666         InFile = 0;
01667         return NULL;
01668     }
01669 
01670     // Lock the memory.
01671     LPSTR MemPtr = (LPSTR) GlobalLock(MemHandle);
01672 
01673     if (MemPtr == NULL)
01674     {
01675         // Unable to lock memory - return error
01676         GlobalFree(MemHandle);
01677         _lclose(InFile);
01678         InFile = 0;
01679         return NULL;
01680     }
01681 
01682     // Seek past the header
01683     _llseek(InFile, sizeof(METAFILEHEADER), 0);
01684 
01685     // Read metafile bits.
01686     BytesRead = _lread(InFile, MemPtr, (UINT32)(MetaHeader.mtSize * 2));
01687 
01688 
01689     // Did we read the correct number of bytes?
01690     if ((UINT32) BytesRead == (MetaHeader.mtSize * 2))
01691     {
01692         // Read the data ok - set the metafile bits.
01693         HMETAFILE MetaFileHandle;
01694         MetaFileHandle = SetMetaFileBitsEx(BytesRead, (LPBYTE) MemPtr);
01695 
01696         if (MetaFileHandle != NULL)
01697         {
01698             // At last - it's all worked; return the metafile handle
01699             pMetaData->Placeable = TRUE;
01700             return MetaFileHandle;
01701         }
01702     }
01703 
01704     // Failure - clean up and return error.
01705     GlobalUnlock(MemHandle);
01706     GlobalFree(MemHandle);
01707     _lclose(InFile);
01708     InFile = 0;
01709 
01710     return NULL;
01711 }

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

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.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/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:
A number between 0 and 10 - see base class version for details
See also:
Filter::HowCompatible; MetaFilefilter::MetaFileHeaderIsOk

Reimplemented from Filter.

Definition at line 1544 of file metafilt.cpp.

01546 {
01547     // Check to see if this is a placeable metafile.
01548     METAFILEHEADER *pMetaFileHeader = (METAFILEHEADER *) HeaderStart;
01549 
01550     if (pMetaFileHeader->key == METAFILEHEADERKEY)
01551         // It's a metafile
01552         return 10;
01553 
01554     // Not a placeable metafile - examine header for sane METAHEADER structure.
01555     METAHEADER *pMetaHeader = (METAHEADER *) HeaderStart;
01556 
01557     if (MetaFileHeaderIsOk(pMetaHeader))
01558     {
01559         // Could be a metafile - check extension
01560         String Extension = Filename.GetType();
01561         if (_tcsicmp((TCHAR *) Extension, "wmf") == 0)
01562             // Likely to be a metafile
01563             return 9;
01564         else
01565             // Could still be a metafile, but less likely
01566             return 5;
01567     }
01568     else
01569         // We can't handle this file
01570         return 0;
01571 }

BOOL MetaFileFilter::Init void   )  [virtual]
 

Initialise the filter.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/93
Returns:
TRUE if it worked, FLASE if it failed

Implements Filter.

Definition at line 1071 of file metafilt.cpp.

01072 {
01073     // Get the OILFilter object
01074     // This is deleted in the base class destructor
01075     pOILFilter = new MetaFileOILFilter(this);
01076     if (pOILFilter==NULL)
01077         // Error state already set by new
01078         return FALSE;       
01079 
01080     MetaFile = NULL;
01081     MetaFileDC = NULL;
01082     Handles = NULL;
01083 
01084     // Register ourselves with the clipboard: We can provide import and export mappings
01085     // between internal "vector" format and windows metafiles (CF_METAFILEPICT).
01086     // Our mapping has a priority level of 100.
01087     InternalClipboardFormat Format(CLIPTYPE_VECTOR);
01088     MetaFileClipMap::CreateAndRegister(CLIPMAP_IMPORTONLY, this, Format, CF_METAFILEPICT, 100);
01089 
01090     // All ok
01091     return TRUE;
01092 }

BOOL MetaFileFilter::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 baseclass version return FALSE and hence assume that the filters that need to will override this function to return TRUE.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/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::IsDefaultDocRequired; FilterFamily::IsDefaultDocRequired; CCamDoc::OnOpenDocument; FilterFamily::DoImport; Filter::DoImport;

Reimplemented from Filter.

Definition at line 1115 of file metafilt.cpp.

01116 {
01117     // No need to check the pathname, just return TRUE as all this current filter has no
01118     // concept of page size, layout etc and hence will require the default document.
01119     return TRUE;
01120 }   

BOOL MetaFileFilter::MetaFileHeaderIsOk METAHEADER *  pHeader  )  [protected]
 

Evaluate a metafile header structure, to see if it looks like a real metafile. This is done as part of the auto-recognition process.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/03/94
Parameters:
pHeader - the header to check. [INPUTS]
Returns:
TRUE if the header looks ok; FALSE if not.
See also:
MetaFileFilter::HowCompatible

Definition at line 1511 of file metafilt.cpp.

01512 {
01513     return( (pHeader->mtType == 1)              &&  // disk-based
01514 
01515             (pHeader->mtHeaderSize >= 9)        &&
01516             (pHeader->mtHeaderSize < 100)       &&  // assumes header wont get huge
01517 
01518             (pHeader->mtSize >= 9)              &&  // minimum file size
01519             (pHeader->mtSize < 0xFF000000L)     &&  // assume <24 bit file length
01520 
01521             (pHeader->mtVersion >= 0x200));         // allow Windows 2 MFs
01522 
01523 }

BOOL MetaFileFilter::OpenAndIterateMetafile CCLexFile pDiskFile  )  [protected, virtual]
 

Virtual fn which opens and enumerates the metafile. This can be overriden for other metafile-based readers (e.g. AldusFormatfilter).

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/3/95
Returns:
TRUE if OK, FALSE if not (and sets error code).
See also:
MetaFileFilter::DoImport

Definition at line 1255 of file metafilt.cpp.

01256 {
01257     // Try to open the file.
01258     if (!pDiskFile->IS_KIND_OF(CCDiskFile))
01259     {
01260         TRACEUSER( "JustinF", _T("Non-CCDiskFile in MetaFileFilter::OpenAndIterateMetafile\n"));
01261         return FALSE;
01262     }
01263 
01264     METADATA MetaData;
01265     PathName Path = ((CCDiskFile*) pDiskFile)->GetPathName();
01266     String_256 PathString = Path.GetPath();
01267     MetaFile = GetMetaFileHandle((TCHAR*) PathString, &MetaData);
01268 
01269     if (MetaFile == NULL)
01270     {
01271         // MetaFile failed to open
01272         TRACEUSER( "Jonathan", _T("Could not open metafile\n"));
01273         ERROR(_R(IDT_IMPORT_NOTFOUND), FALSE);
01274     }
01275 
01276     // Set the placeable flag so the callback knows what kind of file this is.
01277     Placeable = MetaData.Placeable;
01278 
01279     // If this is a placeable, get the size and origin of this file.
01280     if (Placeable)
01281     {
01282         // Origin is bottom left of bounding box
01283         MetaFileOrigin.x = MetaData.Header.bbox.left;
01284         MetaFileOrigin.y = MetaData.Header.bbox.bottom;
01285 
01286         // Find out the width and height of the bbox
01287         FlipYCoords = FALSE;
01288         IsYExtentNegative = FALSE;
01289 
01290         // See which way up it all is
01291         INT32 YExtent = MetaData.Header.bbox.top-MetaFileOrigin.y;
01292         if (YExtent < 0)
01293             IsYExtentNegative = TRUE;
01294 
01295         // adjust the origin if needed
01296         if (MetaFileOrigin.y > MetaData.Header.bbox.top)
01297             YShift = -YExtent;
01298 
01299         // Scaling factor is defined in units per inch
01300         // Convert to millipoints: (n / units per inch) * 72000
01301         Dpi = MetaData.Header.inch;
01302         ScaleFactor = (72000 / MetaData.Header.inch);
01303 
01304         TRACEUSER( "Jonathan", _T("Placable metafile -\n  (%ld, %ld) %ld\n"), MetaFileOrigin.x, MetaFileOrigin.y, ScaleFactor);
01305         TRACEUSER( "Jonathan", _T("Bbox (%ld, %ld)\n     (%ld, %ld)\n"), MetaData.Header.bbox.left, MetaData.Header.bbox.bottom, MetaData.Header.bbox.right, MetaData.Header.bbox.top);
01306         TRACEUSER( "Jonathan", _T("Is Negative %d\n"), IsYExtentNegative);
01307     }
01308     else
01309     {
01310         // Sensible default values for non-placeable metafiles.
01311         MetaFileOrigin.x = 0;
01312         MetaFileOrigin.y = 0;
01313         ScaleFactor = 72000 / 96;
01314         FlipYCoords = FALSE;
01315         YShift = 0;
01316         
01317         // By default windows has the 0,0 at the top left, we have it at the bottom left
01318         IsYExtentNegative = TRUE;
01319         Dpi = 96;
01320         TRACEUSER( "Jonathan", _T("Non-Placable metafile -\n  Origin (%ld, %ld) ScaleFactor %ld\n"), MetaFileOrigin.x, MetaFileOrigin.y, ScaleFactor);
01321         TRACEUSER( "Jonathan", _T("Is Negative %d\n"), IsYExtentNegative);
01322     }
01323 
01324     // Find out the size of the file, in bytes.
01325     FileSize = GetMetaFileBitsEx(MetaFile, 0, NULL);
01326     if (FileSize == 0)
01327     {
01328         if (IsUserName("Rik"))
01329             TRACE( _T("Couldn't take size of the MetaFile\n"));
01330         ERROR(_R(IDT_IMPORT_NOTFOUND), FALSE);
01331     }
01332 
01333     // Create a device context for our metafile
01334     MetaFileDC = CreateMetaFile(NULL);
01335     if (MetaFileDC == NULL)
01336     {
01337         return FALSE;
01338     }
01339 
01340     // Set the progress indicator, this next bit might take a while.
01341     String_64 ImportMessage(_R(IDT_IMPORTMSG_METAFILE));
01342     ImportMessage = GetImportProgressString(pDiskFile, _R(IDT_IMPORTMSG_METAFILE));
01343     BeginSlowJob(FileSize, TRUE, &ImportMessage);
01344 
01345     // Process the metafile by enumerating it via GDI
01346     BOOL Worked = ::EnumMetaFile(MetaFileDC, MetaFile, DecodeMetaFile, (LPARAM) this);
01347 
01348     EndSlowJob();
01349 
01350     return Worked;
01351 }

BOOL MetaFileFilter::PrepareToExport CCLexFile ,
Spread pSpread
[protected, virtual]
 

Definition at line 3746 of file metafilt.cpp.

03747 {
03748     // the member variable OutputFile is deliberately a vanilla CCLexFile because
03749     // metafile output must be made to work to all file types, especially memory files
03750     OutputFile = pFile;
03751 
03752     // work out the clip rect by exporting the whole drawing
03753     // Start out with an empty clip rect
03754     DocRect SpreadRect;
03755     SpreadRect.MakeEmpty();
03756 
03757     // We need to take into account the fact that some layers may not be visible
03758     Node* pNode = pSpread->FindFirstChild();
03759     while (pNode!=NULL)
03760     {
03761         // See if this is a layer
03762         if (IS_A(pNode, Layer))
03763         {
03764             // It sure is... lets see if it is visible
03765             Layer* pLayer = (Layer*) pNode;
03766             if (pLayer->IsVisible())
03767             {
03768                 // This one is visible, so union it in
03769                 DocRect LayerRect = pLayer->GetBoundingRect();
03770                 SpreadRect = SpreadRect.Union(LayerRect);
03771             }
03772         }
03773 
03774         // Get the next sibling
03775         pNode = pNode->FindNext();
03776     }
03777 
03778     // Set the clip rect
03779     DocRect ClipRect = SpreadRect;
03780     ExportClipRect = SpreadRect;
03781 
03782     // we need a View to Attach to, so that:
03783     //      default Quality setting
03784     //      CalcPixelWidth etc get called
03785     //View *pView = View::GetCurrent();
03786     pMetaView = new MetafileView();
03787     if (pMetaView==NULL)
03788         return FALSE;
03789 
03790     // Init the view
03791     if (!pMetaView->Init())
03792     {
03793         delete pMetaView;
03794         pMetaView = NULL;
03795         return FALSE;
03796     }
03797 
03798     // now lets get a render region suitably contructed
03799     FIXED16 XScale, YScale;
03800     pMetaView->GetScaleFactor(&XScale, &YScale);
03801     Matrix Identity(XScale, YScale);
03802 
03803     // Don't use view scale; set to 1
03804     FIXED16 Scale(1);
03805 
03806     // Create the region
03807     ExportRegion = OSRenderRegion::Create(ClipRect, Identity, Scale, RENDERTYPE_METAFILE16, pMetaView, TRUE );
03808     if (ExportRegion == NULL)
03809         // Error already set by new, so just return
03810         return FALSE;
03811 
03812     // lets create a metafile DC now
03813     if (!MetafileDC.Create( NULL ))                                 // create it in memory
03814         ERROR1( FALSE, _R(IDE_MF_NOCREATE) );
03815 
03816     // need a refernce DC - don't just use the view window because it will get messed up
03817     // We use a fresh new screen DC
03818     if (!ReferenceDC.CreateIC( "DISPLAY", NULL, NULL, NULL ))
03819         ERROR1( FALSE, _R(IDE_MF_NOCREATE) );
03820 
03821     // if we don't do this then a load of Getxxx calls will fail
03822     MetafileDC.SetAttribDC( ReferenceDC.m_hDC );
03823 
03824     // this (i) stops paper etc from being rendered, and (ii) stops background rendering screwing us up
03825     MetafileDC.m_bPrinting = TRUE;
03826 
03827     // Attach to the right device
03828     return ExportRegion->AttachDevice(pMetaView, &MetafileDC, pSpread);
03829 }

BOOL MetaFileFilter::PrepareToImport  )  [protected]
 

Sets up the MetaFile filter so it can read in a metafile.

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

Errors: None

Definition at line 1133 of file metafilt.cpp.

01134 {
01135     // Not attached to a metafile
01136     ENSURE(MetaFile == NULL, "PrepareToImport: still attached to a metafile!");
01137     MetaFile = NULL;
01138     ENSURE(MetaFileDC == NULL, "PrepareToImport: still attached to a metafile DC!");
01139     MetaFileDC = NULL;
01140 
01141     // Get some attributes
01142     if (!SetUpCurrentAttrs())
01143         return FALSE;
01144 
01145     // Get a handle table
01146     ENSURE(Handles == NULL, "PrepareToImport: still got a handle table!");
01147     Handles = new HandleTable(this);
01148     if (Handles==NULL)
01149         // Error state already set by new
01150         return FALSE;
01151 
01152     // For progress cursor update.
01153     FileSize = 0;
01154     BytesRead = 0;
01155 
01156     // Prepare pseudo-graphics mode
01157     CurrentMappingMode = MM_TEXT;
01158     MetaFileOrigin.x = 0;
01159     MetaFileOrigin.y = 0;
01160 
01161     // Default to Black text
01162     TextColour = DocColour(0,0,0);
01163 
01164     return TRUE;
01165 }

void MetaFileFilter::ScaleCoord DocCoord C  )  [protected]
 

Definition at line 3423 of file metafilt.cpp.

03424 {
03425     // Scale the coordinates
03426     if (Placeable)
03427     {
03428         // Scale the X Coord
03429         C->x *= ScaleFactor;
03430         C->y *= ScaleFactor;
03431     }
03432     else
03433     {
03434         switch (CurrentMappingMode)
03435         {
03436             case MM_TEXT:
03437                 // Scale is in pixels
03438                 // Convert to millipoints
03439                 C->x *= ScaleFactor;
03440                 C->y *= ScaleFactor;
03441                 break;
03442 
03443             case MM_LOMETRIC:
03444                 // Scale of 0.1mm per unit
03445                 // Convert to millipoints: n * (72000 / (10 * 25.4))
03446                 C->x *= (72000 / 254);
03447                 C->y *= (72000 / 254);
03448                 break;
03449 
03450             case MM_HIMETRIC:
03451                 // Scale of 0.01mm per unit
03452                 // Convert to millipoints: n * (72000 / (100 * 25.4))
03453                 C->x *= (72000 / 2540);
03454                 C->y *= (72000 / 2540);
03455                 break;
03456 
03457             case MM_LOENGLISH:
03458                 // Scale of 0.01 inches per unit
03459                 // Convert to millipoints: (n / 100) * 72000
03460                 C->x *= (72000 / 100);
03461                 C->y *= (72000 / 100);
03462                 break;
03463 
03464             case MM_HIENGLISH:
03465                 // Scale of 0.001 inches per unit
03466                 // Convert to millipoints: (n / 1000) * 72000
03467                 C->x *= (72000 / 1000);
03468                 C->y *= (72000 / 1000);
03469                 break;
03470 
03471             case MM_TWIPS:
03472                 // Scale of 1/1440th of an inch per unit
03473                 // Convert to millipoints: (n / 1440) * 72000
03474                 C->x *= (72000 / 1440);
03475                 C->y *= (72000 / 1440);
03476                 break;
03477 
03478             //case MM_ISOTROPIC:
03479             //  ENSURE(FALSE, "Can't cope with ISOTROPIC mapping in metafiles!");
03480             //  break;
03481 
03482             //case MM_ANISOTROPIC:
03483             //  ENSURE(FALSE, "Can't cope with ANISOTROPIC mapping in metafiles!");
03484             //  break;
03485 
03486             default:
03487                 C->x *= ScaleFactor;
03488                 C->y *= ScaleFactor;
03489                 break;
03490         }
03491     }
03492 
03493     // Scale the Y Coord
03494     if (FlipYCoords)
03495         C->y = -C->y;
03496 }

void MetaFileFilter::SetLogicalFont LOGFONT_16 *  pNewFont  ) 
 

Makes a note of the selected font ready for when it is used.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/5/95
Parameters:
pNewFont - the details about the newly selected font [INPUTS]

Definition at line 2846 of file metafilt.cpp.

02847 {
02848     // record the font
02849     // Copy the values from the 16 bit version to the 32 bit version
02850     SelectedFont.lfHeight = pNewFont->lfHeight;
02851     SelectedFont.lfWidth = pNewFont->lfWidth;
02852     SelectedFont.lfEscapement = pNewFont->lfEscapement;
02853     SelectedFont.lfOrientation = pNewFont->lfOrientation;
02854     SelectedFont.lfWeight = pNewFont->lfWeight;
02855     SelectedFont.lfItalic = pNewFont->lfItalic;
02856     SelectedFont.lfUnderline = pNewFont->lfUnderline;
02857     SelectedFont.lfStrikeOut = pNewFont->lfStrikeOut;
02858     SelectedFont.lfCharSet = pNewFont->lfCharSet;
02859     SelectedFont.lfOutPrecision = pNewFont->lfOutPrecision;
02860     SelectedFont.lfClipPrecision = pNewFont->lfClipPrecision;
02861     SelectedFont.lfQuality = pNewFont->lfQuality;
02862     SelectedFont.lfPitchAndFamily = pNewFont->lfPitchAndFamily;
02863     camStrcpy(SelectedFont.lfFaceName, pNewFont->lfFaceName);
02864 
02865     // Scale the text size according to the current mapping mode.
02866     switch (CurrentMappingMode)
02867     {
02868         case MM_TEXT:
02869             // Scale is in pixels
02870             SelectedFont.lfHeight = (SelectedFont.lfHeight * 96) / Dpi;
02871             SelectedFont.lfWidth = (SelectedFont.lfWidth * 96) / Dpi;
02872             break;
02873 
02874         case MM_LOMETRIC:
02875             // Scale of 0.1mm per unit
02876             // Convert to 96 dpi
02877             SelectedFont.lfHeight = (SelectedFont.lfHeight * 96) / 254;
02878             SelectedFont.lfWidth = (SelectedFont.lfWidth * 96) / 254;
02879             break;
02880 
02881         case MM_HIMETRIC:
02882             // Scale of 0.01mm per unit
02883             // Convert to millipoints: n * (72000 / (100 * 25.4))
02884             SelectedFont.lfHeight = (SelectedFont.lfHeight * 96) / 2540;
02885             SelectedFont.lfWidth = (SelectedFont.lfWidth * 96) / 2540;
02886             break;
02887 
02888         case MM_LOENGLISH:
02889             // Scale of 0.01 inches per unit
02890             // Convert to millipoints: (n / 100) * 72000
02891             SelectedFont.lfHeight = (SelectedFont.lfHeight * 96) / 100;
02892             SelectedFont.lfWidth = (SelectedFont.lfWidth * 96) / 100;
02893             break;
02894 
02895         case MM_HIENGLISH:
02896             // Scale of 0.001 inches per unit
02897             // Convert to millipoints: (n / 1000) * 72000
02898             SelectedFont.lfHeight = (SelectedFont.lfHeight * 96) / 1000;
02899             SelectedFont.lfWidth = (SelectedFont.lfWidth * 96) / 1000;
02900             break;
02901 
02902         case MM_TWIPS:
02903             // Scale of 1/1440th of an inch per unit
02904             // Convert to millipoints: (n / 1440) * 72000
02905             SelectedFont.lfHeight = (SelectedFont.lfHeight * 96) / 1440;
02906             SelectedFont.lfWidth = (SelectedFont.lfWidth * 96) / 1440;
02907             break;
02908 
02909         default:
02910             SelectedFont.lfHeight = (SelectedFont.lfHeight * 96) / Dpi;
02911             SelectedFont.lfWidth = (SelectedFont.lfWidth * 96) / Dpi;
02912             break;
02913     }
02914 }

void MetaFileFilter::TransformCoord DocCoord C  )  [protected]
 

Definition at line 3398 of file metafilt.cpp.

03399 {
03400     // Convert from metafile origin
03401     C->x -= MetaFileOrigin.x;
03402     C->y -= MetaFileOrigin.y;
03403 
03404     // Add in any offset that may be needed
03405     C->y += YShift;
03406 
03407     // Scale it
03408     ScaleCoord(C);
03409 }

BOOL MetaFileFilter::WriteToFile HMETAFILE  ,
METAFILEHEADER * 
[protected, virtual]
 

Definition at line 3879 of file metafilt.cpp.

03880 {
03881     // write header first
03882     OutputFile->write( PlaceableHeader, sizeof(METAFILEHEADER) );
03883 
03884     // now the actual data
03885     UINT32 size = GetMetaFileBitsEx( hMetafile, 0, NULL );          // does NOT invalidate hMetafile
03886     ERROR1IF( size==0, FALSE, _R(IDE_MF_NOMEMLOCK) );
03887 
03888     LPVOID block = CCMalloc( size );
03889     ERROR1IF( block==NULL, FALSE, _R(IDS_OUT_OF_MEMORY) );
03890 
03891     size = GetMetaFileBitsEx( hMetafile, size, block );
03892     if (size)
03893     {
03894         OutputFile->write( block, size );
03895         CCFree( block );
03896         return TRUE;
03897     }
03898     else
03899     {
03900         CCFree( block );
03901         ERROR1( FALSE, _R(IDE_MF_NOMEMLOCK) );
03902     }
03903 }


Friends And Related Function Documentation

friend class MetaFileClipMap [friend]
 

Definition at line 237 of file metafilt.h.


Member Data Documentation

BOOL MetaFileFilter::AllUnderstood [protected]
 

Definition at line 368 of file metafilt.h.

INT32 MetaFileFilter::BytesRead [protected]
 

Definition at line 354 of file metafilt.h.

INT32 MetaFileFilter::CurrentMappingMode [protected]
 

Definition at line 319 of file metafilt.h.

DocCoord MetaFileFilter::CurrentPoint [protected]
 

Definition at line 365 of file metafilt.h.

INT32 MetaFileFilter::Dpi [protected]
 

Definition at line 362 of file metafilt.h.

DocRect MetaFileFilter::ExportClipRect [protected]
 

Definition at line 381 of file metafilt.h.

RenderRegion* MetaFileFilter::ExportRegion [protected]
 

Definition at line 380 of file metafilt.h.

INT32 MetaFileFilter::FileSize [protected]
 

Definition at line 353 of file metafilt.h.

BOOL MetaFileFilter::FlipYCoords [protected]
 

Definition at line 321 of file metafilt.h.

HandleTable* MetaFileFilter::Handles [protected]
 

Definition at line 347 of file metafilt.h.

friend MetaFileFilter::HandleTable [protected]
 

Definition at line 350 of file metafilt.h.

CImportInfo MetaFileFilter::ImportInfo [protected]
 

Definition at line 340 of file metafilt.h.

HFILE MetaFileFilter::InFile [private]
 

Definition at line 392 of file metafilt.h.

BOOL MetaFileFilter::IsYExtentNegative [protected]
 

Definition at line 322 of file metafilt.h.

INT32 MetaFileFilter::LastProgressUpdate [protected]
 

Definition at line 354 of file metafilt.h.

HMETAFILE MetaFileFilter::MetaFile [protected]
 

Definition at line 271 of file metafilt.h.

CMetaFileDC MetaFileFilter::MetafileDC [protected]
 

Definition at line 379 of file metafilt.h.

HDC MetaFileFilter::MetaFileDC [protected]
 

Definition at line 272 of file metafilt.h.

DocCoord MetaFileFilter::MetaFileOrigin [protected]
 

Definition at line 320 of file metafilt.h.

CCLexFile* MetaFileFilter::OutputFile [protected]
 

Definition at line 377 of file metafilt.h.

BOOL MetaFileFilter::Placeable [protected]
 

Definition at line 358 of file metafilt.h.

Node* MetaFileFilter::pLastInsertedNode [private]
 

Definition at line 385 of file metafilt.h.

Layer* MetaFileFilter::pLayer [protected]
 

Definition at line 326 of file metafilt.h.

MetafileView* MetaFileFilter::pMetaView [protected]
 

Definition at line 382 of file metafilt.h.

Node* MetaFileFilter::pNode [protected]
 

Definition at line 329 of file metafilt.h.

CDC MetaFileFilter::ReferenceDC [protected]
 

Definition at line 378 of file metafilt.h.

MILLIPOINT MetaFileFilter::ScaleFactor [protected]
 

Definition at line 361 of file metafilt.h.

LOGFONT MetaFileFilter::SelectedFont [protected]
 

Definition at line 310 of file metafilt.h.

DocColour MetaFileFilter::TextColour [protected]
 

Definition at line 344 of file metafilt.h.

INT32 MetaFileFilter::YShift [protected]
 

Definition at line 323 of file metafilt.h.


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