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 }