CMXExportDC Class Reference

Export device context for CMX files. More...

#include <cmxexdc.h>

Inheritance diagram for CMXExportDC:

ExportDC KernelDC CCDummyDC CCDC ListItem CCObject SimpleCCObject List of all members.

Public Types

enum  CMXSectionType {
  CMXSECTION_NONE, CMXSECTION_HEADER, CMXSECTION_PAGE, CMXSECTION_REFLIST,
  CMXSECTION_INDEX, CMXSECTION_ARROW, CMXSECTION_ARROWHEADS, CMXSECTION_COLOUR,
  CMXSECTION_DOTDASH, CMXSECTION_FONT, CMXSECTION_IMAGE, CMXSECTION_OUTLINE,
  CMXSECTION_LINESTYLE, CMXSECTION_PEN, CMXSECTION_LENS, CMXSECTION_SCREEN,
  CMXSECTION_TRAILER, CMXSECTION_IMAGINFO, CMXSECTION_IMAGDATA, CMXSECTION_PROCBITFILL,
  CMXSECTION_PREVIEWBITMAP
}
enum  CMXBitmapColourSource { CMXBITMAPCOLOURSOURCE_NONE, CMXBITMAPCOLOURSOURCE_LINEANDFILL, CMXBITMAPCOLOURSOURCE_FILLGEOMETRY }

Public Member Functions

 CMXExportDC (Filter *)
 Initialise a DC for exporting EPS.
BOOL Init (CCLexFile *, CMXRenderRegion *pReg, BOOL bThirtyTwoBit, BOOL ClipboardExport)
 Calls the base class Init function and then sets up the DC to throw exceptions when it gets errors as that is how the EPS stuff expects errors to be reported.
BOOL StartSection (CMXSectionType Type)
 Start writing a section to a CMX file.
BOOL EndSection (void)
 Finish off writing a section to a CMX file.
BOOL StartRIFFList (INT32 Type)
 Start writing a section to a CMX file.
BOOL EndRIFFList (void)
 Finish off writing a section to a CMX file.
BOOL CreateHeader (DocRect *pFileBBox)
 Write the file's header, and name notes of the location of things like the relevant sizes and indices and other stuff which can only be written after the export.
BOOL PolishOffThatFile (void)
 Finish off the file, update indexes and all that.
BOOL WriteNumber (INT32 Position, UINT32 DataSize, INT32 Value)
 Finish off the file, update indexes and all that.
BOOL WriteBBox (DocRect *BBox, BOOL Transform=TRUE)
 Write a bounding box to the file.
BOOL WriteString (StringBase *Str)
 Write a bounding box to the file.
void CleanUp (void)
 Cleans up after writing to a file.
BOOL WriteReferenceList (void)
 writes the reference list for the page we've just done
BOOL WriteData (void *data, INT32 Size)
void WriteByte (BYTE Thing)
BOOL WriteIndex (void)
 writes the index for the file
BOOL WriteAnIndex (INT32 Which)
 writes the a particular index to the file
BOOL WriteADesc (INT32 Which)
 writes the a particular index to the file
BOOL WriteDescriptionSections (void)
BOOL WriteMatrix (Matrix *pMatrix=NULL)
 writes a matrix to the file
INT32 GetGroupCount (void)
void WriteAngle (double theta)
 writes an angle to the file
BOOL WriteReferSections (void)
 gets all refer list items which are sections to write themselves
void WriteSizeInFile (WORD Size)
BOOL WriteCamComment (void)
 writes a helpful comment so we can see where dodgy cam cmx files come from
BOOL WritePreviewBitmap (void)
 writes a preview bitmap type thing
void SetTransMatrix (Matrix *pM)
MatrixGetTransMatrix (void)
INT32 GetFilePosition ()
 returns the position of the current file pointer in the export file
BOOL IsThirtyTwoBit ()
INT32 GetFirstInstrFilePosition (void)
INT32 GetCurrentInstrFilePosition (void)
INT32 GetRefListOffset (void)
INT32 GetInstructionTally (void)
WORD GetLayerNumber (void)
CMXRenderRegionGetRenderRegion (void)
double GetScaleFactor (void)
void SetInfo (Operation *op, PathName *ptPath, Document *ptDoc)
BOOL StartPage (DocRect *BBox, BOOL IsProcedure=FALSE)
 starts a Page
BOOL EndPage (void)
 ends a Page
BOOL StartLayer (String_256 &Name)
 starts a layer
BOOL EndLayer (void)
 ends a layer
BOOL StartGroup (DocRect *BBox, BOOL TransformBBox=TRUE)
 starts a group
BOOL EndGroup (void)
 ends a group
void SetCMXFlag (INT32 flag)
 sets a flag for pages, layers
BOOL WriteCommand (UINT32 Tag, void *Data=0, UINT32 Size=0)
 Write a command to the file -- one off operation, writes command and data in one go. Use default params for a no-data command.
BOOL StartCommand (UINT32 Tag)
 starts writing a command for a command where the data is of indetermant size. Use EndCommand to finish it off
BOOL EndCommand (void)
 ends a command
BOOL WriteTag (INT32 Tag, void *Data=0, UINT32 Size=0)
BOOL StartTag (INT32 Tag)
 starts writing a tag to the file
BOOL EndTag (void)
 ends a tag
BOOL StartNestedTag (INT32 Tag)
 starts writing a nested tag to the file
BOOL EndNestedTag (void)
 ends a nested tag
BOOL WriteNestedTag (INT32 Tag, void *Data=0, UINT32 Size=0)
BOOL WriteMinEndTag (void)
BOOL WriteAttributes (CMXRenderRegion *pReg, INT32 Tag, DocCoord *Coords, INT32 NumCoords, BOOL ForceNoFill=FALSE)
 Writes the attributes to the DC. if ForceNoFill == TRUE, the path will not be filled whatever the colour.
BOOL WriteBlankAttributes (INT32 Tag)
 writes a blank attribute tag and contents, which specifies nothing but keeps everything happy
BOOL WriteAttrCheckLens (CMXRenderRegion *pReg, INT32 Tag, DocCoord *Coords, INT32 NumCoords, BOOL *WasLens)
 checks to see if this object should be outputed as a lens. If so, we need to output the attributes for it ourselves (as we can't use the full range of possible things) and add things to the list
BOOL WriteAttrCheckIgnoreLens (CMXRenderRegion *pReg, DocCoord *Coords, INT32 NumCoords)
 checks to see if we should ignore this lens -- it sees if it's going to overlap with too many lenses. This is basically as bodge as CorelDRAW will just fall over if we export a file with lots of overlapped lenses in it.
BOOL WriteOutlineSpec (CMXRenderRegion *pReg)
 writes the outline specification to the file
BOOL WriteFillSpec (CMXRenderRegion *pReg, DocCoord *Coords, INT32 NumCoords, BOOL NoFill)
 Writes the fill specifcation to the DC.
BOOL WriteFillType (WORD FillID)
 Writes the fill type to the DC.
BOOL WriteFillSpecFlat (CMXRenderRegion *pReg, FillGeometryAttribute *pAttr)
 Writes the flat fill specifcation to the DC.
BOOL WriteFillSpecGrad (CMXRenderRegion *pReg, FillGeometryAttribute *pAttr, DocCoord *Coords, INT32 NumCoords)
 Writes the grad fill specifcation to the DC.
BOOL WriteFillSpecBitmap (CMXRenderRegion *pReg, FillGeometryAttribute *pAttr, DocCoord *Coords, INT32 NumCoords)
 Writes the bitmap fill specifcation to the DC (also does fractals).
WORD GetColourReference (DocColour *pTheLovelyColour)
 to find a reference number for the colour when writing a CMX file
WORD GetBitmapReference (KernelBitmap *pTheLovelyBitmap, DocColour *pStartCol, DocColour *pEndCol, EFFECTTYPE Effect, CMXReferBitmap **ppRB=NULL)
 to find a reference number for the bitmap when writing a CMX file. ppRB is set to a pointer to the CMXReferBitmap object if ppRB != 0
WORD GetProcedureReference (CMXReferListItem *pProc)
 checks to see if this object should be outputed as a lens. If so, we need to output the attributes for it ourselves (as we can't use the full range of possible things) and add things to the list
WORD GetArrowReference (ArrowRec *pArrow)
 to find a reference number for the arrow when writing a CMX file will return 0 (ie no arrowhead) if it isn't one
BOOL WritePath (DocCoord *Coords, PathVerb *Verbs, INT32 NumCoords, BOOL Filled)
 Writes a path instruction -- transformed by matrix.
BOOL WriteBitmap (KernelBitmap *pBitmap, DocCoord *pParallelogram, CMXBitmapColourSource ColSource=CMXBITMAPCOLOURSOURCE_NONE, BOOL TransformParallelogram=TRUE, WORD BitmapReference=0)
 writes a bitmap object to the file

Static Public Member Functions

static void CalcCorelBBox (DocCoord *Coords, INT32 NumCoords, DocRect *Result)
 calculates the corel bounding box of a path. This is just a simple union of all point. The result is not transformed by the export transform matrix.
static double Round (double ToRound)
 Rounds a value up or down to the nearest integer.

Protected Member Functions

 DoWriteTag (INT32 Tag, void *Data=0, UINT32 Size=0, BOOL Nested=FALSE)
 writes a tag in one go
BOOL WriteFutureDataCache ()
 Write the Numbers from the cache to the file See also:.

Private Attributes

CMXRenderRegionpRenderRegion
CMXSectionType CurrentSection
CMXFutureLength SectionLengthFuture
BOOL ThirtyTwoBit
CMXFutureLength FileLengthFuture
CMXFutureNumber Tally
CMXFutureIndex PageEndIndexFuture
CMXFutureNumber PageInstructionCount
CMXFutureNumber PageGroupCount
CMXFutureNumber PageFlags
CMXFutureNumber LayerInstructionCount
CMXFutureNumber LayerFlags
CMXFutureLength CommandLengthFuture
CMXFutureIndex IndexSectionFuture
CMXFutureIndex TrailerIndexFuture
CMXFutureIndex ThumbnailIndexFuture
CMXFutureLength TagLengthFuture
CMXFutureLength RIFFListLengthFuture
BOOL DoingCommand
BOOL DoingPage
BOOL DoingLayer
BOOL DoingTag
WORD LayerNumber
BOOL DoingRIFFList
BOOL PageIsProc
INT32 NestedTagLevel
List NestedTagList
List ReferList
CMXReferPagePageRefer
INT32 RefListOffset
List GroupList
MatrixpMatrix
INT32 FirstInstrFilePosition
INT32 CurrentInstrFilePosition
INT32 NumberOfEntriesUsedInCache
CMXFutureDataCacheEntry FutureDataCache [128]
double ScaleFactor
List LensBBoxes
BOOL OverlappedLensesHaveBeenIgnored
BOOL AreIgnoreingOverlappedLenses
BOOL HaveAskedUserAboutLenses
DocumentTheDocument
OperationpOp
PathNamepPath

Classes

struct  CMXFutureDataCacheEntry

Detailed Description

Export device context for CMX files.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/6/96
See also:
ExportDC

Definition at line 232 of file cmxexdc.h.


Member Enumeration Documentation

enum CMXExportDC::CMXBitmapColourSource
 

Enumerator:
CMXBITMAPCOLOURSOURCE_NONE 
CMXBITMAPCOLOURSOURCE_LINEANDFILL 
CMXBITMAPCOLOURSOURCE_FILLGEOMETRY 

Definition at line 362 of file cmxexdc.h.

enum CMXExportDC::CMXSectionType
 

Enumerator:
CMXSECTION_NONE 
CMXSECTION_HEADER 
CMXSECTION_PAGE 
CMXSECTION_REFLIST 
CMXSECTION_INDEX 
CMXSECTION_ARROW 
CMXSECTION_ARROWHEADS 
CMXSECTION_COLOUR 
CMXSECTION_DOTDASH 
CMXSECTION_FONT 
CMXSECTION_IMAGE 
CMXSECTION_OUTLINE 
CMXSECTION_LINESTYLE 
CMXSECTION_PEN 
CMXSECTION_LENS 
CMXSECTION_SCREEN 
CMXSECTION_TRAILER 
CMXSECTION_IMAGINFO 
CMXSECTION_IMAGDATA 
CMXSECTION_PROCBITFILL 
CMXSECTION_PREVIEWBITMAP 

Definition at line 239 of file cmxexdc.h.


Constructor & Destructor Documentation

CMXExportDC::CMXExportDC Filter Parent  ) 
 

Initialise a DC for exporting EPS.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/6/96
Parameters:
The filter object associated with this export DC. [INPUTS]

Definition at line 792 of file cmxexdc.cpp.

00792                                        : ExportDC(Parent)
00793 {
00794 }


Member Function Documentation

void CMXExportDC::CalcCorelBBox DocCoord Coords,
INT32  NumCoords,
DocRect Result
[static]
 

calculates the corel bounding box of a path. This is just a simple union of all point. The result is not transformed by the export transform matrix.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/07/96
Parameters:
coords,num coords and output rec [INPUTS]
Returns:
-

Definition at line 1855 of file cmxdcobj.cpp.

01856 {
01857     ERROR3IF(Coords == NULL || NumCoords < 1, "dodgy coords");
01858 
01859     // write some sensible starting values
01860     Result->lo = Coords[0];
01861     Result->hi = Coords[0];
01862 
01863     // run through the rest
01864     for(INT32 l = 1; l < NumCoords; l++)
01865     {
01866         if(Result->lo.x > Coords[l].x) Result->lo.x = Coords[l].x;
01867         if(Result->lo.y > Coords[l].y) Result->lo.y = Coords[l].y;
01868         if(Result->hi.x < Coords[l].x) Result->hi.x = Coords[l].x;
01869         if(Result->hi.y < Coords[l].y) Result->hi.y = Coords[l].y;
01870     }
01871 
01872     // sorted
01873 }

void CMXExportDC::CleanUp void   ) 
 

Cleans up after writing to a file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/06/96
Parameters:
none [INPUTS]
Returns:
none
See also:

Definition at line 894 of file cmxexdc.cpp.

00895 {
00896     WriteFutureDataCache();
00897     ReferList.DeleteAll();
00898     LensBBoxes.DeleteAll();
00899 }

BOOL CMXExportDC::CreateHeader DocRect pFileBBox  ) 
 

Write the file's header, and name notes of the location of things like the relevant sizes and indices and other stuff which can only be written after the export.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/06/96
Parameters:
bounding box of file [INPUTS]
Returns:
success
This fn is called Create rather than Write because it's not finished off properly until the end of the file.
See also:

Definition at line 1412 of file cmxexdc.cpp.

01413 {
01414     ERROR2IF(pMatrix == NULL, FALSE, "No matrix yet");
01415 
01416     // first of all, think about the riff file header
01417     RIFFFile_Header rhdr;
01418     rhdr.CK.ckID = RIFFTYPE_RIFF;
01419     rhdr.CK.ckSize = 0;
01420     rhdr.FormType = cmxRIFFFORMTYPE_CMX;
01421 
01422     ExportFile->write(&rhdr, sizeof(rhdr));
01423 
01424     // set up the future length object
01425     FileLengthFuture.Init(this, FUTURE_BACKLOC(&rhdr, CK.ckSize), sizeof(rhdr.CK.ckSize));
01426     FileLengthFuture.SetLengthStartPos(this, /*-((INT32)sizeof(rhdr))*/ -(INT32)sizeof(DWORD));
01427 
01428     // start the CMX header section
01429     if(!StartSection(CMXSECTION_HEADER))
01430         return FALSE;
01431 
01432     // write the CMX header
01433     cmxHeader fhdr;
01434     memset(&fhdr, 0, sizeof(fhdr));         // set everything to zero
01435     camStrcpy((char *)fhdr.Id, cmxID);
01436     camStrcpy((char *)fhdr.OS, cmxOS);
01437     fhdr.ByteOrder = cmxBYTEORDER_INTEL | 0x30;
01438     if(ThirtyTwoBit)
01439     {
01440         fhdr.CoordSize = cmxCOORDSIZE_32 | 0x30;
01441         fhdr.Major = cmxMAJOR_32 | 0x30;
01442         fhdr.Factor = cmxFACTOR_32;
01443         fhdr.Unit = cmxUNIT_MILLIMETER;
01444     }
01445     else
01446     {
01447         fhdr.CoordSize = cmxCOORDSIZE_16 | 0x30;
01448         fhdr.Major = cmxMAJOR_16 | 0x30;
01449         fhdr.Factor = cmxFACTOR_16;
01450         fhdr.Unit = cmxUNIT_INCH;
01451     }
01452     fhdr.Minor = cmxMINOR | 0x30;
01453 
01454     // bounding box
01455     DocRect bb = *pFileBBox;
01456     pMatrix->TransformBounds(&bb);
01457 
01458     fhdr.IBBLeft    = bb.lo.x;
01459     fhdr.IBBTop     = bb.hi.y;
01460     fhdr.IBBRight   = bb.hi.x;
01461     fhdr.IBBBottom  = bb.lo.y;
01462     fhdr.IThumbnail = -1;
01463 
01464     ExportFile->write(&fhdr, sizeof(fhdr));
01465 
01466     // set up it's future value objects
01467     Tally.Init(this, FUTURE_BACKLOC(&fhdr, ITally), sizeof(fhdr.ITally));
01468     Tally = 0;
01469     IndexSectionFuture.Init(this, FUTURE_BACKLOC(&fhdr, IIndexSection), sizeof(fhdr.IIndexSection));
01470     TrailerIndexFuture.Init(this, FUTURE_BACKLOC(&fhdr, IInfoSection), sizeof(fhdr.IInfoSection));
01471     ThumbnailIndexFuture.Init(this, FUTURE_BACKLOC(&fhdr, IThumbnail), sizeof(fhdr.IThumbnail));
01472 
01473     // end the CMX header section
01474     if(!EndSection())
01475         return FALSE;
01476 
01477     return TRUE;
01478 }

BOOL CMXExportDC::DoWriteTag INT32  Tag,
void *  Data = 0,
UINT32  Size = 0,
BOOL  Nested = FALSE
[protected]
 

writes a tag in one go

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1245 of file cmxexdc.cpp.

01246 {
01247     if(!Nested)
01248     {
01249         ERROR2IF(DoingTag == TRUE, FALSE, "already doing a tag");
01250     }
01251 
01252     // if we're not doing a 32 bit file, we just want to export the data
01253     if(ThirtyTwoBit)
01254     {
01255         // write the tag header
01256         cmxTagHdr hdr;
01257         hdr.ID = (BYTE)Tag;
01258         hdr.Size = sizeof(hdr)+Size;
01259         ExportFile->write(&hdr, sizeof(hdr));
01260     }
01261 
01262     // write the data, if required
01263     if(Size != 0)
01264         ExportFile->write(Data, Size);
01265 
01266     return TRUE;
01267 }

BOOL CMXExportDC::EndCommand void   ) 
 

ends a command

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1373 of file cmxexdc.cpp.

01374 {
01375     ERROR2IF(DoingCommand != TRUE, FALSE, "Already writing a command");
01376 
01377     // word align the file
01378     if((GetFilePosition() & 1) != 0)
01379     {
01380         // put an extra byte in the file
01381         ExportFile->put('\0');
01382     }
01383 
01384     CommandLengthFuture.Write(this);
01385 
01386     DoingCommand = FALSE;
01387 
01388     CurrentInstrFilePosition = -1;
01389 
01390     return TRUE;
01391 }

BOOL CMXExportDC::EndGroup void   ) 
 

ends a group

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2203 of file cmxexdc.cpp.

02204 {
02205     // get the last entry off the group list
02206     CMXGroupRecord *pGRec = (CMXGroupRecord *)GroupList.GetTail();
02207 
02208     // get it to write itself
02209     if(!pGRec->Write(this))
02210         return FALSE;
02211 
02212     // delete the group record
02213     delete GroupList.RemoveTail();
02214 
02215     // write the end group command
02216     if(!WriteCommand(cmxINSTR_EndGroup))
02217         return FALSE;
02218 
02219     return TRUE;
02220 }

BOOL CMXExportDC::EndLayer void   ) 
 

ends a layer

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2114 of file cmxexdc.cpp.

02115 {
02116     ERROR2IF(DoingLayer == FALSE, FALSE, "Already doing a layer");
02117 
02118     // write the end layer command
02119     WriteCommand(cmxINSTR_EndLayer);
02120 
02121     // write the count of instructions in the layer
02122     LayerInstructionCount.Write(this);
02123     LayerFlags.Write(this);
02124 
02125     DoingLayer = FALSE;
02126 
02127     return TRUE;
02128 }

BOOL CMXExportDC::EndNestedTag void   ) 
 

ends a nested tag

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/07/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1205 of file cmxexdc.cpp.

01206 {
01207     if(!ThirtyTwoBit)
01208         return TRUE;        // 16 bit files don't have tags
01209 
01210     ERROR2IF(DoingTag == FALSE, FALSE, "not doing a tag");
01211     ERROR2IF(NestedTagLevel <= 0, FALSE, "not doing a nested tag");
01212 
01213     // get the last tag record
01214     CMXNestedTagRecord *pRec = (CMXNestedTagRecord *)NestedTagList.GetTail();
01215 
01216     // check it's OK
01217     ERROR2IF(!IS_A(pRec, CMXNestedTagRecord), FALSE, "tag record not a tag record");
01218 
01219     // write the length
01220     pRec->LengthFuture.Write(this);
01221 
01222     // delete the record
01223     delete NestedTagList.RemoveTail();
01224 
01225     // flag
01226     NestedTagLevel--;
01227 
01228     return TRUE;
01229 }

BOOL CMXExportDC::EndPage void   ) 
 

ends a Page

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1991 of file cmxexdc.cpp.

01992 {
01993     ERROR2IF(DoingPage == FALSE, FALSE, "Not doing a page");
01994 
01995     // write the index of the end page command
01996     PageEndIndexFuture.Write(this);
01997 
01998     // write the end page command
01999     if(!PageIsProc)
02000         WriteCommand(cmxINSTR_EndPage);
02001     else
02002         WriteCommand(cmxINSTR_EndSection);
02003 
02004     // write future values
02005     PageFlags.Write(this);
02006     PageInstructionCount.Write(this);
02007     PageGroupCount.Write(this);
02008 
02009     // finish the section
02010     if(!PageIsProc)
02011         EndSection();
02012 
02013     DoingPage = FALSE;
02014 
02015     return TRUE;
02016 }

BOOL CMXExportDC::EndRIFFList void   ) 
 

Finish off writing a section to a CMX file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/07/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1058 of file cmxexdc.cpp.

01059 {
01060     ERROR2IF(!DoingRIFFList, FALSE, "Tried to end a riff list which didn't exist");
01061 
01062     // write the length
01063     RIFFListLengthFuture.Write(this);
01064 
01065     // word align the file
01066     if((GetFilePosition() & 1) != 0)
01067     {
01068         // put an extra byte in the file
01069         ExportFile->put('\0');
01070     }
01071 
01072     // flag
01073     DoingRIFFList = FALSE;
01074 
01075     return TRUE;
01076 }

BOOL CMXExportDC::EndSection void   ) 
 

Finish off writing a section to a CMX file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 986 of file cmxexdc.cpp.

00987 {
00988     ERROR2IF(CurrentSection == CMXSECTION_NONE, FALSE, "Tried to end a section which didn't exist");
00989 
00990     // write the length
00991     SectionLengthFuture.Write(this);
00992 
00993     // set the section type to none
00994     CurrentSection = CMXSECTION_NONE;
00995 
00996     // word align the file
00997     if((GetFilePosition() & 1) != 0)
00998     {
00999         // put an extra byte in the file
01000         ExportFile->put('\0');
01001     }
01002 
01003     return TRUE;
01004 }

BOOL CMXExportDC::EndTag void   ) 
 

ends a tag

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1129 of file cmxexdc.cpp.

01130 {
01131     if(!ThirtyTwoBit)
01132         return TRUE;        // 16 bit files don't have tags
01133 
01134     ERROR2IF(DoingTag == FALSE, FALSE, "not doing a tag");
01135     ERROR2IF(NestedTagLevel != 0, FALSE, "tried to end a main tag when nested tags are active");
01136 
01137     // write the length
01138     TagLengthFuture.Write(this);
01139 
01140     // flag
01141     DoingTag = FALSE;
01142 
01143     return TRUE;
01144 }

WORD CMXExportDC::GetArrowReference ArrowRec pArrow  ) 
 

to find a reference number for the arrow when writing a CMX file will return 0 (ie no arrowhead) if it isn't one

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/07/96
Parameters:
colour [INPUTS]
Returns:
reference number of a colour

Definition at line 1201 of file cmxdcobj.cpp.

01202 {
01203     // check to see if the arrowrec is in fact an arrowhead
01204     if(pArrow->IsNullArrow())
01205         return 0;       // ie no arrow on here mate
01206 
01207     // the reference we need -- references count up from 1
01208     INT32 Ref = 0;
01209 
01210     // scan that list!
01211     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01212     while(pEn != 0)
01213     {
01214         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01215 
01216         if(pEn->IsInWhichDesc() == cmxDESC_ARROW)
01217         {
01218             Ref++;
01219 
01220             CMXReferArrow *pAr = (CMXReferArrow *)pEn;
01221             ERROR3IF(!pAr->IsKindOf(CC_RUNTIME_CLASS(CMXReferArrow)), "not an arrow, when it said it was");
01222             
01223             // is it this colour?
01224             if(pAr->AreYouThisArrow(pArrow))
01225             {
01226                 // yep. return the reference number
01227                 return Ref;
01228             }
01229         }
01230 
01231         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01232     }
01233 
01234     // we haven't got one... make a new one, set it up and add it to the list
01235     CMXReferArrow *pNewArrow = new CMXReferArrow(this);
01236     if(pNewArrow == 0)
01237         return 0;
01238 
01239     pNewArrow->Set(pArrow);
01240 
01241     ReferList.AddTail(pNewArrow);
01242 
01243     // return the next reference number, Ref is the ref of the last one in the list
01244     return (WORD)Ref + 1;
01245 }

WORD CMXExportDC::GetBitmapReference KernelBitmap pTheLovelyBitmap,
DocColour pStartCol,
DocColour pEndCol,
EFFECTTYPE  Effect,
CMXReferBitmap **  ppRB = NULL
 

to find a reference number for the bitmap when writing a CMX file. ppRB is set to a pointer to the CMXReferBitmap object if ppRB != 0

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/07/96
Parameters:
bitmap [INPUTS]
Returns:
refernce number of a bitmap

Definition at line 1261 of file cmxdcobj.cpp.

01263 {
01264     // the reference we need -- references count up from 1
01265     INT32 Ref = 0;
01266 
01267     // scan that list!
01268     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01269     while(pEn != 0)
01270     {
01271         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01272 
01273         if(pEn->IsInWhichIndex() == cmxINDEX_EMBEDFILE && IS_A(pEn, CMXReferBitmap))
01274         {
01275             Ref++;
01276 
01277             CMXReferBitmap *pBitty = (CMXReferBitmap *)pEn;
01278             
01279             // is it this bitmap?
01280             if(pBitty->AreYouThisBitmap(pTheLovelyBitmap, pStartCol, pEndCol, Effect))
01281             {
01282                 // yep. set bitmap object addr and return the reference number
01283                 if(ppRB != 0)
01284                     (*ppRB) = pBitty;
01285 
01286                 return Ref;
01287             }
01288         }
01289 
01290         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01291     }
01292 
01293     // we haven't got one... make a new one, set it up and add it to the list
01294     CMXReferBitmap *pNewRefBit = new CMXReferBitmap(this);
01295     if(pNewRefBit == 0)
01296         return 0;
01297 
01298     pNewRefBit->Set(pTheLovelyBitmap, pStartCol, pEndCol, Effect);
01299 
01300     ReferList.AddTail(pNewRefBit);
01301 
01302     // set bitmap object addr
01303     if(ppRB != 0)
01304         (*ppRB) = pNewRefBit;
01305 
01306     // return the next reference number, Ref is the ref of the last one in the list
01307     return (WORD)Ref + 1;
01308 }

WORD CMXExportDC::GetColourReference DocColour pTheLovelyColour  ) 
 

to find a reference number for the colour when writing a CMX file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/07/96
Parameters:
colour [INPUTS]
Returns:
refernce number of a colour

Definition at line 1140 of file cmxdcobj.cpp.

01141 {
01142     // algorithm:
01143     // scan the refer list to see if the colour is already there.
01144     // if it is, return it's index.
01145     // if it isn't add the colour to the refer list, and return the new index.
01146 
01147     // the reference we need -- references count up from 1
01148     INT32 Ref = 0;
01149 
01150     // scan that list!
01151     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01152     while(pEn != 0)
01153     {
01154         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01155 
01156         if(pEn->IsInWhichDesc() == cmxDESC_COLOUR)
01157         {
01158             Ref++;
01159 
01160             CMXReferColour *pLC = (CMXReferColour *)pEn;
01161             ERROR3IF(!pLC->IsKindOf(CC_RUNTIME_CLASS(CMXReferColour)), "not a refer colour, when it said it was");
01162             
01163             // is it this colour?
01164             if(pLC->AreYouThisColour(pTheLovelyColour))
01165             {
01166                 // yep. return the reference number
01167                 return Ref;
01168             }
01169         }
01170 
01171         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01172     }
01173 
01174     // we haven't got one... make a new one, set it up and add it to the list
01175     CMXReferColour *pNewRefCol = new CMXReferColour(this);
01176     if(pNewRefCol == 0)
01177         return 0;
01178 
01179     pNewRefCol->SetColour(pTheLovelyColour);
01180 
01181     ReferList.AddTail(pNewRefCol);
01182 
01183     // return the next reference number, Ref is the ref of the last one in the list
01184     return (WORD)Ref + 1;
01185 }

INT32 CMXExportDC::GetCurrentInstrFilePosition void   )  [inline]
 

Definition at line 310 of file cmxexdc.h.

00310 {return CurrentInstrFilePosition;};

INT32 CMXExportDC::GetFilePosition  ) 
 

returns the position of the current file pointer in the export file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1535 of file cmxexdc.cpp.

01536 {
01537     return ExportFile->tell();
01538 }

INT32 CMXExportDC::GetFirstInstrFilePosition void   )  [inline]
 

Definition at line 309 of file cmxexdc.h.

00309 {return FirstInstrFilePosition;};

INT32 CMXExportDC::GetGroupCount void   )  [inline]
 

Definition at line 289 of file cmxexdc.h.

00289 {return PageGroupCount;};

INT32 CMXExportDC::GetInstructionTally void   )  [inline]
 

Definition at line 312 of file cmxexdc.h.

00312 {return Tally;};

WORD CMXExportDC::GetLayerNumber void   )  [inline]
 

Definition at line 313 of file cmxexdc.h.

00313 {return LayerNumber;};

WORD CMXExportDC::GetProcedureReference CMXReferListItem pProc  ) 
 

checks to see if this object should be outputed as a lens. If so, we need to output the attributes for it ourselves (as we can't use the full range of possible things) and add things to the list

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/07/96
Parameters:
render region, tag, pointer to flag [INPUTS]
Returns:
error flag

Definition at line 1890 of file cmxdcobj.cpp.

01891 {
01892     ERROR3IF(!pProc->IsAProcedure(), "item is not a procedure");
01893 
01894     // scan the refer list for this item, counting procedures before it
01895     WORD Ref = 0;
01896     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01897     while(pEn != 0)
01898     {
01899         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01900 
01901         if(pEn->IsAProcedure())
01902         {
01903             // inc reference number
01904             Ref++;
01905 
01906             // is it this one?
01907             if(pEn == pProc)
01908                 return Ref;
01909         }
01910 
01911         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01912     }
01913 
01914     return 1;       // fairly OK default
01915 }

INT32 CMXExportDC::GetRefListOffset void   )  [inline]
 

Definition at line 311 of file cmxexdc.h.

00311 {return RefListOffset;};

CMXRenderRegion* CMXExportDC::GetRenderRegion void   )  [inline]
 

Definition at line 314 of file cmxexdc.h.

00314 {return pRenderRegion;};

double CMXExportDC::GetScaleFactor void   )  [inline]
 

Definition at line 315 of file cmxexdc.h.

00315 {return ScaleFactor;};

Matrix* CMXExportDC::GetTransMatrix void   )  [inline]
 

Definition at line 306 of file cmxexdc.h.

00306 {return pMatrix;};

BOOL CMXExportDC::Init CCLexFile pFile,
CMXRenderRegion pReg,
BOOL  bThirtyTwoBit,
BOOL  ClipboardExport
 

Calls the base class Init function and then sets up the DC to throw exceptions when it gets errors as that is how the EPS stuff expects errors to be reported.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/6/96
Parameters:
pFile - The file to attach to the DC [INPUTS]
Returns:
TRUE if all went well, FALSE if not
See also:
ExportDC::Init

Definition at line 812 of file cmxexdc.cpp.

00813 {
00814     // First get the base class to do its thing
00815     if (!ExportDC::Init(pFile)) return FALSE;
00816 
00817     // now do what I want done.
00818     // We want export files to throw exceptions, and not report errors.
00819     ExportFile->SetThrowExceptions(TRUE);
00820     ExportFile->SetReportErrors(FALSE);
00821 
00822     // set the bitness of the file
00823     ThirtyTwoBit = bThirtyTwoBit;
00824 
00825     // mark the fact that we've not actually doing a section at all
00826     CurrentSection = CMXSECTION_NONE;
00827 
00828     // set up a few more variables
00829     DoingCommand = FALSE;
00830     DoingPage = FALSE;
00831     DoingLayer = FALSE;
00832     PageRefer = NULL;
00833     DoingTag = FALSE;
00834     pMatrix = NULL;
00835     NestedTagLevel = 0;
00836     CurrentInstrFilePosition = -1;
00837     pRenderRegion = pReg;
00838     DoingRIFFList = FALSE;
00839     NumberOfEntriesUsedInCache = 0;
00840 
00841     // overlapped lenses flag
00842     if(!ClipboardExport)
00843     {
00844         // normal ask the user mode
00845         AreIgnoreingOverlappedLenses = FALSE;
00846         OverlappedLensesHaveBeenIgnored = FALSE;
00847         HaveAskedUserAboutLenses = FALSE;
00848     }
00849     else
00850     {
00851         // don't ask the user
00852         AreIgnoreingOverlappedLenses = TRUE;
00853         OverlappedLensesHaveBeenIgnored = FALSE;
00854         HaveAskedUserAboutLenses = TRUE;
00855     }
00856 
00857     for(INT32 i = 0 ; i < CMXFUTUREVALUECACHESIZE ; i++)
00858     {
00859         //  init the write-cache 
00860         FutureDataCache[i].Location = INT32_MAX;
00861         FutureDataCache[i].Data     = 0;
00862         FutureDataCache[i].DataSize = 0;
00863     }
00864 
00865     // pop in the default screen thingy
00866     CMXReferDefaultScreen *pDefScreen = new CMXReferDefaultScreen(this);
00867     if(pDefScreen == NULL) return FALSE;
00868 
00869     // and add it to the list
00870     ReferList.AddTail(pDefScreen);
00871 
00872     // pop in the default dot dash thingy
00873     CMXReferDefaultDotDash *pDefdd = new CMXReferDefaultDotDash(this);
00874     if(pDefdd == NULL) return FALSE;
00875 
00876     // and add it to the list
00877     ReferList.AddTail(pDefdd);
00878     return TRUE;
00879 }

BOOL CMXExportDC::IsThirtyTwoBit  )  [inline]
 

Definition at line 308 of file cmxexdc.h.

00308 {return ThirtyTwoBit;};

BOOL CMXExportDC::PolishOffThatFile void   ) 
 

Finish off the file, update indexes and all that.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1494 of file cmxexdc.cpp.

01495 {
01496     ERROR2IF(CurrentSection != CMXSECTION_NONE, FALSE, "Didn't end the section before ending the file");
01497 
01498 
01499     // write some future values
01500     if(!Tally.Write(this))
01501         return FALSE;
01502 
01503     // write the info section
01504     if(!TrailerIndexFuture.Write(this))
01505         return FALSE;
01506     if(!StartSection(CMXSECTION_TRAILER))
01507         return FALSE;
01508     if(!EndSection())
01509         return FALSE;
01510 
01511     // and pop the length in
01512     if(!FileLengthFuture.Write(this))
01513         return FALSE;
01514     
01515 
01516     WriteFutureDataCache(); 
01517 
01518 
01519     return TRUE;
01520 }

double CMXExportDC::Round double  ToRound  )  [static]
 

Rounds a value up or down to the nearest integer.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
8/5/00
Parameters:
ToRound - The value to be rounded up. [INPUTS]
Returns:
double - The rounded value.

Definition at line 3207 of file cmxexdc.cpp.

03208 {
03209     // Add 0.5 to the value, and floor it. This will return the nearest integer.
03210     return floor ( ToRound + 0.5 );
03211 }

void CMXExportDC::SetCMXFlag INT32  flag  ) 
 

sets a flag for pages, layers

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/07/96
Parameters:
none [INPUTS]
Returns:
none
See also:

Definition at line 2677 of file cmxexdc.cpp.

02678 {
02679     PageFlags = ((INT32)PageFlags) | flag;
02680     LayerFlags = ((INT32)LayerFlags) | flag;
02681 }

void CMXExportDC::SetInfo Operation op,
PathName ptPath,
Document ptDoc
[inline]
 

Definition at line 316 of file cmxexdc.h.

00316 {pOp = op, pPath = ptPath, TheDocument = ptDoc;};

void CMXExportDC::SetTransMatrix Matrix pM  )  [inline]
 

Definition at line 298 of file cmxexdc.h.

00299     {
00300         pMatrix = pM;
00301         FIXED16 sf;
00302         pMatrix->Decompose(&sf);
00303         ScaleFactor = sf.MakeDouble();
00304     };

BOOL CMXExportDC::StartCommand UINT32  Tag  ) 
 

starts writing a command for a command where the data is of indetermant size. Use EndCommand to finish it off

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:
WriteCommand -- use for one off commands

Definition at line 1334 of file cmxexdc.cpp.

01335 {
01336     ERROR2IF(DoingCommand != FALSE, FALSE, "Already writing a command");
01337 
01338     // record the start of the file
01339     CurrentInstrFilePosition = GetFilePosition();
01340 
01341     // write the header
01342     cmxInstrHdr hdr = {0, ThirtyTwoBit?Tag:(0 - (SWORD)Tag)};
01343     ExportFile->write(&hdr, sizeof(hdr));
01344 
01345     Tally++;
01346     PageInstructionCount++;
01347     LayerInstructionCount++;
01348 
01349     // set the future length
01350     CommandLengthFuture.Init(this, FUTURE_BACKLOC(&hdr, Size), sizeof(hdr.Size));
01351     CommandLengthFuture.SetLengthStartPos(this, 0 - (INT32)sizeof(hdr));
01352 
01353     // set whether we're doing a command
01354     DoingCommand = TRUE;
01355 
01356     return TRUE;
01357 }

BOOL CMXExportDC::StartGroup DocRect BBox,
BOOL  TransformBBox = TRUE
 

starts a group

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2145 of file cmxexdc.cpp.

02146 {
02147     ERROR2IF(DoingLayer == FALSE && !PageIsProc, FALSE, "Groups should be in layers");
02148     
02149     // increment the group count
02150     PageGroupCount++;
02151 
02152     // start the command
02153     if(!StartCommand(cmxINSTR_BeginGroup))
02154         return FALSE;
02155 
02156     // start the tag
02157     if(!StartTag(cmxTAG_BeginGroup_GroupSpecification))
02158         return FALSE;
02159 
02160     // write the bounding box
02161     if(!WriteBBox(BBox, TransformBBox))
02162         return FALSE;
02163 
02164     // get a group record object
02165     CMXGroupRecord *pGRec = new CMXGroupRecord(this);
02166     if(pGRec == NULL)
02167         return FALSE;
02168 
02169     // add the group record object to the list
02170     GroupList.AddTail(pGRec);
02171 
02172     // write a place holder data chunk
02173     cmxGroupInfo gi = {0,0,0};
02174     ExportFile->write(&gi, sizeof(gi));
02175 
02176     if(!EndTag())
02177         return FALSE;
02178 
02179     if(!WriteMinEndTag())
02180         return FALSE;
02181 
02182     // end the command
02183     if(!EndCommand())
02184         return FALSE;
02185 
02186     return TRUE;
02187 }

BOOL CMXExportDC::StartLayer String_256 Name  ) 
 

starts a layer

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
layer name [INPUTS]
Returns:
success
See also:

Definition at line 2032 of file cmxexdc.cpp.

02033 {
02034     ERROR2IF(DoingPage == FALSE, FALSE, "Layers should be in pages");
02035     ERROR2IF(DoingLayer == TRUE, FALSE, "Already doing a layer");
02036 
02037     LayerNumber++;
02038 
02039     // get a entry for this thingy in the reference list
02040     CMXReferLayer *pRL = new CMXReferLayer(this);
02041     if(pRL == NULL)
02042         return FALSE;
02043     pRL->SetLayerDetails(LayerNumber, &Name);
02044     ReferList.AddTail(pRL);             // add it to the list
02045 
02046     // start the command
02047     StartCommand(cmxINSTR_BeginLayer);
02048 
02049     // tag
02050     if(!StartTag(cmxTAG_BeginLayer_LayerSpecification))
02051         return FALSE;
02052 
02053     // write the first bit of the instruction
02054     cmxInstrLayer1 chdr1;
02055     chdr1.PageNumber = 1;
02056     chdr1.LayerNumber = (WORD)LayerNumber;
02057     chdr1.LayerFlags = 0;
02058     chdr1.InstructionCount = 0;
02059     ExportFile->write(&chdr1, sizeof(chdr1));
02060 
02061     // set up the instruciton count future
02062     LayerInstructionCount.Init(this, FUTURE_BACKLOC(&chdr1, InstructionCount), sizeof(chdr1.InstructionCount));
02063     LayerFlags.Init(this, FUTURE_BACKLOC(&chdr1, LayerFlags), sizeof(chdr1.LayerFlags));
02064     LayerFlags = 0;
02065 
02066     // write it's name out
02067     WriteString(&Name);
02068 
02069     // end the tag
02070     if(!EndTag())
02071         return FALSE;
02072 
02073     // write the second bit of the thingy
02074     if(!StartTag(cmxTAG_BeginLayer_Matrix))
02075         return FALSE;
02076     if(!WriteMatrix())
02077         return FALSE;
02078     if(!EndTag())
02079         return FALSE;
02080 
02081     // mapping mode...
02082     BYTE MapMode = 0;
02083     if(!WriteTag(cmxTAG_BeginLayer_MappingMode, &MapMode, sizeof(MapMode)))
02084         return FALSE;
02085     
02086     // end tag
02087     if(!WriteMinEndTag())
02088         return FALSE;
02089 
02090     // end the command
02091     EndCommand();
02092 
02093     LayerInstructionCount = 1;      // to include this one
02094 
02095     DoingLayer = TRUE;
02096 
02097     return TRUE;
02098 }

BOOL CMXExportDC::StartNestedTag INT32  Tag  ) 
 

starts writing a nested tag to the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/06/96
Parameters:
Tag for the command [INPUTS]
Returns:
success
See also:

Definition at line 1160 of file cmxexdc.cpp.

01161 {
01162     if(!ThirtyTwoBit)
01163         return TRUE;        // 16 bit files don't have tags
01164 
01165     ERROR2IF(DoingTag == FALSE, FALSE, "tried to start a nested tag outside a tag");
01166 
01167     // write the tag header
01168     cmxTagHdr hdr;
01169     hdr.ID = (BYTE)Tag;
01170     hdr.Size = 0;
01171     ExportFile->write(&hdr, sizeof(hdr));
01172 
01173     // get one of those nested tag record things
01174     CMXNestedTagRecord *pRec = new CMXNestedTagRecord;
01175     if(pRec == NULL)
01176         return FALSE;
01177 
01178     // initialise the future value
01179     pRec->LengthFuture.Init(this, FUTURE_BACKLOC(&hdr, Size), sizeof(hdr.Size));
01180     pRec->LengthFuture.SetLengthStartPos(this, 0-(INT32)sizeof(hdr));
01181 
01182     // add the record to the list
01183     NestedTagList.AddTail(pRec);
01184 
01185     // flag
01186     NestedTagLevel++;
01187 
01188     return TRUE;
01189 }

BOOL CMXExportDC::StartPage DocRect BBox,
BOOL  IsProcedure = FALSE
 

starts a Page

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1833 of file cmxexdc.cpp.

01834 {
01835     ERROR2IF(DoingPage == TRUE, FALSE, "Already doing a page");
01836 
01837     if(!IsProcedure)
01838     {
01840 
01841         // make the page reference object
01842         PageRefer = new CMXReferPage(this);
01843         if(PageRefer == NULL)
01844             return FALSE;
01845         ReferList.AddTail(PageRefer);
01846 
01847         // start the section
01848         StartSection(CMXSECTION_PAGE);
01849 
01850         // write the page start
01851         StartCommand(cmxINSTR_BeginPage);
01852 
01853         // tag this bit
01854         if(!StartTag(cmxTAG_BeginPage_PageSpecification))
01855             return FALSE;
01856 
01857         cmxInstrPage1 phdr1;
01858         phdr1.PageNumber = 1;
01859         phdr1.Flags = 0;
01860         ExportFile->write(&phdr1, sizeof(phdr1));
01861 
01862         // set the future flags value
01863         PageFlags.Init(this, FUTURE_BACKLOC(&phdr1, Flags), sizeof(phdr1.Flags));
01864         PageFlags = 0;
01865 
01866         // write the bbox, transforming the thing of course
01867         WriteBBox(BBox);
01868 
01869         // write the rest of the page command
01870         cmxInstrPage2 phdr2;
01871         phdr2.EndPageOffset = 0;
01872         phdr2.GroupCount = 0;
01873         phdr2.InstructionCount = 0;
01874         ExportFile->write(&phdr2, sizeof(phdr2));
01875 
01876         // set up some future values
01877         PageEndIndexFuture.Init(this, FUTURE_BACKLOC(&phdr2, EndPageOffset), sizeof(phdr2.EndPageOffset));
01878         PageGroupCount.Init(this, FUTURE_BACKLOC(&phdr2, GroupCount), sizeof(phdr2.GroupCount));
01879         PageGroupCount = 0;
01880         PageInstructionCount.Init(this, FUTURE_BACKLOC(&phdr2, InstructionCount), sizeof(phdr2.InstructionCount));
01881         PageInstructionCount = 1; // to include this instr
01882 
01883         // end the tag
01884         if(!EndTag())
01885             return FALSE;
01886 
01887         // matrix tag...
01888         if(!StartTag(cmxTAG_BeginPage_Matrix))
01889             return FALSE;
01890 
01891         // write the matrix
01892         if(!WriteMatrix())
01893             return FALSE;
01894 
01895         // end the tag
01896         if(!EndTag())
01897             return FALSE;
01898 
01899         // mapping mode...
01900         BYTE MapMode = 0;
01901         if(!WriteTag(cmxTAG_BeginPage_MappingMode, &MapMode, sizeof(MapMode)))
01902             return FALSE;
01903 
01904         // end tag
01905         if(!WriteMinEndTag())
01906             return FALSE;
01907 
01908         // end the command
01909         EndCommand();
01910 
01911         // flag
01912         PageIsProc = FALSE;
01913     }
01914     else
01915     {
01917 
01918         // write the procedure start
01919         StartCommand(cmxINSTR_BeginProcedure);
01920 
01921         // tag this bit
01922         if(!StartTag(cmxTAG_BeginProcedure_ProcedureSpecification))
01923             return FALSE;
01924 
01925         cmxInstrProc1 phdr1;
01926         phdr1.Flags = 0;
01927         ExportFile->write(&phdr1, sizeof(phdr1));
01928 
01929         // set the future flags value
01930         PageFlags.Init(this, FUTURE_BACKLOC(&phdr1, Flags), sizeof(phdr1.Flags));
01931         PageFlags = 0;
01932 
01933         // write the bbox, not transforming it as we've already done that
01934         WriteBBox(BBox, FALSE);
01935 
01936         // write the rest of the page command
01937         cmxInstrProc2 phdr2;
01938         phdr2.EndPageOffset = 0;
01939         phdr2.GroupCount = 0;
01940         phdr2.InstructionCount = 0;
01941         ExportFile->write(&phdr2, sizeof(phdr2));
01942 
01943         // set up some future values
01944         PageEndIndexFuture.Init(this, FUTURE_BACKLOC(&phdr2, EndPageOffset), sizeof(phdr2.EndPageOffset));
01945         PageGroupCount.Init(this, FUTURE_BACKLOC(&phdr2, GroupCount), sizeof(phdr2.GroupCount));
01946         PageGroupCount = 0;
01947         PageInstructionCount.Init(this, FUTURE_BACKLOC(&phdr2, InstructionCount), sizeof(phdr2.InstructionCount));
01948         PageInstructionCount = 1; // to include this instr
01949 
01950         // end the tag
01951         if(!EndTag())
01952             return FALSE;
01953 
01954         // end tag
01955         if(!WriteMinEndTag())
01956             return FALSE;
01957 
01958         // end the command
01959         EndCommand();
01960 
01961         // flag
01962         PageIsProc = TRUE;
01963     }
01964 
01965     DoingPage = TRUE;
01966     LayerNumber = 0;
01967 
01968     // record the location of the first instruction in the file, which will follow immediately
01969     if(!IsProcedure)
01970         FirstInstrFilePosition = GetFilePosition();
01971 
01972     // write a comment to say where this file came from
01973     // return WriteCamComment();
01974     return TRUE;                // Graeme (10-2-00) replaced above return with return TRUE.
01975 }

BOOL CMXExportDC::StartRIFFList INT32  Type  ) 
 

Start writing a section to a CMX file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/07/96
Parameters:
The type of section to start [INPUTS]
Returns:
success
See also:

Definition at line 1020 of file cmxexdc.cpp.

01021 {
01022     ERROR2IF(DoingRIFFList, FALSE, "Tried to start a riff list without ending the previous one");
01023 
01024     // write the riff list header
01025     RIFFck chdr;
01026     chdr.ckID = RIFFTYPE_LIST;
01027     chdr.ckSize = 0;
01028     ExportFile->write(&chdr, sizeof(chdr));
01029 
01030     // set the future length
01031     RIFFListLengthFuture.Init(this, FUTURE_BACKLOC(&chdr, ckSize), sizeof(chdr.ckSize));
01032     RIFFListLengthFuture.SetLengthStartPos(this, 0);
01033 
01034     // write the list type, if we're doing a list
01035     DWORD id = Type;
01036     ExportFile->write(&id, sizeof(id));
01037 
01038     // flag...
01039     DoingRIFFList = TRUE;
01040     
01041     return TRUE;
01042 }

BOOL CMXExportDC::StartSection CMXSectionType  Type  ) 
 

Start writing a section to a CMX file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/6/96
Parameters:
The type of section to start [INPUTS]
Returns:
success
See also:

Definition at line 915 of file cmxexdc.cpp.

00916 {
00917     ERROR2IF(CurrentSection != CMXSECTION_NONE, FALSE, "Tried to start a section without ending the previous one");
00918 
00919     // write the riff file header
00920     // first, decide what riff chunck id we want
00921     DWORD id;
00922     BOOL IsAList = FALSE;           // whether in fact it's a list
00923     switch(Type)
00924     {
00925     case CMXSECTION_NONE:
00926         ERROR2(FALSE, "Tried to start a section of type none. Oh dear");
00927         break;
00928     case CMXSECTION_HEADER:     id = cmxRIFFCI_Header;          break;
00929     case CMXSECTION_PAGE:       id = cmxRIFFCI_Page;            break;
00930     case CMXSECTION_REFLIST:    id = cmxRIFFCI_ReferenceList;   break;
00931     case CMXSECTION_INDEX:      id = cmxRIFFLIST_Index; IsAList=TRUE;   break;
00932     case CMXSECTION_TRAILER:    id = cmxRIFFLIST_Trail; IsAList=TRUE;   break;
00933     case CMXSECTION_ARROW:      id = cmxRIFFCI_Desc_Arrow;      break;
00934     case CMXSECTION_ARROWHEADS: id = cmxRIFFCI_Desc_Arrowheads; break;
00935     case CMXSECTION_COLOUR:     id = cmxRIFFCI_Desc_Colour;     break;
00936     case CMXSECTION_DOTDASH:    id = cmxRIFFCI_Desc_DotDash;    break;
00937     case CMXSECTION_FONT:       id = cmxRIFFCI_Desc_Font;       break;
00938     case CMXSECTION_OUTLINE:    id = cmxRIFFCI_Desc_Outline;    break;
00939     case CMXSECTION_LINESTYLE:  id = cmxRIFFCI_Desc_LineStyle;  break;
00940     case CMXSECTION_PEN:        id = cmxRIFFCI_Desc_Pen;        break;
00941     case CMXSECTION_LENS:       id = cmxRIFFCI_Desc_Lens;       break;
00942     case CMXSECTION_SCREEN:     id = cmxRIFFCI_Desc_Screen;     break;
00943     case CMXSECTION_IMAGINFO:   id = cmxRIFFCI_ImageInfo;       break;
00944     case CMXSECTION_IMAGDATA:   id = cmxRIFFCI_ImageData;       break;
00945     case CMXSECTION_PROCBITFILL:id = cmxRIFFCI_Procedure;       break;
00946     case CMXSECTION_PREVIEWBITMAP: id = cmxRIFFCI_Thumbnail;    break;
00947     default:
00948         ERROR2(FALSE, "Unknown section type");
00949         break;
00950     }
00951 
00952     // OK, write the RIFF header
00953     RIFFck chdr;
00954     chdr.ckID = IsAList?RIFFTYPE_LIST:id;
00955     chdr.ckSize = 0;
00956     ExportFile->write(&chdr, sizeof(chdr));
00957 
00958     // set the future length
00959     SectionLengthFuture.Init(this, FUTURE_BACKLOC(&chdr, ckSize), sizeof(chdr.ckSize));
00960     SectionLengthFuture.SetLengthStartPos(this, 0 /* - (INT32)sizeof(chdr)*/);
00961 
00962     // write the list type, if we're doing a list
00963     if(IsAList)
00964         ExportFile->write(&id, sizeof(id));
00965 
00966     // note which section type we just did
00967     CurrentSection = Type;
00968     
00969     return TRUE;
00970 }

BOOL CMXExportDC::StartTag INT32  Tag  ) 
 

starts writing a tag to the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/06/96
Parameters:
Tag for the command [INPUTS]
Returns:
success
See also:

Definition at line 1092 of file cmxexdc.cpp.

01093 {
01094     if(!ThirtyTwoBit)
01095         return TRUE;        // 16 bit files don't have tags
01096 
01097     ERROR2IF(DoingTag == TRUE, FALSE, "already doing a tag");
01098 
01099     // write the tag header
01100     cmxTagHdr hdr;
01101     hdr.ID = (BYTE)Tag;
01102     hdr.Size = 0;
01103     ExportFile->write(&hdr, sizeof(hdr));
01104 
01105     // initialise the future value
01106     TagLengthFuture.Init(this, FUTURE_BACKLOC(&hdr, Size), sizeof(hdr.Size));
01107     TagLengthFuture.SetLengthStartPos(this, 0-(INT32)sizeof(hdr));
01108 
01109     // flag
01110     DoingTag = TRUE;
01111 
01112     return TRUE;
01113 }

BOOL CMXExportDC::WriteADesc INT32  Which  ) 
 

writes the a particular index to the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2728 of file cmxexdc.cpp.

02729 {
02730     // get some types and sort out the master index entry for this table
02731     // and do any special actions for certain index types
02732     INT32 Section;
02733     CMXReferMasterIndex *pMIE = new CMXReferMasterIndex(this);
02734     if(pMIE == NULL)
02735         return FALSE;
02736     BOOL NoMIE = FALSE;
02737     BOOL HasRecordCount = TRUE;
02738     BOOL CanOmit = FALSE;
02739     switch(Which)
02740     {
02741     case cmxDESC_ARROW:
02742         Section = CMXSECTION_ARROW;
02743         CanOmit = TRUE;
02744         pMIE->SetType(cmxMASTERIN_ARROW);
02745         HasRecordCount = FALSE;
02746         break;
02747 
02748     case cmxDESC_ARROWHEADS:
02749         Section = CMXSECTION_ARROWHEADS;
02750         pMIE->SetType(cmxMASTERIN_ARROWHEADS);
02751         break;
02752 
02753     case cmxDESC_COLOUR:
02754         Section = CMXSECTION_COLOUR;
02755         pMIE->SetType(cmxMASTERIN_COLOUR);
02756         break;
02757 
02758     case cmxDESC_DOTDASH:
02759         Section = CMXSECTION_DOTDASH;
02760         pMIE->SetType(cmxMASTERIN_DOTDASH);
02761         break;
02762 
02763     case cmxDESC_FONT:
02764         Section = CMXSECTION_FONT;
02765         pMIE->SetType(cmxMASTERIN_FONT);
02766         CanOmit = TRUE;
02767         HasRecordCount = FALSE;
02768         break;
02769 
02770 /*  case cmxDESC_IMAGE:
02771         Section = CMXSECTION_IMAGE;
02772         pMIE->SetType(cmxMASTERIN_IMAGE);
02773         CanOmit = TRUE;
02774         HasRecordCount = FALSE;
02775         break;
02776 */
02777     case cmxDESC_OUTLINE:
02778         Section = CMXSECTION_OUTLINE;
02779         pMIE->SetType(cmxMASTERIN_OUTLINE);
02780         break;
02781 
02782     case cmxDESC_LINESTYLE:
02783         Section = CMXSECTION_LINESTYLE;
02784         pMIE->SetType(cmxMASTERIN_LINESTYLE);
02785         break;
02786 
02787     case cmxDESC_PEN:
02788         Section = CMXSECTION_PEN;
02789         pMIE->SetType(cmxMASTERIN_PEN);
02790         break;
02791 
02792     case cmxDESC_SCREEN:
02793         Section = CMXSECTION_SCREEN;
02794         pMIE->SetType(cmxMASTERIN_SCREEN);
02795         break;
02796     
02797     default:
02798         ERROR3("Don't know what type of desc to write!");
02799     }
02800 
02801     // scan the refer list and see how many entries we've got, and how long they are
02802     WORD Entries = 0;
02803     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
02804     while(pEn != 0)
02805     {
02806         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02807 
02808         if(pEn->IsInWhichDesc() == Which)
02809         {
02810             Entries++;
02811         }
02812 
02813         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02814     }
02815 
02816     // do we need to save this section?
02817     if(Entries == 0 && CanOmit)
02818     {
02819         delete pMIE;        // delete the record
02820         return TRUE;        // don't do anything
02821     }
02822 
02823     // add this section to the master entry list
02824     if(NoMIE)
02825     {
02826         delete pMIE;        // don't need this
02827     }
02828     else
02829     {
02830         ReferList.AddTail(pMIE);
02831     }
02832 
02833     // start the section, and maybe write a record count
02834     if(!StartSection((CMXExportDC::CMXSectionType)Section))
02835         return FALSE;
02836     if(HasRecordCount)
02837         ExportFile->write(&Entries, sizeof(Entries));       // write record count
02838 
02839     // write the entries
02840     pEn = (CMXReferListItem *)ReferList.GetHead();
02841     while(pEn != 0)
02842     {
02843         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02844 
02845         if(pEn->IsInWhichDesc() == Which)
02846         {
02847             if(!pEn->WriteInDesc(this))
02848                 return FALSE;
02849         }
02850 
02851         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02852     }
02853 
02854     // end the section
02855     if(!EndSection())
02856         return FALSE;
02857 
02858     // done
02859     return TRUE;
02860 }

void CMXExportDC::WriteAngle double  theta  ) 
 

writes an angle to the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/07/96
Parameters:
angle,in radians [INPUTS]
Returns:
-
See also:

Definition at line 1595 of file cmxexdc.cpp.

01596 {
01597     // Convert theta to be measured in degrees.
01598     theta = ( theta * 360.0 ) / ( 2.0 * PI );
01599 
01600     // 32-bit export uses a larger scale factor.
01601     if(ThirtyTwoBit)
01602     {
01603         INT32   Angle32 = ( INT32 ) ( theta * 1000000.0 );
01604         ExportFile->write ( &Angle32, sizeof ( Angle32 ) );
01605     }
01606     else
01607     {
01608         short   Angle16 = ( short ) ( theta * 10.0);
01609         ExportFile->write ( &Angle16, sizeof ( Angle16 ) );
01610     }
01611 }

BOOL CMXExportDC::WriteAnIndex INT32  Which  ) 
 

writes the a particular index to the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2498 of file cmxexdc.cpp.

02499 {
02500     // size of the table -- special actions may add some stuff to it
02501     INT32 TableSize = sizeof(WORD); // for record count
02502 
02503     // get some types and sort out the master index entry for this table
02504     // and do any special actions for certain index types
02505     INT32 id;
02506     CMXReferMasterIndex *pMIE = new CMXReferMasterIndex(this);
02507     if(pMIE == NULL)
02508         return FALSE;
02509     BOOL NoMIE = FALSE;
02510     switch(Which)
02511     {
02512     case cmxINDEX_LAYER:
02513         {
02514             ERROR2IF(PageRefer == NULL, FALSE, "no page refer set up");
02515             PageRefer->SetLayerTableOffset(GetFilePosition());
02516 
02517             id = cmxRIFFCI_LayerIndex;
02518             NoMIE = TRUE;
02519             TableSize += sizeof(WORD);          // for page number
02520 
02521             // add an entry for the master layer table
02522             CMXReferMasterLayer *pML = new CMXReferMasterLayer(this);
02523             if(pML == NULL)
02524                 return FALSE;
02525             ReferList.AddTail(pML);             // add it -- nothing else to set
02526         }
02527         break;
02528 
02529     case cmxINDEX_PAGE:
02530         id = cmxRIFFCI_PageIndex;
02531         pMIE->SetType(cmxMASTERIN_PAGE);
02532         break;
02533 
02534     case cmxINDEX_MASTERINDEX:
02535         // note the start of the index section in the file header
02536         IndexSectionFuture.Write(this);
02537 
02538         TableSize += sizeof(cmxMasterIndexHeader);
02539         id = cmxRIFFCI_MasterIndex;
02540         pMIE->SetType(cmxMASTERIN_MASTERIN);
02541         break;
02542 
02543     case cmxINDEX_MASTERLAYER:              // remember this is single entry table and is fudged
02544         id = cmxRIFFCI_MasterLayerIndex;    // in the refer list object
02545         pMIE->SetType(cmxMASTERIN_MASTERLAYER);
02546         break;
02547 
02548     case cmxINDEX_PROCEDURE:
02549         id = cmxRIFFCI_ProcIndex;
02550         pMIE->SetType(cmxMASTERIN_PROCEDURE);
02551         break;
02552 
02553     case cmxINDEX_EMBEDFILE:
02554         id = cmxRIFFCI_EmbeddedFileIndex;
02555         pMIE->SetType(cmxMASTERIN_EMBEDFILE);
02556         break;
02557 
02558     case cmxINDEX_ARROW:
02559         id = cmxRIFFCI_ArrowIndex;
02560         pMIE->SetType(cmxMASTERIN_ARROW);
02561         TableSize += sizeof(cmxArrowIndexHeader) + (ThirtyTwoBit?sizeof(WORD):0);
02562         break;
02563 
02564     default:
02565         ERROR3("Don't know what type of index to write!");
02566     }
02567 
02568     if(NoMIE)
02569     {
02570         delete pMIE;        // don't need this
02571     }
02572     else
02573     {
02574         ReferList.AddTail(pMIE);
02575     }
02576 
02577     // scan the refer list and see how many entries we've got, and how long they are
02578     WORD Entries = 0;
02579     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
02580     while(pEn != 0)
02581     {
02582         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02583 
02584         if(pEn->IsInWhichIndex() == Which)
02585         {
02586             Entries++;
02587             TableSize += pEn->IndexEntrySize(this);
02588         }
02589 
02590         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02591     }
02592 
02593     if(Entries == 0)
02594     {
02595         // nothing to write -- go away now after removing the entry from the master index
02596         delete ReferList.RemoveItem(pMIE);
02597         return TRUE;
02598     }
02599 
02600     // write the header
02601     RIFFck ck;
02602     ck.ckID = id;
02603     ck.ckSize = TableSize;
02604     ExportFile->write(&ck, sizeof(ck));
02605 
02606     if(Which == cmxINDEX_MASTERINDEX)
02607     {
02608         // write it's special header
02609         cmxMasterIndexHeader mih = {cmxMASTERIN_MASTERIN, ThirtyTwoBit?0xfff:0x18};
02610         ExportFile->write(&mih, sizeof(mih));
02611     }
02612 
02613     ExportFile->write(&Entries, sizeof(Entries));       // write record count
02614 
02615     // do specials
02616     switch(Which)
02617     {
02618     case cmxINDEX_LAYER:
02619         {
02620             WORD PageNumber = 1;
02621             ExportFile->write(&PageNumber, sizeof(PageNumber));
02622         }
02623         break;
02624 
02625     case cmxINDEX_ARROW:
02626         {
02627             cmxArrowIndexHeader aih;
02628             WriteSizeInFile(sizeof(cmxArrowIndexEntry));
02629             aih.Type = cmxARROWINDEXTYPE;
02630             ExportFile->write(&aih, sizeof(aih));
02631         }
02632         break;
02633 
02634     default:
02635         break;
02636     }
02637 
02638     // write the entries
02639     pEn = (CMXReferListItem *)ReferList.GetHead();
02640     while(pEn != 0)
02641     {
02642         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02643 
02644         if(pEn->IsInWhichIndex() == Which)
02645         {
02646             if(!pEn->WriteInIndex(this))
02647                 return FALSE;
02648         }
02649 
02650         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02651     }
02652 
02653     // if necessary, word align the thingy
02654     if((GetFilePosition() & 1) != 0)
02655     {
02656         // put an extra byte in the file
02657         ExportFile->put('\0');
02658     }
02659 
02660     // done
02661     return TRUE;
02662 }

BOOL CMXExportDC::WriteAttrCheckIgnoreLens CMXRenderRegion pReg,
DocCoord Coords,
INT32  NumCoords
 

checks to see if we should ignore this lens -- it sees if it's going to overlap with too many lenses. This is basically as bodge as CorelDRAW will just fall over if we export a file with lots of overlapped lenses in it.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/08/96
Parameters:
region,coords,num coords [INPUTS]
Returns:
whether to ignore a lens on this object

Definition at line 2099 of file cmxdcobj.cpp.

02100 {
02101     // first thing, find the bbox of the object we're about to lens to
02102     DocRect BBox;
02103     CalcCorelBBox(Coords, NumCoords, &BBox);
02104 
02105     // now search the list to see how many existing lenses intersect with it
02106     INT32 LensesBehindThisOne = 0;
02107     CMXLensBBox *pEn = (CMXLensBBox *)LensBBoxes.GetHead();
02108     while(pEn != 0)
02109     {
02110         // check for intersection
02111         if(pEn->DoesIntersect(&BBox))
02112             LensesBehindThisOne++;
02113 
02114         // next, please
02115         pEn = (CMXLensBBox *)LensBBoxes.GetNext(pEn);
02116     }
02117 
02118     // make up a new object to add to the nice list thingy
02119     CMXLensBBox *pNewLensBBox = new CMXLensBBox(&BBox);
02120     if(pNewLensBBox != NULL)
02121         LensBBoxes.AddTail(pNewLensBBox);
02122 
02123     // do we want to ignore this?
02124     if(LensesBehindThisOne > CMX_MAX_OVERLAP_LENSES)
02125     {
02126         TRACEUSER( "Ben", _T("found transparency to ignore, %d lenses behind\n"), LensesBehindThisOne);
02127         // maybe we could ask the user if it wanted to ignore the overlapped things
02128         if(!AreIgnoreingOverlappedLenses && !HaveAskedUserAboutLenses)
02129         {
02130             HaveAskedUserAboutLenses = TRUE;
02131 
02132             INT32 Result = InformWarning(_R(IDW_CMXOVERLAPPEDLENS), _R(IDB_CMXDOLENSES), _R(IDB_CMXIGNORELENSES), 0, 0, 2, 1);
02133 
02134             switch(Result)
02135             {
02136             case 1: //_R(IDB_CMXDOLENSES):
02137                 AreIgnoreingOverlappedLenses = FALSE;
02138                 break;
02139 
02140             case 2: //_R(IDB_CMXIGNORELENSES):
02141             default:
02142                 AreIgnoreingOverlappedLenses = TRUE;
02143                 break;
02144             }
02145         }
02146 
02147         // ignore it?
02148         if(AreIgnoreingOverlappedLenses)
02149         {
02150             // OK, we've got to ignore this -- mark the fact
02151             OverlappedLensesHaveBeenIgnored = TRUE;
02152 
02153             return TRUE;        // ignore it
02154         }
02155     }
02156 
02157     return FALSE;       // don't ignore this one
02158 }

BOOL CMXExportDC::WriteAttrCheckLens CMXRenderRegion pReg,
INT32  Tag,
DocCoord Coords,
INT32  NumCoords,
BOOL *  WasLens
 

checks to see if this object should be outputed as a lens. If so, we need to output the attributes for it ourselves (as we can't use the full range of possible things) and add things to the list

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/07/96
Parameters:
render region, tag, pointer to flag [INPUTS]
Returns:
error flag

Definition at line 1932 of file cmxdcobj.cpp.

01933 {
01934     // set the flag for no lens
01935     *WasLens = FALSE;
01936 
01937     // get the transparency attr
01938     TranspFillAttribute *pTra =
01939         (TranspFillAttribute *)pReg->GetCurrentAttribute(ATTR_TRANSPFILLGEOMETRY);
01940     // check it out
01941     if(pTra == NULL)
01942     {
01943         TRACEUSER( "Ben", _T("No transparent fill attribute -- assuming it's not transparent\n"));
01944         return TRUE;
01945     }
01946     ERROR3IF(!pTra->IsKindOf(CC_RUNTIME_CLASS(TranspFillAttribute)), "not a transparent fill attribute");
01947 
01948     // right then, let's work out what transparency value we've got here
01949     UINT32 TransparencyValue = 0;
01950     if(pTra->IsAFlatFill())
01951     {
01952         TransparencyValue = *pTra->GetStartTransp();
01953     }
01954     else
01955     {
01956         // average the start and end values
01957         TransparencyValue = (*pTra->GetStartTransp() + *pTra->GetEndTransp()) / 2;
01958     }
01959 
01960     // check to see if we really want to do this thingy
01961     if (TransparencyValue == 0)
01962         return TRUE;            // nothing to do, it's not transparent
01963 
01964     TRACEUSER( "Ben", _T("transparent, has value %d\n"), TransparencyValue);
01965 
01966     // OK, do we want to ignore this lens to stop CorelDRAW from dieing when we import the file
01967     if(WriteAttrCheckIgnoreLens(pReg, Coords, NumCoords))
01968     {
01969         // yes, ignore the damn thing
01970         return TRUE;
01971     }
01972 
01973     // transparency has the range 0-255 in Cam, but 0-1000 in CMX
01974     WORD UniformRate = 1000 - ((TransparencyValue * 1000) / 255);   // the value to export
01975 
01976     // now we need to work out what colour the thingy will be
01977     WORD ColourReference = 1;       // nice default value
01978 
01979     // get the attribute
01980     FillGeometryAttribute *pFillGeometry
01981             = (FillGeometryAttribute *)pReg->GetCurrentAttribute(ATTR_FILLGEOMETRY);
01982 
01983     // check it out
01984     ERROR2IF(pFillGeometry == 0, FALSE, "No fill geometry");
01985     ERROR3IF(!pFillGeometry->IsKindOf(CC_RUNTIME_CLASS(FillGeometryAttribute)), "not one of them there fill geometries");
01986 
01987     // get the start colour of the attribute
01988     DocColour *pColour = pFillGeometry->GetStartColour();
01989 
01990     if(pColour != 0 && !pColour->IsTransparent())
01991     {
01992         // get a reference for this nice colour
01993         ColourReference = GetColourReference(pColour);
01994     }
01995 
01996     // right then, we now need to create one of those lens refer list items
01997     CMXReferLens *pLens = new CMXReferLens(this);
01998     if(pLens == NULL)
01999         return FALSE;
02000 
02001     // get the bounding box
02002     DocRect bb;
02003     CalcCorelBBox(Coords, NumCoords, &bb);
02004 
02005     // set up the lens list item
02006     if(!pLens->Set(this, &bb))
02007         return FALSE;
02008 
02009     // add it to the list
02010     ReferList.AddTail(pLens);
02011 
02012     // right then, we now need to write some attributes to the file
02013     // start the tag
02014     if(Tag != -1)
02015         if(!StartTag(Tag))
02016             return FALSE;
02017 
02018     // write the attribute mask thingy
02019     WriteByte(cmxRENDATTRMASK_FILL | cmxRENDATTRMASK_OUTLINE | cmxRENDATTRMASK_LENS);
02020 
02021     // write the fill specification
02022     if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec)
02023         ||!WriteFillType(cmxFILLID_UNIFORM))
02024         return FALSE;
02025     struct {
02026         WORD FillReference;
02027         WORD ScreenReference;
02028     } filldef = {ColourReference, cmxSCREENREFERENCE};
02029     if(!WriteNestedTag(cmxTAG_RenderAttr_FillSpec_Uniform, &filldef, sizeof(filldef))
02030         || !WriteMinEndTag()
02031         || !EndNestedTag()
02032         || !WriteMinEndTag())
02033         return FALSE;
02034 
02035     // write the outline specification
02036     if(!WriteOutlineSpec(pReg))
02037         return FALSE;
02038 
02039     // and write the lens specification
02040     cmxGlassLensDefn lendef;
02041     lendef.LensType = cmxLENSTYPE_GLASS;
02042 
02043     switch(pTra->GetTranspType())
02044     {
02045         default:            lendef.TintMethod = cmxLENSTINTMETH_AVERAGE;    break;
02046         case TT_StainGlass: lendef.TintMethod = cmxLENSTINTMETH_SUBTRACT;   break;
02047         case TT_Bleach:     lendef.TintMethod = cmxLENSTINTMETH_ADD;        break;
02048     }
02049     lendef.UniformRate = UniformRate;
02050     lendef.ColourReference = ColourReference;
02051     lendef.RangeProcReference = GetProcedureReference(pLens);
02052 
02053     if(!WriteNestedTag(cmxTAG_RenderAttr_LensSpec_Base, &lendef, sizeof(lendef)))
02054         return FALSE;
02055 
02056     if(ThirtyTwoBit)
02057     {
02058         cmxLensFrozView fv;         // no idea what this is
02059         fv.FlagFrozen = 0;
02060         fv.FlagActive = 0;
02061         fv.ViewPointX = 0;
02062         fv.ViewPointY = 0;
02063 
02064         if(!WriteNestedTag(cmxTAG_RenderAttr_LensSpec_FrozViewp, &fv, sizeof(fv))
02065             || !WriteMinEndTag())
02066             return FALSE;
02067     }
02068 
02069     // end the tag
02070     if(Tag != -1)
02071         if(!EndTag())
02072             return FALSE;
02073 
02074     // tell the caller that we did something
02075     *WasLens = TRUE;
02076 
02077     // set the page flag to say we had a lens
02078     SetCMXFlag(cmxSTRUCTFLAGS_HASLENS);
02079 
02080     return TRUE;
02081 }

BOOL CMXExportDC::WriteAttributes CMXRenderRegion pReg,
INT32  Tag,
DocCoord Coords,
INT32  NumCoords,
BOOL  ForceNoFill = FALSE
 

Writes the attributes to the DC. if ForceNoFill == TRUE, the path will not be filled whatever the colour.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
01/07/96
Parameters:
render region [INPUTS]
Returns:
success

Definition at line 158 of file cmxdcobj.cpp.

00159 {
00160     // give lenses a chance
00161     BOOL WasLens = FALSE;
00162     if(!WriteAttrCheckLens(pReg, Tag, Coords, NumCoords, &WasLens))
00163         return FALSE;
00164 
00165     // now did the lens checking bit output something?
00166     if(WasLens)
00167         return TRUE;        // yep, so we don't want to output them too
00168 
00169     // start the tag
00170     if(Tag != -1)
00171         if(!StartTag(Tag))
00172             return FALSE;
00173 
00174     // write the attribute mask thingy
00175     WriteByte((ForceNoFill?0:cmxRENDATTRMASK_FILL) | cmxRENDATTRMASK_OUTLINE);
00176 
00177     // write the fill specification
00178     if(!ForceNoFill)
00179         if(!WriteFillSpec(pReg, Coords, NumCoords, ForceNoFill))
00180             return FALSE;
00181 
00182     // write the outline specification
00183     if(!WriteOutlineSpec(pReg))
00184         return FALSE;
00185 
00186     // end the tag
00187     if(Tag != -1)
00188         if(!EndTag())
00189             return FALSE;
00190     
00191     return TRUE;
00192 }

BOOL CMXExportDC::WriteBBox DocRect BBox,
BOOL  Transform = TRUE
 

Write a bounding box to the file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1553 of file cmxexdc.cpp.

01554 {
01555     ERROR2IF(pMatrix == NULL, FALSE, "No matrix");
01556 
01557     if(ThirtyTwoBit)
01558     {
01559         DocRect bb = *BBox;
01560         if(Transform)
01561             pMatrix->TransformBounds(&bb);
01562         
01563         cmxBBox32 b = {bb.lo.x, bb.hi.y, bb.hi.x, bb.lo.y};
01564 
01565         ExportFile->write(&b, sizeof(b));
01566     }
01567     else
01568     {
01569         DocRect bb = *BBox;
01570         if(Transform)
01571             pMatrix->TransformBounds(&bb);
01572         
01573         cmxBBox16 b = {(SWORD)bb.lo.x, (SWORD)bb.hi.y, (SWORD)bb.hi.x, (SWORD)bb.lo.y};
01574 
01575         ExportFile->write(&b, sizeof(b));
01576     }
01577 
01578     return TRUE;
01579 }

BOOL CMXExportDC::WriteBitmap KernelBitmap pBitmap,
DocCoord pParallelogram,
CMXBitmapColourSource  ColSource = CMXBITMAPCOLOURSOURCE_NONE,
BOOL  TransformParallelogram = TRUE,
WORD  BitmapReference = 0
 

writes a bitmap object to the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/07/96
Parameters:
render region, bitmap, parllelogram for the bitmap [INPUTS]
Returns:
success
See also:

Definition at line 2469 of file cmxdcobj.cpp.

02474 {
02475     // sort out some colours for contoning the bitmap
02476     DocColour *pStartColour = 0;
02477     DocColour *pEndColour = 0;
02478     EFFECTTYPE Effect = EFFECT_RGB;
02479 
02480     // we have three possible methods for getting some colours...
02481     switch(ColSource)
02482     {
02483     case CMXBITMAPCOLOURSOURCE_FILLGEOMETRY:
02484         ERROR2(FALSE, "fill geometry bitmap colour source not implemented");
02485         break;
02486 
02487     case CMXBITMAPCOLOURSOURCE_LINEANDFILL:
02488         {
02489         // right then, we get the start colour from the line effect
02490         // get the attribute
02491         StrokeColourAttribute *pColA
02492                 = (StrokeColourAttribute *)pRenderRegion->GetCurrentAttribute(ATTR_STROKECOLOUR);
02493         // check it out
02494         ERROR2IF(pColA == 0, FALSE, "No stroke colour attribute");
02495         ERROR3IF(!pColA->IsKindOf(CC_RUNTIME_CLASS(StrokeColourAttribute)), "not a stroke colour attribute");
02496         pStartColour = pColA->GetStartColour();
02497         // check to see if we need to do contoning
02498         if(pStartColour != 0 && pStartColour->IsTransparent())
02499             pStartColour = 0;
02500 
02501         // get the end colour from a fill attribute
02502         if(pStartColour != 0)
02503         {
02504             // get the attribute
02505             FillGeometryAttribute *pFillGeometry
02506                     = (FillGeometryAttribute *)pRenderRegion->GetCurrentAttribute(ATTR_FILLGEOMETRY);
02507             // check it out
02508             ERROR2IF(pFillGeometry == 0, FALSE, "No fill geometry");
02509             ERROR3IF(!pFillGeometry->IsKindOf(CC_RUNTIME_CLASS(FillGeometryAttribute)), "not one of them there fill geometries");
02510 
02511             // get the start colour of the fill attribute
02512             pEndColour = pFillGeometry->GetStartColour();
02513 
02514             if(pEndColour == NULL || pEndColour->IsTransparent())
02515             {
02516                 // no end colour -- can't be contoned then
02517                 pStartColour = 0;
02518                 pEndColour = 0;
02519             }
02520             else
02521             {
02522                 // get the fill effect
02523                 Effect = pRenderRegion->GetFillEffect();
02524             }
02525         }
02526         }
02527         break;
02528 
02529     default:
02530     case CMXBITMAPCOLOURSOURCE_NONE:
02531         break;      // do nothing
02532     }
02533 
02534     // get a reference number for the bitmap
02535     WORD BitmapRef = 0;
02536     if(pBitmap == 0)
02537     {
02538         BitmapRef = BitmapReference;
02539     }
02540     else
02541     {
02542         BitmapRef = GetBitmapReference(pBitmap, pStartColour, pEndColour, Effect);
02543     }
02544     if(BitmapRef == 0)
02545         return TRUE;            // if it isn't able to be got, sod it.
02546 
02547     // make a new transformed parallelogram thingy
02548     DocCoord Para[4];
02549     ERROR2IF(pMatrix == NULL, FALSE, "no matrix");
02550     for(INT32 z = 0; z < (sizeof(Para) / sizeof(DocCoord)); z++)
02551     {
02552         Para[z] = pParallelogram[z];
02553         if(TransformParallelogram)
02554             pMatrix->transform(&(Para[z]));
02555     }
02556 
02557     // begin the command
02558     if(!StartCommand(cmxINSTR_DrawImage))
02559         return FALSE;
02560 
02561     // output the rendering attributes
02562     if(!WriteBlankAttributes(cmxTAG_DrawImage_RenderingAttr))
02563         return FALSE;
02564 
02565     // write the image data
02566     if(!StartTag(cmxTAG_DrawImage_DrawImageSpecification))
02567         return FALSE;
02568 
02569     // image extent and cropping rectangle, in pixels
02570     DocRect ImEx;
02571     if(ThirtyTwoBit)
02572     {
02573         ImEx.lo.x = ImEx.lo.y = 0;
02574         ImEx.hi.x = 2048;
02575         ImEx.hi.y = 2048;
02576     }
02577     else
02578     {
02579         ImEx.lo.x = 0;
02580         ImEx.lo.y = -2048;
02581         ImEx.hi.x = 2048;
02582         ImEx.hi.y = 0;
02583     }
02584     if(!WriteBBox(&ImEx, FALSE) ||
02585         !WriteBBox(&ImEx, FALSE))
02586         return FALSE;
02587 
02588     // construct a transformation matrix -- no point in going through the write matrix fn
02589     double magX = 2048.0;
02590     double magY = 2048.0;
02591     cmxMatrix Matrix = {cmxMATRIXTYPE_GENERAL,
02592         (double)(Para[2].x - Para[3].x) / magX,
02593         (double)(Para[2].y - Para[3].y) / magY,
02594         (double)(Para[0].x - Para[3].x) / magX,
02595         (double)(Para[0].y - Para[3].y) / magY,
02596         Para[3].x,
02597         Para[3].y};
02598 
02599     if(!ThirtyTwoBit)
02600     {
02601         // add correction for bitmapnesses in 16 bit CMX files
02602         Matrix.f += Matrix.d * 2048;
02603     }
02604 
02605     // save out the matrix
02606     ExportFile->write(&Matrix, sizeof(Matrix));
02607 
02608     // other bits and pieces
02609     cmxDrawImageEndBits eb;
02610     eb.ImageType = cmxDRAWIMAGE_IMAGETYPE_COLOUR;
02611     eb.FileRef1 = BitmapRef;
02612     eb.FileRef2 = 0;            // nothing associated with this
02613     if(!WriteData(&eb, sizeof(eb)))
02614         return FALSE;
02615 
02616     // end the specification thingy
02617     if(!EndTag())
02618         return FALSE;
02619 
02620     // end the command
02621     if(!WriteMinEndTag()
02622         || !EndCommand())
02623         return FALSE;
02624 
02625     return TRUE;
02626 }

BOOL CMXExportDC::WriteBlankAttributes INT32  Tag  ) 
 

writes a blank attribute tag and contents, which specifies nothing but keeps everything happy

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/07/96
Parameters:
render region [INPUTS]
Returns:
success

Definition at line 126 of file cmxdcobj.cpp.

00127 {
00128     // start the tag
00129     if(Tag != -1)
00130         if(!StartTag(Tag))
00131             return FALSE;
00132 
00133     // write the attribute mask thingy
00134     WriteByte(0);
00135 
00136     // end the tag
00137     if(Tag != -1)
00138         if(!EndTag())
00139             return FALSE;
00140     
00141     return TRUE;
00142 }

void CMXExportDC::WriteByte BYTE  Thing  )  [inline]
 

Definition at line 283 of file cmxexdc.h.

00283 {ExportFile->put(Thing);};  // will exception not return false

BOOL CMXExportDC::WriteCamComment void   ) 
 

writes a helpful comment so we can see where dodgy cam cmx files come from

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
01/08/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2401 of file cmxexdc.cpp.

02402 {
02403     if(PageIsProc)
02404         return TRUE;            // only write comments in pages
02405 
02406     CCamApp*    Application;
02407     String_64   Text;
02408     String_256  TheText = String_256("saved from " PRODUCT_NAME " "); // WEBSTER - markn 26/11/96
02409 
02410     // munge an info string together
02411     Application = (CCamApp*) AfxGetApp();           // Find our main application object
02412 
02413     Application->GetCamelotVersion(&Text);
02414     Text += TEXT("(v");
02415     Text += TEXT(PRODUCT_VERSION_NO);
02416     Text += TEXT(")");
02417     TheText += Text;
02418 
02419 //  Text.MakeMsg(_R(IDS_CAMVERSION), &Text1);
02420 
02421     Text._MakeMsg(TEXT(" (#1%d) "), (INT32) CAMELOT_VERSION_MINOR);
02422     TheText += Text;
02423 
02424     Application->GetCamelotType(&Text);
02425     TheText += Text;
02426     
02427     TheText += " on ";
02428     Application->GetHostOSName(&Text);              // ... plonk info from it into the dlog
02429     TheText += Text;
02430 
02431     TRACEUSER( "Ben", _T("setting comment = %s\n"), (TCHAR *)TheText);
02432 
02433     // now start a command and a tag
02434     if(!StartCommand(cmxINSTR_Comment) || !StartTag(cmxTAG_Comment_CommentSpecification))
02435         return FALSE;
02436 
02437     WORD Size = TheText.Length();
02438 
02439     ExportFile->write(&Size, sizeof(Size));
02440 
02441     ExportFile->write((TCHAR *)TheText, Size);
02442 
02443     // end the command
02444     if(!EndTag() || !WriteMinEndTag() || !EndCommand())
02445         return FALSE;
02446 
02447     return TRUE;    
02448 }

BOOL CMXExportDC::WriteCommand UINT32  Tag,
void *  Data = 0,
UINT32  Size = 0
 

Write a command to the file -- one off operation, writes command and data in one go. Use default params for a no-data command.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/6/96
Parameters:
Tag for the command, the data, and the size [INPUTS]
Returns:
success
See also:

Definition at line 1284 of file cmxexdc.cpp.

01285 {
01286     ERROR2IF(DoingCommand != FALSE, FALSE, "Already writing a command");
01287     
01288     // write the header
01289     cmxInstrHdr hdr = {Size + sizeof(hdr), ThirtyTwoBit?Tag:(0 - (SWORD)Tag)};
01290 
01291     // word align the size
01292     if((hdr.Size & 1) != 0)
01293         hdr.Size++;
01294 
01295     ExportFile->write(&hdr, sizeof(hdr));
01296 
01297     if(Size != 0)
01298     {
01299         ERROR2IF(Data == 0, FALSE, "didn't get some data");
01300 
01301         // write the command
01302         ExportFile->write(Data, Size);
01303     }
01304 
01305     Tally++;
01306     PageInstructionCount++;
01307     LayerInstructionCount++;
01308 
01309     // word align the file
01310     if((/*GetFilePosition()*/ Size & 1) != 0)
01311     {
01312         // put an extra byte in the file
01313         ExportFile->put('\0');
01314     }
01315 
01316     return TRUE;
01317 }

BOOL CMXExportDC::WriteData void *  data,
INT32  Size
[inline]
 

Definition at line 282 of file cmxexdc.h.

00282 {ExportFile->write(data, Size); return TRUE;};

BOOL CMXExportDC::WriteDescriptionSections void   ) 
 

Definition at line 2699 of file cmxexdc.cpp.

BOOL CMXExportDC::WriteFillSpec CMXRenderRegion pReg,
DocCoord Coords,
INT32  NumCoords,
BOOL  NoFill
 

Writes the fill specifcation to the DC.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/07/96
Parameters:
render region [INPUTS]
Returns:
success

Definition at line 227 of file cmxdcobj.cpp.

00228 {
00229     // tag the start
00230     if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec))
00231         return FALSE;
00232 
00233     if(NoFill)
00234     {
00235         if(!WriteFillType(cmxFILLID_NONE))
00236             return FALSE;
00237     }
00238     else
00239     {
00240         // get the attribute
00241         FillGeometryAttribute *pFillGeometry
00242                 = (FillGeometryAttribute *)pReg->GetCurrentAttribute(ATTR_FILLGEOMETRY);
00243 
00244         // check it out
00245         ERROR2IF(pFillGeometry == 0, FALSE, "No fill geometry");
00246         ERROR3IF(!pFillGeometry->IsKindOf(CC_RUNTIME_CLASS(FillGeometryAttribute)), "not one of them there fill geometries");
00247 
00248         // right then, decide what to do with the thingy
00249         if(pFillGeometry->IsAFlatFill())
00250         {
00251             // flat fill -- check to see if it's transparent
00252             DocColour *pCol = pFillGeometry->GetStartColour();
00253             ERROR2IF(pCol == NULL, FALSE, "not one of your earth colours");
00254             if(pCol->IsTransparent())
00255             {
00256                 // it's transparent, write no fill
00257                 if(!WriteFillType(cmxFILLID_NONE))
00258                     return FALSE;
00259             }
00260             else
00261             {
00262                 // it's OK, it is. Write it.
00263                 if(!WriteFillType(cmxFILLID_UNIFORM)
00264                     || !WriteFillSpecFlat(pReg, pFillGeometry))
00265                     return FALSE;
00266             }
00267         }
00268         else if(pFillGeometry->IsAKindOfBitmapFill())
00269         {
00270             // bitmap type fill -- do nothing for now
00271             if(!WriteFillType(9) //cmxFILLID_COLPATTERN)
00272                 || !WriteFillSpecBitmap(pReg, pFillGeometry, Coords, NumCoords))
00273                 return FALSE;
00274         }
00275         else if(pFillGeometry->IsAGradFill())
00276         {
00277             // grad fill
00278             if(!WriteFillType(cmxFILLID_FOUNTAIN)
00279                 || !WriteFillSpecGrad(pReg, pFillGeometry, Coords, NumCoords))
00280                 return FALSE;
00281         }
00282         else
00283         {
00284             // catch all -- write a no fill thingy
00285             if(!WriteFillType(cmxFILLID_NONE))
00286                 return FALSE;
00287         }
00288     }
00289 
00290     // end the tag
00291     if(!EndNestedTag())
00292         return FALSE;
00293     
00294     // write the end tag
00295     if(!WriteMinEndTag())
00296         return FALSE;
00297 
00298     return TRUE;
00299 }

BOOL CMXExportDC::WriteFillSpecBitmap CMXRenderRegion pReg,
FillGeometryAttribute pFill,
DocCoord Coords,
INT32  NumCoords
 

Writes the bitmap fill specifcation to the DC (also does fractals).

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/07/96
Parameters:
render region [INPUTS]
Returns:
success

Definition at line 838 of file cmxdcobj.cpp.

00839 {
00840     // make up a bitmap fill object -- first find the refer bitmap object necessary
00841     BitmapFillAttribute *pBFillAttr = (BitmapFillAttribute *)pFill;
00842     ERROR3IF(!pBFillAttr->IsKindOf(CC_RUNTIME_CLASS(BitmapFillAttribute)), "not a bitmap fill attr");
00843 
00844     // colours
00845     DocColour *pStartColour = 0;
00846     DocColour *pEndColour = 0;
00847     EFFECTTYPE Effect = EFFECT_RGB;
00848 
00849     // get the colours we should use, and the fill effect
00850     pStartColour = pFill->GetStartColour();
00851     pEndColour = pFill->GetEndColour();
00852     if(pStartColour == 0 || pEndColour == 0
00853         || pStartColour->IsTransparent()
00854         || pEndColour->IsTransparent())
00855     {
00856         pStartColour = 0;
00857         pEndColour = 0;
00858     }
00859     
00860     if(pStartColour != 0)
00861     {
00862         // get the fill effect
00863         Effect = pReg->GetFillEffect();
00864     }
00865 
00866     // get the reference for the bitmap
00867     KernelBitmap *pBitmap = pBFillAttr->BitmapRef.GetBitmap();
00868     WORD BitmapRef = GetBitmapReference(pBitmap, pStartColour, pEndColour, Effect);
00869 
00870     // make a new bitmap fill object
00871     CMXReferBitmapFill *pBFill = new CMXReferBitmapFill(this);
00872     if(pBFill == 0)
00873         return FALSE;
00874     pBFill->Set(BitmapRef);
00875 
00876     // add it to the refer list
00877     ReferList.AddTail(pBFill);
00878 
00879     // get it's reference
00880     WORD BitmapFillProcReference = GetProcedureReference(pBFill);
00881 
00882     // ready to write...
00883     if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec_ColorBM))
00884         return FALSE;
00885     
00886     ExportFile->write(&BitmapFillProcReference, sizeof(BitmapFillProcReference));
00887 
00888     // write tiling
00889     if(!StartNestedTag(cmxTAG_Tiling))
00890         return FALSE;
00891 
00892     // get points from the attribute
00893     DocCoord *Start = pFill->GetStartPoint();
00894     DocCoord *End1 = pFill->GetEndPoint();
00895     DocCoord *End2 = pFill->GetEndPoint2();
00896 
00897     // get a tiling structure
00898     cmxTilingEnd tile;
00899 
00900     // Variables for rendering the texture to the file. I've deferred the scaling of
00901     // the image until it's written. It's slightly ugly doing it this way, but it
00902     // removes a few multipications, and so should get rid of some rounding errors
00903     // along the way.
00904     DocRect cBBox;
00905     double  TileWidth   = Start->Distance ( *End1 );
00906     double  TileHeight  = Start->Distance ( *End2 );
00907 
00908     // Calculate the untransformed Corel bounding box.
00909     CalcCorelBBox(Coords, NumCoords, &cBBox);
00910 
00911     // Graeme (9-5-00) - I've simplified Ben's code a little, and removed the
00912     // repeated bits in both branches of the if statement.
00913     if ( ThirtyTwoBit )
00914     {
00915         cmxTilingBegin32 Tile32;
00916         Tile32.Width    = static_cast<DWORD> ( Round ( TileWidth  * ScaleFactor ) );
00917         Tile32.Height   = static_cast<DWORD> ( Round ( TileHeight * ScaleFactor ) );
00918 
00919         WriteData ( &Tile32, sizeof ( Tile32 ) );
00920     }
00921     else
00922     {
00923         cmxTilingBegin16 Tile16;
00924         Tile16.Width    = static_cast<WORD> ( Round ( TileWidth  * ScaleFactor ) );
00925         Tile16.Height   = static_cast<WORD> ( Round ( TileHeight * ScaleFactor ) );
00926 
00927         WriteData ( &Tile16, sizeof ( Tile16 ) );
00928     }
00929 
00930     // now work out the offsets to the start of the tile
00931     double  dX  = static_cast<double> ( Start->x - cBBox.lo.x );
00932     double  dY  = static_cast<double> ( cBBox.hi.y - Start->y );
00933 
00934     // Graeme (9-5-00) - Round the offset up.
00935     tile.XOffset = ( static_cast<WORD> ( Round ( ( dX * 100.0 ) / TileWidth  ) ) ) % 100;
00936     tile.YOffset = ( static_cast<WORD> ( Round ( ( dY * 100.0 ) / TileHeight ) ) ) % 100;
00937 
00938     tile.InterTileOffset = tile.TilingFlags = 0;
00939 
00940     // write the structure to the file
00941     ExportFile->write(&tile, sizeof(tile));
00942     if(!EndNestedTag() || !WriteMinEndTag())
00943         return FALSE;
00944 
00945     // bounding box of bit to use
00946     DocRect bbox = DocRect(0, 0, cmxBITMAPFILLTILESIZE_X, cmxBITMAPFILLTILESIZE_Y);
00947 
00948     if(!WriteBBox(&bbox, FALSE))
00949         return FALSE;
00950 
00951     if(!EndNestedTag() || !WriteMinEndTag())
00952         return FALSE;
00953 
00954     return TRUE;
00955 }

BOOL CMXExportDC::WriteFillSpecFlat CMXRenderRegion pReg,
FillGeometryAttribute pFill
 

Writes the flat fill specifcation to the DC.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/07/96
Parameters:
render region [INPUTS]
Returns:
success

Definition at line 313 of file cmxdcobj.cpp.

00314 {
00315     // get the colour
00316     DocColour *pFillColour = pFill->GetStartColour();
00317     ERROR2IF(pFillColour == NULL, FALSE, "Wibble. No fill colour on this here flat fill");
00318 
00319     // find a reference for it
00320     WORD FillReference = GetColourReference(pFillColour);
00321 
00322     // write some stuff
00323     struct {
00324         WORD FillReference;
00325         WORD ScreenReference;
00326     } filldef = {FillReference, cmxSCREENREFERENCE};
00327 
00328     if(!WriteNestedTag(cmxTAG_RenderAttr_FillSpec_Uniform, &filldef, sizeof(filldef))
00329         || !WriteMinEndTag())
00330         return FALSE;
00331 
00332     return TRUE;
00333 }

BOOL CMXExportDC::WriteFillSpecGrad CMXRenderRegion pReg,
FillGeometryAttribute pFill,
DocCoord Coords,
INT32  NumCoords
 

Writes the grad fill specifcation to the DC.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/07/96
Parameters:
render region [INPUTS]
Returns:
success

Definition at line 351 of file cmxdcobj.cpp.

00355 {
00356     DocColour   StartColour;                // The first colour in the fill.
00357     DocColour   EndColour;                  // The end colour of the fill.
00358     DocColour   MidColour;                  // Only used to approximate four colour fills.
00359     BOOL        Radial          = FALSE;    // Is it a radial fill?
00360     BOOL        FourColour      = FALSE;    // Is it a four colour fill?
00361 
00362     // is this a radial type derivative?
00363     if ( pFill->IsARadialFill () )
00364     {
00365         // We need to swap the colours over as Corel has a different idea
00366         // of start and finish colours to Camelot.
00367         StartColour = *( pFill->GetEndColour () );
00368         EndColour   = *( pFill->GetStartColour () );
00369 
00370         Radial = TRUE;
00371     }
00372     else if ( pFill->IsAConicalFill () || pFill->IsASquareFill () )
00373     {
00374         // Set up the colour values.
00375         StartColour = *( pFill->GetStartColour () );
00376         EndColour   = *( pFill->GetEndColour () );
00377 
00378         Radial = TRUE;
00379     }
00380     else if ( pFill->IsAFourColFill () )
00381     {
00382         // Set up the start and end colours as usual, but create a third colour value to
00383         // help fake the four colour fill.
00384         StartColour = *( pFill->GetStartColour () );
00385         EndColour   = *( pFill->GetEndColour3 () );
00386         MidColour.Mix ( pFill->GetEndColour (), pFill->GetEndColour2 (), 0.5f, NULL, FALSE, NULL );
00387 
00388         // Reset the four colour flag.
00389         FourColour  = TRUE;
00390     }
00391     else if ( pFill->IsAThreeColFill () )
00392     {
00393         // Set up the colour values. I'm blending the colours of the two endpoints
00394         // to get a better approximation of a three colour fill.
00395         StartColour = *( pFill->GetStartColour () );
00396         EndColour.Mix ( pFill->GetEndColour (), pFill->GetEndColour2 (), 0.5f, NULL, FALSE, NULL );
00397     }
00398     else
00399     {
00400         // Default behaviour: Store the start and end colours.
00401         StartColour = *( pFill->GetStartColour () );
00402         EndColour   = *( pFill->GetEndColour () );
00403     }
00404 
00405     // Find references for the color, and sort out the fill effect.
00406     WORD    StartColReference   = GetColourReference ( &StartColour );
00407     WORD    EndColReference     = GetColourReference ( &EndColour );
00408     WORD    MidColReference     = 0;
00409     WORD    FillMode            = cmxFILLMODE_RGB;
00410 
00411     // Get a colour reference to MidColour if it's been declared. (i.e. the fill is a
00412     // four colour fill.)
00413     if ( FourColour )
00414     {
00415         MidColReference = GetColourReference ( &MidColour );
00416     }
00417 
00418     // get the fill effect attribute
00419     FillEffectAttribute *pFillEff =
00420         (FillEffectAttribute *)pReg->GetCurrentAttribute(ATTR_FILLEFFECT);
00421     ERROR2IF(pFillEff == NULL || !pFillEff->IsKindOf(CC_RUNTIME_CLASS(FillEffectAttribute)), FALSE, "not a fill effect");
00422     BOOL Rainbow = FALSE, Alt = FALSE;
00423     if(IS_A(pFillEff, FillEffectRainbowAttribute))
00424         Rainbow = TRUE;
00425     if(IS_A(pFillEff, FillEffectAltRainbowAttribute))
00426         Rainbow = Alt = TRUE;
00427 
00428     if(Rainbow)
00429     {
00430         // right, we need to work out which direction we want the colour to go
00431         // around the HSV colour wheel. Convert both colours to HSV.
00432         ColourContext *Conv = ColourContext::GetGlobalDefault(COLOURMODEL_HSVT);
00433 
00434         ColourHSVT StartC;
00435         ColourHSVT EndC;
00436 
00437         Conv->ConvertColour( &StartColour, (ColourGeneric *)&StartC);
00438         Conv->ConvertColour( &EndColour, (ColourGeneric *)&EndC);
00439 
00440         // compare the hues and work out a difference
00441         double Difference = (EndC.Hue.MakeDouble()) - (StartC.Hue.MakeDouble());
00442 
00443         BOOL ClockWise = (Difference < 0);
00444 
00445         if(fabs(Difference) >= 0.5)
00446             ClockWise = !ClockWise;
00447 
00448         if(Alt = TRUE)
00449             ClockWise = !ClockWise;
00450         
00451         // set the correct thingy attribute
00452         if(ClockWise)
00453             FillMode = cmxFILLMODE_HSB_CW;
00454         else
00455             FillMode = cmxFILLMODE_HSB_CCW;
00456     }
00457 
00458     // find the start and end coords of the fill
00459     DocCoord StartPoint = *( pFill->GetStartPoint() );
00460     DocCoord EndPoint;
00461 
00462     // Graeme (18-2-00) - Modifications to handle three and four colour fills better.
00463     if ( pFill->IsAFourColFill () )
00464     {
00465         // Use EndPoint3 to get a diagonal across the bounding box.
00466         EndPoint = *( pFill->GetEndPoint3 () );
00467     }
00468     else if ( pFill->IsAThreeColFill () )
00469     {
00470         // Merge the existing two endpoints to get the correct endpoint for the fill.
00471         EndPoint = *( pFill->GetEndPoint () ) +
00472                    *( pFill->GetEndPoint2 () ) -
00473                    *( pFill->GetStartPoint () );
00474     }
00475     else
00476     {
00477         // Default: Use the standard endpoint.
00478         EndPoint = *( pFill->GetEndPoint () );
00479     }
00480 
00481 
00482     // find the corel bounding box of the path we're about to fiddle with
00483     DocRect cBBox;
00484     CalcCorelBBox(Coords, NumCoords, &cBBox);
00485 
00486     // run the chicken out clause for extreme cases I can't be bothered to handle
00487     if ( StartPoint == EndPoint || cBBox.Width () == 0 || cBBox.Height () == 0 )
00488         return WriteFillSpecFlat(pReg, pFill);
00489 
00490     // calc the central coord
00491     DocCoord Centre;
00492     Centre.x = cBBox.lo.x + cBBox.Width() / 2;
00493     Centre.y = cBBox.lo.y + cBBox.Height() / 2;
00494 
00495     // calc the fill parameters
00496 
00497     // first work out the distance between the start and end points
00498     double dx = EndPoint.x - StartPoint.x;
00499     double dy = EndPoint.y - StartPoint.y;
00500     double PointDist = sqrt(((dx * dx) + (dy * dy)));
00501 
00502     // now we need to work out the angle of the fill
00503     double Angle = atan2(dy, dx);
00504         // atan2 is defined if dx == 0
00505         // but not at the origin -- however we've filtered out this case
00506 
00507     INT32 StartPercent;
00508     INT32 EndPercent;
00509 
00510     cmxFillBase1 fb1;
00511     fb1.Padding = 0;
00512     cmxFillBase2 fb2;
00513     fb2.XOffset = 0;
00514     fb2.YOffset = 0;
00515 
00516     if(Radial)
00517     {
00518         //------------------------------------------------- radial type fill calucations
00519 
00520         // ...and for my first trick, I will calculate the X and Y
00521         // offsets of the centre of this fill
00522         DocCoord dCentre = StartPoint - Centre;
00523         fb2.XOffset = (dCentre.x * 100) / cBBox.Width();
00524         fb2.YOffset = (dCentre.y * 100) / cBBox.Height();
00525         // get these values within the required range
00526         if(fb2.XOffset > 100) fb2.XOffset = 100;
00527         if(fb2.XOffset < -100) fb2.XOffset = -100;
00528         if(fb2.YOffset > 100) fb2.YOffset = 100;
00529         if(fb2.YOffset < -100) fb2.YOffset = -100;
00530 
00531         // now this is the scary bit. Corel use a complex method for specifing
00532         // their radial type fills. 
00533         double w = cBBox.Width(), h = cBBox.Height();
00534         double bboxdiagonal = sqrt(w*w + h*h);
00535         double cdx = dCentre.x, cdy = dCentre.y;
00536         double cendist = sqrt(cdx*cdx + cdy*cdy);
00537         double BodgeFactor = 1 + (cendist / (bboxdiagonal / 2));
00538         double targetradius = PointDist / BodgeFactor;
00539         double Pad = 50 * (1 - (2 * targetradius) / bboxdiagonal);
00540         // munge the Pad value to the allowed range
00541         if(Pad < 0) Pad = 0;
00542         if(Pad > 44) Pad = 44;
00543         // and bung in the structure for export
00544         fb1.Padding = (WORD)Pad;
00545 
00546         // set the percentages to 0
00547         StartPercent = 0;
00548         EndPercent = 0;
00549 
00550         // if it's a square fill, swap the colours over
00551         if(pFill->IsASquareFill())
00552         {
00553             WORD t = StartColReference;
00554             StartColReference = EndColReference;
00555             EndColReference = t;
00556         }
00557     } // if ( Radial )
00558 
00559     else // if ( !Radial )
00560     {
00561         //------------------------------------------------- linear type fill calucations
00562 
00563         // now work out the coords of the intersection of a line through the
00564         // centre of the bbox and the edges of the bbox
00565 
00566         // right then, we want the angle within 0 and PI/2
00567         double cAngle = Angle;
00568         INT32 cAR = 0;
00569         while(cAngle > (PI/2))
00570         {
00571             cAngle -= PI/2;
00572             cAR++;
00573         }
00574 
00575         // luckily, everything is symmetrical so all we need do is calc the
00576         // intersect in the top quadrant.
00577         INT32 qdx = cBBox.Width() / 2;
00578         INT32 qdy = cBBox.Height() / 2;
00579         if((cAR & 1) != 0)
00580         {
00581             // we rotated by an odd multiple of PI/2 radians. Rotate the box as well.
00582             INT32 t = qdy;
00583             qdy = qdx;
00584             qdx = t;
00585         }
00586         DocCoord i;
00587         if(qdy == 0)
00588         {
00589             // special case to avoid division by tan(0) = 0
00590             i.x = qdx;
00591             i.y = 0;
00592         }
00593         else
00594         {
00595             double predqdy = qdx * tan(cAngle);
00596             if(predqdy > qdy)
00597             {
00598                 // intersects on the horizontal
00599                 i.x = (INT32)(((double)qdy) / tan(cAngle));
00600                 i.y = qdy;
00601             }
00602             else
00603             {
00604                 // intersects on the vertical
00605                 i.x = qdx;
00606                 i.y = (INT32)(((double)qdx) * tan(cAngle));
00607             }
00608         }
00609 
00610         // i is the offset from the centre of the bbox where the line of the
00611         // grad fill rotated to the top right quadrent intersects with the
00612         // rectange of the bounding box.
00613 
00614         // now we need to work out the percentages along this line of the start
00615         // and stop bit.
00616         INT32 linelength = (INT32)sqrt(((double)(i.x) * (double)(i.x)) + ((double)(i.y) * (double)(i.y)));
00617         // chicken out clause #2
00618         if(linelength == 0)
00619             return WriteFillSpecFlat(pReg, pFill);
00620 
00621         // work out the start and end points as offsets from the centre point
00622         DocCoord    dStartPoint = StartPoint - Centre;
00623         DocCoord    dEndPoint   = EndPoint - Centre;
00624 
00625         // rotate these points around the origin
00626         // TODO: do the rotation myself, instead of going through matrices
00627         Matrix Mat(((- Angle) * 360.0) / (2*PI));   // why can't people use proper measure? 
00628         Mat.transform(&dStartPoint);
00629         Mat.transform(&dEndPoint);
00630 
00631         // find out the smallest distance from the end of the line
00632         INT32 dStart = dStartPoint.x + linelength;
00633         INT32 dEnd = linelength - dEndPoint.x;
00634         if(dStart < 0) dStart = 0;
00635         if(dEnd < 0) dEnd = 0;
00636         INT32 dPad;     // smallest of dStart and dEnd
00637         if(dStart < dEnd)
00638             dPad = dStart;
00639         else
00640             dPad = dEnd;
00641 
00642         INT32 padval = (dPad * 100) / (linelength * 2);
00643         if(padval < 0) padval = 0;
00644         if(padval > 44) padval = 44;
00645         fb1.Padding = (WORD)padval;
00646         
00647         // right, now munge the line length value to take account of this padding
00648         linelength -= dPad;
00649 
00650         // right then, we can now simply compare the x coords of the start and end
00651         // with the linelength above to find the start and end percentages
00652         StartPercent = (INT32)((dStartPoint.x + linelength) * 100);
00653         EndPercent = (INT32)((dEndPoint.x + linelength) * 100);
00654         StartPercent /= (linelength * 2);
00655         EndPercent /= (linelength * 2);
00656 
00657         // sanity check the numbers so Corel is happy
00658         if(StartPercent < 0) StartPercent = 0;
00659         if(StartPercent > 100) StartPercent = 100;
00660         if(EndPercent < 0) EndPercent = 0;
00661         if(EndPercent > 100) EndPercent = 100;
00662         if(EndPercent < StartPercent)
00663         {
00664             INT32 t = StartPercent;
00665             StartPercent = EndPercent;
00666             EndPercent = t;
00667         }
00668     } // else if ( !Radial )
00669 
00670     // I allege we now know enough to get this thing to the file
00671     // start the tag
00672     if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec_Fountain_Base))
00673         return FALSE;
00674 
00675     if(pFill->IsARadialFill())
00676         fb1.Type = cmxFOUNTAINTYPE_RADIAL;
00677     else if(pFill->IsASquareFill())
00678         fb1.Type = cmxFOUNTAINTYPE_SQUARE;
00679     else if(pFill->IsAConicalFill())
00680         fb1.Type = cmxFOUNTAINTYPE_CONICAL;
00681     else
00682         fb1.Type = cmxFOUNTAINTYPE_LINEAR;
00683     fb1.Screen = cmxSCREENREFERENCE;
00684     // padding set earlier
00685 
00686     // offsets set earlier
00687     fb2.StepCount = 0;
00688     fb2.FillMode = FillMode;
00689     fb2.RateMethod = 0;
00690     fb2.RateValue = 50;         // 50% is the centre, a commonly held belief
00691 
00692     if(!Radial)
00693     {
00694         if(FillMode == cmxFILLMODE_RGB)
00695         {
00696             // if it's an RGB mix in a linear fill, we can accurately
00697             // specify the fill by using a custom fill mode, and specifing
00698             // the end points presicely.
00699             fb2.FillMode = cmxFILLMODE_CUSTOM;
00700         }
00701         else
00702         {
00703             // if it's not an RGB mix, we need to approximate the fill using the
00704             // padding (set already) as we can't specify where we want the
00705             // colours to start and finish along the line of the fill
00706             StartPercent = 0;
00707             EndPercent = 0;
00708         }
00709     }
00710 
00711     // write the data
00712     ExportFile->write(&fb1, sizeof(fb1));
00713 
00714     WriteAngle(Angle);
00715 
00716     if(ThirtyTwoBit)
00717     {
00718         ExportFile->write(&fb2, sizeof(fb2));
00719     }
00720     else
00721     {
00722         // OK, so this way is a bit of a bodge
00723         cmxFillBase2_16 b = {0, (SWORD)fb2.XOffset, (SWORD)fb2.YOffset,
00724             fb2.StepCount, fb2.FillMode};
00725 
00726         ExportFile->write(&b, sizeof(b));
00727     }
00728 
00729     // end the tag
00730     if(!EndNestedTag())
00731         return FALSE;
00732 
00733     // write the colours
00734     if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec_Fountain_Color))
00735         return FALSE;
00736 
00737     cmxGradFillColour   col;
00738     ColourRamp          *pRamp  = pFill->GetColourRamp ();
00739     WORD                NCol    = 2 + ( ( StartPercent != 0 ) ? 1 : 0 ) +
00740                                   ( ( EndPercent != 100 ) ? 1 : 0 ) + ( FourColour ? 1 : 0 );
00741 
00742     // If the fill has a colour ramp, calculate the number of entries within it.
00743     if ( pRamp != NULL )
00744     {
00745         UINT32  FirstIndex  = 0;
00746         UINT32  LastIndex   = 0;
00747 
00748         // Call a member function to get the indices to the first and last elements within
00749         // the colour ramp.
00750         pRamp->GetIndexRange ( &FirstIndex, &LastIndex );
00751 
00752         // Add the difference between these to the number of colours to be exported. The +1
00753         // in this sum is necessary since the index values include the number of the element
00754         // that they represent. E.g. for a one element ramp, we have 1024 for both the first
00755         // and last items. Thus, without the +1, we would get 0 colours in the index.
00756         NCol += 1 + LastIndex - FirstIndex;
00757     }
00758 
00759     // Write the number of colours.
00760     ExportFile->write ( &NCol, sizeof ( NCol ) );
00761 
00762     // Write as many colours as necessary to get accurate fills. First the start colour.
00763     if(StartPercent != 0)
00764     {
00765         col.ColRef = StartColReference;
00766         col.ColPos = 0;
00767         ExportFile->write(&col, sizeof(col));
00768     }
00769 
00770     col.ColRef = StartColReference;
00771     col.ColPos = (WORD)StartPercent;
00772     ExportFile->write(&col, sizeof(col));
00773 
00774     // If it's a four colour fill, add the middle colour to the mix.
00775     if ( FourColour )
00776     {
00777         col.ColRef  = MidColReference;
00778         col.ColPos  = ( WORD ) ( ( StartPercent + EndPercent ) / 2 );
00779         ExportFile->write ( &col, sizeof ( col ) );
00780     }
00781 
00782     // Process the colour ramp.
00783     if ( pRamp != NULL )
00784     {
00785         ColRampItem *pColour = pRamp->GetFirstCol ();
00786 
00787         // Write in the ramp's colour values.
00788         while ( pColour != NULL )
00789         {
00790             cmxGradFillColour   RampColour;
00791 
00792             // Get the position of the colour in the fill.
00793             RampColour.ColPos   = ( WORD ) ( 100.0f * pColour->GetPosition () );
00794             RampColour.ColRef   = GetColourReference ( &( pColour->GetColour () ) );
00795 
00796             // Write the colour.
00797             ExportFile->write ( &RampColour, sizeof ( RampColour ) );
00798 
00799             // Increment the pointer onto the next item.
00800             pColour = pRamp->GetNextCol ( pColour );
00801         }
00802     }
00803 
00804     // And finally the end colour.
00805     col.ColRef = EndColReference;
00806     col.ColPos = (WORD)EndPercent;
00807     ExportFile->write(&col, sizeof(col));
00808 
00809     if(EndPercent != 100)
00810     {
00811         col.ColPos = 100;
00812         ExportFile->write(&col, sizeof(col));
00813     }
00814 
00815     if(!EndNestedTag())
00816         return FALSE;
00817 
00818     // write the ending bit
00819     if(!WriteMinEndTag())
00820         return FALSE;
00821 
00822     return TRUE;
00823 }

BOOL CMXExportDC::WriteFillType WORD  FillID  ) 
 

Writes the fill type to the DC.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/07/96
Parameters:
fill type [INPUTS]
Returns:
success

Definition at line 207 of file cmxdcobj.cpp.

00208 {
00209     ExportFile->write(&FillID, sizeof(FillID));
00210 
00211     return TRUE;
00212 }

BOOL CMXExportDC::WriteFutureDataCache  )  [protected]
 

Write the Numbers from the cache to the file See also:.

Author:
Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/07/96
Parameters:
none [INPUTS]
Returns:
Success

Definition at line 1758 of file cmxexdc.cpp.

01759 {
01760     //  Find out the current position in the file
01761     INT32 here = ExportFile->tell();
01762 
01763     for(INT32 i = 0 ; i < NumberOfEntriesUsedInCache ; i++)
01764     {   // write the numbers to file
01765         
01766         TRACEUSER( "Claude", _T("Writing cache %x at %d, size %d\n"),
01767                         FutureDataCache[i].Data,
01768                         FutureDataCache[i].Location, 
01769                         FutureDataCache[i].DataSize);
01770 
01771         //  Get the location where to put the info in the file
01772         ExportFile->seek(FutureDataCache[i].Location);
01773         
01774         if(FutureDataCache[i].DataSize != 0)
01775         {   //  If there is something flush it (there should always be something)
01776             
01777             switch(FutureDataCache[i].DataSize)
01778             {
01779                 case sizeof(BYTE):
01780                 {   //  If it's a BYTE, write a BYTE
01781                     BYTE Num = (BYTE)FutureDataCache[i].Data;
01782                     ExportFile->write(&Num, sizeof(Num));
01783                 }
01784                 break;
01785         
01786                 case sizeof(WORD):
01787                 {   //  If it's a WORD, write a WORD
01788                     WORD Num = (WORD)FutureDataCache[i].Data;
01789                     ExportFile->write(&Num, sizeof(Num));
01790                 }
01791                 break;
01792 
01793                 case sizeof(INT32):
01794                 {   //  If it's a INT32, write a INT32
01795                     INT32 Num = FutureDataCache[i].Data;
01796                     ExportFile->write(&Num, sizeof(Num));
01797                 }
01798                 break;
01799     
01800                 default:
01801                     //  If it's anything else, something went wrong
01802                     ERROR3("OOOKK! Non supported data size");
01803                 break;
01804             }
01805             //  Empty that entry of the cache, putting the Location to the maximum possible
01806             FutureDataCache[i].Location =   INT32_MAX;
01807             FutureDataCache[i].Data     =   0;
01808             FutureDataCache[i].DataSize =   0;
01809         }
01810     }   
01811     //  Put the file back to wherever it was before we used it
01812     ExportFile->seek(here);
01813 
01814     // reset the cache count thingy
01815     NumberOfEntriesUsedInCache = 0;
01816 
01817     return TRUE;
01818 }

BOOL CMXExportDC::WriteIndex void   ) 
 

writes the index for the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2346 of file cmxexdc.cpp.

02347 {
02348     // start the section
02349     if(!StartSection(CMXSECTION_INDEX))
02350         return FALSE;
02351 
02352     // write the layer index
02353     if(!WriteAnIndex(cmxINDEX_LAYER))
02354         return FALSE;
02355 
02356     // write the master layer index
02357     if(!WriteAnIndex(cmxINDEX_MASTERLAYER))
02358         return FALSE;
02359 
02360     // write the page index
02361     if(!WriteAnIndex(cmxINDEX_PAGE))
02362         return FALSE;
02363 
02364     // write the procedure index
02365     if(!WriteAnIndex(cmxINDEX_PROCEDURE))
02366         return FALSE;
02367 
02368     // write the embedded file index
02369     if(!WriteAnIndex(cmxINDEX_EMBEDFILE))
02370         return FALSE;
02371 
02372     // write the embedded file index
02373     if(!WriteAnIndex(cmxINDEX_ARROW))
02374         return FALSE;
02375 
02376     // write the master index
02377     if(!WriteAnIndex(cmxINDEX_MASTERINDEX))
02378         return FALSE;
02379 
02380     // end the section
02381     if(!EndSection())
02382         return FALSE;
02383 
02384     return TRUE;
02385 }

BOOL CMXExportDC::WriteMatrix Matrix pMatrix = NULL  ) 
 

writes a matrix to the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/06/96
Parameters:
matrix to write, NULL for identity matrix [INPUTS]
Returns:
success
See also:

Definition at line 1652 of file cmxexdc.cpp.

01653 {
01654     if(pMatrix == NULL)
01655     {
01656         // write an identity matrix
01657         WORD MatrixType = cmxMATRIXTYPE_IDENTITY;
01658         ExportFile->write(&MatrixType, sizeof(MatrixType));
01659     }
01660     else
01661     {
01662         // write the matrix
01663         cmxMatrix Thingy;
01664         FIXED16 abcd[4];
01665         INT32 ef[2];
01666         pMatrix->GetComponents((FIXED16 *)(&abcd), (INT32 *)(&ef));
01667         Thingy.Type = cmxMATRIXTYPE_GENERAL;
01668         Thingy.a = abcd[0].MakeDouble();
01669         Thingy.b = abcd[1].MakeDouble();
01670         Thingy.c = abcd[2].MakeDouble();
01671         Thingy.d = abcd[3].MakeDouble();
01672         Thingy.e = (DOUBLE)ef[0];
01673         Thingy.f = (DOUBLE)ef[1];
01674 
01675         ExportFile->write(&Thingy, sizeof(Thingy));
01676     }
01677 
01678     return TRUE;
01679 }

BOOL CMXExportDC::WriteMinEndTag void   )  [inline]
 

Definition at line 341 of file cmxexdc.h.

00341 {if(ThirtyTwoBit) WriteByte(cmxTAG_EndTag); return TRUE;};

BOOL CMXExportDC::WriteNestedTag INT32  Tag,
void *  Data = 0,
UINT32  Size = 0
[inline]
 

Definition at line 337 of file cmxexdc.h.

00338         {return DoWriteTag(Tag, Data, Size, TRUE);};

BOOL CMXExportDC::WriteNumber INT32  Position,
UINT32  DataSize,
INT32  Value
 

Finish off the file, update indexes and all that.

Author:
Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/06/96
Parameters:
none [INPUTS]
Returns:
success
Fixed by Ben so it doesn't write over the end of the array and screw up the other variables in the class and cause nasty AVs in retail builds which annoy Charles and take me ages to find.

Definition at line 1697 of file cmxexdc.cpp.

01698 {
01699 TRACEUSER( "Claude", _T("Writing number %x at %d, size %d\n"), Value, Position, DataSize);
01700 
01701     //  When cache full => Flush it to the file.
01702     if(NumberOfEntriesUsedInCache >= (CMXFUTUREVALUECACHESIZE - 1))
01703         WriteFutureDataCache();
01704 
01705     //  Variable used to find out what entry is to be used
01706     INT32 theEntryInCache = 0;
01707     
01708     //  Search for the right place in the cache, i.e. sort the cache as
01709     //  it's generated
01710     while((theEntryInCache < NumberOfEntriesUsedInCache) && (Position > FutureDataCache[theEntryInCache].Location))
01711         theEntryInCache++;
01712     
01713     TRACEUSER( "Claude", _T("Writing entry %d"), theEntryInCache);
01714     
01715     if(theEntryInCache < NumberOfEntriesUsedInCache)
01716     {   //  If the entry to use is before the last entry already used in the cache
01717         //  Push all entries used from the one we want onward.
01718         
01719         //  Variable used to determine which entry is to be pushed
01720         //  Starting from the end.
01721         
01722         for(INT32 entrySorting = NumberOfEntriesUsedInCache;
01723             entrySorting >= theEntryInCache; entrySorting--)
01724         {
01725             //  Copy the entry onto the next one
01726             FutureDataCache[entrySorting+1] = FutureDataCache[entrySorting];
01727         }
01728     }
01729     
01730     //  Copy the information into the cache
01731     FutureDataCache[theEntryInCache].Location   =   Position;
01732     FutureDataCache[theEntryInCache].Data       =   Value;
01733     FutureDataCache[theEntryInCache].DataSize   =   DataSize;
01734     
01735     TRACEUSER( "Claude", _T("Writing number %x at %d, size %d\n"),
01736                     FutureDataCache[theEntryInCache].Data,
01737                     FutureDataCache[theEntryInCache].Location, 
01738                     FutureDataCache[theEntryInCache].DataSize);
01739     //  Put the entry to use on the next one.
01740     NumberOfEntriesUsedInCache++;
01741     
01742     return TRUE;
01743 }

BOOL CMXExportDC::WriteOutlineSpec CMXRenderRegion pReg  ) 
 

writes the outline specification to the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/07/96
Parameters:
render region [INPUTS]
Returns:
sucess

Definition at line 1499 of file cmxdcobj.cpp.

01500 {
01501     // algorithm:
01502     // examine the render region and create the structures we want
01503     // this involves scanning the refer list to find the components of the
01504     // outline, and possibly adding new bits to it.
01505     // then, once we've got this structure, we need to scan the list
01506     // to see if it's already there. However, if we needed to create
01507     // anything new in the first phase, we can just skip this.
01508     // but we need to know how many outlines are in there, so
01509     // keep a count in the first bit.
01510 
01511     // find out the line width
01512     MILLIPOINT Width;
01513     // get the attribute
01514     LineWidthAttribute *pLineWidthA
01515             = (LineWidthAttribute *)pReg->GetCurrentAttribute(ATTR_LINEWIDTH);
01516 
01517     // check it out
01518     ERROR2IF(pLineWidthA == 0, FALSE, "No line width attribute");
01519     ERROR3IF(!pLineWidthA->IsKindOf(CC_RUNTIME_CLASS(LineWidthAttribute)), "not a line width attribute");
01520 
01521     Width = pLineWidthA->LineWidth;
01522 
01523     // find the colour
01524     DocColour *pColour;
01525     // get the attribute
01526     StrokeColourAttribute *pColA
01527             = (StrokeColourAttribute *)pReg->GetCurrentAttribute(ATTR_STROKECOLOUR);
01528     // check it out
01529     ERROR2IF(pColA == 0, FALSE, "No stroke colour attribute");
01530     ERROR3IF(!pColA->IsKindOf(CC_RUNTIME_CLASS(StrokeColourAttribute)), "not a stroke colour attribute");
01531 
01532     pColour = pColA->GetStartColour();
01533 
01534     // get the reference for the colour -- check to see if it's transparent
01535     BOOL TransparentLine = FALSE;
01536     WORD ColRef;
01537     if(pColour->IsTransparent())
01538     {
01539         TransparentLine = TRUE;
01540         Width = 0;                  // Graeme (15-2-00) - Remove line if transparent.
01541     }
01542     else
01543         ColRef = GetColourReference(pColour);
01544 
01545     // sort out the line style
01546     cmxLineStyle LineStyle;
01547     LineStyle.Spec = TransparentLine?cmxLINESPEC_NONE:0;
01548     LineStyle.CapAndJoin = 0;
01549 
01550     // find the join type
01551     // get the attribute
01552     JoinTypeAttribute *pJTA
01553             = (JoinTypeAttribute *)pReg->GetCurrentAttribute(ATTR_JOINTYPE);
01554     // check it out
01555     ERROR2IF(pJTA == 0, FALSE, "No join type attribute");
01556     ERROR3IF(!pJTA->IsKindOf(CC_RUNTIME_CLASS(JoinTypeAttribute)), "not a join type attribute");
01557     // set
01558     switch(pJTA->JoinType)
01559     {
01560         case RoundJoin: LineStyle.CapAndJoin |= cmxCAPJOIN_ROUNDJOIN; break;
01561         case BevelledJoin: LineStyle.CapAndJoin |= cmxCAPJOIN_BEVELJOIN; break;
01562         default: break;
01563     }
01564 
01565     // find the end cap
01566     // get the attribute
01567     StartCapAttribute *pSCA
01568             = (StartCapAttribute *)pReg->GetCurrentAttribute(ATTR_STARTCAP);
01569     // check it out
01570     ERROR2IF(pSCA == 0, FALSE, "No start cap attribute");
01571     ERROR3IF(!pSCA->IsKindOf(CC_RUNTIME_CLASS(StartCapAttribute)), "not a start cap attribute");
01572     // set
01573     switch(pSCA->StartCap)
01574     {
01575         case LineCapRound: LineStyle.CapAndJoin |= cmxCAPJOIN_ROUNDCAP; break;
01576         case LineCapSquare: LineStyle.CapAndJoin |= cmxCAPJOIN_SQUARECAP; break;
01577         default: break;
01578     }
01579 
01580     // find the dotdash pattern
01581     DashRec *pDash;
01582     DashPatternAttribute *pDas
01583             = (DashPatternAttribute *)pReg->GetCurrentAttribute(ATTR_DASHPATTERN);
01584     // check it out
01585     ERROR2IF(pDas == 0, FALSE, "No dash pattern attribute");
01586     ERROR3IF(!pDas->IsKindOf(CC_RUNTIME_CLASS(DashPatternAttribute)), "not a dash pattern attribute");
01587     // get it...
01588     pDash = &pDas->DashPattern;
01589 
01590     if(pDash->Elements != 0)
01591         LineStyle.Spec |= cmxLINESPEC_DOTDASH;
01592     else
01593         LineStyle.Spec |= cmxLINESPEC_SOLIDOUTLINE;
01594     
01595     // now we want to aquire some arrowhead references
01596     EndArrowAttribute *pEa
01597             = (EndArrowAttribute *)pReg->GetCurrentAttribute(ATTR_ENDARROW);
01598     // check it out
01599     ERROR2IF(pEa == 0, FALSE, "No arrow attribute");
01600     ERROR3IF(!pEa->IsKindOf(CC_RUNTIME_CLASS(EndArrowAttribute)), "not a arrow attribute");
01601     StartArrowAttribute *pSa
01602             = (StartArrowAttribute *)pReg->GetCurrentAttribute(ATTR_STARTARROW);
01603     // check it out
01604     ERROR2IF(pSa == 0, FALSE, "No arrow attribute");
01605     ERROR3IF(!pSa->IsKindOf(CC_RUNTIME_CLASS(StartArrowAttribute)), "not a arrow attribute");
01606 
01607     // get the arrow references
01608     WORD StartArrow = GetArrowReference(&pSa->StartArrow);
01609     WORD EndArrow = GetArrowReference(&pEa->EndArrow);
01610 
01611     // right then, we need to run through the table to construct the specification
01612     BOOL FoundPen = FALSE;          // whether we found the pen
01613     WORD PenRef = 0;                // reference number for the pen
01614     BOOL FoundLineStyle = FALSE;
01615     WORD LineStyleRef = 0;
01616     BOOL FoundArrowheads = FALSE;
01617     WORD ArrowheadsRef = 0;
01618     BOOL FoundDotDash = FALSE;
01619     WORD DotDashRef = 0;
01620 
01621     WORD LastOutlineRef = 0;        // count up the outlines to find out the ref of the last one
01622 
01623     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01624     while(pEn != 0)
01625     {
01626         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01627 
01628         switch(pEn->IsInWhichDesc())
01629         {
01630 
01631         case cmxDESC_PEN:
01632             if(!FoundPen)
01633             {
01634                 PenRef++;
01635 
01636                 CMXReferPen *pPen = (CMXReferPen *)pEn;
01637                 ERROR3IF(!pPen->IsKindOf(CC_RUNTIME_CLASS(CMXReferPen)), "not a refer pen, when it said it was");
01638                 
01639                 // is it this width?
01640                 if(pPen->AreYouThisWidth(Width))
01641                 {
01642                     // yes
01643                     FoundPen = TRUE;
01644                 }
01645             }
01646             break;
01647 
01648         case cmxDESC_LINESTYLE:
01649             if(!FoundLineStyle)
01650             {
01651                 LineStyleRef++;
01652 
01653                 CMXReferLineStyle *pSt = (CMXReferLineStyle *)pEn;
01654                 ERROR3IF(!pSt->IsKindOf(CC_RUNTIME_CLASS(CMXReferLineStyle)), "not a refer LineStyle, when it said it was");
01655                 
01656                 // is it this style?
01657                 if(pSt->AreYouThisStyle(&LineStyle))
01658                 {
01659                     // yes
01660                     FoundLineStyle = TRUE;
01661                 }
01662             }
01663             break;
01664 
01665         case cmxDESC_ARROWHEADS:
01666             if(!FoundArrowheads)
01667             {
01668                 ArrowheadsRef++;
01669 
01670                 CMXReferArrowheads *pAh = (CMXReferArrowheads *)pEn;
01671                 ERROR3IF(!pAh->IsKindOf(CC_RUNTIME_CLASS(CMXReferArrowheads)), "not a arrowheads, when it said it was");
01672                 
01673                 // is it this arrowheads?
01674                 if(pAh->AreYouThisArrowheads(StartArrow, EndArrow))
01675                 {
01676                     // yes
01677                     FoundArrowheads = TRUE;
01678                 }
01679             }
01680             break;
01681 
01682         case cmxDESC_DOTDASH:
01683             if(!FoundDotDash)
01684             {
01685                 DotDashRef++;
01686 
01687                 CMXReferDotDash *pDd = (CMXReferDotDash *)pEn;
01688                 ERROR3IF(!pDd->IsKindOf(CC_RUNTIME_CLASS(CMXReferDotDash)), "not a refer dot dash, when it said it was");
01689                 
01690                 // is it this style?
01691                 if(pDd->AreYouThisDotDash(pDash))
01692                 {
01693                     // yes
01694                     FoundDotDash = TRUE;
01695                 }
01696             }
01697             break;
01698 
01699         case cmxDESC_OUTLINE:
01700             LastOutlineRef++;       // inc the ref for each outline object enountered
01701             break;
01702 
01703         default:
01704             // do nothing
01705             break;
01706         }
01707 
01708         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01709     }
01710 
01711     // right then, create some new refer objects if necessary
01712     BOOL NewReferObjectCreated = FALSE;     // whether an refer object was created
01713 
01714     if(!FoundPen)
01715     {
01716         NewReferObjectCreated = TRUE;
01717         // knock up a pen object
01718         CMXReferPen *pPen = new CMXReferPen(this);
01719         if(pPen == NULL)
01720             return FALSE;
01721 
01722         pPen->SetWidth(Width);
01723         PenRef++;               // the reference
01724 
01725         ReferList.AddTail(pPen);
01726     }
01727 
01728     if(!FoundLineStyle)
01729     {
01730         NewReferObjectCreated = TRUE;
01731         // knock up a pen object
01732         CMXReferLineStyle *pLs = new CMXReferLineStyle(this);
01733         if(pLs == NULL)
01734             return FALSE;
01735 
01736         pLs->SetLineStyle(&LineStyle);
01737         LineStyleRef++;             // the reference
01738 
01739         ReferList.AddTail(pLs);
01740     }
01741 
01742     if(!FoundArrowheads)
01743     {
01744         NewReferObjectCreated = TRUE;
01745         // knock up a pen object
01746         CMXReferArrowheads *pAh = new CMXReferArrowheads(this);
01747         if(pAh == NULL)
01748             return FALSE;
01749 
01750         pAh->SetArrowheads(StartArrow, EndArrow);
01751         ArrowheadsRef++;                // the reference
01752 
01753         ReferList.AddTail(pAh);
01754     }
01755 
01756     if(!FoundDotDash)
01757     {
01758         NewReferObjectCreated = TRUE;
01759         // knock up a pen object
01760         CMXReferDotDash *pDd = new CMXReferDotDash(this);
01761         if(pDd == NULL)
01762             return FALSE;
01763 
01764         pDd->Set(pDash);
01765         DotDashRef++;               // the reference
01766 
01767         ReferList.AddTail(pDd);
01768     }
01769 
01770     // make up an outline def
01771     cmxOutline Outline;
01772     memset(&Outline, 0, sizeof(Outline));
01773 
01774     Outline.LineStyle = LineStyleRef;
01775     Outline.Screen = cmxSCREENREFERENCE;
01776     if(TransparentLine)
01777         Outline.Colour = 1;     // any random number will do as long the colour exists
01778     else
01779         Outline.Colour = ColRef;
01780     Outline.Arrowheads = ArrowheadsRef;
01781     Outline.Pen = PenRef;
01782     Outline.DotDash = DotDashRef;
01783 
01784     // run through the table to see if there's a 
01785     BOOL FoundOutline = FALSE;
01786     WORD OutlineRef = 0;
01787     if(NewReferObjectCreated == FALSE) // only bother looking if no new objects have been created
01788     {
01789         CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01790         while(pEn != 0)
01791         {
01792             ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01793 
01794             if(pEn->IsInWhichDesc() == cmxDESC_OUTLINE)
01795             {
01796                 OutlineRef++;
01797 
01798                 CMXReferOutline *pLC = (CMXReferOutline *)pEn;
01799                 ERROR3IF(!pLC->IsKindOf(CC_RUNTIME_CLASS(CMXReferOutline)), "not a refer outline, when it said it was");
01800                 
01801                 // is it this outline?
01802                 if(pLC->AreYouThisOutline(&Outline))
01803                 {
01804                     FoundOutline = TRUE;
01805                     break;
01806                 }
01807             }
01808 
01809             pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01810         }
01811     }
01812 
01813     // right then, maybe we want to create a new outline object?
01814     if(FoundOutline == FALSE)
01815     {
01816         OutlineRef = LastOutlineRef + 1;
01817 
01818         // make a new object
01819         CMXReferOutline *pOlt = new CMXReferOutline(this);
01820         if(pOlt == NULL)
01821             return FALSE;
01822 
01823         // set it's outline thingy
01824         pOlt->SetOutline(&Outline);
01825 
01826         // and add it to the list
01827         ReferList.AddTail(pOlt);
01828     }
01829 
01830     // finally, write the reference to the file
01831     if(!WriteNestedTag(cmxTAG_RenderAttr_OutlineSpec, &OutlineRef, sizeof(OutlineRef)))
01832         return FALSE;
01833 
01834     // and the end tag
01835     if(!WriteMinEndTag())
01836         return FALSE;
01837 
01838     return TRUE;
01839 }

BOOL CMXExportDC::WritePath DocCoord Coords,
PathVerb Verbs,
INT32  NumCoords,
BOOL  Filled
 

Writes a path instruction -- transformed by matrix.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
01/07/96
Parameters:
render region, coords, verbs and number of coords [INPUTS]
Returns:
success

Definition at line 973 of file cmxdcobj.cpp.

00977 {
00978     // if this is one of those nasty 16 bit files, sort out a transform matrix
00979 
00980     // scan the verbs to see if there's a close path in it
00981     // as if there isn't, we need to force no fill on the thingy
00982     BOOL ForceNoFill = TRUE;
00983     for(INT32 p = 0; p < NumCoords; p++)
00984     {
00985         if((Verbs[p] & PT_CLOSEFIGURE) != 0)
00986             ForceNoFill = FALSE;
00987     }
00988     if(!Filled)
00989         ForceNoFill = TRUE;
00990 
00991     // begin the command
00992     if(!StartCommand(cmxINSTR_PolyCurve))
00993         return FALSE;
00994 
00995     // output the rendering attributes
00996     if(!WriteAttributes(pRenderRegion, cmxTAG_PolyCurve_RenderingAttr, Coords, NumCoords, ForceNoFill))
00997         return FALSE;
00998 
00999     // write the point list, transformed of course. Start by tagging it
01000     if(!StartTag(cmxTAG_PolyCurve_PointList))
01001         return FALSE;
01002 
01003     // we have to collect a bounding box as we go through as Corel use a
01004     // naff bbox which is simply the union of all points
01005     DocRect bb;             // which is written as a corel one
01006     DocCoord fc = Coords[0];
01007     pMatrix->transform(&fc);
01008     bb.lo = fc;             // start with sensible coords to begin with
01009     bb.hi = fc;
01010 
01011     // write the point count
01012     WORD Count = (WORD)NumCoords;
01013     ExportFile->write(&Count, sizeof(Count));
01014 
01015     // run through the coords writing and transforming
01016     INT32 l;
01017 TRACEUSER( "Ben", _T("\nPath\n"));
01018     for(l = 0; l < NumCoords; l++)
01019     {
01020         DocCoord Coord = Coords[l];
01021         pMatrix->transform(&Coord);
01022 
01023         // write it...
01024         if(ThirtyTwoBit)
01025         {
01026             cmxPoint32 p = {Coord.x, Coord.y};
01027             ExportFile->write(&p, sizeof(p));
01028         }
01029         else
01030         {
01031 TRACEUSER( "Ben", _T("Coord %d %d\n"), Coord.x, Coord.y);
01032             cmxPoint16 p = {(SWORD)Coord.x, (SWORD)Coord.y};
01033             ExportFile->write(&p, sizeof(p));
01034         }
01035 
01036         // flibble the bounding box with those lovely new coords
01037         if(Coord.x < bb.lo.x) bb.lo.x = Coord.x;
01038         if(Coord.y < bb.lo.y) bb.lo.y = Coord.y;
01039         if(Coord.x > bb.hi.x) bb.hi.x = Coord.x;
01040         if(Coord.y > bb.hi.y) bb.hi.y = Coord.y;
01041     }
01042 
01043     // run through the verbs writing point types
01044     INT32 BezCount = 0;     // for counting Bez
01045     for(l = 0; l < NumCoords; l++)
01046     {
01047         BYTE Type;
01048 
01049         switch(Verbs[l] & (PT_LINETO | PT_MOVETO | PT_BEZIERTO))
01050         {
01051         case PT_MOVETO:
01052             {
01053                 Type = CMXNODETYPE_TYPE_MOVE | CMXNODETYPE_USER;
01054             
01055                 // wibble forwards through the verbs to see if the correspondingness is closed
01056                 for(INT32 lp = l + 1; lp < NumCoords; lp++)
01057                 {
01058                     // OK, is this a move?
01059                     if((Verbs[lp] & (PT_LINETO | PT_MOVETO | PT_BEZIERTO)) == PT_MOVETO)
01060                         break;
01061 
01062                     // is closefigure set?
01063                     if((Verbs[lp] & PT_CLOSEFIGURE) != 0)
01064                     {
01065                         Type |= CMXNODETYPE_CLOSED;
01066                         break;
01067                     }
01068                 }
01069             }
01070             BezCount = 0;
01071             break;
01072 
01073         case PT_LINETO:
01074             Type = CMXNODETYPE_TYPE_LINE | CMXNODETYPE_USER;
01075             BezCount = 0;
01076             break;
01077 
01078         case PT_BEZIERTO:
01079             // in CMX, the control points have type ARC, and the end points
01080             // have type CURVE. This code does the trickery.
01081             if(BezCount == 2)
01082             {
01083                 Type = CMXNODETYPE_TYPE_CURVE | CMXNODETYPE_USER;
01084             }
01085             else
01086             {
01087                 Type = CMXNODETYPE_TYPE_ARC;
01088             }
01089             BezCount++;
01090             if(BezCount > 2)
01091                 BezCount = 0;       // so that only the end points of beziers get user flag
01092             break;
01093 
01094         default:
01095             ERROR3("Unknown node type");
01096             break;
01097         }
01098 
01099         if((Verbs[l] & PT_CLOSEFIGURE) != 0)
01100         {
01101             Type |= CMXNODETYPE_CLOSED;
01102         }
01103 
01104         ExportFile->write(&Type, sizeof(Type));
01105     }
01106 
01107     // end the point list
01108     if(!EndTag())
01109         return FALSE;
01110 
01111     // write bbox we've collected
01112     if(!StartTag(cmxTAG_PolyCurve_BoundingBox)
01113         || !WriteBBox(&bb, FALSE)
01114         || !EndTag())
01115         return FALSE;
01116 
01117     // end the command
01118     if(!WriteMinEndTag()
01119         || !EndCommand())
01120         return FALSE;
01121 
01122     // if necessary, get rid of the horrid transform matrix
01123 
01124     return TRUE;
01125 }

BOOL CMXExportDC::WritePreviewBitmap void   ) 
 

writes a preview bitmap type thing

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/08/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 3128 of file cmxexdc.cpp.

03129 {
03130     Filter* pFilter = NULL;
03131     pFilter = Filter::GetFirst();
03132     while ((pFilter != NULL) && (pFilter->FilterID != FILTERID_PREVIEW_BMP))
03133     {
03134         // Try the next filter
03135         pFilter = Filter::GetNext(pFilter);
03136     }
03137 
03138     // Make sure that we found the preview bitmap filter
03139     if ((pFilter != NULL) && (pFilter->IS_KIND_OF(BaseBitmapFilter)))
03140     {
03141         // write the index of this thumbnail section
03142         ThumbnailIndexFuture.Write(this);
03143 
03144         // start the section
03145         if(!StartSection(CMXSECTION_PREVIEWBITMAP))
03146             return FALSE;
03147 
03148         // write a number
03149         DWORD Eight = 8;
03150         Eight = NativetoLE(Eight);
03151         ExportFile->write(&Eight, sizeof(Eight));
03152 
03153         // fudge things a bit
03154         INT32 Start = ExportFile->tell();
03155         BITMAPFILEHEADER hdr;
03156         ExportFile->seek(Start - sizeof(hdr));
03157         ExportFile->read(&hdr, sizeof(hdr));
03158         ExportFile->seek(Start - sizeof(hdr));
03159 
03160         //WEBSTER-Martin-03/01/97
03161         // force the Preview to a fixed size
03162         INT32 OldPreviewSize = PreviewFilter::PreviewBitmapSize;
03163         // Set the Preview to be just over an inch accross
03164         PreviewFilter::PreviewBitmapSize = 96000;
03165 
03166         // Get as Bitmap Filter and set it up
03167         BaseBitmapFilter* pBitmapFilter = (BaseBitmapFilter*) pFilter;
03168         pBitmapFilter->SetPreviewBitmap(TRUE);
03169 
03170         // Export the Preview to the file
03171         BOOL ok = pFilter->DoExport(pOp, ExportFile, pPath, TheDocument);
03172         // If the Preview bitmap failed to export then we still need to clean up
03173 
03174         // Set it back
03175         pBitmapFilter->SetPreviewBitmap(FALSE);
03176         // Set the Preview back to its default setting
03177         PreviewFilter::PreviewBitmapSize = OldPreviewSize;
03178 
03179         // replace the data which was overwritten
03180         INT32 Here = ExportFile->tell();
03181         ExportFile->seek(Start - sizeof(hdr));
03182         ExportFile->write(&hdr, sizeof(hdr));
03183         ExportFile->seek(Here);
03184 
03185         // finish the section
03186         if(!EndSection())
03187             return FALSE;
03188 
03189         return ok;
03190     }
03191 
03192     return TRUE;
03193 }

BOOL CMXExportDC::WriteReferenceList void   ) 
 

writes the reference list for the page we've just done

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2286 of file cmxexdc.cpp.

02287 {
02288     // first, find the number of entries in this list
02289     WORD RefListEntries = 0;
02290     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
02291     while(pEn != 0)
02292     {
02293         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "Entry in the refer list isn't a correct list item");
02294 
02295         if(pEn->IsInReferenceList())
02296             RefListEntries++;
02297 
02298         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02299     }
02300 
02301     // set the location in the page reference item
02302     ERROR2IF(PageRefer == NULL, FALSE, "no page reference item");
02303     PageRefer->SetRefListOffset(GetFilePosition());
02304     RefListOffset = GetFilePosition();
02305 
02306     // start the section
02307     if(!StartSection(CMXSECTION_REFLIST))
02308         return FALSE;
02309 
02310     // write the number of entries in the list
02311     ExportFile->write(&RefListEntries, sizeof(RefListEntries));
02312 
02313     // write the entries
02314     pEn = (CMXReferListItem *)ReferList.GetHead();
02315     while(pEn != 0)
02316     {
02317         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "Entry in the refer list isn't a correct list item");
02318 
02319         if(!pEn->WriteInReferenceList(this))
02320             return FALSE;
02321 
02322         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02323     }
02324 
02325     // end the section
02326     if(!EndSection())
02327         return FALSE;
02328 
02329     return TRUE;
02330 }

BOOL CMXExportDC::WriteReferSections void   ) 
 

gets all refer list items which are sections to write themselves

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/07/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 2464 of file cmxexdc.cpp.

02465 {
02466     // wander through the list
02467     CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
02468     while(pEn != 0)
02469     {
02470         ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02471 
02472         if(pEn->IsASection())
02473         {
02474             if(!pEn->WriteSection(this))
02475                 return FALSE;
02476         }
02477 
02478         pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02479     }
02480 
02481     return TRUE;
02482 }

void CMXExportDC::WriteSizeInFile WORD  Size  )  [inline]
 

Definition at line 293 of file cmxexdc.h.

00293 {if(ThirtyTwoBit) ExportFile->write(&Size, sizeof(Size));};

BOOL CMXExportDC::WriteString StringBase Str  ) 
 

Write a bounding box to the file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/06/96
Parameters:
none [INPUTS]
Returns:
success
See also:

Definition at line 1626 of file cmxexdc.cpp.

01627 {
01628     INT32 StrLen = Str->Length();
01629 
01630     cmxString h;
01631     h.Length = (WORD)StrLen;
01632     ExportFile->write(&h, sizeof(h));
01633 
01634     ExportFile->write((TCHAR *)(*Str), StrLen);
01635 
01636     return TRUE;
01637 }

BOOL CMXExportDC::WriteTag INT32  Tag,
void *  Data = 0,
UINT32  Size = 0
[inline]
 

Definition at line 331 of file cmxexdc.h.

00332         {return DoWriteTag(Tag, Data, Size, FALSE);};


Member Data Documentation

BOOL CMXExportDC::AreIgnoreingOverlappedLenses [private]
 

Definition at line 435 of file cmxexdc.h.

CMXFutureLength CMXExportDC::CommandLengthFuture [private]
 

Definition at line 402 of file cmxexdc.h.

INT32 CMXExportDC::CurrentInstrFilePosition [private]
 

Definition at line 425 of file cmxexdc.h.

CMXSectionType CMXExportDC::CurrentSection [private]
 

Definition at line 389 of file cmxexdc.h.

BOOL CMXExportDC::DoingCommand [private]
 

Definition at line 409 of file cmxexdc.h.

BOOL CMXExportDC::DoingLayer [private]
 

Definition at line 411 of file cmxexdc.h.

BOOL CMXExportDC::DoingPage [private]
 

Definition at line 410 of file cmxexdc.h.

BOOL CMXExportDC::DoingRIFFList [private]
 

Definition at line 414 of file cmxexdc.h.

BOOL CMXExportDC::DoingTag [private]
 

Definition at line 412 of file cmxexdc.h.

CMXFutureLength CMXExportDC::FileLengthFuture [private]
 

Definition at line 394 of file cmxexdc.h.

INT32 CMXExportDC::FirstInstrFilePosition [private]
 

Definition at line 424 of file cmxexdc.h.

CMXFutureDataCacheEntry CMXExportDC::FutureDataCache[128] [private]
 

Definition at line 428 of file cmxexdc.h.

List CMXExportDC::GroupList [private]
 

Definition at line 422 of file cmxexdc.h.

BOOL CMXExportDC::HaveAskedUserAboutLenses [private]
 

Definition at line 436 of file cmxexdc.h.

CMXFutureIndex CMXExportDC::IndexSectionFuture [private]
 

Definition at line 403 of file cmxexdc.h.

CMXFutureNumber CMXExportDC::LayerFlags [private]
 

Definition at line 401 of file cmxexdc.h.

CMXFutureNumber CMXExportDC::LayerInstructionCount [private]
 

Definition at line 400 of file cmxexdc.h.

WORD CMXExportDC::LayerNumber [private]
 

Definition at line 413 of file cmxexdc.h.

List CMXExportDC::LensBBoxes [private]
 

Definition at line 433 of file cmxexdc.h.

INT32 CMXExportDC::NestedTagLevel [private]
 

Definition at line 417 of file cmxexdc.h.

List CMXExportDC::NestedTagList [private]
 

Definition at line 418 of file cmxexdc.h.

INT32 CMXExportDC::NumberOfEntriesUsedInCache [private]
 

Definition at line 427 of file cmxexdc.h.

BOOL CMXExportDC::OverlappedLensesHaveBeenIgnored [private]
 

Definition at line 434 of file cmxexdc.h.

CMXFutureIndex CMXExportDC::PageEndIndexFuture [private]
 

Definition at line 396 of file cmxexdc.h.

CMXFutureNumber CMXExportDC::PageFlags [private]
 

Definition at line 399 of file cmxexdc.h.

CMXFutureNumber CMXExportDC::PageGroupCount [private]
 

Definition at line 398 of file cmxexdc.h.

CMXFutureNumber CMXExportDC::PageInstructionCount [private]
 

Definition at line 397 of file cmxexdc.h.

BOOL CMXExportDC::PageIsProc [private]
 

Definition at line 415 of file cmxexdc.h.

CMXReferPage* CMXExportDC::PageRefer [private]
 

Definition at line 420 of file cmxexdc.h.

Matrix* CMXExportDC::pMatrix [private]
 

Definition at line 423 of file cmxexdc.h.

Operation* CMXExportDC::pOp [private]
 

Definition at line 439 of file cmxexdc.h.

PathName* CMXExportDC::pPath [private]
 

Definition at line 440 of file cmxexdc.h.

CMXRenderRegion* CMXExportDC::pRenderRegion [private]
 

Definition at line 387 of file cmxexdc.h.

List CMXExportDC::ReferList [private]
 

Definition at line 419 of file cmxexdc.h.

INT32 CMXExportDC::RefListOffset [private]
 

Definition at line 421 of file cmxexdc.h.

CMXFutureLength CMXExportDC::RIFFListLengthFuture [private]
 

Definition at line 407 of file cmxexdc.h.

double CMXExportDC::ScaleFactor [private]
 

Definition at line 430 of file cmxexdc.h.

CMXFutureLength CMXExportDC::SectionLengthFuture [private]
 

Definition at line 390 of file cmxexdc.h.

CMXFutureLength CMXExportDC::TagLengthFuture [private]
 

Definition at line 406 of file cmxexdc.h.

CMXFutureNumber CMXExportDC::Tally [private]
 

Definition at line 395 of file cmxexdc.h.

Document* CMXExportDC::TheDocument [private]
 

Definition at line 438 of file cmxexdc.h.

BOOL CMXExportDC::ThirtyTwoBit [private]
 

Definition at line 392 of file cmxexdc.h.

CMXFutureIndex CMXExportDC::ThumbnailIndexFuture [private]
 

Definition at line 405 of file cmxexdc.h.

CMXFutureIndex CMXExportDC::TrailerIndexFuture [private]
 

Definition at line 404 of file cmxexdc.h.


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