cmxicmds.cpp

Go to the documentation of this file.
00001 // $Id: cmxicmds.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // handles CMX commands
00099 
00100 #include "camtypes.h"
00101 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00102 #include "riffform.h"
00103 #include "progress.h"
00104 #include "nodepath.h"
00105 #include "nodebmp.h"
00106 #include "nodershp.h"
00107 
00108 #include "cmxifltr.h"
00109 #include "cmxistut.h"
00110 #include "cmxidata.h"
00111 #include "cmxibits.h"
00112 #include "cmxibitm.h"
00113 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 #include "riffform.h"
00115 #include "progress.h"
00116 #include "nodepath.h"
00117 //#include "nev.h"
00118 
00119 #include "nodetxts.h"
00120 #include "unicdman.h"
00121 #include "nodetxtl.h"
00122 
00123 
00124 /********************************************************************************************
00125 
00126 >   BOOL CMXImportFilter::Stage4_ConvertPage(void)
00127 
00128     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00129     Created:    07/08/96
00130     Inputs:     None
00131     Returns:    error flag
00132     Purpose:    Goes through the page processing the commands.
00133 
00134 ********************************************************************************************/
00135 
00136 BOOL CMXImportFilter::Stage4_ConvertPage(void)
00137 {
00138     TRACEUSER( "Ben", _T("Stage4_ConvertPage\n"));
00139     // plan here -- read the index entries to find the start of the page,
00140     // wander over to the right position in the file and start processing
00141     // we simply loop around calling the process command function, and
00142     // sorting out the progress thingy. Admittedly, this does mean that
00143     // during the loading of the description sections you'll just get a
00144     // zero progress count. Oh well, c'est la vie.
00145 
00146     // find the page index, and grab the first page in it
00147     if(Data->MasterIndexEntries[cmxMASTERIN_PAGE] == 0)
00148         CMXFORMATERROR(FALSE)
00149 
00150     TRACEUSER( "Ben", _T("index page at %d?\n"), Data->MasterIndexEntries[cmxMASTERIN_PAGE]);
00151     Seek(Data->MasterIndexEntries[cmxMASTERIN_PAGE]);
00152     RIFFck chdr;
00153     pFile->read(&chdr, sizeof(chdr));
00154     if(chdr.ckID != cmxRIFFCI_PageIndex)
00155         CMXFORMATERROR(FALSE)
00156 
00157     // get the index header
00158     CI_READDATA(SimpleIndexHeader, ih)
00159     if(ih.RecordCount < 1)
00160         CMXFORMATERROR(FALSE)
00161 
00162     // get the first index entry
00163     CI_READDATA(PageIndexEntry, ie)
00164     TRACEUSER( "Ben", _T("Page is at %d\n"), ie.PageOffset);
00165 
00166     // seek to that position, and check the riff header
00167     Seek(ie.PageOffset);
00168     pFile->read(&chdr, sizeof(chdr));
00169     if(chdr.ckID != cmxRIFFCI_Page)
00170         CMXFORMATERROR(FALSE)               // didn't get one of those page things there. Oh dear...
00171 
00172     // set the end position of the page
00173     INT32 PageEndFileLoc = Tell() + chdr.ckSize;
00174     Data->InPage = TRUE;
00175 
00176     // progress system stuff
00177     INT32 wobble = 0;
00178 
00179     // run through the loop... what follows is a load of instructions
00180     TRACEUSER( "Ben", _T("processing commands:\n"));
00181     while(Data->InPage == TRUE)
00182     {
00183         // process a command
00184         if(!ProcessCommand(&wobble))
00185             return FALSE;                   // error
00186 
00187         // check to see if we've over run the page...
00188         if(Tell() >= PageEndFileLoc)
00189             Data->InPage = FALSE;
00190 
00191         // progress system
00192         if(Data->CommandsInPage != -1)
00193         {
00194             wobble++;
00195             if(!Data->pProgress->Update(wobble))
00196             { 
00197 TRACEUSER( "claude", _T("User Escaped!\n"));
00198                 Error::SetError(_R(IDN_CMXCANCELIMPORT));
00199             //TRACEUSER( "claude", _T("after SetError()\n"));
00200                 //InformError(_R(IDN_CMXCANCELIMPORT));//_R(IDN_USER_CANCELLED));//Error::GetErrorNumber());
00201             TRACEUSER( "claude", _T("after InformError()\n"));
00202                 return FALSE;       // user pressed escape... abort abort!
00203             }
00204         }
00205     }
00206     TRACEUSER( "Ben", _T("finished processing commands\n"));
00207 TRACEUSER( "claude", _T("finished processing commands\n"));
00208     // that's it, chaps
00209     return TRUE;
00210 }
00211 
00212 
00213 /********************************************************************************************
00214 
00215 >   BOOL CMXImportFilter::Stage5_ConvertPage(void)
00216 
00217     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00218     Created:    08/08/96
00219     Inputs:     None
00220     Returns:    error flag
00221     Purpose:    process a CMX command -- mainly a dispatch function
00222 
00223 ********************************************************************************************/
00224 
00225 #define PC_DISPATCH(instr)  case cmxINSTR_##instr: \
00226                             TRACEUSER( "Ben", _T(" * " #instr "\n")); \
00227                             TRACEUSER( "Claude", _T(" * " #instr "\n")); \
00228                             if(!Process_##instr()) return FALSE; break;
00229 #define NEEDLAYER           {if(Data->pCurrentLayer == NULL) {TRACEUSER( "Ben", _T("no layer\n")); \
00230                             CMXFORMATERROR(FALSE)}}
00231 
00232 BOOL CMXImportFilter::ProcessCommand(INT32 *ProgressThingy)
00233 {
00234     // get the current file position
00235     INT32 CommandEndFilePos = Tell();
00236 
00237     // read the command header
00238     CI_READDATA(CommandHeader, ch)
00239 
00240     // if the command thing is negative, we may need to fudge it if we're going 16 bitness
00241     if(ch.Code < 0 && !Is32Bit)
00242         ch.Code = 0 - ch.Code;
00243 
00244     CommandEndFilePos += ch.Size;           // get the file pos of the end of the instruction
00245 
00246     // dispatch it to the relevant function
00247     switch(ch.Code)
00248     {
00249     PC_DISPATCH(BeginPage)
00250     PC_DISPATCH(EndPage)
00251     PC_DISPATCH(BeginLayer)
00252     PC_DISPATCH(EndLayer)
00253     PC_DISPATCH(BeginGroup)
00254     PC_DISPATCH(EndGroup)
00255     PC_DISPATCH(EndSection)
00256     PC_DISPATCH(PolyCurve)
00257     PC_DISPATCH(Rectangle)                      // Graeme ( 1-2-00 ).
00258     PC_DISPATCH(AddGlobalTransform)
00259     PC_DISPATCH(SetGlobalTransform)
00260     PC_DISPATCH(RestoreLastGlobalTransform)
00261     PC_DISPATCH(DrawImage)
00262     PC_DISPATCH(AddClippingRegion)
00263     PC_DISPATCH(RemoveLastClippingRegion)
00264     PC_DISPATCH(ClearClipping)
00265     PC_DISPATCH(BeginTextStream)
00266     PC_DISPATCH(TextFrame)
00267     PC_DISPATCH(Characters)
00268     PC_DISPATCH(CharInfo)
00269     PC_DISPATCH(BeginParagraph)
00270     PC_DISPATCH(EndParagraph)
00271     PC_DISPATCH(EndTextStream)
00272     
00273 
00274     case cmxINSTR_JumpAbsolute:
00275         {
00276             CI_READDATA(JumpAbsolute, ja)
00277             TRACEUSER( "Ben", _T(" * JumpAbsolute to %d\n"), ja.Offset);
00278             TRACEUSER( "Claude", _T(" * JumpAbsolute to %d\n"), ja.Offset);
00279             // got a jump absolute thingy -- alter the next thing to skip over something
00280             // silly that Corel's lovely amazingly neat method of storing stuff in a
00281             // file has stuck in our way
00282             CommandEndFilePos = ja.Offset;      // make us seek there later
00283             // JumpAbsolutes aren't counted as instructions, for some reason
00284             if(ProgressThingy != NULL)
00285                 (*ProgressThingy)--;
00286         }
00287         break;
00288 
00289     default:
00290         // don't understand this command, don't need to do anything special here
00291         TRACEUSER( "Ben", _T(" * <<unknown command>>\n"));
00292         TRACEUSER( "Claude", _T(" * <<unknown command>>\n"));
00293         TRACEUSER( "Graeme", _T(" * <<unknown command>>\n"));
00294         break;
00295     }
00296 
00297     // finally, check that we're in the right position in the file for the next command
00298     if(Tell() != CommandEndFilePos)
00299         Seek(CommandEndFilePos);
00300 
00301     return TRUE;
00302 }
00303 
00304 /********************************************************************************************
00305 
00306 >   BOOL CMXImportFilter::Process_EndPage(void)
00307 
00308     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00309     Created:    08/08/96
00310     Inputs:     None
00311     Returns:    error flag
00312     Purpose:    process a EndPage command
00313 
00314 ********************************************************************************************/
00315 
00316 BOOL CMXImportFilter::Process_EndPage(void)
00317 {
00318     // stop it. Stop it now. I mean it, stop processing that page right now
00319     // or I set the killer carrot on you, and you wouldn't want that, would you?
00320     Data->InPage = FALSE;
00321 
00322     return TRUE;
00323 }
00324 
00325 
00326 /********************************************************************************************
00327 
00328 >   BOOL CMXImportFilter::Process_BeginPage(void)
00329 
00330     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00331     Created:    08/08/96
00332     Inputs:     None
00333     Returns:    error flag
00334     Purpose:    process a BeginPage command
00335 
00336 ********************************************************************************************/
00337 
00338 BOOL CMXImportFilter::Process_BeginPage(void)
00339 {
00340     // read the begin page structure from the file
00341     CI_READDATA(BeginPage, bp)
00342 
00343     // set progress system up (again)
00344     Data->CommandsInPage = bp.InstructionCount;
00345     if(Data->pProgress != NULL)
00346     {
00347         delete Data->pProgress;
00348         Data->pProgress = NULL;
00349     }
00350     Data->pProgress = new Progress(_R(IDT_CMX_IMPORTMSG), Data->CommandsInPage, FALSE);
00351     if(Data->pProgress == NULL)
00352         return FALSE;
00353 
00354     return TRUE;
00355 }
00356 
00357 
00358 /********************************************************************************************
00359 
00360 >   BOOL CMXImportFilter::Process_EndLayer(void)
00361 
00362     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00363     Created:    09/08/96
00364     Inputs:     None
00365     Returns:    error flag
00366     Purpose:    process a EndLayer command
00367 
00368 ********************************************************************************************/
00369 
00370 BOOL CMXImportFilter::Process_EndLayer(void)
00371 {
00372     if(Data->pCurrentLayer == NULL) // then we weren't doing a layer
00373         CMXFORMATERROR(FALSE)
00374 
00375     // mark as not doing a layer
00376     Data->pCurrentLayer = NULL;
00377     
00378     return TRUE;
00379 }
00380 
00381 
00382 /********************************************************************************************
00383 
00384 >   BOOL CMXImportFilter::Process_BeginLayer(void)
00385 
00386     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00387     Created:    09/08/96
00388     Inputs:     None
00389     Returns:    error flag
00390     Purpose:    process a BeginLayer command
00391 
00392 ********************************************************************************************/
00393 
00394 BOOL CMXImportFilter::Process_BeginLayer(void)
00395 {
00396     if(Data->pCurrentLayer != NULL) // already doing a layer
00397         CMXFORMATERROR(FALSE)
00398 
00399     // read the data from the file
00400     CI_READDATA(BeginLayer, bl)
00401     TRACEUSER( "Ben", _T("   layer name = %s\n"), (TCHAR *)(*bl.pLayerName));
00402 
00403     // create a new layer object
00404     Data->pCurrentLayer = new CMXImportLayer;
00405     if(Data->pCurrentLayer == NULL)
00406         return FALSE;
00407 
00408     // add the layer to the list
00409     Data->Layers.AddTail(Data->pCurrentLayer);
00410 
00411     // set the name of the layer
00412     Data->pCurrentLayer->SetName(bl.pLayerName);
00413 
00414     // clear up
00415     delete bl.pLayerName;
00416 
00417     return TRUE;
00418 }
00419 
00420 
00421 /********************************************************************************************
00422 
00423 >   BOOL CMXImportFilter::Process_BeginGroup(void)
00424 
00425     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00426     Created:    09/08/96
00427     Inputs:     None
00428     Returns:    error flag
00429     Purpose:    process a BeginGroup command
00430 
00431 ********************************************************************************************/
00432 
00433 BOOL CMXImportFilter::Process_BeginGroup(void)
00434 {
00435     NEEDLAYER
00436 
00437     if(!Data->pCurrentLayer->StartGroup())
00438         return FALSE;
00439 
00440     return TRUE;
00441 }
00442 
00443 
00444 /********************************************************************************************
00445 
00446 >   BOOL CMXImportFilter::Process_EndGroup(void)
00447 
00448     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00449     Created:    09/08/96
00450     Inputs:     None
00451     Returns:    error flag
00452     Purpose:    process a EndGroup command
00453 
00454 ********************************************************************************************/
00455 
00456 BOOL CMXImportFilter::Process_EndGroup(void)
00457 {
00458     NEEDLAYER
00459 
00460     if(!Data->pCurrentLayer->EndGroup())
00461         return FALSE;
00462 
00463     return TRUE;
00464 }
00465 
00466 
00467 /********************************************************************************************
00468 
00469 >   BOOL CMXImportFilter::Process_PolyCurve(void)
00470 
00471     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00472     Created:    09/08/96
00473     Inputs:     None
00474     Returns:    error flag
00475     Purpose:    process a PolyCurve command
00476 
00477 ********************************************************************************************/
00478 
00479 BOOL CMXImportFilter::Process_PolyCurve(void)
00480 {
00481     NEEDLAYER
00482 
00483     // read everything I need to know from the file
00484     CI_READDATA(PolyCurve, pc)
00485 
00486     // check to see if there's a container to think about
00487     // ONLY polycurves will have containers in a meaningful way -- other objects
00488     // needn't bother to check the flag
00489     if((pc.RenderAttributes.Mask & cmxRENDATTRMASK_CONTAIN) != 0)
00490     {
00491         if(!Process_PolyCurveContainer(pc))
00492             return FALSE;
00493     }
00494     
00495     // process it... create a node path with the nice path we've just got
00496     NodePath *pPNode = new NodePath;
00497     if(pPNode == NULL || !pPNode->SetUpPath(pc.PointList->GetNumCoords() + 4))
00498         return FALSE;
00499 
00500     if(!pPNode->InkPath.CloneFrom(*pc.PointList))
00501         return FALSE;
00502 
00503     pPNode->InkPath.IsFilled = pc.PointList->IsFilled;
00504     pPNode->InkPath.IsStroked = pc.PointList->IsStroked;
00505 
00506     if(!pPNode->InkPath.EnsureValid())
00507         return FALSE;
00508 
00509     Node *pNode = pPNode;
00510 
00511     // do all the necessary things on the path
00512     if(!TransformNode(pNode)
00513         || !SetAttributesForNode(pNode, &pc.RenderAttributes)
00514         || !ClipNode(&pNode)
00515         || !ApplyAttributesToNode(pNode))
00516         return FALSE;
00517 
00518     // add the node
00519     Data->pCurrentLayer->AddNode(pNode);
00520 
00521     // clear up after ourselves
00522     delete pc.PointList;
00523 
00524     return TRUE;
00525 }
00526 
00527 /********************************************************************************************
00528 
00529 >   BOOL CMXImportFilter::Process_PolyCurveContainer(cmxiPolyCurve &pc)
00530 
00531     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00532     Created:    26/08/96
00533     Inputs:     None
00534     Returns:    error flag
00535     Purpose:    does all the stuff
00536 
00537 ********************************************************************************************/
00538 
00539 BOOL CMXImportFilter::Process_PolyCurveContainer(cmxiPolyCurve &pc)
00540 {
00541     // right then, we've got to process one of those there containers
00542     // we get a reference to a procedure of things inside a page
00543 
00544     // check the procedure reference
00545     if(pc.RenderAttributes.ContainerSpec.ContainerReference <= 0
00546             || pc.RenderAttributes.ContainerSpec.ContainerReference > Data->NumProcedures)
00547         CMXFORMATERROR(FALSE)
00548 
00549     // see if we can get a position for it
00550     INT32 Position = Data->Procedures[pc.RenderAttributes.ContainerSpec.ContainerReference-1].Position;
00551     if(Position <= 0)
00552         CMXFORMATERROR(FALSE)
00553     
00554     // store the position of the file for later
00555     INT32 StartFilePos = Tell();
00556 
00557     // jump to the position of the vector fill procedure
00558     Seek(Position);
00559 
00560     // and see if we can find a draw image command in there somewhere -- skip the header
00561     RIFFck hdr;
00562     pFile->read(&hdr, sizeof(hdr));
00563     // I'm not going to check the type of this chunk as corel specify one type, and put
00564     // another in the file. Stupid documentionness
00565     BOOL EndProcLoc = Tell() + hdr.ckSize;
00566 
00567     // make a copy of the path of the polycurve, and set a new clipping region to it
00568     Path *pClipPath = new Path;
00569     if(pClipPath == NULL || !pClipPath->Initialise())
00570         return FALSE;       // no pathy thingy for us to use
00571     pClipPath->CloneFrom(*pc.PointList);
00572     CMXImportClipper *pClipper = new CMXImportClipper(pClipPath, TRUE);
00573     if(pClipper == NULL)
00574         return FALSE;
00575     Data->ClipperStack.Push(pClipper);
00576 
00577     // run through the commands processing them
00578     TRACEUSER( "Ben", _T("processing commands in container procedure:\n"));
00579     BOOL InProc = TRUE;
00580     Data->EndSectionFound = FALSE;
00581     while(InProc == TRUE)
00582     {
00583         // process a command
00584         if(!ProcessCommand())
00585             return FALSE;                   // error
00586 
00587         if(Data->EndSectionFound == TRUE)
00588             InProc = FALSE;
00589 
00590         // check to see if we've over run the page...
00591         if(Tell() >= EndProcLoc)
00592             InProc = FALSE;
00593     }
00594     TRACEUSER( "Ben", _T("finished processing commands in procedure\n"));
00595 
00596     // go back to where we were in the file
00597     Seek(StartFilePos);
00598 
00599     // get rid of the clipping region
00600     delete Data->ClipperStack.Pop();
00601 
00602     return TRUE;
00603 }
00604 
00605 /********************************************************************************************
00606 
00607 >   BOOL CMXImportFilter::Process_Rectangle ( void )
00608 
00609     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
00610     Created:    01/02/00
00611     Inputs:     -
00612     Returns:    TRUE if success, FALSE otherwise.
00613     Purpose:    Processes a rectangle command from within the CMX filter.
00614 
00615 ********************************************************************************************/
00616 
00617 BOOL CMXImportFilter::Process_Rectangle ( void )
00618 {
00619     NodeRegularShape    *pRectangle = NULL;
00620     Matrix              RectMatrix;
00621     DocCoord            MajorAxis   ( 0, 0 );
00622     DocCoord            MinorAxis   ( 0, 0 );
00623     double              RootTwo     = sqrt ( 2 );
00624     FIXED16             RotateCos;
00625     FIXED16             RotateSin;
00626 
00627     // One of Ben's macros. It generates an error if there isn't a layer present.
00628     NEEDLAYER
00629 
00630     // Read the data from the file.
00631     CI_READDATA ( Rectangle, Rect )
00632 
00633     // Create a new node.
00634     if ( ( pRectangle = new NodeRegularShape () ) == NULL )
00635         return FALSE;
00636 
00637     // The major and minor axes of the NodeRegularShape correspond to the height and
00638     // width of the bounding ellipse. By multiplying half of their values by the
00639     // square root of two, the ellipse's dimensions are obtained.
00640     MajorAxis.y = ( INT32 ) ( ( double ) ( Rect.Height / 2 ) * RootTwo );
00641     MinorAxis.x = ( INT32 ) ( ( double ) ( Rect.Width / 2 ) * RootTwo );
00642 
00643     // Calculate the sine and cosine for the rotation matrix.
00644     RotateSin = sin ( Rect.Rotation );
00645     RotateCos = cos ( Rect.Rotation );
00646 
00647     // Compose the transformation matrix for the shape.
00648     RectMatrix.Compose ( RotateCos, RotateCos, -RotateSin, RotateSin, Rect.Centre );
00649 
00650     pRectangle->SetUpShape ();                      // Initialise the shape node.
00651     pRectangle->SetNumSides ( 4 );                  // Always four sides to a rectangle.
00652     pRectangle->SetTransformMatrix ( &RectMatrix ); // The position of the rectangle.
00653     pRectangle->SetCentrePoint ( DocCoord (0, 0) ); // Always centred at the origin.
00654     pRectangle->SetMajorAxes ( MajorAxis );         // The height of the rectangle.
00655     pRectangle->SetMinorAxes ( MinorAxis );         // The width of the rectangle.
00656 
00657     // Attempt to prepare the node for insertion into the tree.
00658     if ( !TransformNode ( pRectangle ) ||
00659          !SetAttributesForNode ( pRectangle, &Rect.RenderAttributes ) ||
00660          !ClipNode ( ( Node ** ) &pRectangle ) ||
00661          !ApplyAttributesToNode ( pRectangle ) )
00662     {
00663         // A problem has been encountered, so return FALSE.
00664         return FALSE;
00665     }
00666 
00667     // Add the node to the tree.
00668     Data->pCurrentLayer->AddNode( pRectangle );
00669 
00670     return TRUE;
00671 }
00672 
00673 /********************************************************************************************
00674 
00675 >   BOOL CMXImportFilter::Process_AddGlobalTransform(void)
00676 
00677     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00678     Created:    13/08/96
00679     Inputs:     None
00680     Returns:    error flag
00681     Purpose:    process a AddGlobalTransform command
00682 
00683 ********************************************************************************************/
00684 
00685 BOOL CMXImportFilter::Process_AddGlobalTransform(void)
00686 {
00687     // get the data from the file
00688     CI_READDATA(AddGlobalTransform, gt)
00689 
00690     // make a new transform stack object
00691     CMXImportTransform *pNewTrans = new CMXImportTransform(&gt.TransformMatrix, TRUE);
00692     if(pNewTrans == NULL)
00693         return FALSE;
00694 
00695     // add the new object to the stack and everything happy is done for us
00696     Data->TransformStack.Push(pNewTrans);
00697 
00698     return TRUE;
00699 }
00700 
00701 
00702 /********************************************************************************************
00703 
00704 >   BOOL CMXImportFilter::Process_SetGlobalTransfo(void)
00705 
00706     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00707     Created:    13/08/96
00708     Inputs:     None
00709     Returns:    error flag
00710     Purpose:    process a SetGlobalTransfo command
00711 
00712 ********************************************************************************************/
00713 
00714 BOOL CMXImportFilter::Process_SetGlobalTransform(void)
00715 {
00716     // get the data from the file
00717     CI_READDATA(SetGlobalTransform, gt)
00718 
00719     // make a new transform stack object
00720     CMXImportTransform *pNewTrans = new CMXImportTransform(&gt.TransformMatrix, FALSE);
00721     if(pNewTrans == NULL)
00722         return FALSE;
00723 
00724     // add the new object to the stack and everything happy is done for us
00725     Data->TransformStack.Push(pNewTrans);
00726 
00727     return TRUE;
00728 }
00729 
00730 
00731 /********************************************************************************************
00732 
00733 >   BOOL CMXImportFilter::Process_RestoreLastGlobalTransform(void)
00734 
00735     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00736     Created:    13/08/96
00737     Inputs:     None
00738     Returns:    error flag
00739     Purpose:    process a RestoreLastGlobalTransform command
00740 
00741 ********************************************************************************************/
00742 
00743 BOOL CMXImportFilter::Process_RestoreLastGlobalTransform(void)
00744 {
00745     // just need to pop the transform off the stack, and delete it
00746     // everything else just happens. Funny, isn't it?
00747     delete Data->TransformStack.Pop();
00748 
00749     return TRUE;
00750 }
00751 
00752 
00753 /********************************************************************************************
00754 
00755 >   BOOL CMXImportFilter::Process_DrawImage(void)
00756 
00757     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00758     Created:    15/08/96
00759     Inputs:     None
00760     Returns:    error flag
00761     Purpose:    process a bitmap command
00762 
00763 ********************************************************************************************/
00764 
00765 BOOL CMXImportFilter::Process_DrawImage(void)
00766 {
00767     NEEDLAYER
00768 
00769     // right then, load our data from this silly thingy
00770     CI_READDATA(DrawImage, db)
00771 
00772     // check to see if it's a RImage type thing
00773     if(db.ImageType != cmxDRAWIMAGE_IMAGETYPE_COLOUR)
00774         return TRUE;        // can't deal with this
00775 
00776     // first of all, is it a cropped bitmap, 'cos it it is, we're going to have
00777     // to import it as a path with a bitmap fill on it
00778     if(db.ImageExtent != db.CroppingRectangle)
00779         return Process_DrawImage_Cropped(db);   // do a cropped one instead
00780 
00781     // right then, let's make one of these objects...
00782     INT32 Ref = db.ImageFileReference1 - 1;
00783     if(!Data->RImages[Ref].IsRImage())
00784         return TRUE;        // can't do that either without one of the RImages
00785     KernelBitmap *pBitmap = Data->RImages[Ref].GetBitmap(this);
00786     if(pBitmap == 0)
00787         return FALSE;       // wasn't converted, oh dear
00788 
00789     // create a bitmap object
00790     NodeBitmap *NewBitmap = new NodeBitmap;
00791 
00792     if((NewBitmap == NULL) || !NewBitmap->SetUpPath())
00793         return FALSE;
00794     
00795     NewBitmap->CreateShape(db.ImageExtent);
00796 
00797     // transform it by the enclosed matrix
00798     Trans2DMatrix Transform(db.Transformation);
00799     NewBitmap->Transform(Transform);
00800 
00801     // set the reference to the bitmap
00802     NewBitmap->GetBitmapRef()->Attach(pBitmap, GetDocument());
00803     if (NewBitmap->GetBitmap() != pBitmap)
00804     {
00805         // It didn't use the bitmap we gave it, so we can delete it
00806         delete pBitmap;
00807     }
00808 
00809     // apply a few nice attributes to it
00810     NewBitmap->ApplyDefaultBitmapAttrs(0);
00811 
00812     // invalidate the bounding rectangle
00813     NewBitmap->InvalidateBoundingRect();
00814 
00815     // put it on the right place on the page, but don't apply attributes to it
00816     Node *pNode = NewBitmap;
00817     if(!TransformNode(pNode)
00818         || !ClipNode(&pNode))
00819         return FALSE;
00820 
00821     // add the node
00822     Data->pCurrentLayer->AddNode(pNode);
00823 
00824     return TRUE;
00825 }
00826 
00827 
00828 /********************************************************************************************
00829 
00830 >   BOOL CMXImportFilter::Process_DrawImage_Cropped(cmxiDrawImage &db)
00831 
00832     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00833     Created:    15/08/96
00834     Inputs:     None
00835     Returns:    error flag
00836     Purpose:    process a bitmap command
00837 
00838 ********************************************************************************************/
00839 
00840 #define BITM_MOVE(px, py) {co.x = (px); co.y = (py); if(!pPath->InkPath.InsertMoveTo(co)) return FALSE;}
00841 #define BITM_LINE(px, py) {co.x = (px); co.y = (py); if(!pPath->InkPath.InsertLineTo(co)) return FALSE;}
00842 #define BITM_CLOSE {if(!pPath->InkPath.CloseSubPath()) return FALSE;}
00843 
00844 BOOL CMXImportFilter::Process_DrawImage_Cropped(cmxiDrawImage &db)
00845 {
00846     // get a nice bitmap to apply as a fill
00847     INT32 Ref = db.ImageFileReference1 - 1;
00848     if(!Data->RImages[Ref].IsRImage())
00849         return TRUE;        // can't do that either without one of the RImages
00850     KernelBitmap *pBitmap = Data->RImages[Ref].GetBitmap(this);
00851     if(pBitmap == 0)
00852         return FALSE;       // wasn't converted, oh dear
00853 
00854     // create a rectangular path object...
00855     // generate a path
00856     NodePath *pPath = new NodePath;
00857     if(pPath == 0 || (!pPath->SetUpPath()))
00858     {
00859         delete pPath;
00860         return FALSE;           // no room to create it
00861     }
00862 
00863     // position the new elements at the beginning of the path
00864     pPath->InkPath.FindStartOfPath();
00865 
00866     DocCoord co, cn1, cn2;
00867 
00868     // make the rectangle shape
00869     BITM_MOVE(db.CroppingRectangle.lo.x, db.CroppingRectangle.lo.y)
00870     BITM_LINE(db.CroppingRectangle.hi.x, db.CroppingRectangle.lo.y)
00871     BITM_LINE(db.CroppingRectangle.hi.x, db.CroppingRectangle.hi.y)
00872     BITM_LINE(db.CroppingRectangle.lo.x, db.CroppingRectangle.hi.y)
00873     BITM_LINE(db.CroppingRectangle.lo.x, db.CroppingRectangle.lo.y)
00874     BITM_CLOSE
00875 
00876     // finish off the path
00877     pPath->InvalidateBoundingRect();
00878     pPath->InkPath.IsFilled = TRUE;
00879 
00880     // set up an attribute or two
00881     Data->ObjFilled = TRUE;
00882 
00883     // set up a nice attribute for this thingy
00884     if(!SetLineColour(DocColour(COLOUR_TRANS)))
00885         return FALSE;
00886 
00887     // set a nice bitmap fill
00888     DocCoord Start  = DocCoord(db.ImageExtent.lo.x, db.ImageExtent.lo.y);
00889     DocCoord End1   = DocCoord(db.ImageExtent.hi.x, db.ImageExtent.lo.y);
00890     DocCoord End2   = DocCoord(db.ImageExtent.lo.x, db.ImageExtent.hi.y);
00891     if(!SetBitmapFill(pBitmap, Start, End1, End2))
00892         return FALSE;
00893     
00894     // apply attributes
00895     SetPathFilled(TRUE);
00896     CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00897     if(!AttributeManager::ApplyBasedOnDefaults(pPath, CurrentAttrs))
00898         return FALSE;
00899     
00900     // transform it by the enclosed matrix
00901     Trans2DMatrix Transform(db.Transformation);
00902     pPath->Transform(Transform);
00903 
00904     // put it on the right place on the page, but don't apply attributes to it
00905     Node *pNode = pPath;
00906     if(!TransformNode(pNode)
00907         || !ClipNode(&pNode))
00908         return FALSE;
00909 
00910     // add the node
00911     Data->pCurrentLayer->AddNode(pNode);
00912 
00913     return TRUE;
00914 }
00915 
00916 
00917 /********************************************************************************************
00918 
00919 >   BOOL CMXImportFilter::Process_AddClippingRegion(void)
00920 
00921     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00922     Created:    25/08/96
00923     Inputs:     None
00924     Returns:    error flag
00925     Purpose:    process a AddClippingRegion command
00926 
00927 ********************************************************************************************/
00928 
00929 BOOL CMXImportFilter::Process_AddClippingRegion(void)
00930 {
00931     CI_READDATA(AddClippingRegion, cr)
00932 
00933     // do we need to do anything?
00934     switch(cr.RegionType)
00935     {
00936     case cmxADDCLIPREGION_TYPE_NONE:
00937         return TRUE;        // nothing to do
00938         break;
00939 
00940     case cmxADDCLIPREGION_TYPE_POLYGON:
00941         break;              // know what to do with these
00942 
00943     default:
00944         TRACEUSER( "Neville", _T("---- thingy. type of clipping region not supported\n"));
00945         // The following wasn't here before 5/11/97, causes access violations on 611.cmx
00946         // as the pPolygon has not been allocated or has been deleted!
00947         // This is not suprising as the other types do not define it!
00948         return TRUE;        // nothing to do
00949         break;
00950     }
00951 
00952     // OK, we've got a polygon type path to deal with -- do we need to intersect or not
00953     BOOL Intersect = TRUE;
00954     if(cr.ClipMode == cmxADDCLIPREGIOM_MODE_COPY)
00955         Intersect = FALSE;
00956 
00957     // make a new stack item
00958     CMXImportClipper *pClipper = new CMXImportClipper(cr.Spec.pPolygon, Intersect);
00959     if(pClipper == NULL)
00960         return FALSE;       // error
00961 
00962     // and add it to the silly stack
00963     if(!Data->ClipperStack.Push(pClipper))
00964         return FALSE;
00965 
00966     return TRUE;
00967 }
00968 
00969 
00970 /********************************************************************************************
00971 
00972 >   BOOL CMXImportFilter::Process_RemoveLastClippingRegion(void)
00973 
00974     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00975     Created:    25/08/96
00976     Inputs:     None
00977     Returns:    error flag
00978     Purpose:    process a RemoveLastClippingRegion command
00979 
00980 ********************************************************************************************/
00981 
00982 BOOL CMXImportFilter::Process_RemoveLastClippingRegion(void)
00983 {
00984     // remove the last item from the clipper stack
00985     if(Data->ClipperStack.GetCount() > 0)
00986         delete Data->ClipperStack.Pop();
00987 
00988     return TRUE;
00989 }
00990 
00991 
00992 /********************************************************************************************
00993 
00994 >   BOOL CMXImportFilter::Process_ClearClipping(void)
00995 
00996     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00997     Created:    26/08/96
00998     Inputs:     None
00999     Returns:    error flag
01000     Purpose:    process a ClearClipping command
01001 
01002 ********************************************************************************************/
01003 
01004 BOOL CMXImportFilter::Process_ClearClipping(void)
01005 {
01006     // go through removing all clipping
01007     while(Data->ClipperStack.GetCount() != 0)
01008     {
01009         delete Data->ClipperStack.Pop();
01010     }
01011 
01012     return TRUE;
01013 }
01014 
01015 /********************************************************************************************
01016 
01017 >   BOOL CMXImportFilter::Process_EndSection(void)
01018 
01019     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01020     Created:    26/08/96
01021     Inputs:     None
01022     Returns:    error flag
01023     Purpose:    process a EndSection command
01024 
01025 ********************************************************************************************/
01026 
01027 BOOL CMXImportFilter::Process_EndSection(void)
01028 {
01029     Data->EndSectionFound = TRUE;
01030 
01031     return TRUE;
01032 }
01033 
01034 /********************************************************************************************
01035 
01036 >   BOOL CMXImportFilter::Process_(void)
01037 
01038     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01039     Created:    13/08/96
01040     Inputs:     None
01041     Returns:    error flag
01042     Purpose:    process a  command
01043 
01044 ********************************************************************************************/
01045 /*
01046 BOOL CMXImportFilter::Process_(void)
01047 {
01048     return TRUE;
01049 }
01050 */
01051 
01052 /********************************************************************************************
01053 
01054 >   BOOL CMXImportFilter::Process_BeginTextStream(void)
01055 
01056     Author:     Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
01057     Created:    14/08/96
01058     Inputs:     None
01059     Returns:    error flag
01060     Purpose:    process a text command, create a text story and set up its
01061                 width.
01062 
01063 ********************************************************************************************/
01064 
01065 BOOL CMXImportFilter::Process_BeginTextStream(void)
01066 {
01067     CI_READDATA(BeginTextStream, text)
01068 TRACEUSER( "Claude", _T("BeginTextStream"));    
01069     //  Take the top corner of the text's bbox as place to start the text
01070     
01071     DocCoord Pos = text.BBox.hi;//HighCorner();
01072     
01073     // create the empty text story
01074     Data->pTextStory = TextStory::CreateTextObject(Pos);
01075 
01076 
01077     return TRUE;
01078 }
01079 
01080 /********************************************************************************************
01081 
01082 >   BOOL CMXImportFilter::Process_TextFrame(void)
01083 
01084     Author:     Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
01085     Created:    15/08/96
01086     Inputs:     None
01087     Returns:    error flag
01088     Purpose:    Put the text in the right place (it was first in a CMX's default
01089                 place) using 
01090 
01091 ********************************************************************************************/
01092 
01093 BOOL CMXImportFilter::Process_TextFrame(void)
01094 {
01095         TRACEUSER( "Claude", _T("TextFrame"));
01096     
01097     CI_READDATA(TextFrame, textf)
01098     
01099 //  if(!Data->TextFrameRead)
01100 //  {
01101         Data->TextFrameRead = TRUE;
01102     
01103         INT32 TextWidth = 70000;    //  The width of the text story
01104 
01105         for(INT32 i = 0 ; i < textf.columns.count ; i++)
01106         {
01107             TextWidth += textf.columns.columns[i];
01108             TextWidth += textf.columns.gutters[i];
01109         }
01110 
01111 
01112         //  Set the width of the text story. In MILLIPOINT!
01113         Data->pTextStory->SetImportFormatWidth((INT32)(TextWidth * Data->BaseScaleFactor));
01114 
01115         //  Set the matrix of the text story
01116         Data->pTextStory->SetStoryMatrix(textf.Mat);
01117 
01118     
01119         //  Clean up the place
01120         delete textf.columns.columns;
01121         delete textf.columns.gutters;
01122 //  }
01123     return TRUE;
01124 }
01125 
01126 
01127 /********************************************************************************************
01128 
01129 >   BOOL CMXImportFilter::Process_Characters(void)
01130 
01131     Author:     Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
01132     Created:    19/08/96
01133     Inputs:     None
01134     Returns:    error flag
01135     Purpose:    Put the characters in the story
01136 
01137 ********************************************************************************************/
01138 
01139 BOOL CMXImportFilter::Process_Characters(void)
01140 {
01141 
01142     CI_READDATA(Characters, fabbyChars)
01143 
01144     //  Create an empty line
01145     Data->pTextLine = Data->pTextStory->FindLastLine();
01146     SetNonTextAttributeIgnore();
01147     if (!AttributeManager::ApplyBasedOnDefaults(Data->pTextLine, CurrentAttrs))
01148     {
01149         delete Data->pTextLine; 
01150         Data->pTextLine = NULL;
01151     }
01152     SetNonTextAttributeNotIgnore();
01153 
01154     for(INT32 i = 0 ; i < fabbyChars.ch.count ; i++)
01155     {
01156     
01157         BOOL Ignore = FALSE;
01158         TRACEUSER( "Claude", _T("Character %d is %c\n"), i, fabbyChars.ch.characters[i]);
01159 
01160         if(fabbyChars.ch.characters[i] < 32)
01161         {
01162             if(fabbyChars.ch.characters[i] == 13)
01163             {   //  End of line to skip and create a new line
01164     
01165                 //  Create an empty line
01166                 Data->pTextLine = TextLine::CreateEmptyTextLine(Data->pTextStory, LASTCHILD);
01167                 SetNonTextAttributeIgnore();
01168                 if (!AttributeManager::ApplyBasedOnDefaults(Data->pTextLine, CurrentAttrs))
01169                 {
01170                     delete Data->pTextLine;
01171                     Data->pTextLine = NULL;
01172                 }
01173                 SetNonTextAttributeNotIgnore();
01174                 Ignore = TRUE;
01175             }
01176             else
01177                 if(fabbyChars.ch.characters[i] == 9)
01178                     fabbyChars.ch.characters[i] = 32;
01179                 else
01180                     //  Ignore the bad characters.
01181                     Ignore = TRUE;
01182         }
01183 
01184         if(!Ignore) 
01185         {
01186             //  Use last text line
01187             VisibleTextNode* pLastNode = Data->pTextLine->FindLastVTN();    
01188             ERROR2IF(pLastNode == NULL, NULL, "Empty Story");
01189             //  Create a new TextChar
01190             VisibleTextNode* pNew = new TextChar(pLastNode, PREV, fabbyChars.ch.characters[i]);
01191             if (pNew != NULL)
01192             {
01193                 
01194                 //  UMASK used to determine if this character has any attributes
01195                 //  different from default.
01196                 //  If so set them
01197                 INT32 UMASK =   0;
01198                 
01199                 if(!CorelDraw7)
01200                 {
01201                     if(Data->NumCharInfo != 0)
01202                         UMASK = Data->CharInfos[fabbyChars.ch.indices[i]].UsageMask;
01203                 }
01204                 else
01205                 {
01206                     if(fabbyChars.ch.indices[i] != cmxMaxValueWORD)
01207                         UMASK = Data->CharInfos[fabbyChars.ch.indices[i]].UsageMask;
01208                 }
01209 
01210                 if(((UMASK & cmxUSAGEMASK_UseTypeNum) != 0) ||
01211                     ((UMASK & cmxUSAGEMASK_UseTypeStyle) != 0))
01212                     
01213                 {
01214                     INT32 fontRef = Data->CharInfos[fabbyChars.ch.indices[i]].FontRef-1;
01215                     String_64 name((TCHAR*)*Data->Fonts[fontRef].mFont);
01216         
01217                     SetTextTypeFace(&name);
01218 
01219                     SetTextItalic(Data->Fonts[fontRef].mIsItalic); 
01220                     SetTextBold(Data->Fonts[fontRef].mIsBold);
01221                 }
01222 
01223                 if((UMASK & cmxUSAGEMASK_UseTypeSize) != 0)
01224                     //  Set up the size of the font
01225                     SetTextSize(Data->CharInfos[fabbyChars.ch.indices[i]].TypeSize);
01226             
01227                 if(((UMASK & cmxUSAGEMASK_UseCharFill) != 0) ||
01228                     ((UMASK & cmxUSAGEMASK_UseCharOutline) != 0))
01229                     //  Apply specific attributes
01230                     SetAttributesForNode(pNew, &Data->CharInfos[fabbyChars.ch.indices[i]].RenderAttributes, FALSE);
01231                 else
01232                     //  Apply default attributes
01233                     SetAttributesForNode(pNew, &Data->textRenderAttributes, FALSE);
01234 
01235 
01236 
01237                 if (!AttributeManager::ApplyBasedOnDefaults(pNew, CurrentAttrs))
01238                 {
01239                     delete pNew;
01240                     pNew = NULL;
01241                 }
01242 
01243             
01244                 //  Set the default back to what they were!
01245                 String_64 name((TCHAR*)*Data->Fonts[Data->currentRef].mFont);
01246     
01247                 SetTextTypeFace(&name);
01248 
01249                 SetTextItalic(Data->Fonts[Data->currentRef].mIsItalic); 
01250                 SetTextBold(Data->Fonts[Data->currentRef].mIsBold);
01251                 SetTextSize(Data->currentSize);
01252 
01253             }
01254 
01255         }
01256     }
01257     
01258 
01259     //  Clean all up
01260     delete fabbyChars.ch.characters;
01261     delete fabbyChars.ch.indices;
01262     
01263     return TRUE;
01264 }
01265 
01266 /********************************************************************************************
01267 
01268 >   BOOL CMXImportFilter::Process_CharInfo(void)
01269 
01270     Author:     Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
01271     Created:    19/08/96
01272     Inputs:     None
01273     Returns:    error flag
01274     Purpose:    Put the characters in the story
01275 
01276 ********************************************************************************************/
01277 
01278 BOOL CMXImportFilter::Process_CharInfo(void)
01279 {
01280     CI_READDATA(CharInfo, ci)
01281 
01282     //  Get the info from the CharInfo
01283     Data->NumCharInfo++;
01284     Data->CharInfos[Data->NumCharInfo-1].UsageMask          = ci.UsageMask;
01285     Data->CharInfos[Data->NumCharInfo-1].FontRef            = ci.FontRef;
01286     Data->CharInfos[Data->NumCharInfo-1].TypeSize           = ci.TypeSize;
01287     Data->CharInfos[Data->NumCharInfo-1].CharAngle          = ci.CharAngle;
01288     Data->CharInfos[Data->NumCharInfo-1].RenderAttributes   = ci.RenderAttributes;
01289     Data->CharInfos[Data->NumCharInfo-1].HShift             = ci.HShift;
01290     Data->CharInfos[Data->NumCharInfo-1].VShift             = ci.VShift;
01291     
01292     return TRUE;
01293 }
01294 
01295 
01296 
01297 /********************************************************************************************
01298 
01299 >   BOOL CMXImportFilter::Process_BeginParagraph(void)
01300 
01301     Author:     Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
01302     Created:    21/08/96
01303     Inputs:     None
01304     Returns:    error flag
01305     Purpose:    Add the attributes to the text
01306 
01307 ********************************************************************************************/
01308 
01309 
01310 BOOL CMXImportFilter::Process_BeginParagraph(void)
01311 {
01312     SetTextAttributeNotIgnore();
01313     
01314     CI_READDATA(BeginParagraph, Paragraph)
01315     
01316     //  Get the correct font reference
01317     Data->currentRef    = Paragraph.FontRef-1;
01318     //  And font size
01319     Data->currentSize   = Paragraph.FontSize;
01320 
01321     //  Set the font
01322     String_64 name((TCHAR*)*Data->Fonts[Paragraph.FontRef-1].mFont);
01323     SetTextTypeFace(&name);
01324 
01325     //  Set the text attributes to whatever they need to be
01326     SetTextItalic(Data->Fonts[Paragraph.FontRef-1].mIsItalic); 
01327     SetTextBold(Data->Fonts[Paragraph.FontRef-1].mIsBold);
01328     SetTextSize(Paragraph.FontSize);
01329     
01330     switch(Paragraph.Justification)
01331     {
01332 
01333         case cmxNoAlignment:    //  Some Corel sillyness, put it Left Justified
01334                                 //  as it's what it looks like anyway.
01335             Data->textJustification = JLEFT;
01336             break;
01337         case cmxLeftJustification:
01338             Data->textJustification = JLEFT;
01339             break;
01340         case cmxCenterJustification:
01341             Data->textJustification = JCENTRE;
01342             break;
01343         case cmxRightJustification:
01344             Data->textJustification = JRIGHT;
01345             break;
01346         case cmxFullJustification:
01347             Data->textJustification = JFULL;
01348             break;
01349         case cmxForceJustification:
01350             Data->textJustification = JFULL;
01351             break;
01352         default: // no worries here.
01353             break;
01354     }
01355 
01356     SetTextJustification(Data->textJustification);
01357     
01358 
01359     
01360     //  Set the indentation for the text story
01361     Data->pTextStory->SetLeftIndent((INT32)(Paragraph.LeftMargin * Data->BaseScaleFactor));
01362     Data->pTextStory->SetRightIndent((INT32)(Paragraph.RightMargin * Data->BaseScaleFactor));
01363     
01364         
01365     //  Save the rendering attributes to use them latter
01366     Data->textRenderAttributes = Paragraph.RenderAttributes;
01367         
01368     return TRUE;
01369 }
01370 
01371 
01372 /********************************************************************************************
01373 
01374 >   BOOL CMXImportFilter::Process_EndParagraph(void)
01375 
01376     Author:     Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
01377     Created:    14/08/96
01378     Inputs:     None
01379     Returns:    error flag
01380     Purpose:    end the paragraph, set the text attributes to be ignored again
01381 
01382 ********************************************************************************************/
01383 
01384 BOOL CMXImportFilter::Process_EndParagraph(void)
01385 {
01386     //  Set the text attributes back to be ignored
01387     SetTextAttributeIgnore();
01388 
01389     return TRUE;
01390 }
01391 
01392 
01393 /********************************************************************************************
01394 
01395 >   BOOL CMXImportFilter::Process_EndTextStream(void)
01396 
01397     Author:     Claude_Quemerais (Xara Group Ltd) <camelotdev@xara.com>
01398     Created:    14/08/96
01399     Inputs:     None
01400     Returns:    error flag
01401     Purpose:    end the text thingy, puting things in the right place, and addig the node
01402                 node.
01403 ********************************************************************************************/
01404 
01405 BOOL CMXImportFilter::Process_EndTextStream(void)
01406 {
01407 
01408     Data->TextFrameRead = FALSE;
01409     //  Make the text story as a node
01410     Node *pNode = Data->pTextStory;
01411 
01412     if( !TransformNode(pNode) ||
01413         !ClipNode(&pNode))// || 
01414 //      !ApplyAttributesToNode(pNode))  // Don't apply the attributes again because that's bad!
01415         return FALSE;
01416     
01417     // add the node
01418     Data->pCurrentLayer->AddNode(pNode);
01419 
01420     return TRUE;
01421 }

Generated on Sat Nov 10 03:44:45 2007 for Camelot by  doxygen 1.4.4