CDRFilter Class Reference

Corel Draw file importing class. More...

#include <cdrfiltr.h>

Inheritance diagram for CDRFilter:

VectorFilter Filter ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 CDRFilter ()
 Constructor.
BOOL Init ()
 Initialisation.
INT32 HowCompatible (PathName &Filename, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize)
 Examines a file to see how compatable it is with this filter.
BOOL DoImport (SelOperation *, CCLexFile *, Document *, BOOL AutoChosen=FALSE, ImportPosition *Pos=NULL, KernelBitmap **ppImportedBitmap=NULL, DocCoord *pPosTranslate=NULL, String_256 *=NULL)
BOOL DoExport (Operation *, CCLexFile *, PathName *, Document *, BOOL)
 Refuses to export a Corel Palette file.

Static Public Member Functions

static void DeleteNodeList (Node *)
 Deletes a linked list of nodes (forward direction only).
static BOOL GetCorelBBox (NodeRenderableBounded *pNode, DocRect *BBox)
 gets the Corel simple union bbox of an object
static ADDR FindDataInObject (cdrfOffsetHeader *Header, WORD Type)
 returns the address of data of the given type in an objects with a standard offset header
static BOOL AddElementsToPath (Path *pPath, INT32 NCoords, cdrfCoord *Coords, BYTE *Types, BOOL *IsClosed)
 Adds elements to a path from a CDR path data.
static BOOL AddStandardColourSet (Document *pDocument)
 Adds the standard set of colours to a Corel file.
static BOOL HasCDRFileGotCMXFile (PathName *FileName, CCLexFile *pFile=NULL)
 to find out whether a CDR file has got a CMX file in it, and therefore whether the CMX filter should grab it instead of this one

Static Public Attributes

static INT32 BitmapNumber = 0
static INT32 PatternNumber = 0

Private Member Functions

 CC_DECLARE_DYNAMIC (CDRFilter)
BOOL ClearUp (void)
 Clears up after an CDR file import.
BOOL UpdateProgress (BOOL Now=FALSE)
 Updating the progress everysooften - called at every significant place to get a nice smooth update on that progress bar thingy.
BOOL ProcessDoc (void)
 Processes the root level doc chunk of a CDR file.
BOOL ProcessPage (void)
 Processes a page list of a CDR file.
BOOL ProcessLayer (void)
 Processes a layer list of a CDR file. This is the function which actually grabs objects to convert.
BOOL ProcessObjectTree (UINT32 Level)
 process objects from the CDR file - they end up linked to pLevelNodeList.
BOOL ProcessObject (void)
 Converts an object. If there's a problem with the object, then it's skipped rather than reporting an error, and the count of problem objects incremented.
BOOL ProcessGroup (UINT32 Level, BOOL FromLink=FALSE)
 Sets up a group end action and alters the level node list to be a new list.
BOOL ProcessLink (void)
 Sets up a group end action and a post transform action and alters the level node list to be a new list.
BOOL ProcessVectorList (ADDR Block, INT32 Size)
 processes the vector list at the beginning of CDR files. This contains a list of objects which are used for things such as full colour fills, texture fills, mould shapes, that sort of thing.
BOOL ProcessVectorListEntry ()
 processes an entry in the vector list
BOOL ProcessTextList4 ()
 Processes the list of text objects for a version 4 CDR file creating text lines and textchars with partially applied attributes.
BOOL ProcessTextListItem4 ()
 Processes a item from the list of text objects for a version 4 CDR file creating text lines and textchars with partially applied attributes.
BOOL ConvertRectangle (cdrfOffsetHeader *)
BOOL ConvertEllipse (cdrfOffsetHeader *)
 generates an ellipse object
BOOL ConvertPath (cdrfOffsetHeader *)
 actually converts a path object to a node. If the object has an unexpected format, then FormatError is set and it return *TRUE* - the return value only indicated environmental errors such as lack of memory
BOOL ConvertText (cdrfOffsetHeader *)
 converts a text object to a node. If the object has an unexpected format, then FormatError is set and it return *TRUE* - the return value only indicated environmental errors such as lack of memory
BOOL ConvertText4Art (cdrfOffsetHeader *)
 converts a version 4 artisitic text object
BOOL ConvertText4Para (cdrfOffsetHeader *)
 converts a version 4 paragraph text object
BOOL ConvertText3 (cdrfOffsetHeader *)
 converts a version 3 text object to a node. If the object has an unexpected format, then FormatError is set and it return *TRUE* - the return value only indicated environmental errors such as lack of memory
BOOL ConvertBitmap (cdrfOffsetHeader *)
BOOL SetLineAttr (cdrfOffsetHeader *Object)
BOOL SetFillAttr (cdrfOffsetHeader *Object)
 sets the fill attributes
BOOL SetLineAttr3 (cdrfOffsetHeader *Object)
BOOL SetFillAttr3 (cdrfOffsetHeader *Object)
 sets the fill attributes for version 3
BOOL SetFillAttrFlat (cdrfFillHeader *Fill, INT32 Size)
 sets flat fill attributes
BOOL SetFillAttrGrad (cdrfFillHeader *Fill, INT32 Size)
 sets graduated fill attributes
BOOL SetUKFill (void)
 sets a fill attribute for unknown fills
BOOL SetLinearGrad (CDRFillInfo *GFill, DocRect &BBox, DocColour *StartColour, DocColour *EndColour)
 sets a linear graduated fill from fill definition in the file Copied from coreleps.cpp and modified
BOOL SetRadialGrad (CDRFillInfo *GFill, DocRect &BBox, DocColour *StartColour, DocColour *EndColour)
 sets a radial graduated fill from fill definition in the file
BOOL SetConicalGrad (CDRFillInfo *GFill, DocRect &BBox, DocColour *StartColour, DocColour *EndColour)
 sets a conical graduated fill from fill definition in the file Copied from coreleps.cpp and modified
BOOL SetFillAttrPattern (CDRTiledFillInfo *Info, DocColour *Colour1, DocColour *Colour2)
 set pattern fill attributes
BOOL SetFillAttrTexture (cdrfFillHeader *Fill, INT32 Size)
 sets texture fill attributes
BOOL SetFillAttrVector (CDRTiledFillInfo *Info)
 set vector fill attributes
BOOL NoFill (void)
 makes an object not filled
BOOL AddAttributesToArrowheadNode (NodeRenderableBounded *N, DocColour *Col, INT32 LineWidth, LineCapType Cap, JointType Join)
 apply attributes to a arrow head node
BOOL AddAttributesToArrowheadPath (NodePath *P, DocColour *Col, INT32 LineWidth, LineCapType Cap, JointType Join)
 apply attributes to a arrow head path
BOOL DoesPathNeedArrowheads (NodePath *P)
 To find out whether a path need attributes.
BOOL TransformArrowhead (NodeRenderableBounded *N, DocCoord *Point, DocCoord *Other, BOOL Start, INT32 LineWidth, INT32 Distance)
 transform an arrowhead path to be the correct size and orientation
BOOL AddArrowheadsToPath (DWORD StartArrow, DWORD EndArrow, DocColour *Col, INT32 LineWidth, LineCapType Cap, JointType Join)
 adds arrowheads to a path. Changes pMadeNode from a path to a group
BOOL ConvertColour (cdrfColour *Col, DocColour *Out)
 converts a colour from the CDR definition taking into account the version
BOOL IsTransformJustMatrices (ADDR Trans, INT32 Size)
 scans a transform chunk. Returns TRUE if the transform was just composed of matrices and unknown transforms.
BOOL TransformConvertedObject (NodeRenderable **N, ADDR Trans, INT32 Size, BOOL TranslateForPage=TRUE, BOOL IsAGroupTransform=FALSE, BOOL WorkAtOrigin=FALSE)
 transforms an object we converted, given a trfd chunk. If TranslateForPage is true (defaults to TRUE) then the object will also be translated to get the origin in the right place. The pointer may be modified to be a pointer to a different object. WorkAtOrigin causes the object to be translated back to the origin before being hacked apon, except if it's in a CDR3 file when it's ignored as the file is mass-translated at the end of the conversion..
BOOL TransformConvertedObjectDoMatrix (NodeRenderable **N, cdrMatrix *Ma, BOOL TranslateForPage)
 transforms an object given a CDR matrix
BOOL TransformConvertedObjectDoPerspective (NodeRenderable **N, cdrPerspective *P, BOOL TranslateShapeForPage=FALSE)
BOOL TransformConvertedObjectDoEnvelope (NodeRenderable **N, Path *P, DocRect *OriginalBBox, INT32 *Corners, BOOL TranslateShapeForPage=FALSE)
 transforms an object given a path to envelope into
BOOL TransformConvertedObjectDoExtrude (NodeRenderable **N, cdrExtrudeInfo *Info, BOOL TranslateShapeForPage=FALSE)
 performs a extrude transform
BOOL TransformConvertedObjectDoExtrudeTransPath (NodePath *pPath, cdrExtrudeInfo *Info)
 does the extrude transform on a path
BOOL GetMatrixFromTransform (Matrix *M, ADDR Trans, INT32 Size, BOOL TranslateForPage=TRUE)
 given some transform data, works out a matrix. This ignores any 3D transforms, TransformConvertedObject should be used in preference.
BOOL GetObjCorelBBox (NodeRenderableBounded *pNode, DocRect *BBox)
 gets the corel bbox of a converted object, looking up the bbox of text objects
KernelBitmapBitmapFromNodeList (Node *List)
 given a list of nodes, if it only contains one bitmap then return a pointer to that bitmap
BOOL MakeTextOnPathLinkList ()
 creates the list of paths which should be linked to text stories to get text on paths.
BOOL AttachTextToPaths ()
 attachs paths to text stories from the list of links.
BOOL CheckTextForLinks (TextStory *pTextStory, cdrfOffsetHeader *Header)
 checks to see if this text story is in the link table
BOOL GetTextStyleFromCDRStyle (CDRTextStyle *TS, WORD StyleRef, BOOL SearchForParent=TRUE)
 gets a text style from a CDR style. If it can't be found, you get the default text style. If SearchForParent is TRUE, the parent style of this style will be located
BOOL GetTextStyleFromDefn (CDRTextStyle *TS, cdrfTextInfoFontDefn *FontDefn, const CDRTextStyle *BasedOn)
 gets a font style from a font definition stored in a txsm chunk. Anything not defined comes from the BasedOn style.
BOOL ApplyTextAttr (Node *ContextNode, const CDRTextStyle *TS, const CDRTextStyle *BasedOn)
 Applies text attributes to a node from a CDRTextStyle. If BasedOn != 0 then the attributes will only be applied if they are different from those in *BasedOn.
BOOL ApplyTextAttrDoApply (Node *ContextNode, TxtBaseClassAttribute *Attr, BOOL CheckExisting)
 Given a text attribute, apply it to a node. If CheckExising is TRUE, the existing attributes will be checked, and this attribute will not be applied if one of it's type already exists.
TCHARGetFontName (WORD FontRef)
 finds a font name
BOOL GetTextStyle3 (CDRTextStyle *TS, WORD Style, CDRTextStyle *BasedOn=0)
 gets a style for version 3 text from the global text styles table
BOOL GetTextStyleFromChar4 (CDRTextStyle *TS, cdrfTextCharStyledV4 *Char, CDRTextStyle *BasedOn)
 gets a text style from a styled version 4 text character

Private Attributes

friend CDRActionTransform
friend CDRActionGroupEnd
friend CDRBitmapStore
friend CDRBitmap
DocumentpDocument
SpreadpSpread
PagepPage
CDRVersion Version
BOOL Success
RIFFFileRIFF
UndoableOperationThisOp
BOOL SlowJobStarted
UINT32 ProgressCount
BOOL InMasterPage
BOOL DoneMasterPage
BOOL DoneDoc
BOOL UseLayers
CDRAttributeStore Fills
CDRAttributeStore Outlines
CDRAttributeStore Styles
CDRFontnameStore Fonts
CDRArrowheadStore Arrowheads
CDRBitmapStore Patterns
CDRBitmapStore Bitmaps
CDRVectorStore Vectors
CDRVectorStore TextV4
CDRPageList Pages
CDRPageListItemThisPage
CDRLayerListItemThisLayer
CDRActionList Actions
CDRBBoxList TextBBoxes
INT32 PageX
INT32 PageY
BOOL Landscape
DocCoord Origin
INT32 TranslateByX
INT32 TranslateByY
INT32 ObjectsConverted
INT32 ObjectsFormatWrong
INT32 ObjectsUnknown
INT32 EnvelopesApproximated
BOOL FormatError
NodeRenderablepLevelNodeList
NodeRenderablepMadeNode
INT32 SerialNumber
BOOL ObjFilled
BOOL ObjStroked
BOOL IsText
BOOL IsTextStory
BOOL AttrsAlreadyApplied
ADDR ObjDataBlock
INT32 ObjDataBlockSize
ColourListColList
ADDR TransformChunk
INT32 TransformChunkSize
ADDR FontTableV3
INT32 FontTableEntriesV3
ADDR FontStylesV3
ADDR LinkTable
BOOL LinkTransformsExist
List TextOnPathLinks
BOOL IsTextOnAPath

Detailed Description

Corel Draw file importing class.

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

Definition at line 764 of file cdrfiltr.h.


Constructor & Destructor Documentation

CDRFilter::CDRFilter void   ) 
 

Constructor.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
As for the Filter class [INPUTS]
Returns:
As for the Filter class
See also:
Filter

Definition at line 234 of file cdrfiltr.cpp.

00235 {
00236     // Set up filter descriptions.
00237     FilterName.Load(_R(IDT_CDRFILTER_FILTERNAME));
00238     FilterInfo.Load(_R(IDT_CDRFILTER_FILTERINFO));
00239     FilterID = FILTERID_CDR;
00240 
00241     Flags.CanImport = TRUE;
00242     Flags.CanExport = FALSE;
00243 
00244     Version = CDRVERSION_NULL;
00245 }


Member Function Documentation

BOOL CDRFilter::AddArrowheadsToPath DWORD  StartArrow,
DWORD  EndArrow,
DocColour Col,
INT32  LineWidth,
LineCapType  Cap,
JointType  Join
[private]
 

adds arrowheads to a path. Changes pMadeNode from a path to a group

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
29 03 95
Parameters:
[INPUTS] 
Returns:
error flag
See also:
Filter

Definition at line 632 of file cdroutl.cpp.

00634 {
00635     if(!IS_A(pMadeNode, NodePath))
00636         return TRUE;            // don't apply arrowheads to non path things
00637 
00638     NodePath *pPath = (NodePath *)pMadeNode;
00639 
00640     // check that the path actaully needs some arrow heads
00641     if(!DoesPathNeedArrowheads(pPath) || (StartArrow == 0 && EndArrow == 0))
00642         return TRUE;
00643     
00644     // get pointers to nodes of the arrow heads to copy
00645     NodeRenderableBounded *StartA = 0;
00646     NodeRenderableBounded *EndA = 0;
00647     INT32 StartDistance;
00648     INT32 EndDistance;
00649     if(StartArrow != 0)
00650     {
00651         BOOL NotPresent;
00652         StartA = Arrowheads.GetConvertedNode(StartArrow, &StartDistance, &NotPresent);
00653 
00654         if(StartA == 0 && NotPresent == FALSE)
00655             return FALSE;   // error occurred
00656     }
00657     if(EndArrow != 0)
00658     {
00659         BOOL NotPresent;
00660         EndA = Arrowheads.GetConvertedNode(EndArrow, &EndDistance, &NotPresent);
00661 
00662         if(EndA == 0 && NotPresent == FALSE)
00663             return FALSE;   // error occurred
00664     }
00665 
00666     // check that enough arrowheads were found to do something with
00667     if(StartA == 0 && EndA == 0)
00668         return TRUE;
00669 
00670     // get rid of any dash patterns
00671     DashRec NoDash;
00672     NoDash = SD_SOLID;
00673     SetDashPattern(NoDash);
00674 
00675     // get some info about the path
00676     DocCoord *Coords = pPath->InkPath.GetCoordArray();
00677     PathVerb *Verbs = pPath->InkPath.GetVerbArray();
00678     INT32 NCoords = pPath->InkPath.GetNumCoords();
00679     INT32 SubPathStart = -1;        // the number of the coord the sub path starts on
00680     INT32 SubPathEnd = -1;          // the number of the coord the sub path ends on
00681 
00682     // set up a pointers for the nodes we're about to create - it points to the made
00683     // at first, but shuffles on as nodes are copied. You see, we have to copy nodes which
00684     // are attached to something
00685     NodeRenderableBounded *ThisNode = pPath;
00686 
00687     // work out the trim distances
00688     double StartTrimDistance;
00689     double EndTrimDistance;
00690     if(StartA != 0)
00691         StartTrimDistance = ((double)LineWidth / (double)cdrfARROWHEAD_LINEWIDTH) * (double)StartDistance;
00692     if(EndA != 0)
00693         EndTrimDistance = ((double)LineWidth / (double)cdrfARROWHEAD_LINEWIDTH) * (double)EndDistance;
00694 
00695     // run through all the coords
00696     INT32 c;
00697     for(c = 0; c < NCoords; c++)
00698     {
00699         UINT32 Verb = Verbs[c] & ~PT_CLOSEFIGURE;
00700         BOOL CloseHere = ((Verbs[c] & PT_CLOSEFIGURE) != 0)?TRUE:FALSE;
00701         
00702         // if the verb is a close figure, this sub path is close, so we can't add arrowheads
00703         // to it. Invalidate the path start to avoid getting any arrowheads
00704         if(CloseHere)
00705             SubPathStart = -1;
00706         
00707         // if we get a new moveto and the sub path start is valid then we have a applying arrowheads
00708         // situation
00709         if((Verb == PT_MOVETO || ((c == (NCoords - 1)) && !CloseHere)) && c != 0)
00710         {
00711             // set the sub path end
00712             if(Verb == PT_MOVETO)
00713             {
00714                 // if it's a moveto, then the sub path end was at the previous coord
00715                 SubPathEnd = c - 1;
00716             } else {
00717                 // if it wasn't, then it's this one (end of path)
00718                 SubPathEnd = c;
00719             }
00720         }
00721 
00722         // have we got a valid start path marker?
00723 
00724         if(SubPathStart != -1 && SubPathEnd != -1)
00725         {
00726             // OK, now we need to trim the sub path
00727             if(StartA != 0)
00728             {
00729                 // trim the start of the path if the next element is a line
00730                 if((Verbs[SubPathStart + 1] & ~PT_CLOSEFIGURE) == PT_LINETO)
00731                 {
00732                     double dx, dy;
00733                     dx = Coords[SubPathStart + 1].x - Coords[SubPathStart].x;
00734                     dy = Coords[SubPathStart + 1].y - Coords[SubPathStart].y;
00735                     double len = sqrt((dx * dx) + (dy * dy));
00736                     // if the resulting path line leaves enough room, trim it
00737                     if((len - StartTrimDistance) >= 32.0)
00738                     {
00739                         double factor = StartTrimDistance / len;
00740                         dx *= factor;
00741                         Coords[SubPathStart].x += (INT32)dx;
00742                         dy *= factor;
00743                         Coords[SubPathStart].y += (INT32)dy;
00744                     }
00745                 }
00746                 
00747                 // now pop an arrowhead on the resulting point
00748 
00749                 // first, make a copy of our node
00750                 if(!StartA->CopyNode(ThisNode, NEXT))
00751                     return FALSE;   // error!
00752 
00753                 ThisNode = (NodeRenderableBounded *)ThisNode->FindNext();
00754                 ERROR3IF(ThisNode == 0, "CopyNode returned a zero path but didn't complain");
00755                 ERROR3IF(ThisNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)) == FALSE, "copied thing isn't a renderable bounded node");
00756 
00757                 // transform it
00758                 if(!TransformArrowhead(ThisNode, &Coords[SubPathStart], &Coords[SubPathStart + 1],
00759                         TRUE, LineWidth, StartDistance))
00760                     return FALSE;
00761 
00762                 // and apply attributes to it
00763                 if(!AddAttributesToArrowheadNode(ThisNode, Col, LineWidth, Cap, Join))
00764                     return FALSE;       
00765             }
00766 
00767             // and the same for the end path
00768             if(EndA != 0)
00769             {
00770                 if((Verbs[SubPathEnd] & ~PT_CLOSEFIGURE) == PT_LINETO)
00771                 {
00772                     double dx, dy;
00773                     dx = Coords[SubPathEnd].x - Coords[SubPathEnd - 1].x;
00774                     dy = Coords[SubPathEnd].y - Coords[SubPathEnd - 1].y;
00775                     double len = sqrt((dx * dx) + (dy * dy));
00776                     // if the resulting path line leaves enough room, trim it
00777                     if((len - EndTrimDistance) >= 32.0)
00778                     {
00779                         double factor = EndTrimDistance / len;
00780                         dx *= factor;
00781                         Coords[SubPathEnd].x += (INT32)dx;
00782                         dy *= factor;
00783                         Coords[SubPathEnd].y += (INT32)dy;
00784                     }
00785                 }
00786                 
00787                 // now pop an arrowhead on the resulting point
00788 
00789                 // first, make a copy of our node
00790                 if(!EndA->CopyNode(ThisNode, NEXT))
00791                     return FALSE;   // error!
00792 
00793                 ThisNode = (NodeRenderableBounded *)ThisNode->FindNext();
00794                 ERROR3IF(ThisNode == 0, "CopyNode returned a zero path but didn't complain");
00795                 ERROR3IF(ThisNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)) == FALSE, "copied thing isn't a renderable bounded node");
00796 
00797                 // transform it
00798                 if(!TransformArrowhead(ThisNode, &Coords[SubPathEnd], &Coords[SubPathEnd - 1],
00799                         FALSE, LineWidth, EndDistance))
00800                     return FALSE;
00801 
00802                 // and apply attributes to it
00803                 if(!AddAttributesToArrowheadNode(ThisNode, Col, LineWidth, Cap, Join))
00804                     return FALSE;               
00805             }
00806         
00807         }
00808             
00809         // set the new sub path start marker and invalidate the end point marker
00810         if(Verb == PT_MOVETO)
00811         {
00812             SubPathStart = c;
00813             SubPathEnd = -1;
00814         }
00815     }
00816 
00817 
00818     // ensure that the bounding rectangle is updated
00819     pPath->InvalidateBoundingRect();
00820 
00821     // get a new group node
00822     NodeGroup *pGroup = new NodeGroup;
00823     if(pGroup == 0)
00824         return FALSE;
00825     
00826     // attach everything to it
00827     pMadeNode->InsertChainSimple(pGroup, FIRSTCHILD);
00828 
00829     // and make the made node the group
00830     pMadeNode = pGroup;
00831     
00832     return TRUE;
00833 }

BOOL CDRFilter::AddAttributesToArrowheadNode NodeRenderableBounded N,
DocColour Col,
INT32  LineWidth,
LineCapType  Cap,
JointType  Join
[private]
 

apply attributes to a arrow head node

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
29 03 95
Parameters:
node,colour and line width [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 442 of file cdroutl.cpp.

00444 {
00445     if(IS_A(N, NodeGroup))
00446     {
00447         // go through all the members of the group setting their attributes
00448         Node *pNode;
00449 
00450         pNode = N->FindFirstChild();
00451 
00452         while(pNode != 0)
00453         {
00454             if(IS_A(pNode, NodePath))
00455                 AddAttributesToArrowheadPath((NodePath *)pNode, Col, LineWidth, Cap, Join);
00456             
00457             pNode = pNode->FindNext();
00458         }
00459     } else if(IS_A(N, NodePath))
00460     {
00461         // simply apply the attributes to this path
00462         AddAttributesToArrowheadPath((NodePath *)N, Col, LineWidth, Cap, Join);
00463     } else {
00464         ERROR3("Something unexpected passed to AddAttributesToArrowheadNode");
00465     }
00466 
00467     return TRUE;
00468 }

BOOL CDRFilter::AddAttributesToArrowheadPath NodePath P,
DocColour Col,
INT32  LineWidth,
LineCapType  Cap,
JointType  Join
[private]
 

apply attributes to a arrow head path

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
29 03 95
Parameters:
node,colour and line width [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 485 of file cdroutl.cpp.

00487 {
00488     if(P->InkPath.IsFilled)
00489     {
00490         // it's a filled path, so it need to be filled with the colour and have no line
00491         // colour
00492         SetPathFilled(TRUE);
00493         if(!SetLineColour(DocColour(COLOUR_TRANS)) || !SetFillColour(*Col))
00494             return FALSE;
00495     } else {
00496         // it's not a filled colour, so don't fill it and stroke it with the line width and colour
00497         if(!SetLineColour(*Col) || !SetLineWidth(LineWidth) || !SetLineCap(Cap) || !SetJoinType(Join))
00498             return FALSE;
00499     }
00500 
00501     // apply the attributes to the object
00502     // If not filled, then set the ignore bit on the fill attribute.
00503 //  if (P->InkPath.IsFilled == FALSE)
00504 //      CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
00505 //  else
00506         CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00507 
00508     // Add attributes to the path, if they are different from the default...
00509     BOOL Result = AttributeManager::ApplyBasedOnDefaults(P, CurrentAttrs);
00510 
00511     //  DeleteCurrentAttrs();
00512     //  SetUpCurrentAttrs();
00513 
00514     // Enable the fill attribute again
00515     CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00516 
00517     return Result;
00518 }

BOOL CDRFilter::AddElementsToPath Path pPath,
INT32  NCoords,
cdrfCoord Coords,
BYTE *  Types,
BOOL *  IsClosed
[static]
 

Adds elements to a path from a CDR path data.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
06/05/95
Parameters:
path to add too, number of coords, pointer to coord data, pointer to types [INPUTS]
Returns:
error flag
See also:

Definition at line 2476 of file cdrfiltr.cpp.

02477 {
02478     // go through the coordinates in the CDR path adding them to the Camelot path
02479     INT32 c;                    // coord counter
02480     UINT32 CoordType;           // type of this coordinate
02481     UINT32 Control1 = 0;        // number of first control point
02482     UINT32 Control2 = 0;        // of second
02483     DocCoord co, cn1, cn2;  // coordinates
02484     PathFlags Flags;
02485     BOOL NeedMoveTo = TRUE;
02486 
02487     if(IsClosed != 0)
02488         (*IsClosed) = FALSE;
02489     
02490     // go though converting all the coords
02491     for(c = 0; c < NCoords; c++)
02492     {
02493         CoordType = Types[c] & cdrfPATHCOORDTYPE_MASK;
02494 
02495         co.x = CDRDATA_SWORD(Coords[c].X) * CDRCOORDS_TO_MILLIPOINTS;
02496         co.y = CDRDATA_SWORD(Coords[c].Y) * CDRCOORDS_TO_MILLIPOINTS;
02497 
02498         // add in a move to if necessary
02499         if(NeedMoveTo && CoordType != cdrfPATHCOORDTYPE_MOVE)
02500         {
02501             if(!pPath->InsertMoveTo(co))
02502                 return FALSE;
02503         }
02504 
02505         NeedMoveTo = FALSE;
02506         
02507         // process the coordinate       
02508         switch(CoordType)
02509         {
02510             case cdrfPATHCOORDTYPE_MOVE:
02511                 // add a move to this path
02512                 if(!pPath->InsertMoveTo(co))
02513                     return FALSE;
02514                 break;
02515             
02516             case cdrfPATHCOORDTYPE_LINETO:
02517                 // add a line to this coord to the path
02518                 if(!pPath->InsertLineTo(co))
02519                     return FALSE;
02520                 break;
02521             
02522             case cdrfPATHCOORDTYPE_CURVE:
02523                 // check we have some control points for this curve
02524                 // a control point cannot be the first coord, so it's OK to check against 0
02525                 if(Control1 == 0 || Control2 == 0)
02526                 {
02527 TRACEUSER( "Ben", _T("No control points for curve element\n"));
02528                     break;
02529                 }
02530 
02531                 // convert the control points
02532                 cn1.x = CDRDATA_SWORD(Coords[Control1].X) * CDRCOORDS_TO_MILLIPOINTS;
02533                 cn1.y = CDRDATA_SWORD(Coords[Control1].Y) * CDRCOORDS_TO_MILLIPOINTS;
02534                 cn2.x = CDRDATA_SWORD(Coords[Control2].X) * CDRCOORDS_TO_MILLIPOINTS;
02535                 cn2.y = CDRDATA_SWORD(Coords[Control2].Y) * CDRCOORDS_TO_MILLIPOINTS;
02536                 
02537                 // create the curve
02538                 Flags.IsSelected = FALSE;
02539                 Flags.IsSmooth = Flags.IsRotate = ((Types[c] & cdrfPATHCOORDATTR_SMOOTH) != 0)?TRUE:FALSE;
02540                 Flags.IsEndPoint;
02541                 
02542                 // insert it into the path
02543                 if(!pPath->InsertCurveTo(cn1, cn2, co, &Flags))
02544                     return FALSE;
02545                 break;
02546 
02547             case cdrfPATHCOORDTYPE_CONTROL:
02548                 // shuffle the control points we've already got and add the new one
02549                 Control1 = Control2;
02550                 Control2 = c;
02551                 break;
02552             
02553             default:
02554                 // can't get here as mask won't allow any other value than the ones above.
02555                 break;
02556         }
02557 
02558         // is this a close subpath situtation?
02559         if((Types[c] & cdrfPATHCOORDATTR_CLOSE) != 0)
02560         {
02561             if(IsClosed != 0)
02562                 (*IsClosed) = TRUE;     // path has at least one closed element and should be filled
02563             
02564             // close the sub path
02565             if(CoordType != cdrfPATHCOORDTYPE_MOVE)
02566             {
02567                 if(!pPath->CloseSubPath())
02568                     return FALSE;
02569 
02570                 // ensure that the next coord is a moveto
02571                 NeedMoveTo = TRUE;
02572             }
02573         }
02574     }
02575 
02576     return TRUE;
02577 }

BOOL CDRFilter::AddStandardColourSet Document pDocument  )  [static]
 

Adds the standard set of colours to a Corel file.

/

typedef struct { BYTE C, M, Y, K; TCHAR *Name; } StandardCDRColour;

static StandardCDRColour StandardCDRColours[] = { {0, 0, 0, 100, "Black"}, {0, 0, 0, 90, "90% Black"}, {0, 0, 0, 80, "80% Black"}, {0, 0, 0, 70, "70% Black"}, {0, 0, 0, 60, "60% Black"}, {0, 0, 0, 50, "50% Black"}, {0, 0, 0, 40, "40% Black"}, {0, 0, 0, 30, "30% Black"}, {0, 0, 0, 20, "20% Black"}, {0, 0, 0, 10, "10% Black"}, {0, 0, 0, 0, "White"}, {100, 100, 0, 0, "Blue"}, {100, 0, 0, 0, "Cyan"}, {100, 0, 100, 0, "Green"}, {0, 0, 100, 0, "Yellow"}, {0, 100, 100, 0, "Red"}, {0, 100, 0, 0, "Magenta"}, {20, 80, 0, 20, "Purple"}, {0, 60, 100, 0, "Orange"}, {0, 40, 20, 0, "Pink"}, {0, 20, 20, 60, "Dark Brown"}, {20, 20, 0, 0, "Powder Blue"}, {40, 40, 0, 0, "Pastel Blue"}, {60, 40, 0, 0, "Baby Blue"}, {60, 60, 0, 0, "Electric Blue"}, {40, 40, 0, 20, "Twilight Blue"}, {60, 40, 0, 40, "Navy Blue"}, {40, 40, 0, 60, "Deep Navy Blue"}, {40, 20, 0, 40, "Desert Blue"}, {100, 20, 0, 0, "Sky Blue"}, {40, 0, 0, 0, "Ice Blue"}, {20, 0, 0, 20, "Light BlueGreen"}, {20, 0, 0, 40, "Ocean Green"}, {20, 0, 0, 60, "Moss Green"}, {20, 0, 0, 80, "Dark Green"}, {40, 0, 20, 60, "Forest Green"}, {60, 0, 40, 40, "Grass Green"}, {40, 0, 20, 40, "Kentucky Green"}, {60, 0, 40, 20, "Light Green"}, {60, 0, 60, 20, "Spring Green"}, {60, 0, 20, 0, "Turquoise"}, {60, 0, 20, 20, "Sea Green"}, {20, 0, 20, 20, "Faded Green"}, {20, 0, 20, 0, "Ghost Green"}, {40, 0, 40, 0, "Mint Green"}, {20, 0, 20, 40, "Army Green"}, {20, 0, 40, 40, "Avocado Green"}, {20, 0, 60, 20, "Martian Green"}, {20, 0, 40, 20, "Dull Green"}, {40, 0, 100, 0, "Chartreuse"}, {20, 0, 60, 0, "Moon Green"}, {0, 0, 20, 80, "Murky Green"}, {0, 0, 20, 60, "Olive Drab"}, {0, 0, 20, 40, "Khaki"}, {0, 0, 40, 40, "Olive"}, {0, 0, 60, 20, "Banana Yellow"}, {0, 0, 60, 0, "Light Yellow"}, {0, 0, 40, 0, "Chalk"}, {0, 0, 20, 0, "Pale Yellow"}, {0, 20, 40, 40, "Brown"}, {0, 40, 60, 20, "Red Brown"}, {0, 20, 60, 20, "Gold"}, {0, 60, 80, 0, "Autumn Orange"}, {0, 40, 80, 0, "Light Orange"}, {0, 40, 60, 0, "Peach"}, {0, 20, 100, 0, "Deep Yellow"}, {0, 20, 40, 0, "Sand"}, {0, 20, 40, 60, "Walnut"}, {0, 60, 60, 40, "Ruby Red"}, {0, 60, 80, 20, "Brick Red"}, {0, 60, 60, 0, "Tropical Pink"}, {0, 40, 40, 0, "Soft Pink"}, {0, 20, 20, 0, "Faded Pink"}, {0, 40, 20, 40, "Crimson"}, {0, 60, 40, 20, "Regal Red"}, {0, 60, 20, 20, "Deep Rose"}, {0, 100, 60, 0, "Neon Red"}, {0, 60, 40, 0, "Deep Pink"}, {0, 80, 40, 0, "Hot Pink"}, {0, 40, 20, 20, "Dusty Rose"}, {0, 40, 0, 60, "Plum"}, {0, 60, 0, 40, "Deep Violet"}, {0, 40, 0, 0, "Light Violet"}, {0, 40, 0, 20, "Violet"}, {0, 20, 0, 40, "Dusty Plum"}, {0, 20, 0, 20, "Pale Purple"}, {20, 60, 0, 20, "Majestic Purple"}, {20, 80, 0, 0, "Neon Purple"}, {20, 60, 0, 0, "Light Purple"}, {20, 40, 0, 20, "Twilight Violet"}, {20, 40, 0, 0, "Easter Purple"}, {20, 40, 0, 60, "Deep Purple"}, {20, 40, 0, 40, "Grape"}, {40, 60, 0, 0, "Blue Violet"}, {40, 100, 0, 0, "Blue Purple"}, {40, 80, 0, 20, "Deep River"}, {60, 80, 0, 0, "Deep Azure"}, {40, 60, 0, 40, "Storm Blue"}, {60, 80, 0, 20, "Deep Blue"}, {100, 100, 100, 100, "100C100M100Y100K"} };

/*!

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/06/95
Parameters:
[INPUTS] 
Returns:

Definition at line 1322 of file cdroutl.cpp.

01323 {
01324     ColourListComponent *pColours = 0;
01325 
01326     DocComponent *pComponent = pDocument->EnumerateDocComponents(NULL);
01327 
01328     while (pComponent != NULL)
01329     {
01330         // If this is the colour component, remember it
01331         if (pComponent->GetRuntimeClass() == CC_RUNTIME_CLASS(ColourListComponent))
01332         {
01333             pColours = (ColourListComponent *) pComponent;
01334             break;
01335         }
01336 
01337         // Look for next doc component
01338         pComponent = pDocument->EnumerateDocComponents(pComponent);
01339     }
01340 
01341     if(pColours == 0)
01342         return TRUE;            // can't be bothered to complain nicely about this very unlikely error
01343 
01344     // get an importedcolours object
01345     ImportedColours *pNewColours = new ImportedColours(pColours, FALSE);
01346     if(pNewColours == 0 || !pNewColours->Init())
01347         return FALSE;
01348 
01349     BOOL ok = TRUE;
01350 
01351     // add colours to it...
01352     ColourCMYK NewColour;
01353     for(INT32 l = 0; l < (sizeof(StandardCDRColours) / sizeof(StandardCDRColour)); l++)
01354     {
01355         NewColour.Cyan = ((double)StandardCDRColours[l].C) / 100;
01356         NewColour.Magenta = ((double)StandardCDRColours[l].M) / 100;
01357         NewColour.Yellow = ((double)StandardCDRColours[l].Y) / 100;
01358         NewColour.Key = ((double)StandardCDRColours[l].K) / 100;
01359         
01360         String_64 ColNameS(StandardCDRColours[l].Name);
01361         if(!pNewColours->AddColour(&ColNameS, &NewColour))
01362         {
01363             ok = FALSE;
01364             break;
01365         }
01366     }
01367 
01368     // add the colours to the document
01369     if(ok)
01370     {
01371         pNewColours->AddColoursToDocument();
01372     }
01373     else
01374     {
01375         pNewColours->DestroyColours();
01376     }
01377 
01378     // delete the imported colours object
01379     delete pNewColours;
01380 
01381     return ok;
01382 }

BOOL CDRFilter::ApplyTextAttr Node ContextNode,
const CDRTextStyle TS,
const CDRTextStyle BasedOn
[private]
 

Applies text attributes to a node from a CDRTextStyle. If BasedOn != 0 then the attributes will only be applied if they are different from those in *BasedOn.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/04/95
Parameters:
[INPUTS] 
Returns:
error flag
See also:

Definition at line 1623 of file cdrtext.cpp.

01624 {
01625     BOOL CheckExisting = FALSE;
01626 
01627     // if the node has children, then we want to check existing attributes
01628     if(ContextNode->FindFirstChild() != 0)
01629         CheckExisting = TRUE;
01630 
01631     // apply italicness
01632     if(BasedOn == 0 || TS->Italic != BasedOn->Italic)
01633     {
01634         // make a font size attribute
01635         TxtItalicAttribute Attr(TS->Italic);
01636     
01637         // attach
01638         if(!ApplyTextAttrDoApply(ContextNode, &Attr, CheckExisting))
01639             return FALSE;
01640     }
01641 
01642     // apply boldness
01643     if(BasedOn == 0 || TS->Bold != BasedOn->Bold)
01644     {
01645         // make a font size attribute
01646         TxtBoldAttribute Attr(TS->Bold);
01647     
01648         // attach
01649         if(!ApplyTextAttrDoApply(ContextNode, &Attr, CheckExisting))
01650             return FALSE;
01651     }
01652 
01653     // apply underline
01654     if(BasedOn == 0 || TS->Underline != BasedOn->Underline)
01655     {
01656         // make a font size attribute
01657         TxtUnderlineAttribute Attr(TS->Underline);
01658     
01659         // attach
01660         if(!ApplyTextAttrDoApply(ContextNode, &Attr, CheckExisting))
01661             return FALSE;
01662     }
01663 
01664     // apply the scriptness
01665     if(BasedOn == 0 || TS->Script != BasedOn->Script)
01666     {
01667         if(TS->Script != CDRSCRIPT_NONE)
01668         {
01669             TxtScriptAttribute Attr((TS->Script == CDRSCRIPT_SUB)?-0.1:0.33, 0.5);
01670 
01671             // attach
01672             if(!ApplyTextAttrDoApply(ContextNode, &Attr, CheckExisting))
01673                 return FALSE;
01674         }
01675     }
01676 
01677     // apply font size
01678     if(BasedOn == 0 || TS->FontSize != BasedOn->FontSize)
01679     {
01680         // make a font size attribute
01681         TxtFontSizeAttribute Attr(TS->FontSize);
01682     
01683         // attach
01684         if(!ApplyTextAttrDoApply(ContextNode, &Attr, CheckExisting))
01685             return FALSE;
01686     }
01687 
01688     // apply font name
01689 //  if(BasedOn == 0 || TS->FontName != BasedOn->FontName)
01690     if(BasedOn == 0 || TS->FontReference != BasedOn->FontReference)
01691     {
01692         // get a font handle
01693         WORD hTypeface = Fonts.GetHandleForReference(TS->FontReference);
01694         //WORD hTypeface = FONTMANAGER->GetFontHandle(&String_64(TS->FontName)); 
01695 
01696         // make a typeface attribute
01697         TxtFontTypefaceAttribute Attr(hTypeface);
01698     
01699         // attach
01700         if(!ApplyTextAttrDoApply(ContextNode, &Attr, CheckExisting))
01701             return FALSE;
01702     }
01703 
01704     // apply the justification stuff
01705     if((BasedOn == 0 || TS->Just != BasedOn->Just) && TS->Just != JLEFT)
01706     {
01707         // make a justification attribute
01708         TxtJustificationAttribute Attr(TS->Just);
01709     
01710         // attach
01711         if(!ApplyTextAttrDoApply(ContextNode, &Attr, CheckExisting))
01712             return FALSE;
01713     }
01714 
01715     // slap on a aspect ratio thingy so it gets transformed OK
01716     TxtAspectRatioAttribute Attr(1);
01717 
01718     if(!ApplyTextAttrDoApply(ContextNode, &Attr, CheckExisting))
01719         return FALSE;
01720 
01721     return TRUE;
01722 }

BOOL CDRFilter::ApplyTextAttrDoApply Node ContextNode,
TxtBaseClassAttribute Attr,
BOOL  CheckExisting
[private]
 

Given a text attribute, apply it to a node. If CheckExising is TRUE, the existing attributes will be checked, and this attribute will not be applied if one of it's type already exists.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/04/95
Parameters:
[INPUTS] 
Returns:
error flag
See also:

Definition at line 1740 of file cdrtext.cpp.

01741 {
01742     // check given attribute
01743     if(Attr == 0)
01744         return FALSE;
01745 
01746     // make a node out of it
01747     NodeAttribute *pNode = Attr->MakeNode();
01748     if(pNode == 0)
01749         return FALSE;
01750 
01751     // if necessary check existing attributes
01752     if(CheckExisting)
01753     {
01754         Node *SearchNode = ContextNode->FindFirstChild();
01755 
01756         // run through it's children
01757         while(SearchNode != 0)
01758         {
01759             if(IS_SAME_CLASS(pNode, SearchNode))
01760             {
01761                 // found an attribute just like the one we're thinking of applying...
01762                 delete pNode;
01763                 return TRUE;        // don't need to do anything more
01764             }
01765 
01766             SearchNode = SearchNode->FindNext();
01767         }
01768     }
01769     
01770     // attach the node
01771     pNode->AttachNode(ContextNode, FIRSTCHILD);
01772     return TRUE;
01773 }

BOOL CDRFilter::AttachTextToPaths  )  [private]
 

attachs paths to text stories from the list of links.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/06/95
Parameters:
- [INPUTS]
Returns:
error flag
See also:
CDRFilter

Definition at line 2621 of file cdrtext.cpp.

02622 {
02623     // set attributes to no colours - we mustn't render these here paths
02624     if(!SetFillColour(DocColour(COLOUR_TRANS)))
02625         return FALSE;
02626     if(!SetLineColour(DocColour(COLOUR_TRANS)))
02627         return FALSE;
02628     CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
02629 
02630     // go through the entries in the list...
02631     CDRTextOnPathLink *Item = (CDRTextOnPathLink *)TextOnPathLinks.GetHead();
02632 
02633     while(Item != 0)
02634     {
02635         // if this is complete, process it
02636         if(Item->pPath != 0 && Item->pTextStory != 0)
02637         {
02638             // both things were found, so join them up nicely...
02639 
02640             // make a copy of the path
02641             NodePath *pPath;
02642             if(!Item->pPath->NodeCopy((Node **)&pPath))
02643                 return FALSE;
02644 
02645             // delete it's old attributes
02646             pPath->DeleteChildren(pPath->FindFirstChild());
02647 
02648             // apply some attributes to the path
02649             pPath->InkPath.IsFilled = FALSE;
02650             pPath->InkPath.IsStroked = FALSE;
02651             if(!AttributeManager::ApplyBasedOnDefaults(pPath, CurrentAttrs))
02652                 return FALSE;
02653 
02654             // and attach the nodes together
02655             Node *pFirstLine = Item->pTextStory->FindFirstChild(CC_RUNTIME_CLASS(TextLine));
02656             ERROR2IF(pFirstLine == 0, FALSE, "TextStory had no line when attaching path");
02657             pPath->AttachNode(pFirstLine, PREV);
02658 
02659             // now sort out justification along the path
02660             if(Item->Justi != JLEFT)
02661             {
02662                 // knock up an attribute and pop it on
02663                 TxtJustificationAttribute Attr(Item->Justi);
02664                 NodeAttribute *pNode = Attr.MakeNode();
02665                 if(pNode == 0)
02666                     return FALSE;
02667                 pNode->AttachNode(Item->pTextStory, FIRSTCHILD);
02668             }
02669             else
02670             {
02671                 TRACEUSER( "Ben", _T("Text on path not completed: path serial = %d, path ptr = %X\ntext serial = %d, text ptr = %X\n\n"), Item->PathSerialNumber, Item->pPath, Item->TextSerialNumber, Item->pTextStory);
02672             }
02673         
02674             // and the positioning
02675             Item->pTextStory->SetImportBaseShift((BaseShiftEnum)Item->Position);
02676         }
02677         
02678         // next!
02679         Item = (CDRTextOnPathLink *)TextOnPathLinks.GetNext(Item);
02680     }
02681 
02682     return TRUE;
02683 }

KernelBitmap * CDRFilter::BitmapFromNodeList Node List  )  [private]
 

given a list of nodes, if it only contains one bitmap then return a pointer to that bitmap

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/04/95
Parameters:
pointer to first node in a list [INPUTS]
Returns:
a pointer to the relevant bitmap, or zero if one couldn't be found
See also:
Filter

Definition at line 1716 of file cdrfill.cpp.

01717 {
01718     // make sure we've got something
01719     if(List == 0)
01720         return 0;
01721 
01722     // is there's more than one item?
01723     if(List->FindNext() != 0)
01724         return 0;
01725 
01726     // is it a bitmap?
01727     if(IS_A(List, NodeBitmap))
01728     {
01729         // right then, woz it's bitmap den?
01730         NodeBitmap *NB = (NodeBitmap *)List;
01731 
01732         // return the bitmap...
01733         return NB->GetBitmap();
01734     }
01735 
01736     return 0;
01737 }

CDRFilter::CC_DECLARE_DYNAMIC CDRFilter   )  [private]
 

BOOL CDRFilter::CheckTextForLinks TextStory pTextStory,
cdrfOffsetHeader Header
[private]
 

checks to see if this text story is in the link table

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/06/95
Parameters:
- [INPUTS]
Returns:
error flag
See also:
CDRFilter

Definition at line 2699 of file cdrtext.cpp.

02700 {
02701     if(IsTextOnAPath != TRUE)
02702         return TRUE;        // not on a path, so don't search
02703 
02704     // go through the entries in the list...
02705     CDRTextOnPathLink *Item = (CDRTextOnPathLink *)TextOnPathLinks.GetHead();
02706 
02707     while(Item != 0)
02708     {
02709         // does this link refer to this text story?
02710         if(SerialNumber == Item->TextSerialNumber)
02711         {
02712             // yep - make the entry refer to this text story
02713             Item->pTextStory = pTextStory;
02714 
02715             // set up some justification and positioning stuff
02716             cdrfTextOnPathInfo *Info;
02717             if((Info = (cdrfTextOnPathInfo *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_PATHTEXT1)) != 0)
02718             {
02719                 switch(CDRDATA_WORD(Info->Alignment))
02720                 {
02721                     case cdrfTEXTONPATHALIGN_RIGHT:
02722                         Item->Justi = JRIGHT;
02723                         break;
02724 
02725                     case cdrfTEXTONPATHALIGN_CENTRE:
02726                         Item->Justi = JCENTRE;
02727                         break;
02728 
02729                     default:
02730                     case cdrfTEXTONPATHALIGN_LEFT:
02731                         Item->Justi = JLEFT;
02732                         break;
02733                 }
02734 
02735                 switch(CDRDATA_WORD(Info->Position))
02736                 {
02737                     case cdrfTEXTONPATHPOS_BOTTOM:
02738                         Item->Position = AlignDescenders;
02739                         break;
02740 
02741                     case cdrfTEXTONPATHPOS_TOP:
02742                         Item->Position = AlignAscenders;
02743                         break;
02744 
02745                     case cdrfTEXTONPATHPOS_CENTRE:
02746                         Item->Position = AlignCentres;
02747                         break;
02748 
02749                     case cdrfTEXTONPATHPOS_BASELINE:
02750                     default:
02751                         Item->Position = AlignBaseline;
02752                         break;
02753 
02754                 }
02755             }
02756 
02757             // return now so we don't get duplicates...
02758             return TRUE;
02759         }
02760         
02761         // next!
02762         Item = (CDRTextOnPathLink *)TextOnPathLinks.GetNext(Item);
02763     }
02764     
02765     return TRUE;
02766 }

BOOL CDRFilter::ClearUp void   )  [private]
 

Clears up after an CDR file import.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
[INPUTS] 
Returns:
See also:
Filter

Definition at line 4632 of file cdrfiltr.cpp.

04633 {
04634     Version = CDRVERSION_NULL;
04635 
04636     if(SlowJobStarted == TRUE)
04637         EndSlowJob();
04638 
04639     if(Success == FALSE)
04640     {
04641         // get rid of the actions list
04642         while(!Actions.IsEmpty())
04643         {
04644             CDRActionListItem *Act = (CDRActionListItem *)Actions.GetTail();
04645 
04646             ERROR3IF(Act == 0, "Returned tail in a non-empty Action list is 0");
04647 
04648             Act->ImportFailure(this);
04649 
04650             delete Actions.RemoveItem(Act);
04651         }
04652 
04653         // get rid of the level's list of nodes
04654         DeleteNodeList(pLevelNodeList);
04655 
04656         // tell everyone about some new layers, if we were doing them
04657         if(UseLayers)
04658         {
04659             LayerSGallery::MakeTopLayerActive(pSpread);
04660             BROADCAST_TO_ALL(SpreadMsg(pSpread, SpreadMsg::LAYERCHANGES));
04661         }
04662     }
04663     
04664 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Fills has %d entries\n"), Fills.GetCount());
04665 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Outlines has %d entries\n"), Outlines.GetCount());
04666 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Styles has %d entries\n"), Styles.GetCount());
04667 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Fonts has %d entries\n"), Fonts.GetCount());
04668 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Arrowheads has %d entries\n"), Arrowheads.GetCount());
04669 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Patterns has %d entries\n"), Patterns.GetCount());
04670 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Bitmaps has %d entries\n"), Bitmaps.GetCount());
04671 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Vectors has %d entries\n"), Vectors.GetCount());
04672 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), TextV4 has %d entries\n"), TextV4.GetCount());
04673 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Pages has %d entries\n"), Pages.GetCount());
04674 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), Actions has %d entries\n"), Actions.GetCount());
04675 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), TextBBoxes has %d entries\n"), TextBBoxes.GetCount());
04676 TRACEUSER( "Ben", _T("At CDRFilter::ClearUp(), TextOnPathLinks has %d entries\n"), TextOnPathLinks.GetCount());
04677 TRACEUSER( "Ben", _T("ObjectsConverted = %d\nObjectsFormatWrong = %d\nObjectsUnknown = %d\nEnvelopesApproximated = %d\n"), ObjectsConverted, ObjectsFormatWrong, ObjectsUnknown, EnvelopesApproximated);
04678 
04679     ERROR3IF(Success == TRUE && Actions.GetCount() != 0, "Not all actions used at the end of a successful CDR convert!");
04680     
04681     Fills.DeleteAll();
04682     Outlines.DeleteAll();
04683     Styles.DeleteAll();
04684     Fonts.DeleteAll();
04685     Arrowheads.DeleteAll();
04686     Patterns.DeleteAll();
04687     Bitmaps.DeleteAll();
04688     Vectors.DeleteAll();
04689     TextV4.DeleteAll();
04690     Pages.DeleteAll();
04691     Actions.DeleteAll();
04692     TextBBoxes.DeleteAll();
04693     TextOnPathLinks.DeleteAll();
04694 
04695     // avoid indexedcolour in uses
04696     ColourCMYK CNullCol;
04697     CNullCol.Cyan = 1;
04698     CNullCol.Magenta = 1;
04699     CNullCol.Yellow = 1;
04700     CNullCol.Key = 1;
04701     DocColour NullCol = DocColour(COLOURMODEL_CMYK, (ColourGeneric *)&CNullCol);
04702     SetLineColour(NullCol);
04703     SetFillColour(NullCol);
04704     
04705     // delete the current attributes
04706     DeleteCurrentAttrs();
04707 
04708     // free a few data blocks
04709     CCFree(ObjDataBlock);
04710     CCFree(FontTableV3);
04711     CCFree(FontStylesV3);
04712     CCFree(LinkTable);
04713 
04714 TRACEUSER( "Ben", _T("ClearUp finished - import of CDR over\n"));
04715     return Success;
04716 }

BOOL CDRFilter::ConvertBitmap cdrfOffsetHeader  )  [private]
 

Definition at line 2743 of file cdrfiltr.cpp.

02744 {
02745     // find the address of the coordinates in the header
02746     cdrfBitmapData *BInfo = (cdrfBitmapData *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
02747 
02748     // it has got some object data, hasn't it?
02749     if(BInfo == 0)
02750     {
02751         FormatError = TRUE;
02752         return TRUE;
02753     }
02754 
02755     // OK, let's get the information in a nice structure to start off with
02756     struct {
02757         DWORD Reference;
02758         INT32 SizeX;
02759         INT32 SizeY;
02760         INT32 Left;         // cropping coordinates
02761         INT32 Right;
02762         INT32 Bottom;
02763         INT32 Top;
02764     } Info;
02765 
02766     // choose the right reference - it's in a slightly different place in CDR 3 files
02767     if(Version != CDRVERSION_3)
02768     {
02769         Info.Reference = CDRDATA_WORD(BInfo->BitmapReference);
02770         Info.SizeX = CDRDATA_SWORD(BInfo->SizeX) * CDRCOORDS_TO_MILLIPOINTS;
02771         Info.SizeY = CDRDATA_SWORD(BInfo->SizeY) * CDRCOORDS_TO_MILLIPOINTS;
02772         Info.Left = CDRDATA_SWORD(BInfo->Left) * CDRCOORDS_TO_MILLIPOINTS;
02773         Info.Right = CDRDATA_SWORD(BInfo->Right) * CDRCOORDS_TO_MILLIPOINTS;
02774         Info.Bottom = CDRDATA_SWORD(BInfo->Bottom) * CDRCOORDS_TO_MILLIPOINTS;
02775         Info.Top = CDRDATA_SWORD(BInfo->Top) * CDRCOORDS_TO_MILLIPOINTS;
02776     }
02777     else
02778     {
02779         cdrfBitmapData3 *B3Info = (cdrfBitmapData3 *)BInfo;
02780         
02781         Info.Reference = CDRDATA_WORD(B3Info->BitmapReference);
02782         Info.SizeX = CDRDATA_SWORD(B3Info->SizeX) * CDRCOORDS_TO_MILLIPOINTS;
02783         Info.SizeY = CDRDATA_SWORD(B3Info->SizeY) * CDRCOORDS_TO_MILLIPOINTS;
02784         Info.Left = CDRDATA_SWORD(B3Info->Left) * CDRCOORDS_TO_MILLIPOINTS;
02785         Info.Right = CDRDATA_SWORD(B3Info->Right) * CDRCOORDS_TO_MILLIPOINTS;
02786         Info.Bottom = CDRDATA_SWORD(B3Info->Bottom) * CDRCOORDS_TO_MILLIPOINTS;
02787         Info.Top = CDRDATA_SWORD(B3Info->Top) * CDRCOORDS_TO_MILLIPOINTS;
02788     }
02789 
02790     // find that there bitmap
02791     KernelBitmap *pBitmap = Bitmaps.FindBitmap(Info.Reference);
02792 
02793     if(pBitmap == 0)
02794     {
02795         FormatError = TRUE;
02796         return TRUE;
02797     }
02798 
02799     // find a bounding box for the bitmap on the page
02800     DocRect BoundsRect;
02801 
02802     if(Info.SizeX > 0)
02803     {
02804         BoundsRect.lo.x = 0;
02805         BoundsRect.hi.x = Info.SizeX;
02806     } else {
02807         BoundsRect.lo.x = Info.SizeX;
02808         BoundsRect.hi.x = 0;
02809     }
02810 
02811     if(Info.SizeY > 0)
02812     {
02813         BoundsRect.lo.y = 0;
02814         BoundsRect.hi.y = Info.SizeY;
02815     } else {
02816         BoundsRect.lo.y = Info.SizeY;
02817         BoundsRect.hi.y = 0;
02818     }
02819 
02820 
02821     // OK, if the bitmap isn't cropped, create a bitmap object, otherwise
02822     // create a rectangle which is the right size and pop a bitmap fill on it
02823     if(Info.Left == 0 && Info.Right == Info.SizeX && Info.Top == 0 && Info.Bottom == Info.SizeY)
02824     {
02825         // create a bitmap object
02826         NodeBitmap *NewBitmap = new NodeBitmap;
02827 
02828         if((NewBitmap == NULL) || !NewBitmap->SetUpPath())
02829             return FALSE;
02830         
02831         NewBitmap->CreateShape(BoundsRect);
02832 
02833         // set the reference to the bitmap
02834         NewBitmap->GetBitmapRef()->Attach(pBitmap, GetDocument());
02835         if (NewBitmap->GetBitmap() != pBitmap)
02836         {
02837             // It didn't use the bitmap we gave it, so we can delete it
02838             delete pBitmap;
02839         }
02840     
02841         // apply a few nice attributes to it
02842         NewBitmap->ApplyDefaultBitmapAttrs(0);
02843 
02844         // invalidate the bounding rectangle
02845         NewBitmap->InvalidateBoundingRect();
02846 
02847         // cool.
02848         ObjFilled = FALSE;
02849         ObjStroked = FALSE; 
02850 
02851         // we don't want any of those fancy attributes things on this object.
02852         AttrsAlreadyApplied = TRUE;
02853 
02854         // set the made node
02855         pMadeNode = NewBitmap;
02856     }
02857     else
02858     {
02859         // create a rectangular path object...
02860         // generate a path
02861         NodePath *pPath = new NodePath;
02862         if(pPath == 0 || (!pPath->SetUpPath()))
02863         {
02864             delete pPath;
02865             return FALSE;           // no room to create it
02866         }
02867 
02868         // position the new elements at the beginning of the path
02869         pPath->InkPath.FindStartOfPath();
02870 
02871         DocCoord co, cn1, cn2;
02872     
02873         // make the rectangle shape
02874         BITM_MOVE(Info.Left,    Info.Bottom)
02875         BITM_LINE(Info.Right,   Info.Bottom)
02876         BITM_LINE(Info.Right,   Info.Top)
02877         BITM_LINE(Info.Left,    Info.Top)
02878         BITM_LINE(Info.Left,    Info.Bottom)
02879         BITM_CLOSE
02880 
02881         // finish off the path
02882         pPath->InvalidateBoundingRect();
02883         pPath->InkPath.IsFilled = TRUE;
02884     
02885         // set up an attribute or two
02886         ObjFilled = TRUE;
02887         ObjStroked = FALSE;
02888 
02889         // set up a nice attribute for this thingy
02890         if(!SetLineColour(DocColour(COLOUR_TRANS)))
02891             return FALSE;
02892 
02893         // set a nice bitmap fill
02894         DocCoord Start  = DocCoord(BoundsRect.lo.x, BoundsRect.lo.y);
02895         DocCoord End1   = DocCoord(BoundsRect.hi.x, BoundsRect.lo.y);
02896         DocCoord End2   = DocCoord(BoundsRect.lo.x, BoundsRect.hi.y);
02897         if(!SetBitmapFill(pBitmap, Start, End1, End2))
02898             return FALSE;
02899         
02900         // apply attributes
02901         SetPathFilled(TRUE);
02902         CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
02903         if(!AttributeManager::ApplyBasedOnDefaults(pPath, CurrentAttrs))
02904             return FALSE;
02905         
02906         // don't apply attributes later
02907         AttrsAlreadyApplied = TRUE;
02908 
02909         // set the made node
02910         pMadeNode = pPath;
02911     }
02912 
02913     return TRUE;
02914 }

BOOL CDRFilter::ConvertColour cdrfColour Col,
DocColour Out
[private]
 

converts a colour from the CDR definition taking into account the version

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 03 95
Parameters:
cdr colour and a DocColour to put it into [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 1970 of file cdrfiltr.cpp.

01971 {
01972     ERROR3IF(Col == 0 || Out == 0, "Null pointers passed to ConvertColour");
01973     
01974     ImportedNewColour ICol;
01975     
01976     switch(Version)
01977     {
01978         case CDRVERSION_5:  CDRColour::Convert5(Col, &ICol);    break;
01979         case CDRVERSION_4:  CDRColour::Convert4(Col, &ICol);    break;
01980         default:            CDRColour::Convert3(Col, &ICol);    break;
01981     }
01982     
01983     IndexedColour *NewCol = new IndexedColour(ICol.Model, &ICol.Colour);
01984 
01985     if(NewCol == 0)
01986         return FALSE;
01987 
01988     ColList->GetUnnamedColours()->AddTail(NewCol);
01989 
01990     Out->MakeRefToIndexedColour(NewCol);
01991 
01992     return TRUE;
01993 }

BOOL CDRFilter::ConvertEllipse cdrfOffsetHeader Header  )  [private]
 

generates an ellipse object

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27 03 95
Parameters:
pointer to header [INPUTS]
Returns:
error flag
See also:

Definition at line 2671 of file cdrfiltr.cpp.

02672 {
02673     // find the address of the coordinates in the header
02674     cdrfEllipseData *Size = (cdrfEllipseData *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
02675 
02676     // it has got some coords, hasn't it?
02677     if(Size == 0)
02678     {
02679         FormatError = TRUE;
02680         return TRUE;
02681     }
02682 
02683     // Create the ellipse
02684     NodeRegularShape *NewShape = new (NodeRegularShape);
02685 
02686     if ((NewShape == NULL) || !NewShape->SetUpShape() )
02687     {
02688         ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY));
02689     }
02690 
02691     // fill it all in for an ellipse
02692     NewShape->SetNumSides(4);
02693 
02694     INT32 Width = CDRDATA_SWORD(Size->Width) * CDRCOORDS_TO_MILLIPOINTS;
02695     INT32 Height = CDRDATA_SWORD(Size->Height) * CDRCOORDS_TO_MILLIPOINTS;
02696 
02697     DocCoord co;
02698     co.x = Width / 2;       // centre - it all starts at (0,0)
02699     co.y = Height / 2;
02700     NewShape->SetCentrePoint(co);
02701     co.x = Width;
02702     NewShape->SetMajorAxes(co);
02703     co.x /= 2;
02704     co.y = Height;
02705     NewShape->SetMinorAxes(co);
02706 
02707     NewShape->SetCircular(TRUE);
02708     NewShape->SetStellated(FALSE);
02709     NewShape->SetPrimaryCurvature(TRUE);
02710     NewShape->SetStellationCurvature(FALSE);
02711 
02712     // finish off the path
02713     NewShape->InvalidateBoundingRect();
02714     
02715     // set up an attribute or two
02716     ObjFilled = TRUE;
02717     ObjStroked = TRUE;              
02718 
02719     // set the made node
02720     pMadeNode = NewShape;
02721 
02722     return TRUE;
02723 }

BOOL CDRFilter::ConvertPath cdrfOffsetHeader Header  )  [private]
 

actually converts a path object to a node. If the object has an unexpected format, then FormatError is set and it return *TRUE* - the return value only indicated environmental errors such as lack of memory

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:

Definition at line 2371 of file cdrfiltr.cpp.

02372 {
02373     // find the address of the coordinates in the header
02374     cdrfPathCoordHeader *CHdr = (cdrfPathCoordHeader *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
02375 
02376     // it has got some coords, hasn't it?
02377     if(CHdr == 0)
02378     {
02379         FormatError = TRUE;
02380         return TRUE;
02381     }
02382 
02383     // find the address of the types and the coordinates
02384     cdrfCoord *Coords = (cdrfCoord *)(CHdr + 1);
02385 
02386     // and the address of the types
02387     UINT32 NCoords = CDRDATA_WORD(CHdr->NCoords);
02388     BYTE *Types = (BYTE *)(Coords + NCoords);
02389 
02390     // check the path a little
02391     if((NCoords * (sizeof(cdrfCoord) + sizeof(BYTE))) > CDRDATA_WORD(Header->Size) || NCoords < 2)
02392     {
02393         FormatError = TRUE;
02394         return TRUE;
02395     }
02396     
02397     // knock up a path node
02398     NodePath *pPath = new NodePath;
02399     if(pPath == 0 || (!pPath->SetUpPath()))
02400     {
02401         delete pPath;
02402         return FALSE;           // no room to create it
02403     }
02404 
02405     // position the new elements at the beginning of the path
02406     pPath->InkPath.FindStartOfPath();
02407 
02408     // flag the initial status of the fill/stokedness of the path
02409     ObjFilled = FALSE;
02410     ObjStroked = TRUE;
02411 
02412     if(!AddElementsToPath(&pPath->InkPath, NCoords, Coords, Types, &ObjFilled))
02413         goto NoMemory;
02414 
02415     // check that the path is OK
02416     if(!pPath->InkPath.EnsureValid())
02417     {
02418         // no, it's completely knackered
02419         delete pPath;
02420         FormatError = TRUE;
02421         return TRUE;
02422     }
02423 
02424     // finish off the path
02425     pPath->InvalidateBoundingRect();                
02426     pPath->InkPath.IsFilled = ObjFilled;
02427 
02428     // save node pointer
02429     pMadeNode = pPath;
02430 
02431     // check to see if text goes along this...
02432     {
02433         CDRTextOnPathLink *Item = (CDRTextOnPathLink *)TextOnPathLinks.GetHead();
02434 
02435         while(Item != 0)
02436         {
02437             // does this link refer to this text story?
02438             if(SerialNumber == Item->PathSerialNumber)
02439             {
02440                 // yep - store a pointer to this path
02441                 Item->pPath = pPath;
02442             }
02443         
02444             // next!
02445             Item = (CDRTextOnPathLink *)TextOnPathLinks.GetNext(Item);
02446         }
02447     }
02448     
02449     // everything was nice
02450     return TRUE;
02451 
02452 NoMemory:
02453     // get rid of any path which is in the process of being created
02454     if(pPath != 0)
02455         pPath->CascadeDelete();
02456 
02457     delete pPath;
02458 
02459     return FALSE;
02460 }

BOOL CDRFilter::ConvertRectangle cdrfOffsetHeader  )  [private]
 

Definition at line 2602 of file cdrfiltr.cpp.

02603 {
02604     // find the address of the coordinates in the header
02605     cdrfRectangleData *Size = (cdrfRectangleData *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
02606 
02607     // it has got some coords, hasn't it?
02608     if(Size == 0)
02609     {
02610         FormatError = TRUE;
02611         return TRUE;
02612     }
02613 
02614     // get the dimensions from the object
02615     INT32 Width = CDRDATA_SWORD(Size->Width) * CDRCOORDS_TO_MILLIPOINTS;
02616     INT32 Height = CDRDATA_SWORD(Size->Height) * CDRCOORDS_TO_MILLIPOINTS;
02617     INT32 CornerRadius = CDRDATA_SWORD(Size->CornerRadius) * CDRCOORDS_TO_MILLIPOINTS;
02618     
02619     if(CornerRadius < 0)
02620         CornerRadius = 0 - CornerRadius;
02621 
02622     // make a rectangle quickshape...
02623     NodeRegularShape *NewShape = new (NodeRegularShape);
02624 
02625     if ((NewShape == NULL) || !NewShape->SetUpShape() )
02626     {
02627         ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY));
02628     }
02629 
02630     INT32 AWidth = Width;
02631     INT32 AHeight = Height;
02632     if(AWidth < 0) AWidth = 0 - AWidth;
02633     if(AHeight < 0) AHeight = 0 - AHeight;
02634     
02635     if(!NewShape->MakeRectangle(AWidth, AHeight, CornerRadius))
02636         return FALSE;
02637 
02638     // translate it a bit so the corner is on the origin, not the thingy
02639     Trans2DMatrix Trans(Width / 2, Height / 2);
02640 
02641     NewShape->Transform(Trans);
02642 
02643     // finish off the shape
02644     NewShape->InvalidateBoundingRect();
02645 
02646     // set up an attribute or two
02647     ObjFilled = TRUE;
02648     ObjStroked = TRUE;              
02649 
02650     // set the made node
02651     pMadeNode = NewShape;
02652 
02653     return TRUE;
02654 
02655 }

BOOL CDRFilter::ConvertText cdrfOffsetHeader Header  )  [private]
 

converts a text object to a node. If the object has an unexpected format, then FormatError is set and it return *TRUE* - the return value only indicated environmental errors such as lack of memory

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:
1.2

Definition at line 136 of file cdrtext.cpp.

00137 {
00138     // check to see if this has an offset for text on a path
00139     if(FindDataInObject(Header, cdrfOBJOFFSETTYPE_PATHTEXT1) != 0
00140             && FindDataInObject(Header, cdrfOBJOFFSETTYPE_PATHTEXT2) != 0)
00141     {
00142         IsTextOnAPath = TRUE;
00143     }
00144     else
00145     {
00146         IsTextOnAPath = FALSE;
00147     }
00148 
00149     // hey, this is text!
00150     IsText = TRUE;
00151     IsTextStory = FALSE;
00152 
00153     // dispatch conversion to appropriate routine
00154     if(Version == CDRVERSION_3)
00155         return ConvertText3(Header);
00156 
00157     if(Version == CDRVERSION_4)
00158     {
00159         if(CDRDATA_WORD(Header->ObjectType) == cdrfOBJTYPE_TEXT)
00160         {
00161             return ConvertText4Art(Header);
00162         }
00163         else
00164         {
00165             return ConvertText4Para(Header);
00166         }
00167     }
00168 
00169     // if it's a text story we're fiddling with, see how big the frame is
00170     INT32 FrameX = 0, FrameY = 0;
00171     DocCoord Trans = DocCoord(0,0);
00172     if(Header->ObjectType == cdrfOBJTYPE_TEXTSTORY)
00173     {
00174         // find the size of the object
00175         cdrfTextStoryCoordData *Coords = (cdrfTextStoryCoordData *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
00176     
00177         if(Coords == 0)
00178         {
00179             FormatError = TRUE;
00180             return TRUE;
00181         }
00182 
00183         FrameX = CDRDATA_WORD(Coords->XSize);
00184         FrameY = CDRDATA_WORD(Coords->YSize);
00185 TRACEUSER( "Ben", _T("Initial frame dimensions: X = %d Y = %d\n"), FrameX, FrameY);
00186 
00187         IsTextStory = TRUE;
00188     }
00189     else
00190     {
00191         IsTextStory = FALSE;
00192     }
00193 
00194     // OK, the header supplied here is in a block of it's own so we can aquire a new RIFF block
00195     // for the text info
00196 
00197     // the RIFF object will be at a loda chunk, which is at a one higher level than that of
00198     // the txsm chunk - find level we don't want to seek over
00199     ERROR3IF(RIFF->GetObjType() != RIFFOBJECTTYPE_CHUNK || RIFF->GetObjChunkType() != cdrT_loda,
00200         "CDFFilter::ConvertText called with RIFF on a non-loda chunk");
00201     UINT32 EndLevel = RIFF->GetObjLevel() - 1;
00202 
00203     // now stroll though the RIFF file
00204     // stop when we find a txsm chunk, and store any trfd chunks we might meet on the way
00205     BOOL Found = FALSE;
00206     do
00207     {
00208         if(RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK && RIFF->GetObjChunkType() == cdrT_txsm)
00209         {
00210             // found the text info thingy
00211             Found = TRUE;
00212         }
00213         else if(RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART && RIFF->GetObjChunkType() == cdrT_trfl)
00214         {
00215             // grab the list contents
00216             if(!RIFF->GetListContents(&TransformChunk, &TransformChunkSize))
00217                 return FALSE;
00218         }
00219 
00220         UpdateProgress();
00221 
00222         if(!Found)
00223             if(!RIFF->NextObject())
00224                 return FALSE;
00225     
00226     } while(Found == FALSE && (RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() >= EndLevel));
00227 
00228     if(RIFF->GetObjType() != RIFFOBJECTTYPE_CHUNK || RIFF->GetObjChunkType() != cdrT_txsm)
00229     {
00230         FormatError = TRUE;
00231         return TRUE;
00232     }
00233 
00234     // get size of chunk
00235     INT32 TextInfoSize = RIFF->GetObjSize();
00236     
00237     // aquire the chunk data
00238     if(!RIFF->AquireChunkData())
00239         return FALSE;
00240 
00241     // and get a pointer to the 'nice' info chunk
00242     ADDR TextInfo;
00243     if((TextInfo = RIFF->GetAquiredData()) == 0)
00244     {
00245         return FALSE;
00246     }
00247     cdrfTextInfoHdr *TIH = (cdrfTextInfoHdr *)TextInfo;
00248 
00249     // make a new text story node
00250     TextStory *TSNode = new TextStory;
00251 
00252     if(TSNode == 0)
00253         return FALSE;
00254     
00255     // get the number of paragraphs
00256     UINT32 NParagraphs = CDRDATA_WORD(TIH->NParagraphs);
00257 
00258     // set up some variables
00259     INT32 Loc = sizeof(cdrfTextInfoHdr);
00260     INT32 FirstLineSpace = -1;
00261     INT32 InitialFirstLineSpace = -1;
00262     INT32 ThisLineSpace = 0;
00263     INT32 PreviousLineSpace = 0;
00264     INT32 MaximumLineX = 0;     // MaximumLineX and
00265     INT32 Lines = 1;                // Lines only used for artisitic text
00266     Justification Just;         // the justification
00267 
00268     // convert the paragraph
00269     UINT32 CurrentPara;
00270     INT32 LineX;
00271     for(CurrentPara = 0; CurrentPara < NParagraphs; CurrentPara++)
00272     {
00273         // set up a few things
00274         LineX = 0;          // current position in the line
00275         
00276         // check sizes
00277         if((Loc + (INT32)sizeof(cdrfTextInfoParaHdr)) > TextInfoSize)
00278             break;
00279     
00280         // get paragraph header info
00281         cdrfTextInfoParaHdr *ParaHdr = (cdrfTextInfoParaHdr *)(TextInfo + Loc);
00282         Loc += sizeof(cdrfTextInfoParaHdr);
00283 
00284         // sort out font style definitions
00285         INT32 NFontDefns = CDRDATA_WORD(ParaHdr->NFontDefns);
00286 
00287         if((Loc + ((INT32)sizeof(cdrfTextInfoFontDefn) * NFontDefns)) > TextInfoSize)
00288             break;
00289     
00290         cdrfTextInfoFontDefn *FontDefns = (cdrfTextInfoFontDefn *)(TextInfo + Loc);
00291         Loc += (sizeof(cdrfTextInfoFontDefn) * NFontDefns);
00292 
00293         // get some memory for the converted font styles
00294         if(NFontDefns <= 0)
00295             break;
00296 
00297         CDRTextStyle *Styles = new CDRTextStyle[NFontDefns];
00298         
00299         // convert the first definiton from the style
00300         if(!GetTextStyleFromCDRStyle(&Styles[0], ParaHdr->Style))
00301             goto NoMemory;
00302 
00303         // store the justificationness
00304         Just = Styles[0].Just;
00305 
00306         // just in case of random Corel behaviour...
00307         PreviousLineSpace = (Styles[0].FontSize * 12) / 10;
00308 
00309         // go through translating all the other styles
00310         for(INT32 l = 1; l < NFontDefns; l++)
00311         {
00312             if(!GetTextStyleFromDefn(&Styles[l], &FontDefns[l], &Styles[0]))
00313                 return FALSE;
00314         }
00315 
00316         // get the paragraph info
00317         if((Loc + (INT32)sizeof(cdrfTextInfoParaInfo)) > TextInfoSize)
00318             break;
00319         
00320         cdrfTextInfoParaInfo *PInfo = (cdrfTextInfoParaInfo *)(TextInfo + Loc);
00321 
00322         Loc += sizeof(cdrfTextInfoParaInfo);
00323         
00324         INT32 NChars = CDRDATA_WORD(PInfo->NChars);
00325 
00326         // sort out the character array
00327         if((Loc + ((INT32)sizeof(cdrfTextInfoChar) * NChars)) > TextInfoSize)
00328             break;
00329         
00330         cdrfTextInfoChar *Chars = (cdrfTextInfoChar *)(TextInfo + Loc);
00331 
00332         Loc += (sizeof(cdrfTextInfoChar) * NChars);
00333     
00334         // make a new text line for this paragraph
00335         TextLine *CurrentLine = new TextLine(TSNode, LASTCHILD);
00336         if(CurrentLine == 0)
00337             goto NoMemory;
00338 
00339         // and run through adding all those nice characters
00340         INT32 CurrentChar;
00341         for(CurrentChar = 0; CurrentChar < NChars; CurrentChar++)
00342         {
00343             BOOL NewLine = FALSE;       // whether to create a new line here
00344 
00345             if(IsTextStory == FALSE && CDRDATA_WORD(Chars[CurrentChar].Code) == cdrfTEXT_NEWLINE)
00346             {
00347                 // update a couple of artisitic text only variables
00348                 Lines++;
00349 
00350                 if(LineX > MaximumLineX)
00351                     MaximumLineX = LineX;
00352 
00353                 // create a new line
00354                 NewLine = TRUE;
00355             }
00356             
00357             // find the style of the character
00358             INT32 Style = ((CDRDATA_WORD(Chars[CurrentChar].Info)) & cdrfTEXTINFOCHAR_INFO_DEFNMASK)
00359                         >> cdrfTEXTINFOCHAR_INFO_DEFNMASKSBY;
00360 
00361             // create it
00362             if(CDRDATA_WORD(Chars[CurrentChar].Code) >= ' ')
00363             {
00364                 TextChar *C = new TextChar(CurrentLine, LASTCHILD, CDRDATA_WORD(Chars[CurrentChar].Code));
00365 
00366                 if(C == 0)
00367                     goto NoMemory;
00368 
00369                 if(Style < 0 || Style >= NFontDefns)
00370                     Style = 0;
00371 
00372                 // apply attributes
00373                 if(!ApplyTextAttr(C, &Styles[Style], 0 /*&Styles[0]*/))     // for now, we can't base attributes on anything 'cos the optimiser can't hack it
00374                     goto NoMemory;
00375             }
00376 
00377             // add the character width
00378             LineX += CDRDATA_SWORD(Chars[CurrentChar].XSize);
00379 
00380             // update this line's spacing thingy
00381             if(Styles[Style].LineSpace > ThisLineSpace)
00382                 ThisLineSpace = Styles[Style].LineSpace;
00383 
00384             // sort out first line spaceing thing
00385             if(InitialFirstLineSpace == -1)
00386                 InitialFirstLineSpace = Styles[Style].LineSpace;
00387 
00388             if(NewLine)
00389             {
00390                 // apply the line spacing attribute - make a font size attribute
00391                 if(ThisLineSpace < 512)
00392                     ThisLineSpace = PreviousLineSpace;
00393                 TxtLineSpaceAttribute Attr((FIXED16)(((double)Styles[0].ParaLineSpacePercent) /* * 1.2*/ / 100));
00394 
00395                 // attach
00396                 if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00397                     return FALSE;
00398 
00399                 // add an EOL
00400                 EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
00401                 if(EOL == 0)
00402                     goto NoMemory;
00403                 // make a new line
00404                 CurrentLine = new TextLine(TSNode, LASTCHILD);
00405                 if(CurrentLine == 0)
00406                     goto NoMemory;
00407 
00408                 // sort out first line spacing thing
00409                 if(FirstLineSpace == -1)
00410                     FirstLineSpace = ThisLineSpace;
00411 
00412                 // reset things
00413                 LineX = 0;
00414                 PreviousLineSpace = ThisLineSpace;
00415                 ThisLineSpace = 0;
00416             }
00417         }
00418 
00419         // sort out first line spaceing thing
00420         if(FirstLineSpace == -1)
00421             FirstLineSpace = ThisLineSpace;
00422 
00423         // apply the line spacing attribute - make a font size attribute
00424         if(ThisLineSpace < 512)
00425             ThisLineSpace = PreviousLineSpace;
00426         TxtLineSpaceAttribute Attr((FIXED16)(((double)Styles[0].ParaLineSpacePercent)  / 100));
00427     
00428         // attach
00429         if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00430             return FALSE;
00431 
00432         // pop on an end of line node
00433         EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
00434 
00435         if(EOL == 0)
00436             goto NoMemory;
00437 
00438         // get rid of the font styles
00439         delete [] Styles;
00440 
00441         PreviousLineSpace = ThisLineSpace;
00442     }
00443 
00444     // pop a caret at the end of the last line
00445     {
00446         Node *LastLine = TSNode->FindLastChild();
00447 
00448         if(LastLine == 0)
00449             goto FormError;
00450 
00451         Node *LastLineNode = LastLine->FindLastChild();
00452 
00453         ERROR3IF(LastLineNode == 0, "Line node doesn't have any children");
00454         ERROR3IF(!LastLineNode->IsKindOf(CC_RUNTIME_CLASS(EOLNode)), "Last entry of a line is not an EOL node");
00455         
00456         CaretNode *C = new CaretNode(LastLineNode, PREV);
00457         if(C == 0)
00458             goto NoMemory;
00459     }
00460 
00461     // set up maximumlinex - only valid for artisitic text
00462     if(LineX > MaximumLineX)
00463         MaximumLineX = LineX;
00464 
00465     // set up a bounding box for this text object and
00466     // if this is a text story, translate it down a bit
00467     // so that the top of the first line is at the top of the frame
00468     if(IsTextStory)
00469     {
00470         if(FirstLineSpace == -1)
00471             goto FormError;         // no first line? How strange...
00472 
00473         // work out the distance to move the text line down = the first line un 120%ed
00474         INT32 Down = (FirstLineSpace * 10) / 12;
00475 
00476         // work out the rightness shifting
00477         INT32 Right = 0;
00478         if(Just == JCENTRE)
00479         {
00480             Right = (FrameX / 2) * CDRCOORDS_TO_MILLIPOINTS;
00481         }
00482         else if(Just == JRIGHT)
00483         {
00484             Right = FrameX * CDRCOORDS_TO_MILLIPOINTS;
00485         }
00486 
00487         // transform the story
00488         TSNode->SetStoryMatrix(Matrix(Trans.x+Right, Trans.y-Down));
00489 
00490         // set the format width
00491         TSNode->SetImportFormatWidth(FrameX * CDRCOORDS_TO_MILLIPOINTS);
00492 TRACEUSER( "Ben", _T("Import format width initially %d\n"), TSNode->GetImportFormatWidth());
00493 
00494         // bounding box for text story
00495         DocRect BBox = DocRect(Trans.x, Trans.y - (FrameY * CDRCOORDS_TO_MILLIPOINTS),
00496                 Trans.x + (FrameX * CDRCOORDS_TO_MILLIPOINTS), Trans.y);
00497 
00498         TextBBoxes.Add(TSNode, &BBox, JLEFT);
00499     }
00500     else
00501     {
00502         // set the matrix of the story
00503         TSNode->SetStoryMatrix(Matrix(0,0));
00504 
00505         // bounding box for a text object
00506         DocRect BBox = DocRect(0, 0 - FirstLineSpace * Lines,
00507                 (MaximumLineX * CDRCOORDS_TO_MILLIPOINTS), FirstLineSpace);
00508 
00509         TextBBoxes.Add(TSNode, &BBox, Just);
00510 
00511         // see if this is linked to a path
00512         CheckTextForLinks(TSNode, Header);
00513     }
00514 
00515     // set some essential variables
00516     ObjFilled = TRUE;
00517     ObjStroked = FALSE;
00518 
00519     // all done return...
00520     pMadeNode = TSNode;
00521 
00522     return TRUE;
00523 
00524 NoMemory:
00525     TSNode->CascadeDelete();
00526     delete TSNode;
00527     
00528     return FALSE;
00529 
00530 FormError:
00531     FormatError = TRUE;
00532     TSNode->CascadeDelete();
00533     delete TSNode;
00534     
00535     return TRUE;
00536 }

BOOL CDRFilter::ConvertText3 cdrfOffsetHeader Header  )  [private]
 

converts a version 3 text object to a node. If the object has an unexpected format, then FormatError is set and it return *TRUE* - the return value only indicated environmental errors such as lack of memory

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:
1.2

1.2

Definition at line 1025 of file cdrtext.cpp.

01026 {
01027     // is it a text story?
01028     if(Header->ObjectType == (cdrfOBJTYPE_TEXTSTORY - cdrfOBJTYPE_V3ADD))
01029         IsTextStory = TRUE;
01030 
01031     // get the data from this object
01032     cdrfTextHeaderV3 *Hdr = (cdrfTextHeaderV3 *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
01033 
01034     // it has got some coords, hasn't it?
01035     if(Hdr == 0)
01036     {
01037         FormatError = TRUE;
01038         return TRUE;
01039     }
01040 //TRACEUSER( "Ben", _T("FrameX = %d, FrameY = %d\n"), Hdr->FrameX, Hdr->FrameY);
01041 
01042     INT32 FrameX = CDRDATA_WORD(Hdr->FrameX) * CDRCOORDS_TO_MILLIPOINTS;
01043     INT32 FrameY = CDRDATA_WORD(Hdr->FrameY) * CDRCOORDS_TO_MILLIPOINTS;
01044 
01045     // find pointer to the characters
01046     cdrfTextCharV3 *ThisChar = (cdrfTextCharV3 *)(Hdr + 1);
01047 
01048     // get the base style
01049     CDRTextStyle BaseStyle;
01050 
01051     if(!GetTextStyle3(&BaseStyle, CDRDATA_WORD(Hdr->BaseFontStyle)))
01052         return FALSE;
01053 
01054     // add the justifcation stuff to it
01055     TRACEUSER( "Ben", _T("Justificatoin V3 = %d\n"), Hdr->Justification);
01056     switch(Hdr->Justification)
01057     {
01058         case cdrfJUSTIFICATIONV3_LEFT:
01059         default:
01060             BaseStyle.Just = JLEFT;
01061             break;
01062 
01063         case cdrfJUSTIFICATIONV3_CENTRE:
01064             BaseStyle.Just = JCENTRE;
01065             break;
01066 
01067         case cdrfJUSTIFICATIONV3_RIGHT:
01068             BaseStyle.Just = JRIGHT;
01069             break;
01070     }
01071     
01072     // make a new text story node
01073     TextStory *TSNode = new TextStory;
01074 
01075     if(TSNode == 0)
01076         return FALSE;
01077 
01078     // run through the text...
01079     INT32 NChars = CDRDATA_WORD(Hdr->NCharacters);
01080     INT32 CurrentChar;
01081     INT32 MaximumLineSpace = BaseStyle.LineSpace;
01082     INT32 Lines = 1;
01083     INT32 Depth = 0;
01084 
01085     // make a new text line
01086     TextLine *CurrentLine = new TextLine(TSNode, LASTCHILD);
01087     if(CurrentLine == 0)
01088         goto NoMemory;
01089 
01090     for(CurrentChar = 0; CurrentChar < NChars; CurrentChar++)
01091     {
01092         BOOL HasStyles = FALSE;
01093 
01094         if(ThisChar->Info != 0)
01095             HasStyles = TRUE;
01096 
01097         if(ThisChar->Code >= ' ')
01098         {
01099             TextChar *C = new TextChar(CurrentLine, LASTCHILD, ThisChar->Code);
01100 
01101             if(C == 0)
01102                 goto NoMemory;
01103 
01104             // apply attributes
01105             if(HasStyles)
01106             {
01107                 // it's got styles of it's own, find and apply them
01108                 cdrfTextCharStyledV3 *SC = (cdrfTextCharStyledV3 *)ThisChar;
01109 
01110                 CDRTextStyle ThisStyle;
01111 
01112                 if(!GetTextStyle3(&ThisStyle, CDRDATA_WORD(SC->Style), &BaseStyle))
01113                     return FALSE;
01114 
01115                 if(!ApplyTextAttr(C, &ThisStyle, 0))
01116                     goto NoMemory;
01117         
01118                 if(ThisStyle.LineSpace > MaximumLineSpace)
01119                     MaximumLineSpace = ThisStyle.LineSpace;
01120             }
01121             else
01122             {
01123                 // just apply the normal attributes
01124                 if(!ApplyTextAttr(C, &BaseStyle, 0))
01125                     goto NoMemory;
01126             }
01127         }
01128 
01129         if(ThisChar->Code == cdrfTEXT_NEWLINE)
01130         {
01131             // create a new line...
01132             // apply the line spacing attribute - make a font size attribute
01133 //          TxtLineSpaceAttribute Attr(MaximumLineSpace);
01134             TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent)  / 100));
01135 
01136             // attach
01137             if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
01138                 return FALSE;
01139 
01140             // add an EOL
01141             EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
01142             if(EOL == 0)
01143                 goto NoMemory;
01144 
01145             // make a new line
01146             CurrentLine = new TextLine(TSNode, LASTCHILD);
01147             if(CurrentLine == 0)
01148                 goto NoMemory;
01149 
01150             // set things
01151             Lines++;
01152             Depth += MaximumLineSpace;
01153             MaximumLineSpace = BaseStyle.LineSpace;
01154         }
01155 
01156         if(HasStyles)
01157         {
01158 //TRACEUSER( "Ben", _T("Char has styles, code %d (%c)\n"), ThisChar->Code, ThisChar->Code); 
01159             // it's got more than normal bytes in it, so add a few more than usual
01160             ThisChar = (cdrfTextCharV3 *)(((cdrfTextCharStyledV3 *)ThisChar) + 1);
01161         }
01162         else
01163         {
01164 //TRACEUSER( "Ben", _T("Char, code %d (%c)\n"), ThisChar->Code, ThisChar->Code); 
01165             // just a normal character, so simply increment it
01166             ThisChar++;
01167         }
01168     }
01169 
01170     // pop a line space attribute on the last line
01171     {
01172 //      TxtLineSpaceAttribute Attr(MaximumLineSpace);
01173         TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent)  / 100));
01174 
01175         // attach
01176         if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
01177             return FALSE;
01178     }
01179 
01180     Depth += MaximumLineSpace;
01181 
01182     // finish the last line with an end of line node
01183     {
01184         EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
01185 
01186         if(EOL == 0)
01187             goto NoMemory;
01188 
01189         // pop a caret at the end of the last line
01190         Node *LastLine = TSNode->FindLastChild();
01191 
01192         if(LastLine == 0)
01193             goto FormError;
01194 
01195         Node *LastLineNode = LastLine->FindLastChild();
01196 
01197         ERROR3IF(LastLineNode == 0, "Line node doesn't have any children");
01198         ERROR3IF(!LastLineNode->IsKindOf(CC_RUNTIME_CLASS(EOLNode)), "Last entry of a line is not an EOL node");
01199         
01200         CaretNode *C = new CaretNode(LastLineNode, PREV);
01201         if(C == 0)
01202             goto NoMemory;
01203     }
01204 
01205     if(IsTextStory)
01206     {
01207         // get a first line height
01208         INT32 FirstLineHeight = (BaseStyle.LineSpace * 10) / 12;
01209 
01210         // work out the rightness shifting
01211         INT32 Right = 0;
01212         if(BaseStyle.Just == JCENTRE)
01213         {
01214             Right = FrameX / 2;
01215         }
01216         else if(BaseStyle.Just == JRIGHT)
01217         {
01218             Right = FrameX;
01219         }
01220 
01221         // set the matrix of the story
01222         TSNode->SetStoryMatrix(Matrix(Right, -FirstLineHeight));
01223 
01224         // bounding box for a text frame
01225         DocRect BBox = DocRect(0, 0 - FrameY, FrameX, 0);
01226 
01227         TextBBoxes.Add(TSNode, &BBox, JLEFT);
01228     
01229         // set it's width to be formatted to
01230         TSNode->SetImportFormatWidth(FrameX);
01231     }
01232     else
01233     {
01234         // set the matrix of the story
01235         TSNode->SetStoryMatrix(Matrix(0,0));
01236 
01237         // bounding box for a artisitic text object - approximate it's width
01238         INT32 Width = (MaximumLineSpace * NChars) / (Lines * 3);
01239 
01240         DocRect BBox = DocRect(0, 0 - Depth, Width, MaximumLineSpace);
01241 
01242         TextBBoxes.Add(TSNode, &BBox, BaseStyle.Just);
01243     
01244         // check it for path on a text
01245         CheckTextForLinks(TSNode, Header);
01246     }
01247 
01248     // set some essential variables
01249     ObjFilled = TRUE;
01250     ObjStroked = FALSE;
01251 
01252     // all done, return...
01253     pMadeNode = TSNode;
01254 
01255     return TRUE;
01256 
01257 NoMemory:
01258     TSNode->CascadeDelete();
01259     delete TSNode;
01260     
01261     return FALSE;
01262 
01263 FormError:
01264     FormatError = TRUE;
01265     TSNode->CascadeDelete();
01266     delete TSNode;
01267     
01268     return TRUE;
01269 }

BOOL CDRFilter::ConvertText4Art cdrfOffsetHeader Header  )  [private]
 

converts a version 4 artisitic text object

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:
1.2

1.2

Definition at line 552 of file cdrtext.cpp.

00553 {
00554     // get the data from this object
00555     cdrfTextHeaderV4 *Hdr = (cdrfTextHeaderV4 *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
00556 
00557     // it has got some coords, hasn't it?
00558     if(Hdr == 0)
00559     {
00560         FormatError = TRUE;
00561         return TRUE;
00562     }
00563     // find pointer to the characters
00564     cdrfTextCharV4 *ThisChar = (cdrfTextCharV4 *)(Hdr + 1);
00565 
00566     // get the base style
00567     CDRTextStyle BaseStyle;
00568 
00569     WORD *StyleRef = (WORD *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_STYLE);
00570     if(StyleRef == 0)
00571     {
00572         FormatError = TRUE;
00573         return TRUE;
00574     }
00575 
00576     if(!GetTextStyleFromCDRStyle(&BaseStyle, CDRDATA_WORD(*StyleRef)))
00577         return FALSE;
00578 
00579     // make a new text story node
00580     TextStory *TSNode = new TextStory;
00581 
00582     if(TSNode == 0)
00583         return FALSE;
00584 
00585     // run through the text...
00586     INT32 NChars = CDRDATA_WORD(Hdr->NCharacters);
00587     INT32 CurrentChar;
00588     INT32 MaximumLineSpace = BaseStyle.LineSpace;
00589     INT32 Lines = 1;
00590     INT32 Depth = 0;
00591 
00592     // make a new text line
00593     TextLine *CurrentLine = new TextLine(TSNode, LASTCHILD);
00594     if(CurrentLine == 0)
00595         goto NoMemory;
00596 
00597     for(CurrentChar = 0; CurrentChar < NChars; CurrentChar++)
00598     {
00599         BOOL HasStyles = FALSE;
00600 
00601         if(ThisChar->Info != 0)
00602             HasStyles = TRUE;
00603 
00604         if(ThisChar->Code >= ' ')
00605         {
00606             TextChar *C = new TextChar(CurrentLine, LASTCHILD, ThisChar->Code);
00607 
00608             if(C == 0)
00609                 goto NoMemory;
00610 
00611             // apply attributes
00612             if(HasStyles)
00613             {
00614                 // it's got styles of it's own, find and apply them
00615                 cdrfTextCharStyledV4 *SC = (cdrfTextCharStyledV4 *)ThisChar;
00616 
00617                 CDRTextStyle ThisStyle;
00618 
00619                 if(!GetTextStyleFromChar4(&ThisStyle, SC, &BaseStyle))
00620                     return FALSE;
00621 
00622                 if(!ApplyTextAttr(C, &ThisStyle, 0))
00623                     goto NoMemory;
00624         
00625                 if(ThisStyle.LineSpace > MaximumLineSpace)
00626                     MaximumLineSpace = ThisStyle.LineSpace;
00627             }
00628             else
00629             {
00630                 // just apply the normal attributes
00631                 if(!ApplyTextAttr(C, &BaseStyle, 0))
00632                     goto NoMemory;
00633             }
00634         }
00635 
00636         if(ThisChar->Code == cdrfTEXT_NEWLINE)
00637         {
00638             // create a new line...
00639             // apply the line spacing attribute - make a font size attribute
00640 //          TxtLineSpaceAttribute Attr(MaximumLineSpace);
00641             TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent)  / 100));
00642 
00643             // attach
00644             if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00645                 return FALSE;
00646 
00647             // add an EOL
00648             EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
00649             if(EOL == 0)
00650                 goto NoMemory;
00651 
00652             // make a new line
00653             CurrentLine = new TextLine(TSNode, LASTCHILD);
00654             if(CurrentLine == 0)
00655                 goto NoMemory;
00656 
00657             // set things
00658             Lines++;
00659             Depth += MaximumLineSpace;
00660             MaximumLineSpace = BaseStyle.LineSpace;
00661         }
00662 
00663         if(HasStyles)
00664         {
00665             // it's got more than normal bytes in it, so add a few more than usual
00666             ThisChar = (cdrfTextCharV4 *)(((cdrfTextCharStyledV4 *)ThisChar) + 1);
00667         }
00668         else
00669         {
00670             // just a normal character, so simply increment it
00671             ThisChar++;
00672         }
00673     }
00674 
00675     // pop a line space attribute on the last line
00676     {
00677 //      TxtLineSpaceAttribute Attr(MaximumLineSpace);
00678         TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent)  / 100));
00679 
00680         // attach
00681         if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00682             return FALSE;
00683     }
00684 
00685     Depth += MaximumLineSpace;
00686 
00687     // finish the last line with an end of line node
00688     {
00689         EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
00690 
00691         if(EOL == 0)
00692             goto NoMemory;
00693 
00694         // pop a caret at the end of the last line
00695         Node *LastLine = TSNode->FindLastChild();
00696 
00697         if(LastLine == 0)
00698             goto FormError;
00699 
00700         Node *LastLineNode = LastLine->FindLastChild();
00701 
00702         ERROR3IF(LastLineNode == 0, "Line node doesn't have any children");
00703         ERROR3IF(!LastLineNode->IsKindOf(CC_RUNTIME_CLASS(EOLNode)), "Last entry of a line is not an EOL node");
00704         
00705         CaretNode *C = new CaretNode(LastLineNode, PREV);
00706         if(C == 0)
00707             goto NoMemory;
00708     }
00709 
00710     // set the matrix of the story
00711     {
00712         TSNode->SetStoryMatrix(Matrix(0,0));
00713 
00714         // bounding box for a artisitic text object - approximate it's width
00715         INT32 Width = (MaximumLineSpace * NChars) / (Lines * 3);
00716 
00717         DocRect BBox = DocRect(0, 0 - Depth, Width, MaximumLineSpace);
00718 
00719         TextBBoxes.Add(TSNode, &BBox, BaseStyle.Just);
00720     }
00721 
00722     // check it for paths...
00723     CheckTextForLinks(TSNode, Header);
00724     
00725     // set some essential variables
00726     ObjFilled = TRUE;
00727     ObjStroked = FALSE;
00728     IsTextStory = FALSE;
00729 
00730     // all done, return...
00731     pMadeNode = TSNode;
00732 
00733     return TRUE;
00734 
00735 NoMemory:
00736     TSNode->CascadeDelete();
00737     delete TSNode;
00738     
00739     return FALSE;
00740 
00741 FormError:
00742     FormatError = TRUE;
00743     TSNode->CascadeDelete();
00744     delete TSNode;
00745     
00746     return TRUE;
00747 }

BOOL CDRFilter::ConvertText4Para cdrfOffsetHeader Header  )  [private]
 

converts a version 4 paragraph text object

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:
1.2

Definition at line 763 of file cdrtext.cpp.

00764 {
00765     // get the data from this object
00766     cdrfParaTextHeaderV4 *Hdr = (cdrfParaTextHeaderV4 *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_COORDS);
00767 
00768     // set the var...
00769     IsTextStory = TRUE;
00770 
00771     // it has got some coords, hasn't it?
00772     if(Hdr == 0)
00773     {
00774         FormatError = TRUE;
00775         return TRUE;
00776     }
00777 
00778 
00779     // find out what text item we need
00780     if(LinkTable == 0)
00781     {
00782         // no link table, oh dear
00783         FormatError = TRUE;
00784         return TRUE;
00785     }
00786 
00787     cdrfLinkTableHdr *th = (cdrfLinkTableHdr *)LinkTable;
00788 
00789     INT32 Entries = CDRDATA_WORD(th->Entries);
00790     BOOL Found = FALSE;
00791     WORD *Offsets = (WORD *)(LinkTable + CDRDATA_WORD(th->OffsetsOffset));
00792     cdrfLinkTableEntryTextV4 *En;
00793     for(INT32 l = 0; l < Entries; l++)
00794     {
00795         En = (cdrfLinkTableEntryTextV4 *)(LinkTable + CDRDATA_WORD(Offsets[l]));
00796     
00797         if(CDRDATA_WORD(En->Type) == cdrfLINKTABLEENTRYV4_TEXT &&
00798                 CDRDATA_WORD(En->ObjectSerial) == SerialNumber)
00799         {
00800             Found = TRUE;
00801             break;
00802         }
00803     }
00804 
00805     if(Found == FALSE)
00806     {
00807         FormatError = TRUE;
00808         return TRUE;
00809     }
00810     
00811     // locate the text item with those attributes
00812     CDRVectorStoredItem *Item = (CDRVectorStoredItem *)TextV4.GetHead();
00813     
00814     // go through the list of items searching for the reference number given
00815     while(Item != 0)
00816     {
00817         if(Item->Reference == CDRDATA_WORD(En->TextID))
00818         {
00819             // OK, we found it...
00820             break;
00821         }
00822 
00823         Item = (CDRVectorStoredItem *)TextV4.GetNext(Item);
00824     }
00825 
00826     if(Item == 0)
00827     {
00828         FormatError = TRUE;
00829         return TRUE;
00830     }
00831 
00832     Node *Text = Item->Objects;
00833 
00834     // find the base attributes
00835     CDRTextStyle BaseStyle;
00836 
00837     WORD *StyleRef = (WORD *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_STYLE);
00838     if(StyleRef == 0)
00839     {
00840         FormatError = TRUE;
00841         return TRUE;
00842     }
00843 
00844     if(!GetTextStyleFromCDRStyle(&BaseStyle, CDRDATA_WORD(*StyleRef)))
00845         return FALSE;
00846     
00847     // get the maximum height of the first line
00848     ERROR2IF(!IS_A(Text, TextLine), FALSE, "Node in text list is not a text line");
00849 
00850     // apply attributes to the lines
00851     TextLine *CurrentLine = (TextLine *)Text;
00852     while(CurrentLine != 0)
00853     {
00854         if(IS_A(CurrentLine, TextLine))
00855         {
00856 /*          Node *pNode = CurrentLine->FindFirstChild();
00857 
00858             while(pNode != 0)
00859             {
00860                 if(IS_A(pNode, TextChar))
00861                 {
00862                     if(!ApplyTextAttr(pNode, &BaseStyle, 0))
00863                         return FALSE;
00864                 }
00865 
00866                 pNode = pNode->FindNext();
00867             }
00868 */
00869             // attach the line spacing onto it
00870             TxtLineSpaceAttribute Attr((FIXED16)(((double)BaseStyle.ParaLineSpacePercent)  / 100));
00871 
00872             if(!ApplyTextAttrDoApply(CurrentLine, &Attr, FALSE))
00873                 return FALSE;
00874         }
00875         
00876         CurrentLine = (TextLine *)CurrentLine->FindNext();
00877     }
00878 
00879     // add it to a text story
00880     TextStory *TSNode = new TextStory;
00881     if(TSNode == 0)
00882         return FALSE;
00883 
00884     Text->InsertChainSimple(TSNode, FIRSTCHILD);
00885 
00886     // remove references to the nodes now inserted from the item
00887     Item->Objects = 0;
00888 
00889     // set the matrix and add the bbox
00890     {
00891         INT32 FirstLineSpace = Item->BBox.hi.y;     // get the line spacing from the bbox defn
00892 
00893         // get the frame size
00894         INT32 FrameX = CDRDATA_WORD(Hdr->FrameX) * CDRCOORDS_TO_MILLIPOINTS;
00895         INT32 FrameY = CDRDATA_WORD(Hdr->FrameY) * CDRCOORDS_TO_MILLIPOINTS;
00896 
00897         // work out the distance to move the text line down = the first line un 120%ed
00898         INT32 Down = (FirstLineSpace * 10) / 12;
00899 
00900         // work out the shift...
00901         INT32 Right = 0;
00902         if(BaseStyle.Just == JCENTRE)
00903         {
00904             Right = FrameX / 2;
00905         }
00906         else if(BaseStyle.Just == JRIGHT)
00907         {
00908             Right = FrameX;
00909         }
00910 
00911         
00912         // transform the story
00913         TSNode->SetStoryMatrix(Matrix(Right,-Down));
00914 
00915         // bounding box for text story
00916         DocRect BBox = DocRect(0, 0 - FrameY, FrameX, 0);
00917 
00918         TextBBoxes.Add(TSNode, &BBox, JLEFT);
00919 
00920         // set it's width to be formatted to
00921         TSNode->SetImportFormatWidth(FrameX);
00922     }
00923 
00924     // delete the item
00925     delete TextV4.RemoveItem(Item);
00926 
00927     // set a few variables
00928     pMadeNode = TSNode;
00929     ObjFilled = TRUE;
00930     ObjStroked = FALSE;
00931 
00932     return TRUE;
00933 }

void CDRFilter::DeleteNodeList Node Start  )  [static]
 

Deletes a linked list of nodes (forward direction only).

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27 03 95
Parameters:
[INPUTS] 
Returns:
See also:
Filter

Definition at line 4732 of file cdrfiltr.cpp.

04733 {
04734     Node *This, *Next;
04735 
04736     This = Start;
04737 
04738     while(This != 0)
04739     {
04740         Next = This->FindNext();
04741 
04742         This->CascadeDelete();
04743 
04744         delete This;
04745 
04746         This = Next;
04747     }
04748 }

BOOL CDRFilter::DoesPathNeedArrowheads NodePath P  )  [private]
 

To find out whether a path need attributes.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
29 03 95
Parameters:
NodePath to search [INPUTS]
Returns:
whether the path need some arrowheads
See also:
Filter

Definition at line 533 of file cdroutl.cpp.

00534 {
00535     // if the number of end points is greater than 0, then it needs some arrowheads
00536     if(P->InkPath.GetNumEndPoints() > 0)
00537         return TRUE;
00538 
00539     return FALSE;
00540 }

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

Refuses to export a Corel Palette file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
As for the Filter class [INPUTS]
Returns:
As for the Filter class
See also:
Filter

Reimplemented from Filter.

Definition at line 4764 of file cdrfiltr.cpp.

04765 {
04766     // No exporting here
04767     return FALSE;
04768 }

BOOL CDRFilter::DoImport SelOperation ,
CCLexFile ,
Document ,
BOOL  AutoChosen = FALSE,
ImportPosition Pos = NULL,
KernelBitmap **  ppImportedBitmap = NULL,
DocCoord pPosTranslate = NULL,
String_256 = NULL
[virtual]
 

Reimplemented from Filter.

Definition at line 367 of file cdrfiltr.cpp.

00370 {
00371     // check to see if we've got a CMX file in there, but only if we weren't autochosen
00372     if(!AutoChosen && HasCDRFileGotCMXFile(NULL, pDiskFile))
00373     {
00374         TRACEUSER( "Ben", _T(">>> loading CDR file with new CMXImportFilter\n"));
00375         // right, somehow we got here -- probably because the user specifically
00376         // asked to see CorelDRAW files only
00377         CMXImportFilter *pFilter = new CMXImportFilter;
00378 
00379         if(pFilter == NULL)
00380             return FALSE;
00381 
00382         BOOL ok = pFilter->DoImport(Op, pDiskFile, DestDoc, AutoChosen, Pos);
00383 
00384         delete pFilter;
00385         pFilter = NULL;
00386 
00387         return ok;
00388     }
00389 
00390     // normal CDR import stuff
00391     BOOL ExtensionMatches = pOILFilter->DoesExtensionOfFileMatch(pDiskFile);
00392 
00393     RIFFFile RIFFo;
00394 
00395 TRACEUSER( "Ben", _T("In CDRFilter::DoImport\n"));
00396     //ERROR2IF(Version == CDRVERSION_NULL, FALSE, "CDRFilter::HowCompatible failed to set recognised version\n");
00397 
00398     // in debug builds, warn about fills hanging around
00399     ERROR3IF(Fills.IsEmpty() == FALSE, "Fills store not empty");
00400     ERROR3IF(Outlines.IsEmpty() == FALSE, "Outlines store not empty");
00401     ERROR3IF(Styles.IsEmpty() == FALSE, "Styles store not empty");
00402     ERROR3IF(Fonts.IsEmpty() == FALSE, "Fonts store not empty");
00403     ERROR3IF(Arrowheads.IsEmpty() == FALSE, "Arrowheads store not empty");
00404     ERROR3IF(Patterns.IsEmpty() == FALSE, "Patterns store not empty");
00405     ERROR3IF(Bitmaps.IsEmpty() == FALSE, "Bitmap store not empty");
00406     ERROR3IF(Vectors.IsEmpty() == FALSE, "Vector store not empty");
00407     ERROR3IF(TextBBoxes.IsEmpty() == FALSE, "TextBBoxes list not empty");
00408     ERROR3IF(TextV4.IsEmpty() == FALSE, "TextV4 store not empty");
00409     ERROR3IF(TextOnPathLinks.IsEmpty() == FALSE, "TextOnPathLinks not empty");
00410 
00411     // in retail builds, just vape any contents
00412     Fills.DeleteAll();
00413     Outlines.DeleteAll();
00414     Styles.DeleteAll();
00415     Fonts.DeleteAll();
00416     Arrowheads.DeleteAll();
00417     Patterns.DeleteAll();
00418     Bitmaps.DeleteAll();
00419     Vectors.DeleteAll();
00420     TextV4.DeleteAll();
00421     Pages.DeleteAll();
00422     Actions.DeleteAll();
00423     TextBBoxes.DeleteAll();
00424     TextOnPathLinks.DeleteAll();
00425 
00426     // set a few flags and initialise some variables
00427     pDocument = DestDoc;
00428     Success = TRUE;
00429     SlowJobStarted = FALSE;
00430     TranslateByX = 0;
00431     TranslateByY = 0;
00432     PageX = 0;
00433     PageY = 0;
00434     pLevelNodeList = 0;
00435     DoneDoc = FALSE;
00436     DoneMasterPage = FALSE;
00437     InMasterPage = FALSE;
00438     ThisPage = 0;
00439     ThisLayer = 0;
00440     pMadeNode = 0;
00441     ObjectsConverted = 0;
00442     ObjectsFormatWrong = 0;
00443     ObjectsUnknown = 0;
00444     EnvelopesApproximated = 0;
00445     ObjDataBlock = 0;
00446     ObjDataBlockSize = 0;
00447     AttrsAlreadyApplied = FALSE;
00448     TransformChunk = 0;
00449     FontTableV3 = 0;
00450     FontStylesV3 = 0;
00451     LinkTable = 0;
00452     ThisOp = Op;
00453     LinkTransformsExist = FALSE;
00454     TheDocument = DestDoc;
00455 
00456     // if the extension matches, check it for being a 2.xx file
00457     if(ExtensionMatches)
00458     {
00459         // get the first few bytes
00460         TCHAR FirstBit[8];
00461 
00462         if(pDiskFile->read((void *)FirstBit, sizeof(FirstBit)).bad())
00463             return FALSE;
00464 
00465         ERROR1IF(camStrncmp((char *)FirstBit, "WL", 2) == 0, FALSE, _R(IDT_CDRFILTER_ISAV2FILE));
00466     
00467         // let's pop the file back to the beginning
00468         if(pDiskFile->seek(0).bad())
00469             return FALSE;
00470     }
00471 
00472     // sort out the RIFF file
00473     RIFF = &RIFFo;
00474 
00475     FOURCC FormType = RIFF->Init(pDiskFile);
00476 
00477     if(FormType == 1)       // error
00478     {
00479         CDRFILTER_DI_RETURNERROR;
00480     }
00481     
00482     // sort out which version we're on
00483     switch(FormType)
00484     {
00485         case cdrT_CDR:
00486             Version = CDRVERSION_3;
00487             break;
00488         
00489         case cdrT_CDR4:
00490         case cdrT_CDST:         // version 4 template
00491             Version = CDRVERSION_4;
00492             break;
00493 
00494         case cdrT_CDR5:
00495         case cdrT_CDT5:
00496             Version = CDRVERSION_5;
00497             break;
00498 
00499         case cdrT_CDR6:
00500         case cdrT_CDT6:
00501             // version 6 file -- we don't support these
00502             ERROR1(FALSE, _R(IDE_CDRFILTER_CDR6));
00503             break;
00504 
00505         default:
00506 TRACEUSER( "Ben", _T("Attempted to load something which wasn't a CDR file. I don't think so..."));
00507             ERROR1(FALSE, _R(IDE_CDRFILTER_NOTCDR));
00508             break;
00509     }
00510 
00511     // sort out a colour list
00512     ColList = DestDoc->GetIndexedColours();
00513     
00514     // do we want to import with layers?
00515     UseLayers = FALSE;
00516 #ifdef WEBSTER
00517     // In Webster, just use the default preference settings as these should be set to
00518     // ImportWithLayers to False.
00519     if (
00520         (!DestDoc->IsImporting() && Filter::OpenWithLayers) ||
00521         (DestDoc->IsImporting() && Filter::ImportWithLayers)
00522         )
00523         UseLayers = TRUE;
00524 #else
00525     // In Camelot, we must check to see if the document is being imported and if so if
00526     // there are any frames present. If there are then don't use layers, if there are
00527     // then use the preference setting.
00528     if (DestDoc->IsImporting())
00529     {
00530         Spread * pTheSpread = DestDoc->GetSelectedSpread();
00531         Layer * pFrame = NULL;
00532         if (pTheSpread != NULL)
00533             pFrame = pTheSpread->FindFirstFrameLayer();
00534         if (pFrame != NULL)
00535             UseLayers = FALSE;                      // Frames present so do not import layers
00536         else
00537             UseLayers = Filter::ImportWithLayers;   // No frames so use the preference setting
00538     }
00539     else
00540     {
00541         UseLayers = Filter::OpenWithLayers;
00542     }
00543 #endif
00544 
00545     // If importing without layers, make sure there is a layer to put things on, and make one if not
00546     if(UseLayers == FALSE)
00547     {
00548         if (!MakeSureLayerExists(DestDoc))
00549         {
00550             // clean up and return and error
00551             CDRFILTER_DI_RETURNERROR;
00552         }
00553     }
00554 
00555     // For now, position Draw objects on 1st page of spread 1
00556     pSpread = DestDoc->GetSelectedSpread();
00557     pPage = (Page *) pSpread->FindFirstPageInSpread();
00558     
00559     // Use bottom left of page as origin
00560     DocRect PageRect = pPage->GetPageRect();
00561     Origin = PageRect.lo;
00562 
00563     // OK, let's get into the swing of things!
00564     
00565     // Get a default set of attributes for ink objects.
00566     if (!SetUpCurrentAttrs())
00567         return FALSE;
00568 
00569     // Let start off by setting the progress indicatorx
00570     UINT32 id;
00571     switch(Version)
00572     {
00573         case CDRVERSION_4:  id = _R(IDT_IMPORTMSG_CDR4);    break;
00574         case CDRVERSION_5:  id = _R(IDT_IMPORTMSG_CDR5);    break;
00575         default:            id = _R(IDT_IMPORTMSG_CDR3);    break;
00576     }
00577     if(!DestDoc->IsImporting())
00578         id += _R(IDT_OPENMSG_CDR3) - _R(IDT_IMPORTMSG_CDR3);
00579     //String_64 ImportMessage(id);
00580     String_64 ImportMessage = GetImportProgressString(pDiskFile, id);
00581     
00582     // this slow job doesn't have a delay because if the CDR file has a bitmap at the
00583     // beginning, ContinueSlowJob can't be called for rather a long time (sometimes)
00584     // and you get 'Nothing Selected' instead of a message telling you what's happening.
00585     BeginSlowJob(RIFF->ProgressLimit(), FALSE, &ImportMessage);
00586     SlowJobStarted = TRUE;
00587 
00588     // loop through looking at top level lists, and dispatch them to various handlers
00589     do
00590     {
00591         // get the next object in the file
00592         if(!RIFF->NextObject())
00593             CDRFILTER_DI_RETURNERROR;
00594 
00595         if(RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART)
00596         {
00597             switch(RIFF->GetObjChunkType())
00598             {
00599                 case cdrT_doc:
00600                     if(!ProcessDoc())
00601                     {
00602 TRACEUSER( "Ben", _T("ProcessDoc returned FALSE\n"));
00603                         CDRFILTER_DI_RETURNERROR;
00604                     }
00605                     break;
00606 
00607                 case cdrT_page:
00608                     if(!ProcessPage())
00609                     {
00610 TRACEUSER( "Ben", _T("ProcessPage returned FALSE\n"));
00611                         CDRFILTER_DI_RETURNERROR;
00612                     }
00613                     break;
00614 
00615                 default:
00616                     // we're not interested in any other root level list, so skip it
00617                     if(!RIFF->SkipToListEnd(RIFF->GetObjLevel()))
00618                         CDRFILTER_DI_RETURNERROR;
00619                     break;
00620             }
00621         }
00622 
00623         if(!UpdateProgress())
00624             return FALSE;
00625     } while(RIFF->GetObjType() != RIFFOBJECTTYPE_FILEEND);
00626 
00627     // make sure we're at the end
00628     ContinueSlowJob(RIFF->ProgressLimit());
00629 
00630     // attach paths to text stories
00631     if(!AttachTextToPaths())
00632         return FALSE;
00633 
00634     // only stick objects into the document if some were converted
00635     if(ObjectsConverted > 0)
00636     {
00637     
00638         // check that there were at least two pages
00639         if(Pages.GetCount() < 1)
00640         {
00641     TRACEUSER( "Ben", _T("not enough pages in file\n"));
00642             CDRFILTER_DI_RETURNERROR;
00643         }
00644     
00645         // get the pointer to the list of levels on the master pages
00646         CDRLayerList *MasterLayers;
00647         CDRPageListItem *En = (CDRPageListItem *)Pages.GetHead();
00648 
00649         if(En == 0)
00650             CDRFILTER_DI_RETURNERROR;
00651 
00652         MasterLayers = &En->Layers;
00653     
00654         // get the list of levels on the actual page
00655         CDRLayerList *PageLayers;
00656         En = (CDRPageListItem *)Pages.GetNext(En);
00657 
00658         if(Version != CDRVERSION_3)
00659         {
00660             if(En == 0)
00661                 CDRFILTER_DI_RETURNERROR;
00662 
00663             PageLayers = &En->Layers;
00664 
00665             // check that they have the same number of layers in their lists
00666             if(MasterLayers->GetCount() != PageLayers->GetCount())
00667             {
00668         TRACEUSER( "Ben", _T("not the same number of layers on master page and on page\n"));
00669                 CDRFILTER_DI_RETURNERROR;
00670             }
00671         } else
00672         {
00673             PageLayers = 0;
00674         }
00675 
00676         if(MasterLayers->GetCount() <= 0)
00677             CDRFILTER_DI_RETURNERROR;
00678 
00679         // if it's a CDR 3 file set the page size and translation things
00680         if(Version == CDRVERSION_3)
00681         {
00682             // set the page size?
00683             if(!DestDoc->IsImporting() && PageX > 0 && PageY > 0)
00684             {
00685 // Make the pasteboard an extra page width either side of the page and an extra
00686 // half page height above and below the page. That should be nicely proportional.
00687 
00688                 INT32 ms = (PageX > PageY)?PageX:PageY;
00689     
00690                 // we're opening the file, so set the page size
00691                 if (pSpread)
00692                 {
00693                     BOOL ok = pSpread->SetPageSize(PageX, PageY, ms, 0, FALSE, TRUE);
00694                     // Must set the origin of the grid to the bottom left corner of the
00695                     // union rectangle of all pages on the spread as this is where the x,y
00696                     // measurements are made from.
00697                     DocRect PagesRect;
00698                     NodeGrid* pGrid = pSpread->FindFirstDefaultGridInSpread();
00699                     ok = ok && pSpread->GetPagesRect(&PagesRect);
00700                     if (pGrid)
00701                         pGrid->SetOrigin(PagesRect.lox, PagesRect.loy);
00702                     
00703                     if (!ok)
00704                         CDRFILTER_DI_RETURNERROR;
00705                 }
00706             }
00707         
00708             DocRect PageRect = pPage->GetPageRect();
00709             Origin = PageRect.lo;
00710 
00711             TranslateByX = Origin.x + (PageX / 2);
00712             TranslateByY = Origin.y + (PageY / 2);
00713         }
00714 
00715         // set up pointers to the layers
00716         CDRLayerListItem *MasterEn = (CDRLayerListItem *)MasterLayers->GetTail();
00717         CDRLayerListItem *PageEn = 0;
00718         if(PageLayers != 0)
00719             PageEn = (CDRLayerListItem *)PageLayers->GetTail();
00720 
00721         EndSlowJob();
00722         BeginSlowJob();
00723 
00724         // insert everything into the document
00725         if(UseLayers)
00726         {
00727             // go through inserting every layer which has sometime on it
00728             while(MasterEn != 0)
00729             {
00730                 // check to see if we have objects to import
00731                 if(MasterEn->Objects != 0 || (PageEn != 0 && PageEn->Objects != 0))
00732                 {
00733                     // OK, we've got some objects to import, create a layer to put them in
00734                     Layer *pLayer = new Layer();
00735 
00736                     if(pLayer == 0)
00737                         CDRFILTER_DI_RETURNERROR;
00738 
00739                     // set it's name and attributes
00740                     pLayer->SetLayerID(MasterEn->Name);
00741                     pLayer->SetVisible(MasterEn->IsVisible);
00742                     pLayer->SetLocked(MasterEn->IsLocked);
00743                     pLayer->SetActive(FALSE);
00744                     pLayer->SetPrintable(TRUE);
00745                     pLayer->SetBackground(FALSE);
00746                     pLayer->SetOutline(FALSE);
00747 
00748                     // stick objects below it
00749                     Node *Objects = 0;
00750 
00751                     if(MasterEn->Objects != 0)
00752                     {
00753                         Objects = MasterEn->Objects;
00754                         MasterEn->LayerInDocument = TRUE;
00755                     }
00756                     else
00757                     {
00758                         Objects = PageEn->Objects;
00759                         PageEn->LayerInDocument = TRUE;
00760                     }
00761 
00762                     ERROR3IF(Objects == 0, "Er, tried to make a layer for objects which didn't exist");
00763 
00764                     // attach the objects to the layer
00765                     Objects->InsertChainSimple(pLayer, FIRSTCHILD);
00766 
00767                     // if it's a CDR 3 file and translate it
00768                     if(Version == CDRVERSION_3)
00769                     {
00770                         Trans2DMatrix Trans(TranslateByX, TranslateByY);
00771                         pLayer->Transform(Trans);
00772                     }
00773                     
00774                     // insert the layer...
00775                     if (!Op->DoInsertNewNode(pLayer, (Node *)pSpread, LASTCHILD, TRUE))
00776                     {
00777                         // It didn't work - delete the sub-tree we just created
00778                         pLayer->CascadeDelete();
00779                         delete pLayer;
00780                         pLayer = NULL;
00781                         CDRFILTER_DI_RETURNERROR;
00782                     }
00783 
00784                     // make sure it's name is unique
00785                     pLayer->EnsureUniqueLayerID();
00786                     
00787                     // ... and finally optimise it's attributes
00788                     if(!pLayer->OptimiseAttributes())
00789                         CDRFILTER_DI_RETURNERROR;
00790                 }
00791     
00792                 // get the next (previous) layer to import
00793                 MasterEn = (CDRLayerListItem *)MasterLayers->GetPrev(MasterEn);
00794                 if(PageEn != 0)
00795                     PageEn = (CDRLayerListItem *)PageLayers->GetPrev(PageEn);
00796             }       
00797 
00798             // get the insertation node set up
00799             DestDoc->ResetInsertionPosition();
00800         }
00801         else 
00802         {
00803             // get a group node to put everything in as we're not using layers here.
00804             NodeGroup *pGroup = new NodeGroup;
00805             if(pGroup == 0)
00806                 CDRFILTER_DI_RETURNERROR;
00807     
00808             // run through the layers putting in the stuff - remember they're in reverse order
00809             while(MasterEn != 0)
00810             {
00811         TRACEUSER( "Ben", _T("Putting layer '%s' into document\n"), (TCHAR *)MasterEn->Name);       
00812         
00813                 // put the master pages objects onto this group
00814                 if(MasterEn->Objects != 0)
00815                 {
00816                     MasterEn->Objects->InsertChainSimple(pGroup, LASTCHILD);
00817         
00818                     MasterEn->LayerInDocument = TRUE;
00819                 }
00820 
00821                 // put the page objects into this group
00822                 if(PageEn != 0 && PageEn->Objects != 0)
00823                 {
00824                     PageEn->Objects->InsertChainSimple(pGroup, LASTCHILD);
00825 
00826                     PageEn->LayerInDocument = TRUE;
00827                 }
00828 
00829         
00830                 // get the next (previous) layer to import
00831                 MasterEn = (CDRLayerListItem *)MasterLayers->GetPrev(MasterEn);
00832                 if(PageEn != 0)
00833                     PageEn = (CDRLayerListItem *)PageLayers->GetPrev(PageEn);
00834             }
00835 
00836             // if it's a CDR 3 file translate it
00837             if(Version == CDRVERSION_3)
00838             {
00839                 Trans2DMatrix Trans(TranslateByX, TranslateByY);
00840                 pGroup->Transform(Trans);
00841             }
00842 
00843             // check to see if the group node has more than one child
00844             // if it doesn't just insert the child and not the group, and then
00845             // delete the group node afterwards
00846             NodeRenderableBounded *InsertNode = pGroup;
00847 
00848             NodeRenderableBounded *FirstChild = (NodeRenderableBounded *)pGroup->FindFirstChild();
00849 
00850             if(FirstChild != 0)
00851             {
00852                 // if the first child hasn't got a sibling, then there's only one
00853                 // child to the group, so just insert the child
00854                 if(FirstChild->FindNext() == 0)
00855                     InsertNode = FirstChild;
00856             }
00857 
00858             // and slap the group into the document
00859             if (!Op->DoInsertNewNode(InsertNode, pSpread, TRUE))
00860             {
00861                 // It didn't work - delete the sub-tree we just created
00862                 pGroup->CascadeDelete();
00863                 delete pGroup;
00864                 pGroup = NULL;
00865                 CDRFILTER_DI_RETURNERROR;
00866             }
00867 
00868             if(InsertNode != pGroup)
00869                 delete pGroup;
00870 
00871             // optimise the attributes in our nice new group
00872             if(!InsertNode->OptimiseAttributes())
00873                 CDRFILTER_DI_RETURNERROR;
00874         }
00875     }
00876     else
00877     {
00878         // if we were opening the document, then we need make a layer and set the insertation node
00879         if(!DestDoc->IsImporting())
00880         {
00881             if (!MakeSureLayerExists(DestDoc))
00882                 CDRFILTER_DI_RETURNERROR;
00883 
00884             DestDoc->ResetInsertionPosition();
00885         }
00886     }
00887 
00888     // add some standard colours
00889     if(!AddStandardColourSet(pDocument))
00890         CDRFILTER_DI_RETURNERROR;
00891 
00892     // do a quick post import on it
00893     DestDoc->PostImport();
00894     
00895     // find out how many dodgy objects were encountered along the way
00896     INT32 ObjNotConv = ObjectsFormatWrong + ObjectsUnknown;
00897 
00898     if(ObjNotConv > 0)
00899     {
00900         // tell the user that some objects couldn't be converted
00901         String_256 WarnMsg;
00902         WarnMsg.MakeMsg((ObjNotConv == 1)?_R(IDT_CDRFILTER_OBJWARNING1):_R(IDT_CDRFILTER_OBJWARNING), ObjNotConv);
00903         Error::SetError(0, WarnMsg, 0);
00904         InformWarning();
00905         Error::ClearError();
00906     }
00907 
00908     if(EnvelopesApproximated > 0)
00909     {
00910         // tell the user that some envelopes were approximated
00911         String_256 WarnMsg;
00912         WarnMsg.MakeMsg((EnvelopesApproximated == 1)?_R(IDT_CDRFILTER_ENVAPPROXWARNING1):_R(IDT_CDRFILTER_ENVAPPROXWARNING), EnvelopesApproximated);
00913         Error::SetError(0, WarnMsg, 0);
00914         InformWarning();
00915         Error::ClearError();
00916     }
00917 
00918 TRACEUSER( "Ben", _T("Do import finished\n"));
00919     return ClearUp();
00920 }

ADDR CDRFilter::FindDataInObject cdrfOffsetHeader Header,
WORD  Type
[static]
 

returns the address of data of the given type in an objects with a standard offset header

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 2931 of file cdrfiltr.cpp.

02932 {
02933     WORD *Types;
02934     WORD *Offsets;
02935 
02936     Types = (WORD *)(((BYTE *)Header) + CDRDATA_WORD(Header->TypesOffset));
02937     Offsets = (WORD *)(((BYTE *)Header) + CDRDATA_WORD(Header->OffsetsOffset));
02938 
02939     UINT32 l;
02940 
02941     for(l = 0; l < CDRDATA_WORD(Header->NOffsets); l++)
02942     {
02943         if(CDRDATA_WORD(Types[l]) == Type)
02944         {
02945             UINT32 Off = CDRDATA_WORD(Offsets[Header->NOffsets - l - 1]);
02946             if(Off > CDRDATA_WORD(Header->Size))
02947                 return 0;
02948             
02949             return (ADDR)(((BYTE *)Header) + Off);
02950         }
02951     }
02952 
02953     return 0;
02954 }

BOOL CDRFilter::GetCorelBBox NodeRenderableBounded pNode,
DocRect BBox
[static]
 

gets the Corel simple union bbox of an object

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 03 95
Parameters:
converted node (after transformation) and a pointer to bbox to fill in [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 664 of file cdrfill.cpp.

00665 {
00666     if(pNode->IsKindOf(CC_RUNTIME_CLASS(NodePath)))
00667     {
00668         // ok, so it's a path. That means we can run through it to find out the simple
00669         // union of all points. That's cool. Nice of corel not to do proper bboxes, isn't
00670         // it?
00671 
00672         NodePath *pNodePath = (NodePath *)pNode;
00673 
00674         // get a pointer to the array of coords in the nice path
00675         INT32 NCoords = pNodePath->InkPath.GetNumCoords();
00676         DocCoord *Coords = pNodePath->InkPath.GetCoordArray();
00677 
00678         ERROR3IF(NCoords < 1, "Awooga! Trying to find a corel bbox of a path with less than one coord.");
00679 
00680         INT32 c;
00681 
00682         INT32 x0, y0, x1, y1;
00683 
00684         // initialise my bbox variables
00685         x0 = x1 = Coords[0].x;
00686         y0 = y1 = Coords[0].y;
00687         
00688         for(c = 1; c < NCoords; c++)
00689         {
00690             // update my bbox
00691             if(Coords[c].x < x0) x0 = Coords[c].x;
00692             if(Coords[c].y < y0) y0 = Coords[c].y;
00693             if(Coords[c].x > x1) x1 = Coords[c].x;
00694             if(Coords[c].y > y1) y1 = Coords[c].y;
00695         }
00696 
00697         // fill in *BBox
00698         BBox->lo.x = x0;
00699         BBox->lo.y = y0;
00700         BBox->hi.x = x1;
00701         BBox->hi.y = y1;
00702     } else {
00703         // if it's not a path object, ask the node what it's bounding box is - we'll just
00704         // have to make do with a *correct* bounding box instead of simply corel union.
00705         *BBox = pNode->GetBoundingRect();
00706     }
00707 
00708     return TRUE;
00709 }

TCHAR * CDRFilter::GetFontName WORD  FontRef  )  [private]
 

finds a font name

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/04/95
Parameters:
[INPUTS] 
Returns:
pointer to font name or 0 for not found
See also:

Definition at line 1789 of file cdrtext.cpp.

01790 {
01791     INT32 Size;
01792     cdrfFontDefn *FD = (cdrfFontDefn *)Fonts.Find(FontRef, &Size);
01793 
01794     if(Version == CDRVERSION_5)
01795     {
01796         if(FD != 0)
01797             return FD->Name;
01798     }
01799     else
01800     {
01801         cdrfFontDefnV4 *FD4 = (cdrfFontDefnV4 *)FD;
01802 
01803         if(FD4 != 0)
01804             return FD4->Name;
01805     }
01806 
01807     return 0;
01808 }

BOOL CDRFilter::GetMatrixFromTransform Matrix M,
ADDR  Trans,
INT32  Size,
BOOL  TranslateForPage = TRUE
[private]
 

given some transform data, works out a matrix. This ignores any 3D transforms, TransformConvertedObject should be used in preference.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25 03 95
Parameters:
the node to transform, and the trfd chunk to transform it by [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 2971 of file cdrfiltr.cpp.

02972 {
02973     // set up a matrix conversion object
02974     CDRTransformConvertor *Conv;
02975     
02976     // putting the convertors here is probably more efficicent than allocating
02977     // a new one in the heap as they're not very big at all
02978     CDRTransformConvertor5 Conv5;
02979     CDRTransformConvertor4 Conv4;
02980     CDRTransformConvertor3 Conv3;
02981     
02982     switch(Version)
02983     {
02984         case CDRVERSION_5:  Conv = &Conv5;  break;
02985         case CDRVERSION_4:  Conv = &Conv4;  break;
02986         case CDRVERSION_3:  Conv = &Conv3;  break;
02987         default:            return FALSE;   break;
02988     }
02989 
02990     // initialise the convertor object
02991     Conv->Init(Trans, Size);
02992     
02993     // set up the initial matrix which just converts to millipoints
02994     // note that these elements are in Corel order
02995     cdrMatrix Ma, Mb, Mt;
02996     BOOL DoneFirst = FALSE;
02997 
02998     // apply all the transformations in the chunk
02999     INT32 t;
03000     for(t = Conv->GetNTransforms() - 1; t >= 0; t--)
03001     {
03002         // check that the transform is a matrix - for now we can only do matrices
03003         if(Conv->GetTransformType(t) != CDRTRANSFORMTYPE_MATRIX)
03004             continue;
03005 
03006         if(DoneFirst)
03007         {
03008             // done the first matrix, so we need get the matrix into another one and then combine.
03009             
03010             // get the matrix
03011             if(!Conv->GetMatrix(&Mb, t))
03012                 return FALSE;
03013 
03014             // and combine it with the matrix we've already got
03015             Mt.a = (Mb.a * Ma.a) + (Mb.d * Ma.b);
03016             Mt.b = (Mb.b * Ma.a) + (Mb.e * Ma.b);
03017             Mt.c = (Mb.c * Ma.a) + (Mb.f * Ma.b) + Ma.c;
03018             Mt.d = (Mb.a * Ma.d) + (Mb.d * Ma.e);
03019             Mt.e = (Mb.b * Ma.d) + (Mb.e * Ma.e);
03020             Mt.f = (Mb.c * Ma.d) + (Mb.f * Ma.e) + Ma.f;
03021 
03022             Ma = Mt;
03023         } else {
03024             // just get the matrix
03025             if(!Conv->GetMatrix(&Ma, t))
03026                 return FALSE;
03027 
03028             DoneFirst = TRUE;
03029         }
03030     }
03031 
03032     // if we didn't get a matrix at all, knock up a quick dummy one
03033     if(!DoneFirst)
03034     {
03035         cdrMatrix Mx = {1, 0, 0, 0, 1, 0};
03036     
03037         Ma = Mx;
03038     }
03039     
03040     // add in the translation bit
03041     if(TranslateForPage)
03042     {
03043         Ma.c += TranslateByX;
03044         Ma.f += TranslateByY;
03045     }
03046 
03047     // convert the final matrix into a Camelot matrix
03048     *M = Matrix(Ma.a, Ma.d, Ma.b, Ma.e, (INT32)Ma.c, (INT32)Ma.f);
03049     
03050     return TRUE;
03051 }

BOOL CDRFilter::GetObjCorelBBox NodeRenderableBounded pNode,
DocRect BBox
[private]
 

gets the corel bbox of a converted object, looking up the bbox of text objects

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 03 95
Parameters:
converted node (after transformation) and a pointer to bbox to fill in [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 643 of file cdrfill.cpp.

00644 {
00645     if(IS_A(pNode, TextStory) && TextBBoxes.Find(pNode, BBox) == TRUE)
00646         return TRUE;
00647 
00648     return GetCorelBBox(pNode, BBox);
00649 }

BOOL CDRFilter::GetTextStyle3 CDRTextStyle TS,
WORD  Style,
CDRTextStyle BasedOn = 0
[private]
 

gets a style for version 3 text from the global text styles table

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/05/95
Parameters:
none [INPUTS]
Returns:
error flag
See also:

Definition at line 1285 of file cdrtext.cpp.

01286 {
01287     // copy in the default text style
01288     if(BasedOn == 0)
01289         *TS = CDRDefaultTextStyle;
01290     else
01291         *TS = *BasedOn;
01292 
01293     // if the styles chunk isn't present, return now
01294     if(FontStylesV3 == 0)
01295         return TRUE;
01296 
01297     // find the font definition
01298     cdrfFontStyleTableHeaderV3 *Hdr = (cdrfFontStyleTableHeaderV3 *)FontStylesV3;
01299 
01300     if(Style >= CDRDATA_WORD(Hdr->NOffsets))
01301         return TRUE;        // if there aren't enough entries to find this style
01302 
01303     cdrfFontStyleTableEntryV3 *En = (cdrfFontStyleTableEntryV3 *)(FontStylesV3 + CDRDATA_WORD(Hdr->Offsets[Style]));
01304 
01305     // convert it
01306 
01307     // find the font name
01308 /*  if(FontTableV3 == 0)
01309         return FALSE;
01310 
01311     cdrfFontTableEntryV3 *FEn = (cdrfFontTableEntryV3 *)FontTableV3;
01312     for(INT32 l = 0; l < FontTableEntriesV3; l++)
01313     {
01314         if(FEn[l].Reference == En->FontRef)     // don't need to bother with CDRDATA stuff
01315         {
01316             TS->FontName = (char *)FEn[l].Name;
01317 
01318             break;
01319         }
01320     }
01321 */
01322     // store the font reference
01323     TS->FontReference = CDRDATA_DWORD(En->FontRef);
01324 TRACEUSER( "Ben", _T("Font reference = %d\n"), TS->FontReference);
01325     
01326     // font size
01327     TS->FontSize = CDRDATA_WORD(En->FontSize) * CDRCOORDS_TO_MILLIPOINTS;
01328 
01329     // style...
01330     INT32 S = CDRDATA_WORD(En->FontStyle) & cdrfFONTSTYLEV3_WEIGHT_MASK;
01331     switch(S)
01332     {
01333         case cdrfFONTSTYLEV3_WEIGHT_NORMAL:
01334         default:
01335             TS->Bold = FALSE;
01336             TS->Italic = FALSE;
01337             break;
01338 
01339         case cdrfFONTSTYLEV3_WEIGHT_BOLD:
01340             TS->Bold = TRUE;
01341             TS->Italic = FALSE;
01342             break;
01343 
01344         case cdrfFONTSTYLEV3_WEIGHT_ITALIC:
01345             TS->Bold = FALSE;
01346             TS->Italic = TRUE;
01347             break;
01348 
01349         case cdrfFONTSTYLEV3_WEIGHT_BOLDITALIC:
01350             TS->Bold = TRUE;
01351             TS->Italic = TRUE;
01352             break;
01353     }
01354 
01355     // super or subscriptness
01356     if((CDRDATA_WORD(En->FontStyle) & cdrfFONTSTYLEV3_FLAG_SUPERSCRIPT) != 0)
01357     {
01358         TS->Script = CDRSCRIPT_SUPER;
01359     }
01360     else if((CDRDATA_WORD(En->FontStyle) & cdrfFONTSTYLEV3_FLAG_SUPERSCRIPT) != 0)
01361     {
01362         TS->Script = CDRSCRIPT_SUB;
01363     }
01364 
01365     // the line spacing is a para wide thingy, so we need to reworkout the linespace value
01366     // the line spacing value is a percentage of 120% of the font size
01367     TS->LineSpace = (TS->FontSize * (12 * TS->ParaLineSpacePercent)) / 1000;
01368 
01369     return TRUE;
01370 }

BOOL CDRFilter::GetTextStyleFromCDRStyle CDRTextStyle TS,
WORD  StyleRef,
BOOL  SearchForParent = TRUE
[private]
 

gets a text style from a CDR style. If it can't be found, you get the default text style. If SearchForParent is TRUE, the parent style of this style will be located

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/04/95
Parameters:
[INPUTS] 
Returns:
error flag
See also:

Definition at line 1388 of file cdrtext.cpp.

01389 {
01390     // copy in the default text style
01391     *TS = CDRDefaultTextStyle;
01392 
01393     // find the style
01394     INT32 Size;
01395     cdrfTextStyleHdr *Hdr = (cdrfTextStyleHdr *)Styles.Find(StyleRef, &Size);
01396 
01397     if(Hdr == 0)
01398         return TRUE;        // don't error if it can't be found
01399 
01400     // if necessary, search for the parent style...
01401     if(SearchForParent)
01402     {
01403         if(CDRDATA_WORD(Hdr->Hdr.ObjectType) < 0x7fff)
01404         {
01405             if(!GetTextStyleFromCDRStyle(TS, CDRDATA_WORD(Hdr->Hdr.ObjectType), FALSE))
01406                 return FALSE;
01407         }
01408     }
01409 
01410     // find the font size and stuff.
01411     cdrfTextStyleFont *FontStyle = (cdrfTextStyleFont *)FindDataInObject(&Hdr->Hdr, cdrfTEXTSTYLE_OFFSETTYPE_FONT);
01412     if(FontStyle != 0)
01413     {   
01414         // set fontname
01415 /*      TCHAR *FontName = GetFontName(CDRDATA_WORD(FontStyle->FontRef));
01416         if(FontName != 0)
01417             TS->FontName = FontName;
01418         else
01419             TS->FontName = CDRDefaultFontName;
01420 */
01421         // set font reference
01422         TS->FontReference = CDRDATA_WORD(FontStyle->FontRef);
01423 
01424         // set font size
01425         TS->FontSize = CDRDATA_WORD(FontStyle->FontSize) * CDRCOORDS_TO_MILLIPOINTS;
01426         
01427         // set font bold and italicness
01428         if(Version == CDRVERSION_5)
01429         {
01430             switch(CDRDATA_WORD(FontStyle->FontType))
01431             {
01432                 case cdrfFONTTYPE_BOLD:
01433                     TS->Bold = TRUE;
01434                     TS->Italic = FALSE;
01435                     break;
01436 
01437                 case cdrfFONTTYPE_ITALIC:
01438                     TS->Bold = FALSE;
01439                     TS->Italic = TRUE;
01440                     break;
01441 
01442                 case cdrfFONTTYPE_BOLDITALIC:
01443                     TS->Bold = TRUE;
01444                     TS->Italic = TRUE;
01445                     break;
01446 
01447                 default:
01448                     TS->Bold = FALSE;
01449                     TS->Italic = FALSE;
01450                     break;
01451             }
01452         }
01453         else
01454         {
01455             switch(CDRDATA_WORD(FontStyle->FontType))
01456             {
01457                 case cdrfFONTTYPEV4_BOLD:
01458                     TS->Bold = TRUE;
01459                     TS->Italic = FALSE;
01460                     break;
01461 
01462                 case cdrfFONTTYPEV4_ITALIC:
01463                     TS->Bold = FALSE;
01464                     TS->Italic = TRUE;
01465                     break;
01466 
01467                 case cdrfFONTTYPEV4_BOLDITALIC:
01468                     TS->Bold = TRUE;
01469                     TS->Italic = TRUE;
01470                     break;
01471 
01472                 default:
01473                     TS->Bold = FALSE;
01474                     TS->Italic = FALSE;
01475                     break;
01476             }
01477         }
01478     }
01479 
01480     // find the spacing info
01481     cdrfTextStyleSpacing *Spacing = (cdrfTextStyleSpacing *)FindDataInObject(&Hdr->Hdr, cdrfTEXTSTYLE_OFFSETTYPE_SPACING);
01482     if(Spacing != 0)
01483     {
01484         // set the paragraph line spacing
01485         TS->ParaLineSpacePercent = CDRDATA_SWORD(Spacing->LineSpacing);
01486 
01487     }
01488 
01489     // work out the line spacing for this thingy
01490     // the line spacing value is a percentage of 120% of the font size
01491     TS->LineSpace = (TS->FontSize * (12 * TS->ParaLineSpacePercent)) / 1000;
01492 
01493     // find the alignment
01494     cdrfTextStyleAlignment *Align = (cdrfTextStyleAlignment *)FindDataInObject(&Hdr->Hdr, cdrfTEXTSTYLE_OFFSETTYPE_ALIGNMENT);
01495     if(Align != 0)
01496     {
01497         switch(CDRDATA_WORD(Align->Alignment))
01498         {
01499             case cdrfALIGNMENT_RIGHT:   TS->Just = JRIGHT;  break;
01500             case cdrfALIGNMENT_CENTRE:  TS->Just = JCENTRE; break;
01501             case cdrfALIGNMENT_FULL:    TS->Just = JFULL;   break;
01502             default:                    TS->Just = JLEFT;   break;
01503         }
01504     }
01505     
01506     return TRUE;
01507 }

BOOL CDRFilter::GetTextStyleFromChar4 CDRTextStyle TS,
cdrfTextCharStyledV4 Char,
CDRTextStyle BasedOn
[private]
 

gets a text style from a styled version 4 text character

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:

Definition at line 949 of file cdrtext.cpp.

00950 {
00951     if(BasedOn != 0)
00952         *TS = *BasedOn;
00953     else
00954         *TS = CDRDefaultTextStyle;
00955 
00956     // font name
00957     if((CDRDATA_WORD(Char->Changes) & cdrfSTYLECHANGEV4_FONTNAME) != 0)
00958     {
00959 /*      TCHAR *FontName = GetFontName(Char->FontRef);
00960         if(FontName != 0)
00961         {
00962             TS->FontName = FontName;
00963         }
00964 */
00965         TS->FontReference = CDRDATA_DWORD(Char->FontRef);
00966     }
00967 
00968     // font size
00969     if((CDRDATA_WORD(Char->Changes) & cdrfSTYLECHANGEV4_FONTSIZE) != 0)
00970     {
00971         if(CDRDATA_WORD(Char->FontSize) != 0)
00972         {
00973             TS->FontSize = CDRDATA_WORD(Char->FontSize) * CDRCOORDS_TO_MILLIPOINTS;
00974         }
00975     }
00976 
00977     // update line spacing
00978     TS->LineSpace = (TS->FontSize * (12 * TS->ParaLineSpacePercent)) / 1000;
00979 
00980     // weight
00981     if((CDRDATA_WORD(Char->Changes) & cdrfSTYLECHANGEV4_WEIGHT) != 0)
00982     {
00983         switch(CDRDATA_WORD(Char->FontType))
00984         {
00985             case cdrfFONTTYPEV4_BOLD:
00986                 TS->Bold = TRUE;
00987                 TS->Italic = FALSE;
00988                 break;
00989 
00990             case cdrfFONTTYPEV4_ITALIC:
00991                 TS->Bold = FALSE;
00992                 TS->Italic = TRUE;
00993                 break;
00994 
00995             case cdrfFONTTYPEV4_BOLDITALIC:
00996                 TS->Bold = TRUE;
00997                 TS->Italic = TRUE;
00998                 break;
00999 
01000             default:
01001                 TS->Bold = FALSE;
01002                 TS->Italic = FALSE;
01003                 break;
01004         }
01005     }
01006     
01007     return TRUE;
01008 }

BOOL CDRFilter::GetTextStyleFromDefn CDRTextStyle TS,
cdrfTextInfoFontDefn FontDefn,
const CDRTextStyle BasedOn
[private]
 

gets a font style from a font definition stored in a txsm chunk. Anything not defined comes from the BasedOn style.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/04/95
Parameters:
[INPUTS] 
Returns:
error flag
See also:

Definition at line 1524 of file cdrtext.cpp.

01525 {
01526     // set up the defaults
01527     if(BasedOn != 0)
01528         *TS = *BasedOn;
01529     else
01530         *TS = CDRDefaultTextStyle;
01531 
01532     // add in things which are changed...
01533     if((CDRDATA_WORD(FontDefn->Changes) & cdrfTEXTINFODEFNCHANGES_FONT) != 0)
01534     {
01535         // change the font reference
01536 /*      TCHAR *NewName = GetFontName(CDRDATA_WORD(FontDefn->FontRef));
01537 
01538         if(NewName != 0)
01539             TS->FontName = NewName;
01540 */
01541         TS->FontReference = CDRDATA_WORD(FontDefn->FontRef);
01542     }
01543 
01544     if((CDRDATA_WORD(FontDefn->Changes) & cdrfTEXTINFODEFNCHANGES_SIZE) != 0)
01545     {
01546         // new font size
01547         TS->FontSize = CDRDATA_WORD(FontDefn->FontSize) * CDRCOORDS_TO_MILLIPOINTS;
01548     }
01549 
01550     if((CDRDATA_WORD(FontDefn->Changes) & cdrfTEXTINFODEFNCHANGES_ATTR) != 0)
01551     {
01552         // weightness of the font
01553         if(CDRDATA_WORD(FontDefn->FontType) != 0)
01554         {
01555             // set font bold and italicness
01556             switch(CDRDATA_WORD(FontDefn->FontType))
01557             {
01558                 case cdrfFONTTYPE_BOLD:
01559                     TS->Bold = TRUE;
01560                     TS->Italic = FALSE;
01561                     break;
01562 
01563                 case cdrfFONTTYPE_ITALIC:
01564                     TS->Bold = FALSE;
01565                     TS->Italic = TRUE;
01566                     break;
01567 
01568                 case cdrfFONTTYPE_BOLDITALIC:
01569                     TS->Bold = TRUE;
01570                     TS->Italic = TRUE;
01571                     break;
01572 
01573                 default:
01574                     TS->Bold = FALSE;
01575                     TS->Italic = FALSE;
01576                     break;
01577             }
01578         }
01579     
01580         // new attributes
01581         if(FontDefn->FontAttr.Underline != cdrfLINETYPE_NONE
01582                 || FontDefn->FontAttr.Overline != cdrfLINETYPE_NONE
01583                 || FontDefn->FontAttr.StrikeOut != cdrfLINETYPE_NONE)
01584         {
01585             TS->Underline = TRUE;
01586         }
01587         else
01588         {
01589             TS->Underline = FALSE;
01590         }
01591 
01592         switch(FontDefn->FontAttr.Placement)
01593         {
01594             default:                            TS->Script = CDRSCRIPT_NONE;    break;
01595             case cdrfPLACEMENTTYPE_SUPERSCRIPT: TS->Script = CDRSCRIPT_SUPER;   break;
01596             case cdrfPLACEMENTTYPE_SUBSCRIPT:   TS->Script = CDRSCRIPT_SUB;     break;
01597         }
01598     }
01599 
01600     // the line spacing is a para wide thingy, so we need to reworkout the linespace value
01601     // the line spacing value is a percentage of 120% of the font size
01602     TS->LineSpace = (TS->FontSize * (12 * TS->ParaLineSpacePercent)) / 1000;
01603 
01604     return TRUE;
01605 }

BOOL CDRFilter::HasCDRFileGotCMXFile PathName FileName,
CCLexFile pFile = NULL
[static]
 

to find out whether a CDR file has got a CMX file in it, and therefore whether the CMX filter should grab it instead of this one

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/08/96
Parameters:
pathname of file to check, or pointer to disk file [INPUTS]
Returns:
whether it has got a cmx file embedded in it

Definition at line 5152 of file cdrfiltr.cpp.

05153 {
05154     CCDiskFile oTheFile;
05155     CCLexFile *pTheFile;
05156     INT32 pos;
05157 
05158     if(pFile == NULL)
05159     {
05160         if (!(oTheFile.open(*FileName, ios::in | ios::binary)))
05161         {
05162             TRACEUSER( "Ben", _T("couldn't open file to check it for CMX\n"));
05163             return FALSE;
05164         }
05165         pTheFile = &oTheFile;
05166     }
05167     else
05168     {
05169         pTheFile = pFile;
05170         pos = pFile->tellIn();
05171     }
05172 
05173     // read in the file header, and check it's a riff file
05174     RIFFFile_Header Hdr;
05175     pTheFile->read(&Hdr, sizeof(Hdr));
05176 
05177     if(Hdr.CK.ckID != RIFFTYPE_RIFF)
05178         return FALSE;           // file is not a riff form
05179 
05180     UINT32 loc = sizeof(Hdr);
05181 
05182     // run through the thingys
05183     BOOL Found = FALSE;
05184     while(loc < Hdr.CK.ckSize)
05185     {
05186         RIFFck ck;
05187         pTheFile->read(&ck, sizeof(ck));
05188         loc += sizeof(ck);
05189         if(ck.ckID == cdrT_cmx1)
05190         {
05191             // found the cmx section
05192             Found = TRUE;
05193             break;  // we can stop now
05194         }
05195 
05196         // skip to start of next chunk
05197         loc += ck.ckSize;
05198         pTheFile->seekIn(loc);
05199     }
05200 
05201     // close it or clear up...
05202     if(pFile == NULL)
05203     {
05204         oTheFile.close();
05205     }
05206     else
05207     {
05208         pFile->seekIn(pos);
05209     }
05210     
05211     return Found;
05212 }

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

Examines a file to see how compatable it is with this filter.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
As for the Filter class [INPUTS]
Returns:
As for the Filter class
See also:
Filter

Reimplemented from Filter.

Definition at line 289 of file cdrfiltr.cpp.

00291 {
00292 PORTNOTE("byteorder", "TODO: Check byte ordering")
00293     BOOL ExtensionMatches = pOILFilter->DoesExtensionOfPathNameMatch(&Filename);
00294 
00295     // check for version 2 files if the extension matches...
00296     if (ExtensionMatches)
00297     {
00298         if(camStrncmp((char *)HeaderStart, "WL", 2) == 0)
00299             return 10;          // a version 2.xx CDR file
00300     }
00301 
00302     // check for version 3 - 5 files...
00303     FOURCC FormType;
00304 
00305     FormType = RIFFFile::CheckRIFFHeader(HeaderStart, FileSize);
00306 
00307     Version  = CDRVERSION_NULL;
00308     
00309     switch (FormType)
00310     {
00311         case cdrT_CDR:
00312             Version = CDRVERSION_3;
00313             break;
00314         
00315         case cdrT_CDR4:
00316         case cdrT_CDST:         // version 4 template
00317             Version = CDRVERSION_4;
00318             break;
00319 
00320         case cdrT_CDR5:
00321         case cdrT_CDT5:
00322             Version = CDRVERSION_5;
00323             break;
00324 
00325         case cdrT_CDR6:
00326         case cdrT_CDT6:
00327             Version = CDRVERSION_6;
00328             break;
00329 
00330         default:
00331             break;
00332     }
00333 
00334     INT32 HowMuchWeLikedThisFile = 0;
00335 
00336     if(Version != CDRVERSION_NULL)
00337     {
00338         HowMuchWeLikedThisFile = 10;        // loved the file
00339 
00340         // check to see if there is a CMX file embedded in there
00341         if(HasCDRFileGotCMXFile(&Filename))
00342         {
00343             HowMuchWeLikedThisFile = 5;     // didn't like it so much then -- let the CMX filter grab it
00344         }
00345     }
00346 
00347     return HowMuchWeLikedThisFile;
00348 }

BOOL CDRFilter::Init void   )  [virtual]
 

Initialisation.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
As for the Filter class [INPUTS]
Returns:
As for the Filter class
See also:
Filter

Implements Filter.

Definition at line 261 of file cdrfiltr.cpp.

00262 {
00263     // Get the OILFilter object
00264     pOILFilter = new CDROILFilter(this);
00265     if (pOILFilter == NULL)
00266         return FALSE;
00267 
00268     // make sure we'll complain about life if HowCompatable isn't called
00269     Version  = CDRVERSION_NULL;
00270 
00271     // All ok
00272     return TRUE;
00273 }

BOOL CDRFilter::IsTransformJustMatrices ADDR  Trans,
INT32  Size
[private]
 

scans a transform chunk. Returns TRUE if the transform was just composed of matrices and unknown transforms.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/05/95
Parameters:
trfd chunk to examine [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 3068 of file cdrfiltr.cpp.

03069 {
03070     // set up a matrix conversion object
03071     CDRTransformConvertor *Conv;
03072     
03073     // putting the convertors here is probably more efficicent than allocating
03074     // a new one in the heap as they're not very big at all
03075     CDRTransformConvertor5 Conv5;
03076     CDRTransformConvertor4 Conv4;
03077     CDRTransformConvertor3 Conv3;
03078     
03079     switch(Version)
03080     {
03081         case CDRVERSION_5:  Conv = &Conv5;  break;
03082         case CDRVERSION_4:  Conv = &Conv4;  break;
03083         case CDRVERSION_3:  Conv = &Conv3;  break;
03084         default:            return FALSE;   break;
03085     }
03086 
03087     // initialise the convertor object
03088     Conv->Init(Trans, Size);
03089     
03090     // check all the transformations in the chunk
03091     for(INT32 t = Conv->GetNTransforms() - 1; t >= 0; t--)
03092     {
03093         switch(Conv->GetTransformType(t))
03094         {
03095             case CDRTRANSFORMTYPE_MATRIX:
03096             case CDRTRANSFORMTYPE_UNKNOWN:
03097                 break;
03098 
03099             default:
03100                 return FALSE;
03101                 break;
03102         }
03103 
03104     }
03105 
03106     return TRUE;
03107 }

BOOL CDRFilter::MakeTextOnPathLinkList  )  [private]
 

creates the list of paths which should be linked to text stories to get text on paths.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/06/95
Parameters:
- [INPUTS]
Returns:
error flag
See also:
CDRFilter

Definition at line 2545 of file cdrtext.cpp.

02546 {
02547     if(LinkTable == 0)
02548         return TRUE;        // no link table, no list...
02549 
02550     // run through the table creating entries
02551     cdrfLinkTableHdr *Table = (cdrfLinkTableHdr *)LinkTable;
02552     INT32 Entries = CDRDATA_WORD(Table->Entries);
02553     WORD *Offsets = (WORD *)(LinkTable + CDRDATA_WORD(Table->OffsetsOffset));
02554 
02555     if(Version != CDRVERSION_3)
02556     {
02557         // make for versions 4 and 5
02558         for(INT32 l = 0; l < Entries; l++)
02559         {
02560             cdrfLinkTableEntryTextOnPath *En = (cdrfLinkTableEntryTextOnPath *)(LinkTable + CDRDATA_WORD(Offsets[l]));
02561 
02562             if(En->Type == cdrfLINKTABLEENTRY_TEXTONPATH)
02563             {
02564                 // make a new list item for this thingy
02565                 CDRTextOnPathLink *Item = new CDRTextOnPathLink;
02566 
02567                 if(Item == 0)
02568                     return FALSE;
02569 
02570                 // pop in the serial numbers
02571                 Item->PathSerialNumber = CDRDATA_WORD(En->PathSerialNumber);
02572                 Item->TextSerialNumber = CDRDATA_WORD(En->TextSerialNumber);
02573 
02574                 // add the item to the list
02575                 TextOnPathLinks.AddTail(Item);
02576             }
02577         }
02578     }
02579     else
02580     {
02581         // make for version 3
02582         for(INT32 l = 0; l < Entries; l++)
02583         {
02584             cdrfLinkTableEntryTextOnPathV3 *En = (cdrfLinkTableEntryTextOnPathV3 *)(LinkTable + CDRDATA_WORD(Offsets[l]));
02585 
02586             if(En->Type == cdrfLINKTABLEENTRYV3_TEXTONPATH)
02587             {
02588                 // make a new list item for this thingy
02589                 CDRTextOnPathLink *Item = new CDRTextOnPathLink;
02590 
02591                 if(Item == 0)
02592                     return FALSE;
02593 
02594                 // pop in the serial numbers
02595                 Item->PathSerialNumber = CDRDATA_WORD(En->PathSerialNumber);
02596                 Item->TextSerialNumber = CDRDATA_WORD(En->TextSerialNumber);
02597 
02598                 // add the item to the list
02599                 TextOnPathLinks.AddTail(Item);
02600             }
02601         }
02602     }
02603     
02604     return TRUE;
02605 }

BOOL CDRFilter::NoFill void   )  [private]
 

makes an object not filled

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/04/95
Parameters:
- [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 272 of file cdrfill.cpp.

00273 {
00274     if(pMadeNode->IsKindOf(CC_RUNTIME_CLASS(NodePath)))
00275     {
00276         NodePath *pPath = (NodePath *)pMadeNode;
00277 
00278         pPath->InkPath.IsFilled = FALSE;
00279     }
00280 
00281     ObjFilled = FALSE;
00282     SetFillColour(DocColour(COLOUR_TRANS));
00283     return SetPathFilled(FALSE);
00284 }

BOOL CDRFilter::ProcessDoc void   )  [private]
 

Processes the root level doc chunk of a CDR file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
22 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 935 of file cdrfiltr.cpp.

00936 {
00937     BOOL InFillTable = FALSE;
00938     BOOL InOutlineTable = FALSE;
00939     BOOL InStyleTable = FALSE;
00940     BOOL InFontTable = FALSE;
00941     BOOL InArrowheadTable = FALSE;
00942     BOOL InPatternTable = FALSE;
00943     BOOL InBitmapTable = FALSE;
00944     BOOL GotPageInfo = FALSE;
00945 
00946     ADDR VectorListContents = 0;
00947     INT32 VectorListContentsSize;
00948 
00949 TRACEUSER( "Ben", _T("In ProcessDoc\n"));
00950 
00951     // store the level we're working on
00952     UINT32 StartLevel = RIFF->GetObjLevel();
00953 
00954     do
00955     {
00956         switch(RIFF->GetObjType())
00957         {
00958             case RIFFOBJECTTYPE_LISTSTART:
00959                 // list start - attributes are stored in lists
00960                 switch(RIFF->GetObjChunkType())
00961                 {
00962                     case cdrT_filt:     InFillTable = TRUE;         break;
00963                     case cdrT_otlt:     InOutlineTable = TRUE;      break;
00964                     case cdrT_stlt:     InStyleTable = TRUE;        break;
00965                     case cdrT_fntt:     InFontTable = TRUE;         break;
00966                     case cdrT_arrt:     InArrowheadTable = TRUE;    break;
00967                     case cdrT_bpft:     InPatternTable = TRUE;      break;
00968                     case cdrT_bmpt:     InBitmapTable = TRUE;       break;
00969                     default:                                        break;
00970 
00971                     case cdrT_vect:
00972                         // get the contents of this list for later
00973                         if(!RIFF->GetListContents(&VectorListContents, &VectorListContentsSize))
00974                             return FALSE;
00975 
00976                         // and skip to the end of it
00977                         if(!RIFF->SkipToListEnd(RIFF->GetObjLevel()))
00978                             return FALSE;
00979                         break;
00980                     
00981                     case cdrT_btxt:
00982                         if(Version == CDRVERSION_4)
00983                         {
00984                             // if we're in a version 4 file, this contains text for the paragraph text objects
00985                             if(!ProcessTextList4())
00986                                 return FALSE;
00987                         }
00988                         break;
00989                 }
00990                 break;
00991 
00992             case RIFFOBJECTTYPE_LISTEND:
00993                 switch(RIFF->GetObjChunkType())
00994                 {
00995                     case cdrT_filt:     InFillTable = FALSE;        break;
00996                     case cdrT_otlt:     InOutlineTable = FALSE;     break;
00997                     case cdrT_stlt:     InStyleTable = FALSE;       break;
00998                     case cdrT_fntt:     InFontTable = FALSE;        break;
00999                     case cdrT_arrt:     InArrowheadTable = FALSE;   break;
01000                     case cdrT_bpft:     InPatternTable = FALSE;     break;
01001                     case cdrT_bmpt:     InBitmapTable = FALSE;      break;
01002                     default:                                        break;
01003                 }
01004                 break;
01005 
01006             case RIFFOBJECTTYPE_CHUNK:
01007                 // got a chunk to be interested about!
01008                 switch(RIFF->GetObjChunkType())
01009                 {
01010                     case cdrT_fill:
01011                         if(InFillTable)
01012                             Fills.AddChunkToStore(RIFF);
01013                         break;
01014 
01015                     case cdrT_outl:
01016                         if(InOutlineTable)
01017                             Outlines.AddChunkToStore(RIFF);
01018                         break;
01019 
01020                     case cdrT_styd:
01021                         if(InStyleTable)
01022                             Styles.AddChunkToStore(RIFF);
01023                         break;
01024 
01025                     case cdrT_font:
01026                         if(InFontTable)
01027                             Fonts.AddChunkToStore(RIFF, Version);
01028                         break;
01029 
01030                     case cdrT_arrw:
01031                         if(InArrowheadTable)
01032                             Arrowheads.AddChunkToStore(RIFF);
01033                         break;
01034 
01035                     case cdrT_bmpf:
01036                         if(InPatternTable)
01037                             Patterns.AddChunkToStore(RIFF, TRUE, this);
01038 
01039                         UpdateProgress(TRUE);
01040                         break;
01041 
01042                     case cdrT_bmp:
01043                         // a couple of forced progress updates here to ensure a
01044                         // resonably often updated progress bar
01045                         UpdateProgress(TRUE);
01046 
01047                         if(InBitmapTable)
01048                             Bitmaps.AddChunkToStore(RIFF, FALSE, this);
01049 
01050                         UpdateProgress(TRUE);
01051                         break;
01052 
01053                     case cdrT_mcfg:
01054                         {   // get the chunk and read the page size
01055                             if(GotPageInfo)     // if we've already got it, then there's a problem with the file
01056                             {
01057 TRACEUSER( "Ben", _T("mcfg chunk encountered twice in doc list\n"));                                
01058                                 ERROR1(FALSE, _R(IDE_CDRFILTER_FORMATERROR));
01059                             }
01060 
01061                             if(!RIFF->AquireChunkData())
01062                                 return FALSE;
01063 
01064                             cdrfPageInfo *i = (cdrfPageInfo *)RIFF->GetAquiredData();
01065 
01066                             ERROR3IF(i == 0, "No aquired data returned from RIFF chunk");
01067 
01068                             PageX = CDRDATA_WORD(i->PageX) * CDRCOORDS_TO_MILLIPOINTS;
01069                             PageY = CDRDATA_WORD(i->PageY) * CDRCOORDS_TO_MILLIPOINTS;
01070                             Landscape = (CDRDATA_WORD(i->Orientation) == cdrf_ORIENTATION_LANDSCAPE)?TRUE:FALSE;
01071 
01072                             GotPageInfo = TRUE;
01073                         }
01074                         break;
01075 
01076                     case cdrT_tspc:     // font style table for version 3
01077                         if(Version == CDRVERSION_3)
01078                         {
01079                             // store the font styles
01080                             if((FontStylesV3 = (ADDR)CCMalloc(RIFF->GetObjSize())) == 0)
01081                                 return FALSE;
01082 
01083                             if(!RIFF->GetChunkData(FontStylesV3, RIFF->GetObjSize()))
01084                                 return FALSE;
01085                         }
01086                         break;
01087 
01088                     case cdrT_ftbl:     // font name table for version 3
01089                         if(Version == CDRVERSION_3)
01090                         {
01091                             // store the font names
01092                             if((FontTableV3 = (ADDR)CCMalloc(RIFF->GetObjSize())) == 0)
01093                                 return FALSE;
01094 
01095                             if(!RIFF->GetChunkData(FontTableV3, RIFF->GetObjSize()))
01096                                 return FALSE;
01097 
01098                             // store number of entries
01099                             FontTableEntriesV3 = RIFF->GetObjSize() / sizeof(cdrfFontTableEntryV3);
01100                             
01101                             // cache the font names
01102                             cdrfFontTableEntryV3 *FT = (cdrfFontTableEntryV3 *)FontTableV3;
01103                             for(INT32 l = 0; l < FontTableEntriesV3; l++)
01104                             {
01105                                 if(FT[l].Name[0] != '\0' && FT[l].Name[0] != ' ')
01106                                 {
01107                                     //GetApplication()->GetFontManager()->CacheNamedFont(&String_64((TCHAR *)&FT[l].Name));
01108                                 
01109                                     Fonts.AddFontToStore(FT[l].Reference, (TCHAR *)&FT[l].Name);
01110                                 }
01111                             }
01112 
01113                         }
01114                         break;
01115 
01116                     case cdrT_lnkt:
01117                         // store the link table - it's a pretty useful piece of kit
01118                         if((LinkTable = (ADDR)CCMalloc(RIFF->GetObjSize())) == 0)
01119                             return FALSE;
01120 
01121                         if(!RIFF->GetChunkData(LinkTable, RIFF->GetObjSize()))
01122                             return FALSE;
01123 
01124                         // generate the links from paths to text text from it
01125                         if(!MakeTextOnPathLinkList())
01126                             return FALSE;
01127                         break;
01128 
01129                     default:
01130                         break;
01131                 }
01132                 break;
01133 
01134             default:
01135                 break;
01136         }
01137         UpdateProgress();
01138         
01139         if(!RIFF->NextObject())
01140             return FALSE;
01141         
01142         ERROR3IF(RIFF->GetObjType() == RIFFOBJECTTYPE_FILEEND, "Unexpected end of RIFF file in ProcessDoc");
01143     } while(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > StartLevel);
01144 
01145     // process the vector list, if we got one
01146     if(VectorListContents != 0)
01147     {
01148         if(!ProcessVectorList(VectorListContents, VectorListContentsSize))
01149         {
01150             CCFree(VectorListContents);
01151             return FALSE;
01152         }
01153 
01154         CCFree(VectorListContents);
01155     }
01156 
01157     // if this isn't a version 3 file, check that we got some page info
01158     if(Version != CDRVERSION_3)
01159     {
01160         if(GotPageInfo == FALSE)
01161         {
01162 TRACEUSER( "Ben", _T("mcfg chunk not found in doc list\n"));
01163             ERROR1(FALSE, _R(IDE_CDRFILTER_FORMATERROR));
01164         
01165         }
01166 
01167         // set the page size?
01168         if(!pDocument->IsImporting() && PageX > 0 && PageY > 0)
01169         {
01170 // Make the pasteboard an extra page width either side of the page and an extra
01171 // half page height above and below the page. That should be nicely proportional.
01172 
01173             INT32 ms = (PageX > PageY)?PageX:PageY;
01174 
01175             // we're opening the file, so set the page size
01176             if (pSpread)
01177             {
01178                 BOOL ok = pSpread->SetPageSize(PageX, PageY, ms, 0, FALSE, TRUE);
01179 
01180                 // Must set the origin of the grid to the bottom left corner of the
01181                 // union rectangle of all pages on the spread as this is where the x,y
01182                 // measurements are made from.
01183                 DocRect PagesRect;
01184                 NodeGrid* pGrid = pSpread->FindFirstDefaultGridInSpread();
01185                 ok = ok && pSpread->GetPagesRect(&PagesRect);
01186                 if (pGrid)
01187                     pGrid->SetOrigin(PagesRect.lox, PagesRect.loy);
01188 
01189                 if (!ok)
01190                     return FALSE;
01191             }
01192         }
01193     
01194         // Use bottom left of page as origin
01195         DocRect PageRect = pPage->GetPageRect();
01196         Origin = PageRect.lo;
01197 
01198         // set the translation variables to position the bottom left hand corner of the page
01199         // at the bottom left hand corner of the page we're importing onto. The origin of
01200         // a CDR file is in the centre of the page
01201         TranslateByX = Origin.x + (PageX / 2);
01202         TranslateByY = Origin.y + (PageY / 2);
01203     }
01204 
01205 TRACEUSER( "Ben", _T("PageX = %d, PageY = %d\n"), PageX, PageY);
01206 
01207     return TRUE;
01208 }

BOOL CDRFilter::ProcessGroup UINT32  Level,
BOOL  FromLink = FALSE
[private]
 

Sets up a group end action and alters the level node list to be a new list.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
26 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:

Definition at line 1535 of file cdrfiltr.cpp.

01536 {
01537     // if it's a CDR3 file we need a transform action
01538     if(Version == CDRVERSION_3)
01539     {
01540         // see if there's a transform object around
01541         BOOL Found = FALSE;
01542         do {
01543             if(!RIFF->NextObject())
01544                 return FALSE;
01545 
01546             FOURCC id = RIFF->GetObjChunkType();
01547 
01548             // the group need not have a transform chunk, so we've got to be a little careful
01549             if(id == cdrT_grp || id == cdrT_lnkg || id == cdrT_obj)
01550             {
01551                 // oh dear, it didn't - make sure this object we've just run onto is seen again
01552                 RIFF->RepeatCurrent();
01553         
01554                 break;
01555             }
01556 
01557             if(id == cdrT_lobj && RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK)
01558             {
01559                 // found a transform chunk
01560                 Found = TRUE;
01561             }
01562         } while(Found == FALSE);
01563 
01564         // if there is, set up a post transform action
01565         if(Found)
01566         {
01567 TRACEUSER( "Ben", _T("Setting transform for CDR3 group at level %d\n"), Level);
01568             CDRActionTransform *TAct = new CDRActionTransform;
01569 
01570             if(TAct == 0)
01571                 return FALSE;
01572 
01573             // initialise my new action, giving it the RIFFFile we're using
01574             // it takes the current chunk as it's data.
01575             if(!TAct->Init(RIFF, Version))
01576                 return FALSE;
01577 
01578             // set it to act on the same level ending as the group
01579             TAct->SetLevel(Level);
01580         
01581             // add my new action to the action list
01582             Actions.AddTail(TAct);
01583         }
01584     }
01585     else if(!FromLink)
01586     {
01587         // see if there's a transform chunk, and if there is, whether it's got a non matrix transform in it or not
01588         BOOL Found = FALSE;
01589         do {
01590             if(!RIFF->NextObject())
01591                 return FALSE;
01592 
01593             FOURCC id = RIFF->GetObjChunkType();
01594 
01595             // the group need not have a transform chunk, so we've got to be a little careful
01596             if(id == cdrT_grp || id == cdrT_lnkg || id == cdrT_obj)
01597             {
01598                 // oh dear, it didn't - make sure this object we've just run onto is seen again
01599                 RIFF->RepeatCurrent();
01600         
01601                 break;
01602             }
01603 
01604             if(id == cdrT_trfl && RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART)
01605             {
01606                 // found a transform list
01607                 Found = TRUE;
01608             }
01609         } while(Found == FALSE);
01610 
01611         // if there is, set up a post transform action
01612         if(Found)
01613         {
01614             CDRActionTransform *Act = new CDRActionTransform;
01615 
01616             if(Act == 0)
01617                 return FALSE;
01618 
01619             // initialise my new action, giving it the RIFFFile we're using
01620             // it takes the current chunk as it's data.
01621             if(!Act->Init(RIFF, Version))
01622                 return FALSE;
01623 
01624             // check to see if the transform contains a non-matrix thingy
01625             if(IsTransformJustMatrices(Act->Chunk, Act->ChunkSize))
01626             {
01627                 // just matrices - don't do this action
01628                 delete Act;
01629             }
01630             else
01631             {
01632                 // set it to act on the same level ending as the group
01633                 Act->SetLevel(Level);
01634         
01635                 // set it to ignore matrices
01636                 Act->SetIsAGroupTransform(TRUE);
01637 
01638                 // add my new action to the action list
01639                 Actions.AddTail(Act);
01640             }
01641         }
01642     }
01643     
01644     CDRActionGroupEnd *Act = new CDRActionGroupEnd;
01645 
01646     if(Act == 0)
01647         return FALSE;
01648 
01649     // store this levels node list
01650     Act->pOldLevelNodeList = pLevelNodeList;
01651 
01652     // set up the level it's interested in
01653     Act->SetLevel(Level);
01654 
01655     // and start a new level node list for this group
01656     pLevelNodeList = 0;
01657 
01658     Actions.AddTail(Act);
01659 
01660     return TRUE;
01661 }

BOOL CDRFilter::ProcessLayer void   )  [private]
 

Processes a layer list of a CDR file. This is the function which actually grabs objects to convert.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:

Definition at line 1313 of file cdrfiltr.cpp.

01314 {
01315 TRACEUSER( "Ben", _T("In ProcessLayer\n")); 
01316     // first of all, create a new layer item in the page list
01317     ERROR3IF(ThisLayer != 0, "ThisLayer is not null - ProcessLayer called in wrong context");
01318     ThisLayer = new CDRLayerListItem;
01319     
01320     if(ThisLayer == 0)
01321         return FALSE;
01322     
01323     // link it into the layer list on the page we're working on
01324     ThisPage->Layers.AddTail(ThisLayer);
01325 
01326     // store the level we're working on
01327     UINT32 StartLevel = RIFF->GetObjLevel();
01328 
01329     ThisLayer->Objects = 0;
01330     ThisLayer->IsVisible = TRUE;
01331     ThisLayer->IsLocked = FALSE;
01332 
01333     // set up the pointer to the node list to add to
01334     ERROR3IF(pLevelNodeList != 0, "Level node list is not empty");
01335     pLevelNodeList = 0;
01336 
01337     // if we're on the master page, find the layer name
01338     if(InMasterPage)
01339     {
01340         BOOL Done = FALSE;
01341         FOURCC LookingFor = (Version == CDRVERSION_3)?cdrT_lobj:cdrT_loda;
01342 
01343         do
01344         {
01345             if(RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK && RIFF->GetObjChunkType() == LookingFor)
01346             {
01347                 // found the interesting chunk of data
01348                 if(!RIFF->AquireChunkData())
01349                     return FALSE;
01350 
01351                 cdrfMasterLayerInfo *i = (cdrfMasterLayerInfo *)RIFF->GetAquiredData();
01352 
01353                 if(i == 0)      // data couldn't be got
01354                     return FALSE;
01355 
01356                 if(i->Size != RIFF->GetObjSize()) {
01357 TRACEUSER( "Ben", _T("level data in master page has wrong size\n"));
01358                     ERROR1(FALSE, _R(IDE_CDRFILTER_FORMATERROR));
01359                 }
01360 
01361                 // different format of layer info for version 3
01362                 if(Version == CDRVERSION_3)
01363                 {
01364                     cdrfMasterLayerInfoV3 *ii = (cdrfMasterLayerInfoV3 *)RIFF->GetAquiredData();
01365 TRACEUSER( "Ben", _T("name of layer = %s\n"), ii->Name);
01366                     ThisLayer->Name = (char *)ii->Name;
01367                 } else
01368                 {
01369 TRACEUSER( "Ben", _T("name of layer = %s\n"), i->Name);
01370                     ThisLayer->Name = (char *)i->Name;
01371                 }
01372 
01373                 Done = TRUE;
01374             }
01375             else if(RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK && RIFF->GetObjChunkType() == cdrT_flgs)
01376             {
01377                 // look at the flags of the layer...
01378                 if(!RIFF->AquireChunkData())
01379                     return FALSE;
01380 
01381                 WORD *pFlags = (WORD *)RIFF->GetAquiredData();
01382 
01383                 ERROR3IF(pFlags == 0, "RIFF class shouldn't have done that");
01384 
01385                 INT32 Flags = CDRDATA_WORD(*pFlags);
01386 
01387                 if((Flags & cdrfLAYERFLAGS_INVISIBLE) != 0)
01388                     ThisLayer->IsVisible = FALSE;
01389 
01390                 if((Flags & cdrfLAYERFLAGS_LOCKED) != 0)
01391                     ThisLayer->IsLocked = TRUE;
01392             }
01393 
01394             if(!RIFF->NextObject())
01395                 return FALSE;
01396         
01397         } while(Done == FALSE && (RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > StartLevel));
01398     
01399         if(Done == FALSE)
01400         {
01401 TRACEUSER( "Ben", _T("Reached level end in master page layer without finding layer attributes\n"));     
01402             ERROR1(FALSE, _R(IDE_CDRFILTER_FORMATERROR));
01403         }
01404     } else {
01405         ThisLayer->Name = "";
01406     }
01407     
01408     // go through the layer list processing the objects
01409     if(!ProcessObjectTree(StartLevel))
01410         return FALSE;
01411 
01412     // put the nodes we got onto the layer we're processing
01413     ThisLayer->Objects = pLevelNodeList;
01414     pLevelNodeList = 0;
01415 
01416     // finally mark ThisLayer as not used
01417     ThisLayer = 0;
01418 
01419 TRACEUSER( "Ben", _T("End ProcessLayer\n"));
01420     return TRUE;
01421 }

BOOL CDRFilter::ProcessLink void   )  [private]
 

Sets up a group end action and a post transform action and alters the level node list to be a new list.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
26 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:

Definition at line 1750 of file cdrfiltr.cpp.

01751 {
01752     // store the level we're on
01753     UINT32 GroupLevel = RIFF->GetObjLevel();
01754 
01755     // only search for a transform block if this isn't a CDR3 file - ProcessGroup
01756     // takes care of it in that case
01757     if(Version != CDRVERSION_3)
01758     {
01759         // we want to set up the transform object first so that it's done *after* the group end
01760         // object as the transform object acts on the last object converted
01761     
01762         // see if there's a transform object around
01763         BOOL Found = FALSE;
01764         do {
01765             if(!RIFF->NextObject())
01766                 return FALSE;
01767 
01768             FOURCC id = RIFF->GetObjChunkType();
01769 
01770             // the group need not have a transform chunk, so we've got to be a little careful
01771             if(id == cdrT_grp || id == cdrT_lnkg || id == cdrT_obj)
01772             {
01773                 // oh dear, it didn't - make sure this object we've just run onto is seen again
01774                 RIFF->RepeatCurrent();
01775         
01776                 break;
01777             }
01778 
01779             if(id == cdrT_trfl && RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART)
01780             {
01781                 // found a transform list
01782                 Found = TRUE;
01783             }
01784         } while(Found == FALSE);
01785 
01786         // if there is, set up a post transform action
01787         if(Found)
01788         {
01789             CDRActionTransform *Act = new CDRActionTransform;
01790 
01791             if(Act == 0)
01792                 return FALSE;
01793 
01794             // initialise my new action, giving it the RIFFFile we're using
01795             // it takes the current chunk as it's data.
01796             if(!Act->Init(RIFF, Version))
01797                 return FALSE;
01798 
01799             // set it to act on the same level ending as the group
01800             Act->SetLevel(GroupLevel);
01801             
01802             // set up link translation things
01803             Act->LinkTrans = TRUE;
01804             LinkTransformsExist = TRUE;
01805         
01806             // add my new action to the action list
01807             Actions.AddTail(Act);
01808         }
01809     }
01810     
01811     // set up a group end action
01812     if(!ProcessGroup(GroupLevel, TRUE))
01813         return FALSE;
01814 
01815     return TRUE;
01816 }

BOOL CDRFilter::ProcessObject void   )  [private]
 

Converts an object. If there's a problem with the object, then it's skipped rather than reporting an error, and the count of problem objects incremented.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
24 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:

Definition at line 2010 of file cdrfiltr.cpp.

02011 {
02012     UINT32 StartLevel = RIFF->GetObjLevel();
02013 
02014     // set the made node to none
02015     pMadeNode = 0;
02016 
02017     // set the already applied flag
02018     AttrsAlreadyApplied = FALSE;
02019     
02020     // set the is text things to make sure bodges don't happen
02021     IsText = FALSE;
02022     IsTextStory = FALSE;
02023 
02024     // find the loda (4 or 5) or lobj (3) chunk... contains the object header
02025     BOOL Found = FALSE;
02026     FOURCC LookingFor = (Version == CDRVERSION_3)?cdrT_lobj:cdrT_loda;
02027     do
02028     {
02029         // is the serial number?
02030         if(RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK && RIFF->GetObjChunkType() == cdrT_spnd) {
02031             // got the serial number block - get it...
02032             if(!RIFF->AquireChunkData())
02033                 return FALSE;
02034         
02035             WORD *Data = (WORD *)RIFF->GetAquiredData();
02036         
02037             if(Data == 0)
02038                 return FALSE;
02039 
02040             // store it...
02041             SerialNumber = CDRDATA_WORD(*Data);
02042         }
02043 
02044         if(RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK && RIFF->GetObjChunkType() == LookingFor) {
02045             Found = TRUE;
02046             break;
02047         }
02048 
02049         if(!UpdateProgress())
02050             return FALSE;
02051         
02052         if(!RIFF->NextObject())
02053             return FALSE;
02054         
02055     } while(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > StartLevel);
02056 
02057     // if we didn't find anything, then the object has a wrong format
02058     if(Found == FALSE)
02059     {
02060 TRACEUSER( "Ben", _T("Could not find loda (or lobj) chunk in object\n"));       
02061         ObjectsFormatWrong++;
02062         return TRUE;
02063     }
02064 
02065     // get the header - but get it into our block, not the one in RIFFFile as we need
02066     // to refer to it later. It shouldn't be too big to make this inefficient...
02067     cdrfOffsetHeader *Header;
02068     
02069     // ensure we have a block big enough
02070     if(ObjDataBlock == 0 || ObjDataBlockSize < RIFF->GetObjSize())
02071     {
02072         // free the old one
02073         CCFree(ObjDataBlock);
02074 
02075         // size?
02076         INT32 Size = RIFF->GetObjSize();
02077 
02078         if((ObjDataBlock = (ADDR)CCMalloc(Size)) == 0)
02079             return FALSE;
02080 
02081         ObjDataBlockSize = Size;
02082     }
02083     
02084     if(!RIFF->GetChunkData(ObjDataBlock, ObjDataBlockSize))
02085         return FALSE;
02086 
02087     Header = (cdrfOffsetHeader *)ObjDataBlock;
02088 
02089     // look at the type and dispatch to appropriate processing function
02090     FormatError = FALSE;
02091     
02092     INT32 ObjectType = CDRDATA_WORD(Header->ObjectType);
02093 
02094     // if this is a version 3 object, alter it's type
02095     if(Version == CDRVERSION_3)
02096         ObjectType += cdrfOBJTYPE_V3ADD;
02097 
02098     switch(ObjectType) {
02099         case cdrfOBJTYPE_RECTANGLE:
02100             if(!ConvertRectangle(Header))
02101                 return FALSE;
02102             break;
02103         
02104         case cdrfOBJTYPE_ELLIPSE:
02105             if(!ConvertEllipse(Header))
02106                 return FALSE;
02107             break;
02108         
02109         case cdrfOBJTYPE_PATH:
02110             if(!ConvertPath(Header))
02111                 return FALSE;
02112             break;
02113 
02114         case cdrfOBJTYPE_TEXT:
02115         case cdrfOBJTYPE_TEXTSTORY:
02116             if(!ConvertText(Header))
02117                 return FALSE;
02118             break;
02119 
02120         case cdrfOBJTYPE_BITMAP:
02121             if(!ConvertBitmap(Header))
02122                 return FALSE;
02123             break;
02124 
02125         default:
02126             // unknown object type
02127             ObjectsUnknown++;
02128             RIFF->SkipToListEnd(StartLevel);
02129             return TRUE;
02130             break;
02131     }
02132     
02133     // check to see if the format was OK
02134     if(FormatError)
02135     {
02136 TRACEUSER( "Ben", _T("A convert object function returned a format error\n"));
02137         ObjectsFormatWrong++;
02138 
02139         if(TransformChunk != 0)
02140         {
02141             CCFree(TransformChunk);
02142             TransformChunk = 0;
02143         }
02144 
02145         return TRUE;
02146     }
02147 
02148     ERROR3IF(pMadeNode == 0, "No node made, but still nothing errored\n");
02149     
02150     // think about lenses
02151     BOOL UnsetTransparency = FALSE;
02152     if(Version == CDRVERSION_5)
02153     {
02154         cdrfLensDefn *Lens = (cdrfLensDefn *)FindDataInObject(Header, cdrfOBJOFFSETTYPE_LENS);
02155 
02156         if(Lens != 0)
02157         {
02158             // we have a lens to worry about... what type is it?
02159             if(Lens->Type == cdrfLENSTYPE_TRANSPARENT)
02160             {
02161                 // check the percentage
02162                 UINT32 Percent = CDRDATA_WORD(Lens->Percent) / 10;
02163                 if(Percent <= 100)
02164                 {
02165                     // munge the percentage a bit to get it to a Camelot definition
02166                     Percent = 256 - ((Percent * 256) / 100);
02167 
02168                     // what subtype is it?
02169                     switch(Lens->SubType)
02170                     {
02171                         case cdrfTRANSPARENTTYPE_MIX:
02172                             SetFlatTranspFill(T_REFLECTIVE, Percent);
02173                             UnsetTransparency = TRUE;
02174                             break;
02175 
02176                         case cdrfTRANSPARENTTYPE_STAINED:
02177                             SetFlatTranspFill(T_SUBTRACTIVE, Percent);
02178                             UnsetTransparency = TRUE;
02179                             break;
02180 
02181                         case cdrfTRANSPARENTTYPE_BLEACH:
02182                             SetFlatTranspFill(T_ADDITIVE, Percent);
02183                             UnsetTransparency = TRUE;
02184                             break;
02185 
02186                         default:
02187                             break;
02188                     }
02189                 }
02190             }
02191         }
02192     }
02193     
02194     // find the transform chunk - it's in a seperate chunk for version 4 or 5 file,
02195     // and in the data chunk for version 3 files
02196     ADDR TransformData = 0;
02197     INT32 TransformDataSize = 0;
02198     if(TransformChunk != 0)
02199     {
02200         // if something had to move forward in the file (for example, text objects)
02201         // past the transform chunk, it will have stored it here.
02202         TransformData = TransformChunk;
02203         TransformDataSize = TransformChunkSize;
02204     } 
02205     else if(Version == CDRVERSION_3)
02206     {
02207         TransformData = FindDataInObject(Header, cdrfOBJOFFSETTYPE_TRANSFORM_V3);
02208     }
02209     else 
02210     {
02211         Found = FALSE;
02212         do
02213         {
02214             if(RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART && RIFF->GetObjChunkType() == cdrT_trfl) {
02215                 Found = TRUE;
02216                 break;
02217             }
02218 
02219             UpdateProgress();
02220         
02221             if(!RIFF->NextObject())
02222                 return FALSE;
02223         
02224         } while(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > StartLevel);
02225 
02226         // if we didn't find anything, then the object has a wrong format
02227         if(Found == FALSE)
02228         {
02229     TRACEUSER( "Ben", _T("Could not find trfd chunk in object\n"));     
02230             ObjectsFormatWrong++;
02231             // delete the current node
02232             delete pMadeNode;
02233             return TRUE;
02234         }
02235 
02236         // aquire the chunk data
02237         if(!RIFF->AquireListContents(&TransformDataSize))
02238         {
02239             delete pMadeNode;
02240             return FALSE;
02241         }
02242         TransformData = RIFF->GetAquiredData();
02243     }
02244 
02245     if(TransformData == 0)
02246     {
02247         ObjectsFormatWrong++;
02248         // delete the current node
02249         delete pMadeNode;
02250         return TRUE;
02251     }
02252 
02253     // go through any link transforms which may exist
02254     if(Version != CDRVERSION_3)
02255     {
02256         if(LinkTransformsExist)
02257         {
02258             BOOL FoundSome = FALSE;
02259         
02260             CDRActionListItem *Act = (CDRActionListItem *)Actions.GetTail();
02261 
02262             while(Act != 0)
02263             {
02264                 if(IS_A(Act, CDRActionTransform))
02265                 {
02266                     CDRActionTransform *Tran = (CDRActionTransform *)Act;
02267                 
02268                     if(Tran->LinkTrans)
02269                     {
02270                         // set the flag to say we found a link transform
02271                         FoundSome = TRUE;
02272 
02273                         // transform the converte object
02274                         if(!TransformConvertedObject(&pMadeNode, Tran->Chunk, Tran->ChunkSize, FALSE))
02275                         {
02276                             delete pMadeNode;
02277                             return FALSE;
02278                         }
02279                     }
02280                 }
02281 
02282                 Act = (CDRActionListItem *)Actions.GetPrev(Act);
02283             }
02284 
02285             LinkTransformsExist = FoundSome;
02286         }
02287     }
02288 
02289     // apply the transform to the converted node
02290     if(!TransformConvertedObject(&pMadeNode, TransformData, TransformDataSize))
02291     {
02292         delete pMadeNode;
02293         return FALSE;
02294     }
02295 
02296     // apply attributes
02297     if(AttrsAlreadyApplied == FALSE)
02298     {
02299         // look at fill attributes
02300         if(!SetFillAttr(Header))
02301             return FALSE;
02302 
02303         // look at line attributes
02304         if(!SetLineAttr(Header))
02305             return FALSE;
02306     }
02307 
02308     BOOL Result;
02309     if(AttrsAlreadyApplied == FALSE)
02310     {
02311         // apply the attributes to the object
02312         // If not filled, then set the ignore bit on the fill attribute.
02313         if (ObjFilled == FALSE)
02314             CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
02315 
02316         // Add attributes to the path, if they are different from the default...
02317         Result = AttributeManager::ApplyBasedOnDefaults(pMadeNode, CurrentAttrs);
02318 
02319         // Enable the fill attribute again
02320         CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
02321     } else {
02322         Result = TRUE;
02323     }
02324 
02325     if(!Result)
02326         return FALSE;
02327 
02328     if(UnsetTransparency)
02329     {
02330         SetNoTranspFill();
02331     }
02332 
02333     // attach the node to the level list
02334     if(pLevelNodeList != 0)
02335         pMadeNode->AttachNode(pLevelNodeList, PREV);
02336 
02337     pLevelNodeList = pMadeNode; 
02338     
02339     // set the made node pointer to zero to prevent accidents
02340     pMadeNode = 0;
02341 
02342     // increment the count of converted objects
02343     ObjectsConverted++;
02344 
02345     // if necessary, get rid of any transform chunk
02346     if(TransformChunk != 0)
02347     {
02348         CCFree(TransformChunk);
02349         TransformChunk = 0;
02350     }
02351     
02352     return TRUE;
02353 }

BOOL CDRFilter::ProcessObjectTree UINT32  Level  )  [private]
 

process objects from the CDR file - they end up linked to pLevelNodeList.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/04/95
Parameters:
the RIFF level the list we're processing starts at [INPUTS]
Returns:
error flag
See also:
Filter, CDRFilter::ProcessLayer, CDRFilter::ProcessVectorList

Definition at line 1437 of file cdrfiltr.cpp.

01438 {
01439     do
01440     {
01441         switch(RIFF->GetObjType())
01442         {
01443             case RIFFOBJECTTYPE_LISTSTART:
01444                 // see if it's anything we're interested in
01445                 switch(RIFF->GetObjChunkType())
01446                 {
01447                     case cdrT_obj:      // found an object
01448                         if(!ProcessObject())
01449                             return FALSE;
01450                         break;
01451 
01452                     
01453                     case cdrT_grp:
01454                         // found a group type objects
01455                         if(!ProcessGroup(RIFF->GetObjLevel()))
01456                             return FALSE;
01457                         break;
01458 
01459                     case cdrT_lnkg:
01460                         // found a link object - treated as the same as a group, but searched for a
01461                         // transformation matrix
01462                         if(!ProcessLink())
01463                             return FALSE;
01464                         break;
01465 
01466                     default:
01467                         break;
01468                 }
01469                 break;
01470 
01471             case RIFFOBJECTTYPE_LISTEND:
01472                 // check to see if any actions are associated with this list end
01473                 if(!Actions.IsEmpty())
01474                 {
01475                     CDRActionListItem *Act, *Previous;
01476 
01477                     Act = (CDRActionListItem *)Actions.GetTail();
01478 
01479                     // perform the actions which end on this level
01480                     while(Act != 0)
01481                     {
01482                         if(Act->GetLevel() >= RIFF->GetObjLevel())
01483                         {
01484                             // the last action ended on this level - perform the action
01485                             if(!Act->DoAction(this))
01486                                 return FALSE;
01487 
01488                             // get the previous item
01489                             Previous = (CDRActionListItem *)Actions.GetPrev(Act);
01490 
01491                             // remove and delete the action we just performed
01492                             delete Actions.RemoveTail();
01493 
01494                             // and set up the pointer to the next action to look at
01495                             Act = Previous;
01496                         } else {
01497                             // the action shouldn't be performed yet - stop looking
01498                             break;
01499                         }
01500                     }
01501                 }
01502                 break;
01503 
01504             default:
01505                 break;
01506         }
01507         
01508         if(!UpdateProgress())
01509             return FALSE;
01510         
01511         if(!RIFF->NextObject())
01512             return FALSE;
01513         
01514         ERROR3IF(RIFF->GetObjType() == RIFFOBJECTTYPE_FILEEND, "Unexpected end of RIFF file in ProcessLayer");
01515 
01516     } while(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > Level);
01517 
01518     return TRUE;
01519 }

BOOL CDRFilter::ProcessPage void   )  [private]
 

Processes a page list of a CDR file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
22 03 95
Parameters:
none [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 1224 of file cdrfiltr.cpp.

01225 {
01226 TRACEUSER( "Ben", _T("In ProcessPage\n"));
01227     // first of all, create a new page item in the page list
01228     ERROR3IF(ThisPage != 0, "ThisPage is not null - ProcessPage called in wrong context");
01229     ThisPage = new CDRPageListItem;
01230     
01231     if(ThisPage == 0)
01232         return FALSE;
01233     
01234     // link it into the page list
01235     Pages.AddTail(ThisPage);
01236 
01237     // set the master page flag
01238     if(DoneMasterPage == FALSE)
01239         InMasterPage = TRUE;
01240     
01241     // go through the page list processing the layers
01242         // store the level we're working on
01243     UINT32 StartLevel = RIFF->GetObjLevel();
01244 
01245     do
01246     {
01247         if(RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART &&
01248                     RIFF->GetObjChunkType() == cdrT_layr)
01249         {
01250             // it's a layer, process it
01251             if(!ProcessLayer())
01252             {
01253 TRACEUSER( "Ben", _T("ProcessLayer returned FALSE\n"));
01254                 return FALSE;
01255             }
01256         }
01257 
01258         // if we're doing a version 3 file, have we got a page
01259         // size chunk to play with?
01260         if(Version == CDRVERSION_3 && RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK &&
01261                     RIFF->GetObjChunkType() == cdrT_mcfg)
01262         {
01263             if(!RIFF->AquireChunkData())
01264                 return FALSE;
01265             
01266             cdrfPageInfoV3 *i = (cdrfPageInfoV3 *)RIFF->GetAquiredData();
01267 
01268             // in a CDR 3 file, the page size is half what it should be 
01269             PageX = CDRDATA_WORD(i->PageX) * CDRCOORDS_TO_MILLIPOINTS * 2;
01270             PageY = CDRDATA_WORD(i->PageY) * CDRCOORDS_TO_MILLIPOINTS * 2;
01271             Landscape = FALSE;
01272         }
01273 
01274         UpdateProgress();
01275         
01276         if(!RIFF->NextObject())
01277             return FALSE;
01278         
01279         ERROR3IF(RIFF->GetObjType() == RIFFOBJECTTYPE_FILEEND, "Unexpected end of RIFF file in ProcessDoc");
01280     } while(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > StartLevel);
01281 
01282 
01283     // finally make ThisPage as not used
01284     ThisPage = 0;
01285 
01286     // sort out master page flags
01287     if(InMasterPage)
01288     {
01289         InMasterPage = FALSE;
01290         DoneMasterPage = TRUE;
01291     }
01292 
01293 TRACEUSER( "Ben", _T("End ProcessPage\n"));
01294 
01295     return TRUE;
01296 }

BOOL CDRFilter::ProcessTextList4  )  [private]
 

Processes the list of text objects for a version 4 CDR file creating text lines and textchars with partially applied attributes.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/05/95
Parameters:
- [INPUTS]
Returns:
error flag
See also:
CDRFilter

Definition at line 2240 of file cdrtext.cpp.

02241 {
02242     // What we've got...
02243     //  btxt                the list we're current on
02244     //      strl            contains text for a paragraph object
02245     //          btid        the id of the text
02246     //          parl        a pargraph
02247     //              para    paragraph info
02248     // then any number of...
02249     //              bnch    n plain characters
02250     //              bsch    a character with styles applied to it
02251 
02252     ERROR3IF(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTSTART || RIFF->GetObjChunkType() != cdrT_btxt,
02253             "ProcessTextList4 called in the wrong context");
02254 
02255     UINT32 EndLevel = RIFF->GetObjLevel();
02256 
02257     do {
02258         if(RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART && RIFF->GetObjChunkType() == cdrT_strl)
02259         {
02260             if(!ProcessTextListItem4())
02261                 return FALSE;
02262         }
02263 
02264         if(!RIFF->NextObject())
02265             return FALSE;
02266     
02267     } while(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > EndLevel);
02268 
02269     return TRUE;
02270 }

BOOL CDRFilter::ProcessTextListItem4  )  [private]
 

Processes a item from the list of text objects for a version 4 CDR file creating text lines and textchars with partially applied attributes.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/05/95
Parameters:
- [INPUTS]
Returns:
error flag
See also:
CDRFilter

Definition at line 2287 of file cdrtext.cpp.

02288 {
02289     // What we've got...
02290     //  strl            contains text for a paragraph object
02291     //      btid        the id of the text
02292     //      parl        a pargraph
02293     //          para    paragraph info
02294     // then any number of...
02295     //          bnch    n plain characters
02296     //          bsch    a character with styles applied to it
02297 
02298     ERROR3IF(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTSTART || RIFF->GetObjChunkType() != cdrT_strl,
02299             "ProcessTextListItem4 called in the wrong context");
02300 
02301     UINT32 EndLevel = RIFF->GetObjLevel();
02302 
02303     TextLine *FirstLine = 0;
02304     TextLine *CurrentLine = 0;
02305     INT32 MaxFirstLineSpace = 0;
02306     BOOL IsFirstLine = TRUE;
02307 
02308     WORD ID = 0;
02309 
02310     CDRTextStyle BaseStyle = CDRDefaultTextStyle;
02311 
02312     do {
02313     
02314         if(RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK)
02315         {
02316             switch(RIFF->GetObjChunkType())
02317             {
02318                 case cdrT_btid:
02319                     // id of thingy, store
02320                     {
02321                         if(!RIFF->AquireChunkData())
02322                             return FALSE;
02323 
02324                         WORD *Thingy = (WORD *)RIFF->GetAquiredData();
02325 
02326                         ERROR2IF(Thingy == 0, FALSE, "Couldn't get aquired data");
02327 
02328                         ID = CDRDATA_WORD(*Thingy);
02329                     }
02330                     break;
02331                 
02332                 case cdrT_para:
02333                     {
02334                         // do we need an end of line node for something?
02335                         if(CurrentLine != 0)
02336                         {
02337                             EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
02338 
02339                             if(EOL == 0)
02340                                 return FALSE;
02341                         }
02342 
02343                         // new paragraph start - create a new line
02344                         if(CurrentLine == 0)
02345                         {
02346                             CurrentLine = new TextLine;
02347                         }
02348                         else
02349                         {
02350                             CurrentLine = new TextLine(CurrentLine, NEXT);
02351                         }
02352 
02353                         if(CurrentLine == 0)
02354                             return FALSE;
02355 
02356                         if(FirstLine == 0)
02357                             FirstLine = CurrentLine;
02358                         else
02359                             IsFirstLine = FALSE;
02360 
02361                         // get the style of this paragraph
02362                         if(!RIFF->AquireChunkData())
02363                             return FALSE;
02364 
02365                         cdrfParaDefnV4 *Para = (cdrfParaDefnV4 *)RIFF->GetAquiredData();
02366                         if(Para == 0)
02367                             return FALSE;
02368 
02369                         if(!GetTextStyleFromCDRStyle(&BaseStyle, CDRDATA_WORD(Para->Style)))
02370                             return FALSE;
02371 
02372                         if(IsFirstLine && BaseStyle.LineSpace > MaxFirstLineSpace)
02373                             MaxFirstLineSpace = BaseStyle.LineSpace;
02374                     }
02375                     break;
02376                 
02377                 case cdrT_bnch:
02378                     // a load of characters
02379                     ERROR2IF(CurrentLine == 0, FALSE, "CurrentLine is zero when characters found");
02380                     
02381                     {
02382                         // get the chunk data
02383                         if(!RIFF->AquireChunkData())
02384                             return FALSE;
02385                     
02386                         // process it...
02387                         cdrfTextListCharV4 *Chars = (cdrfTextListCharV4 *)RIFF->GetAquiredData();
02388                         ERROR2IF(Chars == 0, FALSE, "no data from aquire data");
02389 
02390                         INT32 NChars = RIFF->GetObjSize() / sizeof(cdrfTextListCharV4);
02391 
02392                         // add all the nice characters we've got
02393                         for(INT32 l = 0; l < NChars; l++)
02394                         {
02395                             if(CDRDATA_WORD(Chars[l].Char) >= ' ')
02396                             {
02397                                 TextChar *NewChar = new TextChar(CurrentLine, LASTCHILD, CDRDATA_WORD(Chars[l].Char));
02398 
02399                                 if(NewChar == 0)
02400                                     return FALSE;
02401 
02402                                 // apply attributes
02403                                 if(!ApplyTextAttr(NewChar, &BaseStyle, 0))
02404                                     return FALSE;
02405                             }
02406                         }
02407                     }                   
02408                     break;
02409 
02410                 case cdrT_bsch:
02411                     // a character with styles attached
02412                     ERROR2IF(CurrentLine == 0, FALSE, "CurrentLine is zero when characters found");
02413                     {
02414                         // get the chunk data
02415                         if(!RIFF->AquireChunkData())
02416                             return FALSE;
02417                     
02418                         // process it...
02419                         cdrfTextListCharStyledV4 *Char = (cdrfTextListCharStyledV4 *)RIFF->GetAquiredData();
02420                         ERROR2IF(Char == 0, FALSE, "no data from aquire data");
02421 
02422                         if(CDRDATA_WORD(Char->Char) >= ' ')
02423                         {
02424                             TextChar *NewChar = new TextChar(CurrentLine, LASTCHILD, CDRDATA_WORD(Char->Char));
02425 
02426                             if(NewChar == 0)
02427                                 return FALSE;
02428 
02429                             // apply attributes to it
02430                             CDRTextStyle ThisStyle = BaseStyle;
02431 
02432                             // font size
02433                             ThisStyle.FontSize = CDRDATA_WORD(Char->FontSize) * CDRCOORDS_TO_MILLIPOINTS;
02434     
02435                             // font name
02436 /*                          TCHAR *FontName = GetFontName(CDRDATA_WORD(Char->FontRef));
02437                             if(FontName != 0)
02438                             {
02439                                 ThisStyle.FontName = FontName;
02440                             }
02441 */
02442                             ThisStyle.FontReference = CDRDATA_WORD(Char->FontRef);
02443 
02444                             // bold and italicness
02445                             switch(Char->Weight)
02446                             {
02447                                 case cdrfFONTTYPEV4_BOLD:
02448                                     ThisStyle.Bold = TRUE;
02449                                     ThisStyle.Italic = FALSE;
02450                                     break;
02451 
02452                                 case cdrfFONTTYPEV4_ITALIC:
02453                                     ThisStyle.Bold = FALSE;
02454                                     ThisStyle.Italic = TRUE;
02455                                     break;
02456 
02457                                 case cdrfFONTTYPEV4_BOLDITALIC:
02458                                     ThisStyle.Bold = TRUE;
02459                                     ThisStyle.Italic = TRUE;
02460                                     break;
02461 
02462                                 default:
02463                                     ThisStyle.Bold = FALSE;
02464                                     ThisStyle.Italic = FALSE;
02465                                     break;
02466                             }
02467 
02468                             // placement
02469                             switch(Char->Placement)
02470                             {
02471                                 default:
02472                                 case cdrfPLACEMENTV4_NONE:  ThisStyle.Script = CDRSCRIPT_NONE;  break;
02473                                 case cdrfPLACEMENTV4_SUPER: ThisStyle.Script = CDRSCRIPT_SUPER; break;
02474                                 case cdrfPLACEMENTV4_SUB:   ThisStyle.Script = CDRSCRIPT_SUB;   break;
02475                             }
02476 
02477                             // apply attributes
02478                             if(!ApplyTextAttr(NewChar, &ThisStyle, 0))
02479                                 return FALSE;
02480 
02481                             // sort out max first line space
02482                             if(IsFirstLine && ThisStyle.LineSpace > MaxFirstLineSpace)
02483                                 MaxFirstLineSpace = ThisStyle.LineSpace;
02484                         }
02485                     }
02486                     break;
02487 
02488                 default:
02489                     break;
02490             }
02491         }
02492 
02493         UpdateProgress();
02494 
02495         if(!RIFF->NextObject())
02496             return FALSE;
02497     
02498     } while(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > EndLevel);
02499 
02500     if(CurrentLine != 0)
02501     {
02502         // pop some ending stuff on it
02503         CaretNode *Caret = new CaretNode(CurrentLine, LASTCHILD);
02504         EOLNode *EOL = new EOLNode(CurrentLine, LASTCHILD);
02505         if(Caret == 0 || EOL == 0)
02506             return FALSE;
02507     }
02508 
02509     if(FirstLine != 0)
02510     {
02511         // got something - add it to the list of text stuff
02512         CDRVectorStoredItem *Item = new CDRVectorStoredItem;
02513 
02514         if(Item == 0)
02515             return FALSE;
02516 
02517         // store objects
02518         Item->Objects = FirstLine;
02519         Item->Reference = ID;
02520 
02521         // pop max first line in the bbox
02522         Item->BBox.hi.y = MaxFirstLineSpace;
02523 
02524         TextV4.AddTail(Item);
02525     }
02526     
02527     return TRUE;
02528 }

BOOL CDRFilter::ProcessVectorList ADDR  Block,
INT32  Size
[private]
 

processes the vector list at the beginning of CDR files. This contains a list of objects which are used for things such as full colour fills, texture fills, mould shapes, that sort of thing.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/04/95
Parameters:
vect list contents and size [INPUTS]
Returns:
error flag
They are referenced by the objects serial number.

This function takes a block containing the vect list contents and it's size as Corel store all these vectors *before* the fill and outline definitions. Are these people really crazy?

See also:
Filter

Definition at line 1455 of file cdrfill.cpp.

01456 {
01457     ERROR3IF(pLevelNodeList != 0, "ProcessVectorList called when LevelNodeList was in use");
01458 
01459     // first of all, make a CCMemFile out of the block so we can do RIFF stuff on it
01460     CCMemFile MFile;
01461 
01462     MFile.open(Block, Size);
01463 
01464     // make a RIFF file out of it - but we don't have a header
01465     RIFFFile RFile;
01466 
01467     RFile.Init(&MFile, TRUE);
01468 
01469     // OK, change a few variables over...
01470     INT32 oTranslateByX = TranslateByX;
01471     INT32 oTranslateByY = TranslateByY;
01472     RIFFFile *oRIFF = RIFF;
01473 
01474     TranslateByX = 0;
01475     TranslateByY = 0;
01476     RIFF = &RFile;
01477 
01478     // get on and process the block
01479     // what we've got it a load of 'grp' lists containing the objects we're interested in
01480     // they contain a serial number which is used to identify the vector and a bbox,
01481     // which we need to find and store in the list
01482     do
01483     {
01484         // is it a group list?
01485         if(RIFF->GetObjType() == RIFFOBJECTTYPE_LISTSTART && RIFF->GetObjChunkType() == cdrT_grp)
01486         {
01487             if(!ProcessVectorListEntry())
01488                 return FALSE;
01489         }
01490 
01491         if(!RIFF->NextObject())
01492             goto Failure;
01493 
01494     } while(RIFF->GetObjType() != RIFFOBJECTTYPE_FILEEND);
01495 
01496     // close everything down and put the variables back
01497     MFile.close();
01498 
01499     TranslateByX = oTranslateByX;
01500     TranslateByY = oTranslateByY;
01501     RIFF = oRIFF;
01502 
01503     return TRUE;
01504 
01505 Failure:
01506     // clear everything up...
01507     MFile.close();
01508 
01509     TranslateByX = oTranslateByX;
01510     TranslateByY = oTranslateByY;
01511     RIFF = oRIFF;
01512 
01513     return FALSE;
01514 }

BOOL CDRFilter::ProcessVectorListEntry  )  [private]
 

processes an entry in the vector list

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/04/95
Parameters:
- [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 1530 of file cdrfill.cpp.

01531 {
01532     UINT32 StartLevel = RIFF->GetObjLevel();
01533 
01534     ERROR3IF(RIFF->GetObjType() != RIFFOBJECTTYPE_LISTSTART && RIFF->GetObjChunkType() != cdrT_grp,
01535         "ProcessVectorListEntry called without RIFF set up correctly");
01536 
01537     // OK, wander though to find the serial number and the bbox
01538     WORD Reference;     // the serial number
01539     DocRect BBox;
01540     BOOL GotReference = FALSE;
01541     BOOL GotBBox = FALSE;
01542 
01543     do
01544     {
01545         if(RIFF->GetObjType() == RIFFOBJECTTYPE_CHUNK)
01546         {
01547             switch(RIFF->GetObjChunkType())
01548             {
01549                 case cdrT_spnd:
01550                     {
01551                         // got the serial number block - get it...
01552                         if(!RIFF->AquireChunkData())
01553                             return FALSE;
01554                     
01555                         WORD *Data = (WORD *)RIFF->GetAquiredData();
01556                     
01557                         if(Data == 0)
01558                             return FALSE;
01559 
01560                         // store it...
01561                         Reference = CDRDATA_WORD(*Data);
01562 
01563                         GotReference = TRUE;
01564                     }
01565                     break;
01566 
01567                 case cdrT_bbox:
01568                     {
01569                         // is it large enought?
01570                         if(RIFF->GetObjSize() < sizeof(cdrfBBox))
01571                         {
01572                             // no - ignore this entry
01573                             RIFF->SkipToListEnd(StartLevel);
01574                             return TRUE;
01575                         }
01576 
01577                         // found the bbox... get the data
01578                         if(!RIFF->AquireChunkData())
01579                             return FALSE;
01580                     
01581                         cdrfBBox *Data = (cdrfBBox *)RIFF->GetAquiredData();
01582                     
01583                         if(Data == 0)
01584                             return FALSE;
01585 
01586                         // get the bounding box
01587                         BBox.lo.x = CDRDATA_SWORD(Data->x0) * CDRCOORDS_TO_MILLIPOINTS;
01588                         BBox.lo.y = CDRDATA_SWORD(Data->y0) * CDRCOORDS_TO_MILLIPOINTS;
01589                         BBox.hi.x = CDRDATA_SWORD(Data->x1) * CDRCOORDS_TO_MILLIPOINTS;
01590                         BBox.hi.y = CDRDATA_SWORD(Data->y1) * CDRCOORDS_TO_MILLIPOINTS;
01591                     
01592                         GotBBox = TRUE;
01593                     }
01594                     break;
01595                 
01596                 default:
01597                     break;
01598             }
01599         }
01600     
01601         if(!RIFF->NextObject())
01602             return FALSE;
01603 
01604     } while((GotReference == FALSE || GotBBox == FALSE) &&
01605         (RIFF->GetObjType() != RIFFOBJECTTYPE_LISTEND || RIFF->GetObjLevel() > StartLevel));
01606 
01607     // OK, now get the object tree
01608     if(!ProcessObjectTree(StartLevel))
01609         return FALSE;
01610 
01611     // right then, the converted nodes are in pLevelNodeList
01612     // create a nice list entry
01613 
01614     CDRVectorStoredItem *Item = new CDRVectorStoredItem;
01615 
01616     if(Item == 0)
01617         return FALSE;
01618 
01619     // set the object data
01620     Item->Objects = pLevelNodeList;
01621     Item->Reference = Reference;
01622     Item->BBox = BBox;
01623 
01624     // make the node list unused
01625     pLevelNodeList = 0;
01626     
01627     // add the list entry
01628     Vectors.AddTail(Item);
01629 
01630     return TRUE;
01631 }

BOOL CDRFilter::SetConicalGrad CDRFillInfo GFill,
DocRect BBox,
DocColour StartColour,
DocColour EndColour
[private]
 

sets a conical graduated fill from fill definition in the file Copied from coreleps.cpp and modified

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 03 95
Parameters:
grad fill defn and converted colours for the fill [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 941 of file cdrfill.cpp.

00942 {
00943     // The desired start and end points of the grad fill 'arrow'.
00944     DocCoord Start, End;
00945 
00946     // Calculate width and height
00947     MILLIPOINT Width = BBox.Width();
00948     MILLIPOINT Height = BBox.Height();
00949 
00950     // Start point is the centre given by Corel.
00951     // This centre is percentage offsets from the centre of the object, i.e. (0,0) is
00952     // the centre of the bounding box.
00953     Start.x = BBox.lo.x + (Width  / 2);
00954     Start.y = BBox.lo.y + (Height / 2);
00955     Start.x += ((GFill->HorizontalCentreOffset * Width) / 100);
00956     Start.y += ((GFill->VerticalCentreOffset * Height) / 100);
00957 
00958     // End point is start point + radius but takes into account the angle
00959     double Radius = Width / 2;
00960     // angle is * 10, and needs to be in radians
00961     double Theta = ((((double)(GFill->Angle)) / 10.0) / 360.0) * (2 * PI);
00962 
00963     // make the angle go anti-clockwise
00964     Theta = 0 - Theta;
00965 
00966     // rotate by PI / 2
00967     Theta -= PI / 2;
00968     
00969     // angle can be negative, ensure it's positive
00970     while(Theta < 0)
00971         Theta += (2 * PI);
00972 
00973     // calculate the triangle
00974     double dx, dy;
00975 
00976     dx = Radius * sin(Theta);
00977     dy = Radius * cos(Theta);
00978 
00979     End.x = Start.x + (INT32)dx;
00980     End.y = Start.y + (INT32)dy;
00981 
00982     // Seems that we need to swap start and end colours...
00983 
00984     // Set the fill type according to these calculations.
00985     return SetConicalFill(*EndColour, *StartColour, Start, End);    
00986 }

BOOL CDRFilter::SetFillAttr cdrfOffsetHeader Object  )  [private]
 

sets the fill attributes

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
27 03 95
Parameters:
address of the object [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 128 of file cdrfill.cpp.

00129 {
00130     if(Version == CDRVERSION_3)
00131     {
00132         return SetFillAttr3(Object);
00133     }
00134 
00135     // find the reference...
00136     DWORD *pReference = (DWORD *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_FILL);
00137 
00138     // if the pointer to the reference is zero, then the reference is probably
00139     // within some random style definition
00140     if(pReference == 0)
00141     {
00142         // OK, try and find a style number within the style reference
00143         WORD *pStyleReference = (WORD *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_STYLE);
00144 
00145         if(pStyleReference != 0)
00146         {
00147             // OK, see if we can find a the style...
00148             cdrfStyle *pStyle;
00149             INT32 StyleSize;
00150 
00151             if((pStyle = (cdrfStyle *)Styles.Find(*pStyleReference, &StyleSize)) != 0)
00152             {
00153                 // OK, got a style... now find a fill reference within it
00154                 pReference = (DWORD *)FindDataInObject(&pStyle->Header, cdrfSTYLEOFFSETTYPE_FILL);
00155             }
00156         }
00157     }
00158     
00159     // should this be filled?
00160     if(pReference == 0 || ObjFilled == FALSE)
00161     {
00162         // set not filled attribute
00163         return NoFill();
00164     }
00165 
00166     cdrfFillHeader *Fill;
00167     INT32 FillSize;
00168     
00169     // set is filled attribute
00170     if(!SetPathFilled(TRUE))
00171         return FALSE;
00172 
00173     // try and find the data for a version 4 or 5 fill
00174     if((Fill = (cdrfFillHeader *)Fills.Find(*pReference, &FillSize)) == 0)
00175         return SetUKFill();
00176 
00177     // check the fill's size
00178     if(FillSize < sizeof(cdrfFillHeader))
00179     {
00180         // if no fill defn or it's just a tad to small, set the unknown fill colour
00181         return SetUKFill();
00182     }
00183 
00184     // OK, what's this fill then?
00185     switch(CDRDATA_WORD(Fill->FillType))
00186     {
00187         case cdrfFILLTYPE_NONE:
00188             // no fill - set things up to be hoopy about that.
00189             return NoFill();
00190             break;
00191 
00192         case cdrfFILLTYPE_FLAT:
00193             return SetFillAttrFlat(Fill, FillSize);
00194             break;
00195 
00196         case cdrfFILLTYPE_GRADUATED:
00197             return SetFillAttrGrad(Fill, FillSize);
00198             break;
00199 
00200         case cdrfFILLTYPE_PATTERN:
00201             {
00202                 CDRTiledFillInfo i;
00203                 cdrfFillPattern *PFill = (cdrfFillPattern *)Fill;
00204 
00205                 // check the size and set an unknown fill if it's too small
00206                 if(FillSize < sizeof(cdrfFillPattern))
00207                     return SetUKFill();
00208     
00209                 // set the info structure
00210                 i.SizeX = CDRDATA_SWORD(PFill->SizeX);
00211                 i.SizeY = CDRDATA_SWORD(PFill->SizeY);
00212                 i.OffsetX = CDRDATA_SWORD(PFill->OffsetX);
00213                 i.OffsetY = CDRDATA_SWORD(PFill->OffsetY);
00214                 i.Reference = CDRDATA_DWORD(PFill->Reference);
00215 
00216                 // convert the colours
00217                 DocColour Colour1;
00218                 DocColour Colour2;
00219                 ConvertColour(&PFill->Colour1, &Colour1);
00220                 ConvertColour(&PFill->Colour2, &Colour2);
00221 
00222                 return SetFillAttrPattern(&i, &Colour1, &Colour2);
00223             }
00224             break;
00225         
00226         case cdrfFILLTYPE_VECTOR:
00227             {
00228                 CDRTiledFillInfo i;
00229                 cdrfFillVector *VFill = (cdrfFillVector *)Fill;
00230 
00231                 // check the size and set an unknown fill if it's too small
00232                 if(FillSize < sizeof(cdrfFillVector))
00233                     return SetUKFill();
00234     
00235                 // set the info structure
00236                 i.SizeX = CDRDATA_SWORD(VFill->SizeX);
00237                 i.SizeY = CDRDATA_SWORD(VFill->SizeY);
00238                 i.OffsetX = CDRDATA_SWORD(VFill->OffsetX);
00239                 i.OffsetY = CDRDATA_SWORD(VFill->OffsetY);
00240                 i.Reference = CDRDATA_DWORD(VFill->VectorReference);
00241 
00242                 return SetFillAttrVector(&i);
00243             }
00244             break;
00245         
00246         case cdrfFILLTYPE_TEXTURE:
00247             return SetFillAttrTexture(Fill, FillSize);
00248             break;
00249 
00250         default:
00251             return SetUKFill();
00252             break;
00253     }
00254 
00255     return TRUE;
00256 }

BOOL CDRFilter::SetFillAttr3 cdrfOffsetHeader Object  )  [private]
 

sets the fill attributes for version 3

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/04/95
Parameters:
address of object [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 299 of file cdrfill.cpp.

00300 {
00301     cdrfFillV3 *Fill = (cdrfFillV3 *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_FILL);
00302     
00303     if(Fill == 0)
00304     {
00305         // set not filled attribute
00306         return NoFill();
00307     }
00308 
00309     // info about the fill
00310     CDRFillInfo fi;
00311 
00312     // find the bounding box of this lovely node
00313     DocRect BBox;
00314     if(!GetObjCorelBBox((NodeRenderableBounded *)pMadeNode, &BBox))
00315         return FALSE;
00316 
00317     // convert colours and things as necessary
00318     DocColour Col1;
00319     DocColour Col2;
00320 
00321     if(Fill->Type == cdrfFILLTYPEV3_FLAT)
00322     {
00323         if(!ConvertColour((cdrfColour *)&Fill->Data.Flat.Colour, &Col1))
00324             return FALSE;
00325     }
00326     else if(Fill->Type == cdrfFILLTYPEV3_LINEAR || Fill->Type == cdrfFILLTYPEV3_RADIAL)
00327     {
00328         fi.Angle = CDRDATA_SWORD(Fill->Data.Grad.Angle);
00329         fi.Pad = CDRDATA_SWORD(Fill->Data.Grad.Pad);
00330         fi.HorizontalCentreOffset = CDRDATA_SWORD(Fill->Data.Grad.HorizontalCentreOffset);
00331         fi.VerticalCentreOffset = CDRDATA_SWORD(Fill->Data.Grad.VerticalCentreOffset);
00332     
00333         if(!ConvertColour((cdrfColour *)&Fill->Data.Grad.Colour1, &Col1))
00334             return FALSE;
00335         if(!ConvertColour((cdrfColour *)&Fill->Data.Grad.Colour2, &Col2))
00336             return FALSE;
00337     }
00338 
00339     // make the path filled
00340     if(!SetPathFilled(TRUE))
00341         return FALSE;
00342     
00343     // set the fill
00344     switch(Fill->Type)
00345     {
00346         case cdrfFILLTYPEV3_NONE:
00347             return NoFill();
00348             break;
00349 
00350         case cdrfFILLTYPEV3_FLAT:
00351             if(!SetFillColour(Col1))
00352                 return FALSE;
00353             break;
00354 
00355         case cdrfFILLTYPEV3_LINEAR:
00356             if(!SetLinearGrad(&fi, BBox, &Col1, &Col2))
00357                 return SetUKFill();
00358             break;
00359 
00360         case cdrfFILLTYPEV3_RADIAL:
00361             if(!SetRadialGrad(&fi, BBox, &Col1, &Col2))
00362                 return SetUKFill();
00363             break;
00364 
00365 
00366         case cdrfFILLTYPEV3_PATTERN:
00367             {
00368                 CDRTiledFillInfo i;
00369 
00370                 // set the info structure
00371                 i.SizeX = CDRDATA_SWORD(Fill->Data.Pattern.SizeX);
00372                 i.SizeY = CDRDATA_SWORD(Fill->Data.Pattern.SizeY);
00373                 i.OffsetX = CDRDATA_SWORD(Fill->Data.Pattern.OffsetX);
00374                 i.OffsetY = CDRDATA_SWORD(Fill->Data.Pattern.OffsetY);
00375                 i.Reference = CDRDATA_DWORD(Fill->Data.Pattern.Reference);
00376 
00377                 // convert the colours
00378                 ConvertColour((cdrfColour *)&Fill->Data.Pattern.Colour1, &Col1);
00379                 ConvertColour((cdrfColour *)&Fill->Data.Pattern.Colour2, &Col2);
00380 
00381                 return SetFillAttrPattern(&i, &Col1, &Col2);
00382             }
00383             break;
00384     
00385         case cdrfFILLTYPEV3_VECTOR:
00386             {
00387                 CDRTiledFillInfo i;
00388 
00389                 // set the info structure
00390                 i.SizeX = CDRDATA_SWORD(Fill->Data.Vector.SizeX);
00391                 i.SizeY = CDRDATA_SWORD(Fill->Data.Vector.SizeY);
00392                 i.OffsetX = CDRDATA_SWORD(Fill->Data.Vector.OffsetX);
00393                 i.OffsetY = CDRDATA_SWORD(Fill->Data.Vector.OffsetY);
00394                 i.Reference = CDRDATA_DWORD(Fill->Data.Vector.Reference);
00395 
00396                 return SetFillAttrVector(&i);
00397             }
00398             break;
00399     
00400         default:
00401             return SetUKFill();
00402             break;
00403     }   
00404 
00405     return TRUE;
00406 }

BOOL CDRFilter::SetFillAttrFlat cdrfFillHeader Fill,
INT32  Size
[private]
 

sets flat fill attributes

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 03 95
Parameters:
pointer to fill header [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 422 of file cdrfill.cpp.

00423 {
00424     cdrfFillFlat *FFill = (cdrfFillFlat *)Fill;
00425 
00426     // check the size and set an unknown fill if it's too small
00427     if(Size < sizeof(cdrfFillFlat))
00428         return SetUKFill();
00429     
00430     // convert and set the line colour
00431     DocColour Col;
00432     ConvertColour(&FFill->Colour, &Col);
00433 
00434     if(!SetFillColour(Col))
00435         return FALSE;
00436 
00437     return TRUE;
00438 }

BOOL CDRFilter::SetFillAttrGrad cdrfFillHeader Fill,
INT32  Size
[private]
 

sets graduated fill attributes

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 03 95
Parameters:
pointer to fill header [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 454 of file cdrfill.cpp.

00455 {
00456     // check that it's big enought to be a realistic grad fill
00457     if(Size < (sizeof(cdrfFillGraduated) + sizeof(cdrfFillGradColour)))
00458     {
00459 TRACEUSER( "Ben", _T("fill too small, size = %d\n"), Size);
00460         return SetUKFill();
00461     }
00462 
00463     // make a new pointer
00464     cdrfFillGraduated *GFill = (cdrfFillGraduated *)Fill;
00465 
00466     // has it got enough colours in it?
00467     if(CDRDATA_WORD(GFill->NColours) < 1)
00468         return SetUKFill();
00469 
00470     // find the bounding box of this lovely node
00471     DocRect BBox;
00472     if(!GetObjCorelBBox((NodeRenderableBounded *)pMadeNode, &BBox))
00473         return FALSE;
00474 
00475     // sort out the colours on this fill - ATM we can only go from one colour to
00476     // another, so we just need to find the last and first ones and use those.
00477     cdrfFillGradColour *Cols = (cdrfFillGradColour *)(GFill + 1);
00478 
00479     UINT32 min = CDRDATA_WORD(Cols[0].Percentage);
00480     UINT32 max = min;
00481     UINT32 minO = 0;
00482     UINT32 maxO = 0;
00483     UINT32 l;
00484 
00485     for(l = 1; l < CDRDATA_WORD(GFill->NColours); l++)
00486     {
00487         UINT32 p = CDRDATA_WORD(Cols[l].Percentage);
00488 
00489         if(p < min)
00490         {
00491             min = p;
00492             minO = l;
00493         }
00494         if(p > max)
00495         {
00496             max = p;
00497             maxO = l;
00498         }
00499     }
00500 
00501     // OK, found the minimum and maximim percentages along the grad fill line.
00502     // get and convert the colours
00503     DocColour StartColour;
00504     DocColour EndColour;
00505 
00506     ConvertColour(&Cols[minO].Colour, &StartColour);
00507     ConvertColour(&Cols[maxO].Colour, &EndColour);
00508 
00509     // now work out what kind of fade we need here
00510     UINT32 FadeType = CDRDATA_WORD(GFill->ColourType);
00511 
00512     // if it's a rainbow effect, work out whether an anti-clockwise thingy will be a
00513     // a normal or alt rainbow fill
00514     BOOL NormalRainbow = TRUE;
00515     if(FadeType == cdrfGRADFILLCOLOURTYPE_RAINBOW_CLOCKWISE ||
00516              FadeType == cdrfGRADFILLCOLOURTYPE_RAINBOW_ANTICLOCKWISE)
00517     {
00518         // convert both colours to HSV to find their hue
00519         ColourContext *Conv = ColourContext::GetGlobalDefault(COLOURMODEL_HSVT);
00520 
00521         ColourHSVT StartC;
00522         ColourHSVT EndC;
00523 
00524         Conv->ConvertColour(&StartColour, (ColourGeneric *)&StartC);
00525         Conv->ConvertColour(&EndColour, (ColourGeneric *)&EndC);
00526 
00527         // compare the hues and work out a difference
00528         ColourValue Difference;
00529 
00530         if(EndC.Hue > StartC.Hue)
00531         {
00532             Difference = EndC.Hue - StartC.Hue;
00533         } else {
00534             Difference = 1.0 - (StartC.Hue - EndC.Hue);
00535         }
00536 
00537         // if the difference is more than 0.5 then it's a alt rainbow thingy
00538         if(Difference > fixed24(0.5))
00539             NormalRainbow = FALSE;
00540     }
00541 
00542     // set the fade effect
00543     switch(FadeType)
00544     {
00545         case cdrfGRADFILLCOLOURTYPE_DIRECT:
00546         case cdrfGRADFILLCOLOURTYPE_CUSTOM:
00547         default:
00548             SetFadeFillEffect();
00549             break;
00550 
00551         case cdrfGRADFILLCOLOURTYPE_RAINBOW_ANTICLOCKWISE:
00552             if(NormalRainbow)
00553                 SetRainbowFillEffect();
00554             else
00555                 SetAltRainbowFillEffect();
00556             break;
00557 
00558         case cdrfGRADFILLCOLOURTYPE_RAINBOW_CLOCKWISE:
00559             if(NormalRainbow)
00560                 SetAltRainbowFillEffect();
00561             else
00562                 SetRainbowFillEffect();
00563             break;
00564     }
00565 
00566     // get the info about the fill
00567     CDRFillInfo fi;
00568 
00569     fi.Angle = CDRDATA_SWORD(GFill->Angle);
00570     fi.Pad = CDRDATA_SWORD(GFill->Pad);
00571     fi.HorizontalCentreOffset = CDRDATA_SWORD(GFill->HorizontalCentreOffset);
00572     fi.VerticalCentreOffset = CDRDATA_SWORD(GFill->VerticalCentreOffset);
00573     
00574     // and finally, sort out the start and end points of the thingy
00575     DocCoord StartPoint;
00576     DocCoord EndPoint;
00577     switch(CDRDATA_WORD(GFill->GradFillType))
00578     {
00579         case cdrfGRADFILLTYPE_LINEAR:
00580             if(!SetLinearGrad(&fi, BBox, &StartColour, &EndColour))
00581                 return SetUKFill();
00582             break;
00583 
00584         case cdrfGRADFILLTYPE_RADIAL:
00585         case cdrfGRADFILLTYPE_SQUARE:       // radial is the nearest Camelot fill to a square fill
00586             if(!SetRadialGrad(&fi, BBox, &StartColour, &EndColour))
00587                 return SetUKFill();
00588             break;
00589 
00590         case cdrfGRADFILLTYPE_CONICAL:
00591             if(!SetConicalGrad(&fi, BBox, &StartColour, &EndColour))
00592                 return SetUKFill();
00593             break;
00594 
00595         default:            
00596             return SetUKFill();
00597             break;
00598     }
00599 
00600     return TRUE;
00601 }

BOOL CDRFilter::SetFillAttrPattern CDRTiledFillInfo Info,
DocColour Colour1,
DocColour Colour2
[private]
 

set pattern fill attributes

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/04/95
Parameters:
pointer to fill header [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 1212 of file cdrfill.cpp.

01213 {
01214     // find the bitmap we're going to use
01215     KernelBitmap *pBitmap = Patterns.FindBitmap(Info->Reference);
01216 
01217     if(pBitmap == 0)
01218         return SetUKFill();
01219 
01220     // work out where it's going to go.
01221 
01222     // find the size of the tile
01223     INT32 SizeX = Info->SizeX * CDRCOORDS_TO_MILLIPOINTS;
01224     INT32 SizeY = Info->SizeY * CDRCOORDS_TO_MILLIPOINTS;
01225 
01226     // find the bounding box of this lovely node
01227     DocRect BBox;
01228     if(!GetObjCorelBBox((NodeRenderableBounded *)pMadeNode, &BBox))
01229         return FALSE;
01230 
01231     // set to the top left + the first tile offset
01232     INT32 XPos = BBox.lo.x + ((SizeX * Info->OffsetX) / 100);
01233     INT32 YPos = BBox.hi.y - SizeY - ((SizeY * Info->OffsetY) / 100);
01234 
01235     // can't do anything with the row/column staggering thingy
01236 
01237     // set the bitmap fill
01238     DocCoord Start  = DocCoord(XPos,            YPos);
01239     DocCoord End1   = DocCoord(XPos + SizeX,    YPos);
01240     DocCoord End2   = DocCoord(XPos,            YPos + SizeY);
01241     if(!SetBitmapFill(pBitmap, Start, End1, End2, Colour1, Colour2))
01242         return FALSE;
01243 
01244     return TRUE;
01245 }

BOOL CDRFilter::SetFillAttrTexture cdrfFillHeader Fill,
INT32  Size
[private]
 

sets texture fill attributes

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/04/95
Parameters:
pointer to fill header [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 1319 of file cdrfill.cpp.

01320 {
01321     cdrfFillTexture *TFill = (cdrfFillTexture *)Fill;
01322 
01323     // check the size and set an unknown fill if it's too small
01324     if(Size < sizeof(cdrfFillTexture))
01325         return SetUKFill();
01326 
01327     // OK, let's try and find the vector thing it represents
01328     DocRect fBBox;
01329     Node *FillNodes;
01330     
01331     FillNodes = Vectors.Find(CDRDATA_WORD(TFill->VectorReference), &fBBox);
01332 
01333     // did we get any?
01334     if(FillNodes == 0)
01335         return SetUKFill();
01336 
01337     // find the associated bitmap
01338     KernelBitmap *pBitmap;
01339 
01340     pBitmap = BitmapFromNodeList(FillNodes);
01341 
01342     // got one?
01343     if(pBitmap == 0)
01344         return SetUKFill();
01345 
01346     // right then, set the fill to cover the object
01347     // what's it's bounding box?
01348     DocRect BBox;
01349     if(!GetObjCorelBBox((NodeRenderableBounded *)pMadeNode, &BBox))
01350         return FALSE;
01351 
01352     // set the bitmap fill
01353     DocCoord Start  = DocCoord(BBox.lo.x,   BBox.lo.y);
01354     DocCoord End1   = DocCoord(BBox.hi.x,   BBox.lo.y);
01355     DocCoord End2   = DocCoord(BBox.lo.x,   BBox.hi.y);
01356     if(!SetBitmapFill(pBitmap, Start, End1, End2))
01357         return FALSE;
01358 
01359     return TRUE;
01360 }

BOOL CDRFilter::SetFillAttrVector CDRTiledFillInfo Info  )  [private]
 

set vector fill attributes

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/04/95
Parameters:
pointer to fill header [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 1261 of file cdrfill.cpp.

01262 {
01263     // find the bitmap we're going to use - at the moment, we can't only do a vector fill
01264     // if it actually referes to a bitmap
01265 
01266     // first things first - find the entry in the vectors list
01267     CDRVectorStoredItem *Item = Vectors.Find(Info->Reference);
01268 
01269     if(Item->Objects == 0)
01270         return SetUKFill();
01271 
01272     // now, does this just refer to a bitmap?
01273     KernelBitmap *pBitmap = BitmapFromNodeList(Item->Objects);
01274 
01275     if(pBitmap == 0)
01276         return SetUKFill();     // no bitmap generation possible
01277 
01278     // work out where it's going to go.
01279 
01280     // find the size of the tile
01281     INT32 SizeX = Info->SizeX * CDRCOORDS_TO_MILLIPOINTS;
01282     INT32 SizeY = Info->SizeY * CDRCOORDS_TO_MILLIPOINTS;
01283 
01284     // find the bounding box of this lovely node
01285     DocRect BBox;
01286     if(!GetObjCorelBBox((NodeRenderableBounded *)pMadeNode, &BBox))
01287         return FALSE;
01288 
01289     // set to the top left + the first tile offset
01290     INT32 XPos = BBox.lo.x + ((SizeX * Info->OffsetX) / 100);
01291     INT32 YPos = BBox.hi.y - SizeY - ((SizeY * Info->OffsetY) / 100);
01292 
01293     // can't do anything with the row/column staggering thingy
01294 
01295     // set the bitmap fill
01296     DocCoord Start  = DocCoord(XPos,            YPos);
01297     DocCoord End1   = DocCoord(XPos + SizeX,    YPos);
01298     DocCoord End2   = DocCoord(XPos,            YPos + SizeY);
01299     if(!SetBitmapFill(pBitmap, Start, End1, End2))
01300         return FALSE;
01301 
01302     return TRUE;
01303 }

BOOL CDRFilter::SetLinearGrad CDRFillInfo GFill,
DocRect BBox,
DocColour StartColour,
DocColour EndColour
[private]
 

sets a linear graduated fill from fill definition in the file Copied from coreleps.cpp and modified

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 03 95
Parameters:
grad fill defn and converted colours for the fill [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 726 of file cdrfill.cpp.

00727 {
00728     // NB. this function is (hopefully!) over-complex and will be simplified.
00729     // However, it's like this atm so I can get my head around the weird maths Corel 
00730     // forces us to use.
00731 
00732     // The desired start and end points of the grad fill 'arrow'.
00733     DocCoord Start, End;
00734 
00735     // Calculate width and height
00736     MILLIPOINT Width = BBox.Width();
00737     MILLIPOINT Height = BBox.Height();
00738 
00739     // bodge just in case of zero height or widths
00740     if(Width < 16)
00741         Width = 16;
00742 
00743     if(Height < 16)
00744         Height = 16;
00745 
00746     // Find centre of box
00747     DocCoord Centre;
00748     Centre.x = BBox.lo.x + (Width / 2);
00749     Centre.y = BBox.lo.y + (Height / 2);
00750 
00751     // Find total area of BBox
00752     double TotalArea = (double) Width * (double) Height;
00753 
00754     // Cope with angles > 180
00755     BOOL Mirror = FALSE;
00756     INT32 Angle = GFill->Angle;     // note angle is * 10
00757     
00758     if (Angle >= 1800)
00759     {
00760         Angle -= 1800;
00761         Mirror = TRUE;
00762     }
00763     else if (Angle < 00)
00764     {
00765         Angle += 1800;
00766         Mirror = TRUE;
00767     }
00768 
00769     Angle += 900;
00770 
00771     if (Angle >= 1800)
00772     {
00773         Angle -= 1800;
00774     }
00775 
00776     // get edge pad value
00777     INT32 EdgePad = GFill->Pad;
00778     
00779     // Calculate tan of the angle - convert angle to radians first.
00780     double Radians = (((double) Angle) / 1800.0) * PI;
00781     double TanTheta;
00782     if (Angle == 900)
00783     {
00784         // Special case for horizontal grad fill arrow.
00785 
00786         // Make 0% padding first
00787         Start.x = BBox.lo.x;
00788         Start.y = Centre.y;
00789         End.x = BBox.hi.x;
00790         End.y = Centre.y;
00791 
00792         // Find out width of padding
00793         INT32 Padding = (Width * EdgePad) / 100;
00794         Start.x += Padding;
00795         End.x -= Padding;
00796     }
00797     else if (Angle == 0)
00798     {
00799         // Special case for vertical grad fill arrow.
00800 
00801         // Make 0% padding first
00802         Start.x = Centre.x;
00803         Start.y = BBox.lo.y;
00804         End.x = Centre.x;
00805         End.y = BBox.hi.y;
00806 
00807         // Find out width of padding
00808         INT32 Padding = (Height * EdgePad) / 100;
00809         Start.y += Padding;
00810         End.y -= Padding;
00811     }
00812     else
00813     {
00814         TanTheta = tan(Radians);
00815 
00816         // Find out what the maximum padding is that we can achieve using just triangles:
00817 
00818         // Find the maximum triangle width
00819         MILLIPOINT TriWidth = (MILLIPOINT) ((double) Height / TanTheta);
00820 
00821         // Limit it to sensible value
00822         if (TriWidth < 0)
00823             TriWidth = -TriWidth;
00824         if (TriWidth > Width)
00825             TriWidth = Width;
00826 
00827         // Find the maximum triangle width
00828         MILLIPOINT TriHeight = (MILLIPOINT) ((double) Width * TanTheta);
00829 
00830         // Limit it to sensible value
00831         if (TriHeight < 0)
00832             TriHeight = -TriHeight;
00833         if (TriHeight > Height)
00834             TriHeight = Height;
00835 
00836         // The 'c' values of the y = mx+c equation.
00837         MILLIPOINT StartC, EndC;
00838 
00839         // Work out the maximum percentage/edge padding this gives us
00840         // (50 because it's 100 / 2 because we want area of triangle, not rectangle).
00841         double Percentage = (50.0 * (double) TriWidth * (double) TriHeight) / TotalArea;
00842 
00843         INT32 Diff = 0;
00844 
00845         // Is this enough?
00846         if (((INT32) Percentage) >= EdgePad)
00847         {
00848             // Yes - calculate exactly how big the triangle needs to be.
00849             TriHeight = (MILLIPOINT) sqrt(ABS(((double) EdgePad * TotalArea * TanTheta) / 100.0));
00850 
00851             TriWidth = (MILLIPOINT) ((double) TriHeight / TanTheta);
00852             if (TriWidth < 0)
00853                 TriWidth = -TriWidth;
00854 
00855             ENSURE(TriWidth < Width, "Error in Corel Grad fill decoding logic");
00856         }
00857         else
00858         {
00859             // How much percentage do we need to add with each rectangle?
00860             Percentage = (EdgePad - Percentage) / 2;
00861 
00862             // Handle the rectangle stuff.
00863             if (TriWidth == Width)
00864             {
00865                 // Need to add rectangles to the top and bottom.
00866                 Diff = (MILLIPOINT) ((Percentage * Height) / 100.0);
00867             }
00868             else
00869             {
00870                 // Need to add rectangles to left and right
00871                 Diff = (MILLIPOINT) ((Percentage * Width) / 100.0);
00872                 Diff = (MILLIPOINT) (Diff / tan(PI - Radians));
00873                 Diff = ABS(Diff);
00874             }
00875         }
00876 
00877         // Work out the C value for the start line (c = y - mx)
00878         // (m = tan(angle) )
00879         if (Angle == 900)
00880         {
00881             //ENSURE(FALSE, "90 degree angle found!");
00882         }
00883         else if (Angle < 900)
00884         {
00885             StartC = (MILLIPOINT) (BBox.lo.y - ((BBox.hi.x - TriWidth) * TanTheta));
00886             EndC = (MILLIPOINT) (BBox.hi.y - ((BBox.lo.x + TriWidth) * TanTheta));
00887         }
00888         else
00889         {
00890             StartC = (MILLIPOINT) (BBox.lo.y - ((BBox.lo.x + TriWidth) * TanTheta));
00891             EndC = (MILLIPOINT) (BBox.hi.y - ((BBox.hi.x - TriWidth) * TanTheta));
00892         }
00893 
00894         // Add on difference for rectangles, if any.
00895         StartC += Diff;
00896         EndC -= Diff;
00897 
00898 
00899         // Work out m and c for the grad fill line.
00900         // We know m is -1/m of the triangle's hypotenuse.
00901         // c = roy - (rox/m)
00902         double FillM = -1.00 / TanTheta;
00903         MILLIPOINT FillC = (MILLIPOINT) (Centre.y - (Centre.x * FillM));
00904 
00905         // Work out intersections:  x = (c2 - c1) / (2m)
00906 
00907         Start.x = (MILLIPOINT) ( (FillC - StartC) / (TanTheta + (1.00 / TanTheta)) );
00908         Start.y = (MILLIPOINT) ((FillM * Start.x) + FillC);
00909 
00910         End.x = (MILLIPOINT) ( (FillC - EndC) / (TanTheta + (1.00 / TanTheta)) );
00911         End.y = (MILLIPOINT) ((FillM * End.x) + FillC);
00912     }
00913 
00914     if (Mirror)
00915     {
00916         // Swap the grid fill end-points over.
00917         DocCoord Tmp = Start;
00918         Start = End;
00919         End = Tmp;
00920     }
00921 
00922     // Set the fill type according to these calculations.
00923     return SetLinearFill(*StartColour, *EndColour, Start, End); 
00924 }

BOOL CDRFilter::SetLineAttr cdrfOffsetHeader Object  )  [private]
 

Definition at line 129 of file cdroutl.cpp.

00130 {
00131     if(Version == CDRVERSION_3)
00132     {
00133         return SetLineAttr3(Object);
00134     }
00135         
00136     // find the reference...
00137     DWORD *pReference = (DWORD *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_LINE);
00138 
00139     // if the pointer to the reference is zero, then the reference is probably
00140     // within some random style definition
00141     if(pReference == 0)
00142     {
00143         // OK, try and find a style number within the style reference
00144         WORD *pStyleReference = (WORD *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_STYLE);
00145 
00146         if(pStyleReference != 0)
00147         {
00148             // OK, see if we can find a the style...
00149             cdrfStyle *pStyle;
00150             INT32 StyleSize;
00151 
00152             if((pStyle = (cdrfStyle *)Styles.Find(*pStyleReference, &StyleSize)) != 0)
00153             {
00154                 // OK, got a style... now find a fill reference within it
00155                 pReference = (DWORD *)FindDataInObject(&pStyle->Header, cdrfSTYLEOFFSETTYPE_OUTLINE);
00156             }
00157         }
00158     }
00159     
00160     cdrfOutline *Out;
00161     INT32 OutSize;
00162     
00163     if(pReference == 0 || (Out = (cdrfOutline *)Outlines.Find(*pReference, &OutSize)) == 0
00164             || OutSize < sizeof(cdrfOutline))
00165     {
00166         // if no outline data, or outline definitions couldn't be found, or outline
00167         // definition is too small, set up the default line attributes
00168         if(!SetLineWidth(cdrfOUTLINE_DEFAULT_WIDTH))
00169             return FALSE;
00170 
00171     PColourCMYK cmyk;
00172     cmyk.Cyan = cmyk.Magenta = cmyk.Yellow = 0;
00173     cmyk.Key = 255;
00174 
00175     DocColour Col;
00176     Col.SetCMYKValue(&cmyk);
00177     
00178         if(!SetLineColour(Col))
00179             return FALSE;
00180 
00181         return TRUE;
00182     }
00183 
00184     // check that this thingy should have an outline
00185     if((CDRDATA_WORD(Out->Flags) & cdrfOUTLINEFLAGS_NOOUTLINE) != 0)
00186     {
00187         if (!SetLineColour(DocColour(COLOUR_TRANS)))
00188             return FALSE;
00189 
00190         return TRUE;
00191     }
00192 
00193     // convert the line colour
00194     DocColour Col;
00195     ConvertColour(&Out->Colour, &Col);
00196 
00197     // find the line width
00198     INT32 LineWidth = CDRDATA_WORD(Out->LineThickness) * CDRCOORDS_TO_MILLIPOINTS;
00199 
00200     if(LineWidth > MAX_LINE_WIDTH)
00201         LineWidth = MAX_LINE_WIDTH;
00202     
00203     // find the join type
00204     JointType JType;
00205     switch(CDRDATA_WORD(Out->JoinStyle))
00206     {
00207         case cdrfJOINSTYLE_SQUARE:  JType = MitreJoin;      break;
00208         case cdrfJOINSTYLE_ROUNDED: JType = RoundJoin;      break;
00209         default:
00210         case cdrfJOINSTYLE_BEVEL:   JType = BevelledJoin;   break;
00211     }
00212     
00213     // set the cap style
00214     LineCapType CType;
00215     switch(CDRDATA_WORD(Out->EndStyle))
00216     {
00217         case cdrfENDSTYLE_BUTT:     CType = LineCapButt;    break;
00218         case cdrfENDSTYLE_ROUNDED:  CType = LineCapRound;   break;
00219         default:
00220         case cdrfENDSTYLE_SQUARE:   CType = LineCapSquare;  break;
00221 
00222     }
00223 
00224     // set the dash pattern
00225     DashRec Dash;
00226     DashElement DashArray[cdrfMAX_DASH_ELEMENTS];
00227     if(CDRDATA_WORD(Out->NDashSegments) > 0 && (CDRDATA_WORD(Out->Flags) & cdrfOUTLINEFLAGS_NODASH) == 0)
00228     {
00229         // set a dash pattern
00230         INT32 NSeg = CDRDATA_WORD(Out->NDashSegments);
00231         if(NSeg > cdrfMAX_DASH_ELEMENTS)
00232             NSeg = cdrfMAX_DASH_ELEMENTS;
00233 
00234         INT32 l;
00235         for(l = 0; l < NSeg; l++)
00236         {
00237             DashArray[l] = CDRDATA_WORD(Out->DashSegments[l]) * LineWidth;
00238         }
00239 
00240         Dash.Elements = NSeg;
00241         Dash.DashStart = 0;
00242         Dash.ElementData = DashArray;
00243 
00244         Dash.LineWidth = LineWidth;
00245         Dash.ScaleWithLineWidth = TRUE;
00246         Dash.DashID = -1;
00247     }
00248     else
00249     {
00250         // no dash pattern
00251         Dash = SD_SOLID;
00252     }
00253 
00254     // set the attributes
00255     if(!SetLineWidth(LineWidth) || !SetLineColour(Col) || !SetJoinType(JType)
00256             || !SetLineCap(CType) || !SetDashPattern(Dash))
00257         return FALSE;
00258 
00259     // check for arrowheads
00260     if(CDRDATA_DWORD(Out->StartArrowReference) != 0 || CDRDATA_DWORD(Out->EndArrowReference) != 0)
00261     {
00262         // apply the attributes to the object
00263         // If not filled, then set the ignore bit on the fill attribute.
00264         if (ObjFilled == FALSE)
00265             CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
00266 
00267         // Add attributes to the path, if they are different from the default...
00268         AttributeManager::ApplyBasedOnDefaults(pMadeNode, CurrentAttrs);
00269 
00270     //  DeleteCurrentAttrs();
00271     //  SetUpCurrentAttrs();
00272 
00273         // Enable the fill attribute again
00274         CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00275 
00276         // ensure that the attributes won't be applied again
00277         AttrsAlreadyApplied = TRUE;
00278 
00279         // apply arrow heads to the path
00280         AddArrowheadsToPath(CDRDATA_DWORD(Out->StartArrowReference), CDRDATA_DWORD(Out->EndArrowReference),
00281                 &Col, LineWidth, CType, JType);
00282     }
00283 
00284     return TRUE;
00285 }

BOOL CDRFilter::SetLineAttr3 cdrfOffsetHeader Object  )  [private]
 

Definition at line 303 of file cdroutl.cpp.

00304 {
00305     cdrfOutlineV3 *Out = (cdrfOutlineV3 *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_LINE);
00306     
00307     if(Out == 0)
00308     {
00309         // if no outline data, or outline definitions couldn't be found, or outline
00310         // definition is too small, set up the default line attributes
00311         if(!SetLineWidth(cdrfOUTLINE_DEFAULT_WIDTH))
00312             return FALSE;
00313 
00314         PColourCMYK cmyk;
00315         cmyk.Cyan = cmyk.Magenta = cmyk.Yellow = 0;
00316         cmyk.Key = 255;
00317 
00318         DocColour Col;
00319         Col.SetCMYKValue(&cmyk);
00320     
00321         if(!SetLineColour(Col))
00322             return FALSE;
00323 
00324         return TRUE;
00325     }
00326 
00327     // check that this thingy should have an outline
00328     if((Out->Flags & cdrfOUTLINEFLAGSV3_STROKED) == 0)
00329     {
00330         if (!SetLineColour(DocColour(COLOUR_TRANS)))
00331             return FALSE;
00332 
00333         return TRUE;
00334     }
00335 
00336     // convert the line colour
00337     DocColour Col;
00338     ConvertColour((cdrfColour *)&Out->Colour, &Col);
00339 
00340     // find the line width
00341     INT32 LineWidth = CDRDATA_WORD(Out->LineThickness) * CDRCOORDS_TO_MILLIPOINTS;
00342 
00343     if(LineWidth > MAX_LINE_WIDTH)
00344         LineWidth = MAX_LINE_WIDTH;
00345     
00346     // find the join type
00347     JointType JType;
00348     switch(CDRDATA_WORD(Out->JoinStyle))
00349     {
00350         case cdrfJOINSTYLE_SQUARE:  JType = MitreJoin;      break;
00351         case cdrfJOINSTYLE_ROUNDED: JType = RoundJoin;      break;
00352         default:
00353         case cdrfJOINSTYLE_BEVEL:   JType = BevelledJoin;   break;
00354     }
00355     
00356     // set the cap style
00357     LineCapType CType;
00358     switch(Out->EndStyle)  // byte
00359     {
00360         case cdrfENDSTYLE_BUTT:     CType = LineCapButt;    break;
00361         case cdrfENDSTYLE_ROUNDED:  CType = LineCapRound;   break;
00362         default:
00363         case cdrfENDSTYLE_SQUARE:   CType = LineCapSquare;  break;
00364 
00365     }
00366 
00367     // set the dash pattern
00368 /*  DashRec Dash;
00369     DashElement DashArray[cdrfMAX_DASH_ELEMENTS];
00370     if((ObjectFlagsV3 & cdrfOBJFLAGSV3_NODASH) == 0 && Out->NDashSegments > 0)      // byte
00371     {
00372         // set a dash pattern
00373         INT32 NSeg = CDRDATA_WORD(Out->NDashSegments);
00374         if(NSeg > cdrfMAX_DASH_ELEMENTS)
00375             NSeg = cdrfMAX_DASH_ELEMENTS;
00376 
00377         INT32 l;
00378         for(l = 0; l < NSeg; l++)
00379         {
00380             DashArray[l] = Out->DashSegments[l] * LineWidth;  // byte
00381         }
00382 
00383         Dash.Elements = NSeg;
00384         Dash.DashStart = 0;
00385         Dash.ElementData = DashArray;
00386 
00387         Dash.LineWidth = LineWidth;
00388         Dash.ScaleWithLineWidth = TRUE;
00389         Dash.DashID = -1;
00390     }
00391     else
00392     {
00393         // no dash pattern
00394         Dash = SD_SOLID;
00395     }
00396 */
00397     // set the attributes
00398     if(!SetLineWidth(LineWidth) || !SetLineColour(Col) || !SetJoinType(JType)
00399             || !SetLineCap(CType)/* || !SetDashPattern(Dash)*/)
00400         return FALSE;
00401 
00402     // check for arrowheads
00403     if(CDRDATA_DWORD(Out->StartArrowReference) != 0 || CDRDATA_DWORD(Out->EndArrowReference) != 0)
00404     {
00405         // apply the attributes to the object
00406         // If not filled, then set the ignore bit on the fill attribute.
00407         if (ObjFilled == FALSE)
00408             CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
00409 
00410         // Add attributes to the path, if they are different from the default...
00411         AttributeManager::ApplyBasedOnDefaults(pMadeNode, CurrentAttrs);
00412 
00413         // Enable the fill attribute again
00414         CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00415 
00416         // ensure that the attributes won't be applied again
00417         AttrsAlreadyApplied = TRUE;
00418 
00419         // apply arrow heads to the path
00420         AddArrowheadsToPath(CDRDATA_DWORD(Out->StartArrowReference), CDRDATA_DWORD(Out->EndArrowReference),
00421                 &Col, LineWidth, CType, JType);
00422     }
00423 
00424     return TRUE;
00425 }

BOOL CDRFilter::SetRadialGrad CDRFillInfo GFill,
DocRect BBox,
DocColour StartColour,
DocColour EndColour
[private]
 

sets a radial graduated fill from fill definition in the file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/04/95
Parameters:
grad fill defn and converted colours for the fill [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 1002 of file cdrfill.cpp.

01003 {
01004     // The desired start and end points of the grad fill 'arrow'.
01005     DocCoord Start, End;
01006 
01007     // Calculate width and height
01008     MILLIPOINT Width = BBox.Width();
01009     MILLIPOINT Height = BBox.Height();
01010 
01011     // caluculate the source area
01012     // first, what's the diagonal length
01013     double dWidth = Width;
01014     double dHeight = Height;
01015     INT32 Diagonal = (INT32)sqrt(dWidth*dWidth + dHeight*dHeight);
01016 
01017     // and from that calculate area of the box containing the bit of the
01018     // bit of the circle in the bbox
01019     INT32 Edge = (Diagonal * (100 - (GFill->Pad * 2))) / 100;
01020 
01021     // Start point is the centre given by Corel.
01022     // This centre is percentage offsets from the centre of the object, i.e. (0,0) is
01023     // the centre of the bounding box.
01024     DocCoord Centre = DocCoord(BBox.lo.x + (Width / 2), BBox.lo.y + (Height / 2));
01025     INT32 OffX = (GFill->HorizontalCentreOffset * Width) / 100;
01026     INT32 OffY = (GFill->VerticalCentreOffset * Height) / 100;
01027     Start.x = Centre.x + OffX;
01028     Start.y = Centre.y + OffY;
01029 
01030     // Find required radius of circle.
01031     double Radius = Edge / 2;
01032 
01033     // how far away is the centre of the fill from the centre of the bbox?
01034     double dOffX = OffX;
01035     double dOffY = OffY;
01036     double Dist = (INT32)sqrt(dOffX*dOffX + dOffY*dOffY);
01037 
01038     // and increase the radius by a bodge factor
01039     double BodgeFactor = 1 + (Dist / (double)(Diagonal / 2));
01040     Radius *= BodgeFactor;
01041     
01042     // End point is start point + radius
01043     End.x = Start.x + ((MILLIPOINT) Radius);
01044     End.y = Start.y;
01045 
01046     // Seems that we need to swap start and end colours...
01047 
01048     // Set the fill type according to these calculations.
01049     return SetRadialFill(*EndColour, *StartColour, Start, End); 
01050 }

BOOL CDRFilter::SetUKFill void   )  [private]
 

sets a fill attribute for unknown fills

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 03 95
Parameters:
pointer to fill header [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 617 of file cdrfill.cpp.

00618 {
00619     PColourCMYK cmyk;
00620     cmyk.Cyan = cmyk.Magenta = cmyk.Yellow = 0;
00621     cmyk.Key = 255;
00622 
00623     DocColour Col;
00624     Col.SetCMYKValue(&cmyk);
00625 
00626     return SetFillColour(Col);
00627 }

BOOL CDRFilter::TransformArrowhead NodeRenderableBounded N,
DocCoord Point,
DocCoord Other,
BOOL  Start,
INT32  LineWidth,
INT32  Distance
[private]
 

transform an arrowhead path to be the correct size and orientation

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
29 03 95
Parameters:
The path to transform, the This coordsinate (the coordinate to apply it to) and the [INPUTS] previous coordinate (the one before or after it), whether it's a start one or not and the line width and the distance to shift it from the arrow definition.
Returns:
error flag
See also:
Filter

Definition at line 559 of file cdroutl.cpp.

00561 {
00562     // first of all, work out how much we need to scale this thingy by
00563     double Scale = (double)LineWidth / (double)cdrfARROWHEAD_LINEWIDTH;
00564 
00565     // work out the adj and opp side of the triangle we're going to rotate around
00566     double Adj = (double)Point->x - (double)Other->x;
00567     double Opp = (double)Point->y - (double)Other->y;
00568     
00569     // work out the hyp of the triangle
00570     double Hyp = sqrt((Adj * Adj) + (Opp * Opp));
00571 
00572     // how far we need to move the arrowhead by
00573     double Move = Scale * (double)Distance;
00574 
00575     // calculate a matrix
00576     double a, b, c, d, e, f;
00577     if(Hyp == 0)
00578     {
00579         // default thing which shouldn't do too much hard - avoid div by zero
00580         a = Scale;
00581         b = 0;
00582         c = 0;
00583         d = Scale;
00584         e = Point->x + Move;
00585         f = Point->y;
00586     } else {
00587         double cosTheta = (Adj / Hyp);
00588         double sinTheta = (Opp / Hyp);
00589 
00590         a = Scale * cosTheta;
00591         b = Scale * sinTheta;
00592         c = 0 - (Scale * sinTheta);
00593         d = Scale * cosTheta;
00594         e = Point->x + (Move * cosTheta);
00595         f = Point->y + (Move * sinTheta);
00596     }
00597 
00598     // knock up a matrix
00599     Matrix M = Matrix(a, b, c, d, (INT32)e, (INT32)f);
00600 
00601     // need to flip it over?
00602     if(Start)
00603     {
00604         Matrix F = Matrix(1, 0, 0, -1, 0, 0);
00605 
00606         M = F * M;
00607     }
00608 
00609     // transform the node
00610     Trans2DMatrix Trans(M);
00611 
00612     N->Transform(Trans);
00613 
00614     return TRUE;
00615 }

BOOL CDRFilter::TransformConvertedObject NodeRenderable **  N,
ADDR  Trans,
INT32  Size,
BOOL  TranslateForPage = TRUE,
BOOL  IsAGroupTransform = FALSE,
BOOL  WorkAtOrigin = FALSE
[private]
 

transforms an object we converted, given a trfd chunk. If TranslateForPage is true (defaults to TRUE) then the object will also be translated to get the origin in the right place. The pointer may be modified to be a pointer to a different object. WorkAtOrigin causes the object to be translated back to the origin before being hacked apon, except if it's in a CDR3 file when it's ignored as the file is mass-translated at the end of the conversion..

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
25 03 95
Parameters:
the node to transform, and the trfd chunk to transform it by [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 3130 of file cdrfiltr.cpp.

03132 {
03133     if(IsText)
03134     {
03135         (*N)->OptimiseAttributes();
03136     }
03137 
03138     // make sure the WorkAtOrigin flag is set correctly - we mustn't use it if we're fiddling with a v3 file
03139     if(Version == CDRVERSION_3) WorkAtOrigin = FALSE;
03140 
03141     // transform it back to the origin if necessary
03142     if(WorkAtOrigin)
03143     {
03144         Trans2DMatrix Trans(-TranslateByX, -TranslateByY);
03145         (*N)->Transform(Trans);
03146     }
03147 
03148     // set up a transform conversion object
03149     CDRTransformConvertor *Conv;
03150 
03151     // putting the convertors here is probably more efficicent than allocating
03152     // a new one in the heap as they're not very big at all
03153     CDRTransformConvertor5 Conv5;
03154     CDRTransformConvertor4 Conv4;
03155     CDRTransformConvertor3 Conv3;
03156     
03157     switch(Version)
03158     {
03159         case CDRVERSION_5:  Conv = &Conv5;  break;
03160         case CDRVERSION_4:  Conv = &Conv4;  break;
03161         case CDRVERSION_3:  Conv = &Conv3;  break;
03162         default:            return FALSE;   break;
03163     }
03164 
03165     // initialise the convertor object
03166     Conv->Init(Trans, Size);
03167     
03168     // note that these elements are in Corel order
03169     cdrMatrix Ma, Mb, Mt;
03170     BOOL HaveMatrix = FALSE;
03171 
03172     BOOL ApplyMatrices = IsAGroupTransform?FALSE:TRUE;
03173 
03174 #ifdef CDR_DOEXTRUDE
03175     for(UINT32 g = 0; g < Conv->GetNTransforms(); g++)
03176     {
03177         CDRTransformType Type = Conv->GetTransformType(t);
03178 
03179         if(Type == CDRTRANSFORMTYPE_EXTRUDE)
03180             ApplyMatrices = FALSE;
03181     }
03182 #endif
03183 
03184 
03185     // apply all the transformations in the chunk
03186     for(UINT32 t = 0; t < Conv->GetNTransforms(); t++)
03187     {
03188         CDRTransformType Type = Conv->GetTransformType(t);
03189         
03190         // check that the transform is something we know about
03191         if(Type == CDRTRANSFORMTYPE_UNKNOWN)
03192             continue;
03193 
03194         // if it's a matrix, then append it to the previous one, if any
03195         if(Type == CDRTRANSFORMTYPE_MATRIX)
03196         {
03197             if(ApplyMatrices)
03198             {
03199                 if(HaveMatrix)
03200                 {
03201                     // done the first matrix, so we need get the matrix into another one and then combine.
03202             
03203                     // get the matrix
03204                     if(!Conv->GetMatrix(&Mb, t))
03205                         return FALSE;
03206 
03207                     // and combine it with the matrix we've already got
03208                     Mt.a = (Ma.a * Mb.a) + (Ma.d * Mb.b);
03209                     Mt.b = (Ma.b * Mb.a) + (Ma.e * Mb.b);
03210                     Mt.c = (Ma.c * Mb.a) + (Ma.f * Mb.b) + Mb.c;
03211                     Mt.d = (Ma.a * Mb.d) + (Ma.d * Mb.e);
03212                     Mt.e = (Ma.b * Mb.d) + (Ma.e * Mb.e);
03213                     Mt.f = (Ma.c * Mb.d) + (Ma.f * Mb.e) + Mb.f;
03214 
03215                     Ma = Mt;
03216                 } else {
03217                     // just get the matrix
03218                     if(!Conv->GetMatrix(&Ma, t))
03219                         return FALSE;
03220 
03221                     HaveMatrix = TRUE;
03222                 }
03223             }
03224         }
03225         else
03226         {
03227             // wasn't a matrix - apply a matrix if we've got one
03228             if(HaveMatrix)
03229             {
03230                 // apply it
03231                 if(!ApplyMatrices)
03232                 {
03233                     if(!TransformConvertedObjectDoMatrix(N, &Ma, FALSE))
03234                         return FALSE;
03235                 }
03236 
03237             }
03238         
03239             // unset the flag
03240             HaveMatrix = FALSE;
03241 
03242             // deal with the transformation
03243             ERROR3IF(Type == CDRTRANSFORMTYPE_MATRIX, "Matrix got through in TransformConvertedObject")
03244 
03245             switch(Type)
03246             {
03247                 case CDRTRANSFORMTYPE_PERSPECTIVE:
03248                     {
03249                         // convert the perpective
03250                         cdrPerspective P;
03251 
03252                         if(!Conv->GetPerspective(&P, t))
03253                             return FALSE;
03254 
03255                         // apply it to the object
03256                         if(!TransformConvertedObjectDoPerspective(N, &P, IsAGroupTransform))
03257                             return FALSE;
03258                     }
03259                     break;
03260 
03261                 case CDRTRANSFORMTYPE_ENVELOPE:
03262                     if(!(Version != CDRVERSION_3 && IsTextStory))       // text stories don't get enveloped - this is used as the frame shape
03263                     {
03264                         // convert the envelope into a path
03265                         DocRect OBBox;
03266                         Path *Shape = 0;
03267                         INT32 Corners[4];
03268 
03269                         if(Conv->GetEnvelope(&Shape, &OBBox, (INT32 *)&Corners, t))
03270                         {
03271                             // apply to object
03272                             if(!TransformConvertedObjectDoEnvelope(N, Shape, &OBBox, (INT32 *)&Corners, IsAGroupTransform))
03273                                 return FALSE;
03274 
03275                             // delete the shape
03276                             delete Shape;
03277                         }
03278                     }
03279                     break;
03280 
03281                 case CDRTRANSFORMTYPE_EXTRUDE:
03282                     {
03283                         cdrExtrudeInfo Info;
03284 
03285                         if(Conv->GetExtrude(&Info, t))
03286                         {
03287                             // apply to object
03288                             if(!TransformConvertedObjectDoExtrude(N, &Info, IsAGroupTransform))
03289                                 return FALSE;
03290                         }
03291                         ApplyMatrices = TRUE;       // start applying the matrices...
03292                     }
03293                     break;
03294  
03295                 default:
03296                     break;
03297             }
03298             
03299             if(Version == CDRVERSION_5)
03300             {
03301                 // we want to apply matrices from now on
03302                 ApplyMatrices = TRUE;
03303             }
03304         }
03305     }
03306 
03307     // if we've got a matrix still to do...
03308     if(HaveMatrix)
03309     {
03310         // apply it
03311         if(ApplyMatrices)
03312         {
03313             if(!TransformConvertedObjectDoMatrix(N, &Ma, TranslateForPage))
03314                 return FALSE;
03315         }
03316     }
03317     else if(!HaveMatrix && TranslateForPage)
03318     {
03319         // we need to apply an identity matrix which then gets translated, but only if we need to
03320         cdrMatrix Mi = {1, 0, 0, 0, 1, 0};
03321         
03322         // apply it
03323         if(!TransformConvertedObjectDoMatrix(N, &Mi, TranslateForPage))
03324             return FALSE;
03325     }
03326 
03327     // reverse the effect of the previous translation
03328     if(WorkAtOrigin)
03329     {
03330         Trans2DMatrix Trans(TranslateByX, TranslateByY);
03331         (*N)->Transform(Trans);
03332     }
03333 
03334     return TRUE;
03335 }

BOOL CDRFilter::TransformConvertedObjectDoEnvelope NodeRenderable **  N,
Path P,
DocRect pOriginalBBox,
INT32 *  Corners,
BOOL  TranslateShapeForPage = FALSE
[private]
 

transforms an object given a path to envelope into

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/05/95
Parameters:
the node to transform, and the trfd chunk to transform it by [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 3499 of file cdrfiltr.cpp.

03500 {
03501 TRACEUSER( "Ben", _T("applying envelope\n"));
03502 
03503     // create a mould parent and insert it in the tree
03504     NodeMould* pMouldParent = new NodeMould;
03505     if (pMouldParent == 0)
03506         return FALSE;
03507 
03508     // give the parent mould object a shape and mould space to work with and stick it
03509     // in the tree
03510     if(!pMouldParent->CreateGeometry(MOULDSPACE_ENVELOPE))
03511     {   
03512         delete pMouldParent;
03513         return FALSE;
03514     }
03515 
03516     // validate the path a bit, and get a good one if this is duff
03517     Path *Shape = P;
03518     UINT32 errID;
03519     if(pMouldParent->GetGeometry()->Validate(Shape,errID) == FALSE)
03520     {
03521         // OK, it's not suitiable so try to create an approximation which is
03522         Path *NewShape;
03523         if(!pMouldParent->GetGeometry()->MakeValidFrom(&NewShape, Shape, Corners))
03524         {
03525             // couldn't make a proper one, so return TRUE to ignore the moulding
03526             return TRUE;
03527         }
03528 
03529         Shape = NewShape;
03530 
03531         // inc count of approximated envelopes so the user can be warned later
03532         EnvelopesApproximated++;
03533     }
03534     
03535     // maybe translate it a bit
03536     DocRect OriginalBBox = *pOriginalBBox;
03537     if(TranslateShapeForPage)
03538     {
03539         Shape->Translate(TranslateByX, TranslateByY);
03540     
03541         OriginalBBox.Translate(TranslateByX, TranslateByY);
03542     }
03543 
03544     // Create and add a mould shape object
03545     NodeMouldPath* pNodeMPath = pMouldParent->AddNewMouldShape(Shape, 0, NULL);
03546     if (!pNodeMPath)
03547         return FALSE;
03548 
03549     // set the geometry using this new mould shape
03550     if(!pMouldParent->GetGeometry()->Define(&(pNodeMPath->InkPath), &OriginalBBox))
03551         return FALSE;
03552 
03553     // now create the mould group object
03554     NodeMouldGroup* pMouldGroup = pMouldParent->AddNewMouldGroup(NULL);
03555     if (!pMouldGroup)
03556         return FALSE;
03557 
03558     // and attach the node to the molder group
03559     (*N)->AttachNode((Node *) pMouldGroup, FIRSTCHILD, FALSE);
03560         
03561     // set the node to the converted one
03562     *N = pMouldParent;
03563 
03564     // delete any created paths
03565     if(Shape != P)
03566         delete Shape;
03567 
03568     return TRUE;
03569 }

BOOL CDRFilter::TransformConvertedObjectDoExtrude NodeRenderable **  N,
cdrExtrudeInfo Info,
BOOL  TranslateShapeForPage = FALSE
[private]
 

performs a extrude transform

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/01/96
Parameters:
node to transform, extrude info [INPUTS]
Returns:
error flag
See also:
CDRFilter

Definition at line 3586 of file cdrfiltr.cpp.

03587 {
03588     // the plan here is to create a new group, and slap the node onto it (it could possibly be
03589     // a group with lots of other stuff under it, but we won't worry about that for the moment)
03590     // Then, wander down the sub-tree attempting to convert all NodeRenderableInk object into
03591     // NodePaths. This will hopefully result in a load of object which can then be transformed
03592 
03593     // first, get one of them there group thingynesseses.
03594     NodeGroup *pTempGroup = new NodeGroup;
03595     if(pTempGroup == 0)
03596         return FALSE;       // no room, oh dear.
03597 
03598     // now attach the thing to it. It isn't attached to anything, so it's easy.
03599     (*N)->AttachNode(pTempGroup, FIRSTCHILD);
03600 
03601     // scan the tree converting non-NodePaths to NodePaths where possible
03602     BecomeA ParamBecomeA(BECOMEA_REPLACE, 
03603                              CC_RUNTIME_CLASS(NodePath),
03604                              NULL);
03605 
03606     // find the first node to think about
03607     Node* Current = (*N); 
03608     while (Current->FindFirstChild() != NULL && !(Current->FindFirstChild())->IsKindOf(CC_RUNTIME_CLASS(TextStory))) 
03609     {
03610         Current = Current->FindFirstChild(); 
03611     }  
03612 
03613     // check each renderable node for not being a path
03614     while(Current != 0)
03615     {
03616         if(Current->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)) && !Current->IsKindOf(CC_RUNTIME_CLASS(NodePath)))
03617         {
03618             if (Current->CanBecomeA(&ParamBecomeA))
03619             {
03620                 // is it a text story?
03621                 if (Current->IsKindOf(CC_RUNTIME_CLASS(TextStory)))
03622                 {
03623                     // give formatting it a go
03624                     ((TextStory *)Current)->FormatAndChildren();
03625                 }
03626                 
03627                 if (!(Current)->DoBecomeA(&ParamBecomeA))
03628                 {
03629                     return FALSE;
03630                 }
03631             }
03632         }
03633 
03634         // get the next one
03635         Current = Current->FindNextDepthFirst(*N);
03636     }
03637 
03638     // now wander through the tree doing the funky transform - find the first one again
03639     Current = pTempGroup; 
03640     while (Current->FindFirstChild() != NULL) 
03641     {
03642         Current = Current->FindFirstChild(); 
03643     }  
03644 
03645     // transform each NodePath
03646     while(Current != 0)
03647     {
03648         if(IS_A(Current, NodePath))
03649         {
03650             if(!TransformConvertedObjectDoExtrudeTransPath((NodePath *)Current, Info))
03651                 return FALSE;       // something very wrong happened
03652         }
03653 
03654         // get the next one
03655         Current = Current->FindNextDepthFirst(pTempGroup);
03656     }
03657 
03658     // update the *N pointer to the node
03659     (*N) = (NodeRenderable *)pTempGroup->FindFirstChild();
03660     ERROR2IF((*N) == 0, FALSE, "Oi! there that node just vanished");
03661     ERROR2IF(!(*N)->IsKindOf(CC_RUNTIME_CLASS(NodeRenderable)), FALSE, "Oh! Mr. Node changing into something non-renderable");
03662 
03663     // remove it from the group
03664     (*N)->UnlinkNodeFromTree();
03665 
03666     // finally, vape that temperary group
03667     delete pTempGroup;
03668     
03669     return TRUE;
03670 }

BOOL CDRFilter::TransformConvertedObjectDoExtrudeTransPath NodePath pPath,
cdrExtrudeInfo Info
[private]
 

does the extrude transform on a path

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/01/96
Parameters:
path to transform, info about the transform [INPUTS]
Returns:
error flag
See also:
CDRFilter

Definition at line 3685 of file cdrfiltr.cpp.

03686 {
03687     // check the inputs
03688     ERROR2IF(pPath == 0 || Info == 0, FALSE, "Null something supplied where a raspberry is required");
03689     ERROR2IF(!IS_A(pPath, NodePath), FALSE, "Oi! I asked for a NodePath you silly person");
03690 
03691     // get some useful info about that there path
03692     DocCoord *Coords = pPath->InkPath.GetCoordArray();
03693     ERROR2IF(Coords == 0, FALSE, "Hmmm. I think that path is a bit of a dodgy one really");
03694     INT32 NCoords = pPath->InkPath.GetNumCoords();
03695 
03696     // mild sanity check...
03697     if(Info->Camera.z == 0)
03698         return TRUE;            // don't try this one at home, kiddies
03699 
03700     // prepare a few handy values
03701     FLOAT8 projA = - Info->Camera.x / Info->Camera.z;
03702     FLOAT8 projB = - Info->Camera.y / Info->Camera.z;
03703     FLOAT8 projC = - 1 / Info->Camera.z;
03704 
03705     // run through that path transforming all those lovely cheeky little coordinates
03706     for(INT32 c = 0; c < NCoords; c++)
03707     {
03708         FLOAT8 x = (FLOAT8)Coords[c].x, y = (FLOAT8)Coords[c].y;
03709 
03710         FLOAT8 alpha =  x * Info->Trans.cf11 + y * Info->Trans.cf21 + Info->Trans.cf41;
03711         FLOAT8 beta =   x * Info->Trans.cf12 + y * Info->Trans.cf22 + Info->Trans.cf42;
03712         FLOAT8 gamma =  x * Info->Trans.cf13 + y * Info->Trans.cf23 + Info->Trans.cf43;
03713 
03714         FLOAT8 norm =   gamma * projC + 1;
03715 
03716         Coords[c].x = (INT32)((alpha + gamma * projA) / norm);
03717         Coords[c].y = (INT32)((beta  + gamma * projB) / norm);
03718     }
03719 
03720     // well, wasn't that squishy?
03721     return TRUE;
03722 }

BOOL CDRFilter::TransformConvertedObjectDoMatrix NodeRenderable **  N,
cdrMatrix Ma,
BOOL  TranslateForPage
[private]
 

transforms an object given a CDR matrix

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/05/95
Parameters:
the node to transform, and the trfd chunk to transform it by [INPUTS]
Returns:
error flag
See also:
Filter

Definition at line 3350 of file cdrfiltr.cpp.

03351 {
03352     // make a camelot matrix
03353     Matrix M(Ma->a, Ma->d, Ma->b, Ma->e, (INT32)Ma->c + (TranslateForPage?TranslateByX:0),
03354             (INT32)Ma->f + (TranslateForPage?TranslateByY:0));
03355 
03356     // if it's a text story node, then it needs to be dealt with differently, and it's got
03357     // an associated bounding box which need transforming
03358     if(IS_A(*N, TextStory))
03359     {       
03360         // find it's bounding box
03361         DocRect *BBox = TextBBoxes.Find(*N);
03362 
03363         // transform it with the unmodifed matrix
03364         Trans2DMatrix TTransform(M);
03365         if(BBox != 0)
03366             TTransform.GetMatrix().TransformBounds(BBox);
03367 
03368         // if it's a text story, not just an artisitic text then don't scale it, but scale the import width
03369         if(IsTextStory)
03370         {
03371             // work out the scale factors along the axes
03372             double ScaleX = sqrt((Ma->a * Ma->a) + (Ma->b * Ma->b));
03373             double ScaleY = sqrt((Ma->d * Ma->d) + (Ma->e * Ma->e));
03374             
03375             // knock up a new matrix which isn't scaled along these axes
03376             M = Matrix(Ma->a / ScaleX, Ma->d / ScaleY, Ma->b / ScaleX, Ma->e / ScaleY,
03377                     (INT32)Ma->c + (TranslateForPage?TranslateByX:0),
03378                     (INT32)Ma->f + (TranslateForPage?TranslateByY:0));
03379         
03380             // get the import format width scaled nicely
03381             TextStory *TSNode = (TextStory *)(*N);
03382             double Width = ((double)TSNode->GetImportFormatWidth()) * ScaleX;
03383             TSNode->SetImportFormatWidth((INT32)Width);
03384         }
03385     }
03386     
03387     // transform the node
03388     Trans2DMatrix Transform(M);
03389     (*N)->Transform(Transform);
03390 
03391     return TRUE;
03392 }

BOOL CDRFilter::TransformConvertedObjectDoPerspective NodeRenderable **  N,
cdrPerspective P,
BOOL  TranslateShapeForPage = FALSE
[private]
 

Definition at line 3412 of file cdrfiltr.cpp.

03413 {
03414 TRACEUSER( "Ben", _T("applying perspective\n"));
03415 
03416     // create a mould parent and insert it in the tree
03417     NodeMould* pMouldParent = new NodeMould;
03418     if (pMouldParent == 0)
03419         return FALSE;
03420 
03421     // give the parent mould object a shape and mould space to work with and stick it
03422     // in the tree
03423     if(!pMouldParent->CreateGeometry(MOULDSPACE_PERSPECTIVE))
03424     {   
03425         delete pMouldParent;
03426         return FALSE;
03427     }
03428 
03429     // create a nice shape to mould into
03430     NodePath *pShape = new NodePath;
03431     if(pShape == 0 || (!pShape->SetUpPath()))
03432     {   
03433         delete pMouldParent;
03434         return FALSE;
03435     }
03436 
03437     // position the new elements at the beginning of the path
03438     pShape->InkPath.FindStartOfPath();
03439 
03440     // make a nice shape out of the corners
03441     DocCoord co;
03442     PERS_MOVE(P->NewCorners[0])
03443     PERS_LINE(P->NewCorners[1])
03444     PERS_LINE(P->NewCorners[2])
03445     PERS_LINE(P->NewCorners[3])
03446     PERS_LINE(P->NewCorners[0])
03447     PERS_CLOSE
03448 
03449     // maybe translate it a bit
03450     DocRect OriginalBBox = P->OriginalBBox;
03451     if(TranslateShapeForPage)
03452     {
03453         Trans2DMatrix Transform(Matrix(TranslateByX, TranslateByY));
03454         pShape->Transform(Transform);
03455     
03456         OriginalBBox.Translate(TranslateByX, TranslateByY);
03457     }
03458 
03459     // Create and add a mould shape object
03460     NodeMouldPath* pNodeMPath = pMouldParent->AddNewMouldShape(&pShape->InkPath, 0, NULL);
03461     if (!pNodeMPath)
03462         return FALSE;
03463 
03464     // set the geometry using this new mould shape
03465     if(!pMouldParent->GetGeometry()->Define(&(pNodeMPath->InkPath), &OriginalBBox))
03466         return FALSE;
03467 
03468     // now create the mould group object
03469     NodeMouldGroup* pMouldGroup = pMouldParent->AddNewMouldGroup(NULL);
03470     if (!pMouldGroup)
03471         return FALSE;
03472 
03473     // and attach the node to the molder group
03474     (*N)->AttachNode((Node *) pMouldGroup, FIRSTCHILD, FALSE);
03475         
03476     // set the node to the converted one
03477     *N = pMouldParent;
03478 
03479     // delete the shape
03480     delete pShape;
03481 
03482     return TRUE;
03483 }

BOOL CDRFilter::UpdateProgress BOOL  Now = FALSE  )  [private]
 

Updating the progress everysooften - called at every significant place to get a nice smooth update on that progress bar thingy.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
22 03 95
Parameters:
None [INPUTS]
Returns:
None
See also:
Filter

Definition at line 194 of file cdrfiltr.cpp.

00195 {
00196     BOOL Result = TRUE;
00197     
00198     if(Now)
00199     {
00200         Result = ContinueSlowJob(RIFF->ProgressNow());
00201         ProgressCount = 0;
00202     }
00203     else
00204     {
00205         if((ProgressCount & PROGRESSUPDATE_MASK) == 0) {
00206             Result = ContinueSlowJob(RIFF->ProgressNow());
00207         }
00208 
00209         ProgressCount++;
00210     }
00211 
00212     if(!Result)
00213     {
00214         Error::ClearError();        // because this may not be handled the first time around
00215         Error::SetError(_R(IDN_USER_CANCELLED));
00216     }
00217     
00218     return Result;
00219 }


Member Data Documentation

CDRActionList CDRFilter::Actions [private]
 

Definition at line 834 of file cdrfiltr.h.

CDRArrowheadStore CDRFilter::Arrowheads [private]
 

Definition at line 822 of file cdrfiltr.h.

BOOL CDRFilter::AttrsAlreadyApplied [private]
 

Definition at line 865 of file cdrfiltr.h.

INT32 CDRFilter::BitmapNumber = 0 [static]
 

Definition at line 790 of file cdrfiltr.h.

CDRBitmapStore CDRFilter::Bitmaps [private]
 

Definition at line 825 of file cdrfiltr.h.

friend CDRFilter::CDRActionGroupEnd [private]
 

Definition at line 767 of file cdrfiltr.h.

friend CDRFilter::CDRActionTransform [private]
 

Definition at line 766 of file cdrfiltr.h.

friend CDRFilter::CDRBitmap [private]
 

Definition at line 769 of file cdrfiltr.h.

friend CDRFilter::CDRBitmapStore [private]
 

Definition at line 768 of file cdrfiltr.h.

ColourList* CDRFilter::ColList [private]
 

Definition at line 870 of file cdrfiltr.h.

BOOL CDRFilter::DoneDoc [private]
 

Definition at line 814 of file cdrfiltr.h.

BOOL CDRFilter::DoneMasterPage [private]
 

Definition at line 812 of file cdrfiltr.h.

INT32 CDRFilter::EnvelopesApproximated [private]
 

Definition at line 850 of file cdrfiltr.h.

CDRAttributeStore CDRFilter::Fills [private]
 

Definition at line 818 of file cdrfiltr.h.

CDRFontnameStore CDRFilter::Fonts [private]
 

Definition at line 821 of file cdrfiltr.h.

ADDR CDRFilter::FontStylesV3 [private]
 

Definition at line 877 of file cdrfiltr.h.

INT32 CDRFilter::FontTableEntriesV3 [private]
 

Definition at line 876 of file cdrfiltr.h.

ADDR CDRFilter::FontTableV3 [private]
 

Definition at line 875 of file cdrfiltr.h.

BOOL CDRFilter::FormatError [private]
 

Definition at line 852 of file cdrfiltr.h.

BOOL CDRFilter::InMasterPage [private]
 

Definition at line 811 of file cdrfiltr.h.

BOOL CDRFilter::IsText [private]
 

Definition at line 862 of file cdrfiltr.h.

BOOL CDRFilter::IsTextOnAPath [private]
 

Definition at line 884 of file cdrfiltr.h.

BOOL CDRFilter::IsTextStory [private]
 

Definition at line 863 of file cdrfiltr.h.

BOOL CDRFilter::Landscape [private]
 

Definition at line 840 of file cdrfiltr.h.

ADDR CDRFilter::LinkTable [private]
 

Definition at line 879 of file cdrfiltr.h.

BOOL CDRFilter::LinkTransformsExist [private]
 

Definition at line 881 of file cdrfiltr.h.

ADDR CDRFilter::ObjDataBlock [private]
 

Definition at line 867 of file cdrfiltr.h.

INT32 CDRFilter::ObjDataBlockSize [private]
 

Definition at line 868 of file cdrfiltr.h.

INT32 CDRFilter::ObjectsConverted [private]
 

Definition at line 847 of file cdrfiltr.h.

INT32 CDRFilter::ObjectsFormatWrong [private]
 

Definition at line 848 of file cdrfiltr.h.

INT32 CDRFilter::ObjectsUnknown [private]
 

Definition at line 849 of file cdrfiltr.h.

BOOL CDRFilter::ObjFilled [private]
 

Definition at line 859 of file cdrfiltr.h.

BOOL CDRFilter::ObjStroked [private]
 

Definition at line 860 of file cdrfiltr.h.

DocCoord CDRFilter::Origin [private]
 

Definition at line 842 of file cdrfiltr.h.

CDRAttributeStore CDRFilter::Outlines [private]
 

Definition at line 819 of file cdrfiltr.h.

CDRPageList CDRFilter::Pages [private]
 

Definition at line 830 of file cdrfiltr.h.

INT32 CDRFilter::PageX [private]
 

Definition at line 838 of file cdrfiltr.h.

INT32 CDRFilter::PageY [private]
 

Definition at line 839 of file cdrfiltr.h.

INT32 CDRFilter::PatternNumber = 0 [static]
 

Definition at line 791 of file cdrfiltr.h.

CDRBitmapStore CDRFilter::Patterns [private]
 

Definition at line 824 of file cdrfiltr.h.

class Document* CDRFilter::pDocument [private]
 

Definition at line 798 of file cdrfiltr.h.

NodeRenderable* CDRFilter::pLevelNodeList [private]
 

Definition at line 854 of file cdrfiltr.h.

NodeRenderable* CDRFilter::pMadeNode [private]
 

Definition at line 855 of file cdrfiltr.h.

class Page* CDRFilter::pPage [private]
 

Definition at line 800 of file cdrfiltr.h.

UINT32 CDRFilter::ProgressCount [private]
 

Definition at line 809 of file cdrfiltr.h.

class Spread* CDRFilter::pSpread [private]
 

Definition at line 799 of file cdrfiltr.h.

RIFFFile* CDRFilter::RIFF [private]
 

Definition at line 805 of file cdrfiltr.h.

INT32 CDRFilter::SerialNumber [private]
 

Definition at line 857 of file cdrfiltr.h.

BOOL CDRFilter::SlowJobStarted [private]
 

Definition at line 808 of file cdrfiltr.h.

CDRAttributeStore CDRFilter::Styles [private]
 

Definition at line 820 of file cdrfiltr.h.

BOOL CDRFilter::Success [private]
 

Definition at line 803 of file cdrfiltr.h.

CDRBBoxList CDRFilter::TextBBoxes [private]
 

Definition at line 836 of file cdrfiltr.h.

List CDRFilter::TextOnPathLinks [private]
 

Definition at line 883 of file cdrfiltr.h.

CDRVectorStore CDRFilter::TextV4 [private]
 

Definition at line 828 of file cdrfiltr.h.

CDRLayerListItem* CDRFilter::ThisLayer [private]
 

Definition at line 832 of file cdrfiltr.h.

UndoableOperation* CDRFilter::ThisOp [private]
 

Definition at line 806 of file cdrfiltr.h.

CDRPageListItem* CDRFilter::ThisPage [private]
 

Definition at line 831 of file cdrfiltr.h.

ADDR CDRFilter::TransformChunk [private]
 

Definition at line 872 of file cdrfiltr.h.

INT32 CDRFilter::TransformChunkSize [private]
 

Definition at line 873 of file cdrfiltr.h.

INT32 CDRFilter::TranslateByX [private]
 

Definition at line 844 of file cdrfiltr.h.

INT32 CDRFilter::TranslateByY [private]
 

Definition at line 845 of file cdrfiltr.h.

BOOL CDRFilter::UseLayers [private]
 

Definition at line 816 of file cdrfiltr.h.

CDRVectorStore CDRFilter::Vectors [private]
 

Definition at line 826 of file cdrfiltr.h.

CDRVersion CDRFilter::Version [private]
 

Definition at line 802 of file cdrfiltr.h.


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