cmxexdc.cpp

Go to the documentation of this file.
00001 // $Id: cmxexdc.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 // CMX export device context
00099 
00100 #include <math.h>
00101 #include "camtypes.h"
00102 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00103 #include "cmxexdc.h"
00104 #include "cmxform.h"
00105 #include "riffform.h"
00106 //#include "docrect.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 #include "colormgr.h"
00108 //#include "colmodel.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 #include "camelot.h"
00110 #include "cversion.h"
00111 #include "prvwflt.h"
00112 //#include "extfilts.h"
00113 #include "product.h"
00114 #include "hardwaremanager.h"
00115 using namespace oilHardwareManager;
00116 
00117 CC_IMPLEMENT_DYNAMIC(CMXFutureUpdater, CCObject);
00118 CC_IMPLEMENT_DYNAMIC(CMXFutureLength, CMXFutureUpdater);
00119 CC_IMPLEMENT_DYNAMIC(CMXFutureNumber, CMXFutureUpdater);
00120 CC_IMPLEMENT_DYNAMIC(CMXFutureIndex, CMXFutureUpdater);
00121 CC_IMPLEMENT_DYNAMIC(CMXReferListItem, ListItem);
00122 CC_IMPLEMENT_DYNAMIC(CMXReferListItemOffset, CMXReferListItem);
00123 CC_IMPLEMENT_DYNAMIC(CMXReferLayer, CMXReferListItemOffset);
00124 CC_IMPLEMENT_DYNAMIC(CMXReferMasterIndex, CMXReferListItemOffset);
00125 CC_IMPLEMENT_DYNAMIC(CMXReferPage, CMXReferListItemOffset);
00126 CC_IMPLEMENT_DYNAMIC(CMXReferMasterLayer, CMXReferListItemOffset);
00127 CC_IMPLEMENT_DYNAMIC(CMXReferColour, CMXReferListItem);
00128 CC_IMPLEMENT_DYNAMIC(CMXReferDefaultScreen, CMXReferListItem);
00129 CC_IMPLEMENT_DYNAMIC(CMXReferDefaultDotDash, CMXReferDotDash);
00130 CC_IMPLEMENT_DYNAMIC(CMXReferPen, CMXReferListItem);
00131 CC_IMPLEMENT_DYNAMIC(CMXReferArrowheads, CMXReferListItem);
00132 CC_IMPLEMENT_DYNAMIC(CMXReferArrow, CMXReferListItem);
00133 CC_IMPLEMENT_DYNAMIC(CMXReferLens, CMXReferListItem);
00134 CC_IMPLEMENT_DYNAMIC(CMXReferLineStyle, CMXReferListItem);
00135 CC_IMPLEMENT_DYNAMIC(CMXReferOutline, CMXReferListItem);
00136 CC_IMPLEMENT_DYNAMIC(CMXReferBitmap, CMXReferListItem);
00137 CC_IMPLEMENT_DYNAMIC(CMXReferBitmapFill, CMXReferListItem);
00138 CC_IMPLEMENT_DYNAMIC(CMXReferDotDash, CMXReferListItem);
00139 CC_IMPLEMENT_DYNAMIC(CMXGroupRecord, ListItem);
00140 CC_IMPLEMENT_DYNAMIC(CMXNestedTagRecord, ListItem);
00141 CC_IMPLEMENT_DYNAMIC(CMXLensBBox, ListItem);
00142 
00143 /********************************************************************************************
00144 
00145 >   CMXFutureUpdater::CMXFutureUpdater()
00146 
00147     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00148     Created:    21/06/96
00149     Inputs:     none
00150     Returns:    none
00151     Purpose:    constructor
00152     SeeAlso:    
00153 
00154 ********************************************************************************************/
00155 
00156 CMXFutureUpdater::CMXFutureUpdater()
00157 {
00158     AbsPosition = -1;
00159     DataSize = 0;
00160 }
00161 
00162 
00163 /********************************************************************************************
00164 
00165 >   CMXFutureUpdater::CMXFutureUpdater()
00166 
00167     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00168     Created:    21/06/96
00169     Inputs:     none
00170     Returns:    none
00171     Purpose:    destructor
00172     SeeAlso:    
00173 
00174 ********************************************************************************************/
00175 
00176 CMXFutureUpdater::~CMXFutureUpdater()
00177 {
00178     if(AbsPosition >= 0)
00179         TRACEUSER( "Ben", _T("AWWOOOOGA! CMXFutureUpdated deleted, but not written\n\n"));
00180 }
00181 
00182 
00183 /********************************************************************************************
00184 
00185 >   BOOL CMXFutureUpdater::Init(CMXExportDC *pDC, INT32 RelativePos, UINT32 DataSize)
00186 
00187     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00188     Created:    21/06/96
00189     Inputs:     export dc, relative position (+ve = forwards in file), size of data
00190     Returns:    none
00191     Purpose:    initialises a updater object
00192     SeeAlso:    
00193 
00194 ********************************************************************************************/
00195 
00196 BOOL CMXFutureUpdater::Init(CMXExportDC *pDC, INT32 RelativePos, UINT32 tDataSize)
00197 {
00198     ERROR2IF(AbsPosition >= 0, FALSE, "Updater already initialised");
00199     ERROR2IF(pDC == 0, FALSE, "No pDC, chaps");
00200     ERROR2IF(DataSize < 0 || DataSize > 4, FALSE, "Bit of a data size problem really");
00201 
00202     INT32 CurrentPos = pDC->GetFilePosition();
00203     ERROR2IF(CurrentPos < 0, FALSE, "Whoops -- negative file position here");
00204     AbsPosition = CurrentPos + RelativePos;
00205     ERROR2IF(AbsPosition < 0, FALSE, "Serious Bummer -- expected to update a position before the start of the file");
00206     DataSize = tDataSize;
00207 
00208     return TRUE;
00209 }
00210 
00211 /********************************************************************************************
00212 
00213 >   BOOL CMXFutureUpdater::WriteValue(CMXExportDC *pDC, INT32 Value)
00214 
00215     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00216     Created:    21/06/96
00217     Inputs:     export dc, value
00218     Returns:    none
00219     Purpose:    writes a value to the file
00220     SeeAlso:    
00221 
00222 ********************************************************************************************/
00223 
00224 BOOL CMXFutureUpdater::WriteValue(CMXExportDC *pDC, INT32 Value)
00225 {
00226     ERROR2IF(pDC == 0, FALSE, "No pDC, chaps");
00227 
00228     // write the number
00229     if(!pDC->WriteNumber(AbsPosition, DataSize, Value))
00230         return FALSE;
00231 
00232     // reset everything for the next run, should we want one.
00233     AbsPosition = -1;
00234     DataSize = 0;
00235     Reset();            // get the derivedness to reset itself too.
00236 
00237     return TRUE;
00238 }
00239 
00240 
00241 /********************************************************************************************
00242 
00243 >   CMXFutureLength::CMXFutureLength()
00244 
00245     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00246     Created:    21/06/96
00247     Inputs:     none
00248     Returns:    none
00249     Purpose:    constructor
00250     SeeAlso:    
00251 
00252 ********************************************************************************************/
00253 
00254 CMXFutureLength::CMXFutureLength()
00255 {
00256     StartPos = -1;
00257 }
00258 
00259 /********************************************************************************************
00260 
00261 >   BOOL CMXFutureLength::SetLengthStartPos(CMXExportDC *pDC, INT32 RelativePos);
00262 
00263     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00264     Created:    21/06/96
00265     Inputs:     export dc, relative position from current position (+ve is forwards)
00266     Returns:    none
00267     Purpose:    sets the start position of the length which is to be written
00268     SeeAlso:    
00269 
00270 ********************************************************************************************/
00271 
00272 BOOL CMXFutureLength::SetLengthStartPos(CMXExportDC *pDC, INT32 RelativePos)
00273 {
00274     ERROR2IF(StartPos >= 0, FALSE, "Start position already set");
00275     ERROR2IF(pDC == 0, FALSE, "No dc");
00276     StartPos = pDC->GetFilePosition() + RelativePos;
00277 
00278     return TRUE;
00279 }
00280 
00281 
00282 /********************************************************************************************
00283 
00284 >   void CMXFutureLength::Reset(void)
00285 
00286     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00287     Created:    21/06/96
00288     Inputs:     export dc, relative position from current position (+ve is forwards)
00289     Returns:    none
00290     Purpose:    resets the future updater object after a write
00291     SeeAlso:    
00292 
00293 ********************************************************************************************/
00294 
00295 void CMXFutureLength::Reset(void)
00296 {
00297     StartPos = -1;
00298 }
00299 
00300 
00301 /********************************************************************************************
00302 
00303 >   BOOL CMXFutureLength::Write(CMXExportDC *pDC)
00304 
00305     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00306     Created:    21/06/96
00307     Inputs:     export dc
00308     Returns:    none
00309     Purpose:    writes the length to the file. The length is the (+ve) value from the
00310                 start position set earlier to the current position in the file.
00311     SeeAlso:    
00312 
00313 ********************************************************************************************/
00314 
00315 BOOL CMXFutureLength::Write(CMXExportDC *pDC)
00316 {
00317     ERROR2IF(pDC == 0, FALSE, "No dc");
00318     ERROR2IF(StartPos < 0, FALSE, "StartPos is negative... has this length been initialised properly?");
00319 
00320     INT32 len = pDC->GetFilePosition() - StartPos;
00321 
00322     ERROR2IF(len < 0, FALSE, "We're talking negative lengths here? I don't think so");
00323     
00324     return WriteValue(pDC, len);
00325 }
00326 
00327 /********************************************************************************************
00328 
00329 >   BOOL CMXFutureIndex::Write(CMXExportDC *pDC)
00330 
00331     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00332     Created:    21/06/96
00333     Inputs:     export dc
00334     Returns:    none
00335     Purpose:    writes the index to the file. The index is the current file position.
00336     SeeAlso:    
00337 
00338 ********************************************************************************************/
00339 
00340 BOOL CMXFutureIndex::Write(CMXExportDC *pDC)
00341 {
00342     ERROR2IF(pDC == 0, FALSE, "No dc");
00343 
00344     return WriteValue(pDC, pDC->GetFilePosition());
00345 }
00346 
00347 
00348 /********************************************************************************************
00349 
00350 >   BOOL CMXFutureIndex::Write(CMXExportDC *pDC)
00351 
00352     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00353     Created:    21/06/96
00354     Inputs:     export dc
00355     Returns:    none
00356     Purpose:    writes the number to the file
00357     SeeAlso:    
00358 
00359 ********************************************************************************************/
00360 
00361 BOOL CMXFutureNumber::Write(CMXExportDC *pDC)
00362 {
00363     ERROR2IF(pDC == 0, FALSE, "No dc");
00364 
00365     return WriteValue(pDC, Number);
00366 }
00367 
00368 /********************************************************************************************
00369 
00370 >   CMXReferListItemOffset::CMXReferListItemOffset(CMXExportDC *pDC)
00371 
00372     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00373     Created:    21/06/96
00374     Inputs:     export dc
00375     Returns:    none
00376     Purpose:    constructs the refer list item by getting the offset
00377     SeeAlso:    
00378 
00379 ********************************************************************************************/
00380 
00381 CMXReferListItemOffset::CMXReferListItemOffset(CMXExportDC *pDC)
00382     : CMXReferListItem(pDC)
00383 {
00384     Offset = pDC->GetFilePosition();        // will throw an exception if it goes wrong
00385 }
00386 
00387 
00388 /********************************************************************************************
00389 
00390 >   void CMXReferLayer::SetLayerDetails(WORD Number, String_256 *tName)
00391 
00392     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00393     Created:    26/06/96
00394     Inputs:     layer number, name
00395     Returns:    none
00396     Purpose:    sets the layer details
00397     SeeAlso:    
00398 
00399 ********************************************************************************************/
00400 
00401 void CMXReferLayer::SetLayerDetails(WORD Number, String_256 *tName)
00402 {
00403     LayerNumber = Number;
00404     Name = *tName;
00405 }
00406 
00407 
00408 /********************************************************************************************
00409 
00410 >   BOOL CMXReferLayer::WriteInReferenceList(CMXExportDC *pDC)
00411 
00412     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00413     Created:    26/06/96
00414     Inputs:     export dc
00415     Returns:    sucess
00416     Purpose:    writes the relevant entry in the reference list of the file
00417     SeeAlso:    
00418 
00419 ********************************************************************************************/
00420 
00421 BOOL CMXReferLayer::WriteInReferenceList(CMXExportDC *pDC)
00422 {
00423     ERROR2IF(pDC == 0, FALSE, "no DC");
00424 
00425     // write the entry
00426     cmxRefListEntryRef en;
00427     memset(&en, '\0', sizeof(en));
00428 
00429     en.Association = cmxREFLISTEN_DESC_COMPONENT;
00430     en.Type = cmxREFLISTEN_TYPE_LAYER;
00431     en.ReferenceNumber = LayerNumber;
00432 
00433     pDC->WriteData(&en, sizeof(en));
00434 
00435     return TRUE;
00436 }
00437 
00438 
00439 /********************************************************************************************
00440 
00441 >   INT32 CMXReferLayer::IndexEntrySize(CMXExportDC *pDC)
00442 
00443     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00444     Created:    26/06/96
00445     Inputs:     none
00446     Returns:    length of entry we'll write
00447     Purpose:    gets the length of the entry we'll write in the index
00448     SeeAlso:    
00449 
00450 ********************************************************************************************/
00451 
00452 INT32 CMXReferLayer::IndexEntrySize(CMXExportDC *pDC)
00453 {
00454     ERROR2IF(pDC == NULL, 0, "no dc");
00455     
00456     INT32 StrLen = Name.Length();
00457 
00458     return StrLen + sizeof(WORD) + sizeof(DWORD) * 2 + ((pDC->IsThirtyTwoBit())?sizeof(WORD):0);
00459 }
00460 
00461 
00462 /********************************************************************************************
00463 
00464 >   BOOL CMXReferLayer::WriteInIndex(CMXExportDC *pDC)
00465 
00466     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00467     Created:    26/06/96
00468     Inputs:     export dc
00469     Returns:    none
00470     Purpose:    writes the layer details in the layer list
00471     SeeAlso:    
00472 
00473 ********************************************************************************************/
00474 
00475 BOOL CMXReferLayer::WriteInIndex(CMXExportDC *pDC)
00476 {
00477     // write size in file
00478     pDC->WriteSizeInFile(Name.Length() + sizeof(DWORD) * 2);
00479 
00480     DWORD tOffset = Offset;
00481     pDC->WriteData(&tOffset, sizeof(tOffset));
00482 
00483     pDC->WriteString(&Name);
00484 
00485     SDWORD RefList = -1;
00486     pDC->WriteData(&RefList, sizeof(RefList));
00487 
00488     return TRUE;
00489 }
00490 
00491 
00492 /********************************************************************************************
00493 
00494 >   BOOL CMXReferPage::WriteInIndex(CMXExportDC *pDC)
00495 
00496     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00497     Created:    26/06/96
00498     Inputs:     export dc
00499     Returns:    none
00500     Purpose:    writes the page details in the layer list
00501     SeeAlso:    
00502 
00503 ********************************************************************************************/
00504 
00505 BOOL CMXReferPage::WriteInIndex(CMXExportDC *pDC)
00506 {
00507 
00508     // write the entry
00509     cmxPageIndexEntry pe;
00510 
00511     // write size in file
00512     pDC->WriteSizeInFile(sizeof(pe));
00513 
00514     pe.PageOffset = Offset;
00515     pe.LayerTableOffset = LayerTableOffset;
00516     pe.ThumbnailOffset = 0;
00517     pe.RefListOffset = RefListOffset;
00518 
00519     if(!pDC->WriteData(&pe, sizeof(pe)))
00520         return FALSE;
00521 
00522     return TRUE;
00523 }
00524 
00525 
00526 /********************************************************************************************
00527 
00528 >   BOOL CMXReferDefaultScreen::WriteInDesc(CMXExportDC *pDC)
00529 
00530     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00531     Created:    26/06/96
00532     Inputs:     export dc
00533     Returns:    none
00534     Purpose:    writes the default screen list entry -- same as the default one corel writes
00535     SeeAlso:    
00536 
00537 ********************************************************************************************/
00538 
00539 BOOL CMXReferDefaultScreen::WriteInDesc(CMXExportDC *pDC)
00540 {
00541     if(pDC->IsThirtyTwoBit())
00542     {
00543         cmxScreenDef32 scrdef = {0,0,0,0,0};
00544 
00545         if(!pDC->WriteTag(cmxTAG_DescrSection_Screen_Basic, &scrdef, sizeof(scrdef))
00546             || !pDC->WriteMinEndTag())
00547             return FALSE;
00548     }
00549     else
00550     {
00551         cmxScreenDef16 scrdef = {0,0,0,0};
00552 
00553         if(!pDC->WriteData(&scrdef, sizeof(scrdef)))
00554             return FALSE;
00555     }
00556 
00557     return TRUE;
00558 }
00559 
00560 
00561 /********************************************************************************************
00562 
00563 >   BOOL CMXReferDefaultDotDash::WriteInDesc(CMXExportDC *pDC)
00564 
00565     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00566     Created:    26/06/96
00567     Inputs:     export dc
00568     Returns:    none
00569     Purpose:    writes the default dot dash list entry
00570     SeeAlso:    
00571 
00572 ********************************************************************************************/
00573 
00574 BOOL CMXReferDefaultDotDash::WriteInDesc(CMXExportDC *pDC)
00575 {
00576     WORD DotCount = 0;
00577 
00578     if(!pDC->WriteTag(cmxTAG_DescrSection_Dash, &DotCount, sizeof(DotCount))
00579         || !pDC->WriteMinEndTag())
00580         return FALSE;
00581 
00582     return TRUE;
00583 }
00584 
00585 
00586 /********************************************************************************************
00587 
00588 >   BOOL CMXReferColour::WriteInDesc(CMXExportDC *pDC)
00589 
00590     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00591     Created:    26/06/96
00592     Inputs:     export dc
00593     Returns:    none
00594     Purpose:    writes the colour to the DC in a description list
00595     SeeAlso:    
00596 
00597 ********************************************************************************************/
00598 
00599 BOOL CMXReferColour::WriteInDesc(CMXExportDC *pDC)
00600 {
00601     ColourModel OutputModel;
00602     struct {
00603         BYTE ColType;
00604         BYTE Palette;
00605     } ColH;
00606     ColH.Palette = 5;       // user palette
00607 
00608     // Work out which CMX colour type we will export as, and therefore which internal
00609     // colour model we should convert the colour to.
00610     switch (Colour.GetColourModel())
00611     {
00612         case COLOURMODEL_HSVT:
00613             OutputModel = COLOURMODEL_HSVT;
00614             ColH.ColType = cmxCOLMODEL_HSB;
00615             break;
00616 
00617         case COLOURMODEL_CMYK:
00618             OutputModel = COLOURMODEL_CMYK;
00619             ColH.ColType = cmxCOLMODEL_CMYK255;
00620             break;
00621 
00622         case COLOURMODEL_GREYT:
00623             OutputModel = COLOURMODEL_GREYT;
00624             ColH.ColType = cmxCOLMODEL_GREY;
00625             break;
00626         
00627         case COLOURMODEL_RGBT:
00628         default:
00629             // It's RGB, or we don't know the model, so we'll output it as RGB
00630             OutputModel = COLOURMODEL_RGBT;
00631             ColH.ColType = cmxCOLMODEL_RGB;
00632             break;
00633     }
00634 
00635     // write the header tag
00636     if(!pDC->WriteTag(cmxTAG_DescrSection_Color_Base, &ColH, sizeof(ColH)))
00637         return FALSE;
00638 
00639     // Find an appropriate colour context to convert the colour for output
00640     ColourContext *OutputCC = ColourManager::GetColourContext(OutputModel);
00641     ERROR3IF(OutputCC == NULL, "Can't find a colour context");
00642 
00643     // Convert the colour into a packed format
00644     ColourPacked Result;
00645     OutputCC->ConvertColour(&Colour, &Result);
00646 
00647     // start the tag
00648     if(!pDC->StartTag(cmxTAG_DescrSection_Color_ColorDescr))
00649         return FALSE;
00650 
00651     // Pull the converted colour out and export it to the CMX file
00652     switch (OutputModel)
00653     {
00654         case COLOURMODEL_HSVT:
00655             {
00656 /*TRACEUSER( "Ben", _T("HSV colour: hue %d, sat %d, val %d\n"), Result.HSVT.Hue, Result.HSVT.Saturation, Result.HSVT.Value);
00657             WORD Hue = Result.HSVT.Hue;
00658             pDC->WriteData(&Hue, sizeof(Hue));
00659             pDC->WriteByte(Result.HSVT.Saturation);
00660             pDC->WriteByte(Result.HSVT.Value); */
00661 
00662                 // BODGE because the colour system can't convert HSVT properly yet
00663             ColourHSVT GResult;
00664             OutputCC->ConvertColour(&Colour, (ColourGeneric *)&GResult);
00665 
00666             WORD Hue = (WORD)(360.0 * GResult.Hue.MakeDouble());
00667             pDC->WriteData(&Hue, sizeof(Hue));
00668             pDC->WriteByte((BYTE)(255.0 * GResult.Saturation.MakeDouble()));
00669             pDC->WriteByte((BYTE)(255.0 * GResult.Value.MakeDouble()));
00670             }
00671             break;
00672 
00673         case COLOURMODEL_CMYK:
00674 TRACEUSER( "Ben", _T("CMYK colour: cyan %d mag %d yel %d key %d\n"), Result.CMYK.Cyan, Result.CMYK.Magenta, Result.CMYK.Yellow, Result.CMYK.Key);
00675             pDC->WriteByte(Result.CMYK.Cyan);
00676             pDC->WriteByte(Result.CMYK.Magenta);
00677             pDC->WriteByte(Result.CMYK.Yellow);
00678             pDC->WriteByte(Result.CMYK.Key);
00679             break;
00680 
00681         case COLOURMODEL_GREYT:
00682 TRACEUSER( "Ben", _T("grey colour: grey %d\n"), Result.GreyT.Intensity);
00683             pDC->WriteByte(Result.GreyT.Intensity);
00684             break;
00685 
00686         case COLOURMODEL_RGBT:
00687         default:
00688 TRACEUSER( "Ben", _T("RGB colour: red %d green %d blue %d\n"), Result.RGBT.Red, Result.RGBT.Green, Result.RGBT.Blue);
00689             pDC->WriteByte(Result.RGBT.Red);
00690             pDC->WriteByte(Result.RGBT.Green);
00691             pDC->WriteByte(Result.RGBT.Blue);
00692             break;
00693     }
00694 
00695     // end the tag
00696     if(!pDC->EndTag())
00697         return FALSE;
00698 
00699     // write the end tag
00700     if(!pDC->WriteMinEndTag())
00701         return FALSE;
00702 
00703     return TRUE;
00704 }
00705 
00706 
00707 /********************************************************************************************
00708 
00709 >   BOOL CMXReferMasterIndex::WriteInIndex(CMXExportDC *pDC)
00710 
00711     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00712     Created:    26/06/96
00713     Inputs:     export dc
00714     Returns:    none
00715     Purpose:    writes the index details in the master index
00716     SeeAlso:    
00717 
00718 ********************************************************************************************/
00719 
00720 BOOL CMXReferMasterIndex::WriteInIndex(CMXExportDC *pDC)
00721 {
00722     // write the entry
00723     cmxMasterIndexEntry me;
00724 
00725     me.Type = Type;
00726     me.Offset = Offset;
00727 
00728 TRACEUSER( "Ben", _T("Writing entry in master index, type = %d, offset = %x = %d, size = %d\n"), Type, Offset, Offset, sizeof(me));
00729 
00730     if(!pDC->WriteData(&me, sizeof(me)))
00731         return FALSE;
00732 
00733     return TRUE;
00734 }
00735 
00736 
00737 /********************************************************************************************
00738 
00739 >   BOOL CMXReferMasterIndex::WriteInIndex(CMXExportDC *pDC)
00740 
00741     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00742     Created:    26/06/96
00743     Inputs:     export dc
00744     Returns:    none
00745     Purpose:    writes the index details in the master index
00746     SeeAlso:    
00747 
00748 ********************************************************************************************/
00749 
00750 BOOL CMXReferMasterLayer::WriteInIndex(CMXExportDC *pDC)
00751 {
00752     // write the entry
00753     if(pDC->IsThirtyTwoBit())
00754     {
00755         cmxMasterLayerEntry32 le;       // note that this is the entire table, not an entry
00756 
00757         le.TableType = cmxMASTERIN_MASTERLAYER;     // quite why we need this is another matter
00758         le.SizeInFile = sizeof(DWORD);
00759         le.ID = 1;                  // first page, I presume
00760         le.Offset = Offset;         // offset...
00761 
00762         if(!pDC->WriteData(&le, sizeof(le)))
00763             return FALSE;
00764     }
00765     else
00766     {
00767         cmxMasterLayerEntry16 le;       // note that this is the entire table, not an entry
00768 
00769         le.TableType = cmxMASTERIN_MASTERLAYER;     // quite why we need this is another matter
00770         le.ID = 1;                  // first page, I presume
00771         le.Offset = Offset;         // offset...
00772 
00773         if(!pDC->WriteData(&le, sizeof(le)))
00774             return FALSE;
00775     }
00776 
00777     return TRUE;
00778 }
00779 
00780 
00781 /********************************************************************************************
00782 
00783 >   CMXExportDC::CMXExportDC(Filter *Parent)
00784 
00785     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00786     Created:    18/6/96
00787     Inputs:     The filter object associated with this export DC.
00788     Purpose:    Initialise a DC for exporting EPS.
00789 
00790 ********************************************************************************************/
00791 
00792 CMXExportDC::CMXExportDC(Filter *Parent) : ExportDC(Parent)
00793 {
00794 }
00795 
00796 
00797 
00798 /********************************************************************************************
00799 
00800 >   BOOL CMXExportDC::Init(CCLexFile* pFile, CMXRenderRegion *pReg, BOOL bThirtyTwoBit)
00801 
00802     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00803     Created:    18/6/96
00804     Inputs:     pFile - The file to attach to the DC
00805     Returns:    TRUE if all went well, FALSE if not
00806     Purpose:    Calls the base class Init function and then sets up the DC to throw exceptions
00807                 when it gets errors as that is how the EPS stuff expects errors to be reported.
00808     SeeAlso:    ExportDC::Init
00809 
00810 ********************************************************************************************/
00811 
00812 BOOL CMXExportDC::Init(CCLexFile* pFile, CMXRenderRegion *pReg, BOOL bThirtyTwoBit, BOOL ClipboardExport)
00813 {
00814     // First get the base class to do its thing
00815     if (!ExportDC::Init(pFile)) return FALSE;
00816 
00817     // now do what I want done.
00818     // We want export files to throw exceptions, and not report errors.
00819     ExportFile->SetThrowExceptions(TRUE);
00820     ExportFile->SetReportErrors(FALSE);
00821 
00822     // set the bitness of the file
00823     ThirtyTwoBit = bThirtyTwoBit;
00824 
00825     // mark the fact that we've not actually doing a section at all
00826     CurrentSection = CMXSECTION_NONE;
00827 
00828     // set up a few more variables
00829     DoingCommand = FALSE;
00830     DoingPage = FALSE;
00831     DoingLayer = FALSE;
00832     PageRefer = NULL;
00833     DoingTag = FALSE;
00834     pMatrix = NULL;
00835     NestedTagLevel = 0;
00836     CurrentInstrFilePosition = -1;
00837     pRenderRegion = pReg;
00838     DoingRIFFList = FALSE;
00839     NumberOfEntriesUsedInCache = 0;
00840 
00841     // overlapped lenses flag
00842     if(!ClipboardExport)
00843     {
00844         // normal ask the user mode
00845         AreIgnoreingOverlappedLenses = FALSE;
00846         OverlappedLensesHaveBeenIgnored = FALSE;
00847         HaveAskedUserAboutLenses = FALSE;
00848     }
00849     else
00850     {
00851         // don't ask the user
00852         AreIgnoreingOverlappedLenses = TRUE;
00853         OverlappedLensesHaveBeenIgnored = FALSE;
00854         HaveAskedUserAboutLenses = TRUE;
00855     }
00856 
00857     for(INT32 i = 0 ; i < CMXFUTUREVALUECACHESIZE ; i++)
00858     {
00859         //  init the write-cache 
00860         FutureDataCache[i].Location = INT32_MAX;
00861         FutureDataCache[i].Data     = 0;
00862         FutureDataCache[i].DataSize = 0;
00863     }
00864 
00865     // pop in the default screen thingy
00866     CMXReferDefaultScreen *pDefScreen = new CMXReferDefaultScreen(this);
00867     if(pDefScreen == NULL) return FALSE;
00868 
00869     // and add it to the list
00870     ReferList.AddTail(pDefScreen);
00871 
00872     // pop in the default dot dash thingy
00873     CMXReferDefaultDotDash *pDefdd = new CMXReferDefaultDotDash(this);
00874     if(pDefdd == NULL) return FALSE;
00875 
00876     // and add it to the list
00877     ReferList.AddTail(pDefdd);
00878     return TRUE;
00879 }
00880 
00881 /********************************************************************************************
00882 
00883 >   void CMXExportDC::CleanUp(void)
00884 
00885     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00886     Created:    26/06/96
00887     Inputs:     none
00888     Returns:    none
00889     Purpose:    Cleans up after writing to a file
00890     SeeAlso:    
00891 
00892 ********************************************************************************************/
00893 
00894 void CMXExportDC::CleanUp(void)
00895 {
00896     WriteFutureDataCache();
00897     ReferList.DeleteAll();
00898     LensBBoxes.DeleteAll();
00899 }
00900 
00901 
00902 /********************************************************************************************
00903 
00904 >   BOOL CMXExportDC::StartSection(CMXSectionType Type)
00905 
00906     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00907     Created:    18/6/96
00908     Inputs:     The type of section to start
00909     Returns:    success
00910     Purpose:    Start writing a section to a CMX file
00911     SeeAlso:    
00912 
00913 ********************************************************************************************/
00914 
00915 BOOL CMXExportDC::StartSection(CMXSectionType Type)
00916 {
00917     ERROR2IF(CurrentSection != CMXSECTION_NONE, FALSE, "Tried to start a section without ending the previous one");
00918 
00919     // write the riff file header
00920     // first, decide what riff chunck id we want
00921     DWORD id;
00922     BOOL IsAList = FALSE;           // whether in fact it's a list
00923     switch(Type)
00924     {
00925     case CMXSECTION_NONE:
00926         ERROR2(FALSE, "Tried to start a section of type none. Oh dear");
00927         break;
00928     case CMXSECTION_HEADER:     id = cmxRIFFCI_Header;          break;
00929     case CMXSECTION_PAGE:       id = cmxRIFFCI_Page;            break;
00930     case CMXSECTION_REFLIST:    id = cmxRIFFCI_ReferenceList;   break;
00931     case CMXSECTION_INDEX:      id = cmxRIFFLIST_Index; IsAList=TRUE;   break;
00932     case CMXSECTION_TRAILER:    id = cmxRIFFLIST_Trail; IsAList=TRUE;   break;
00933     case CMXSECTION_ARROW:      id = cmxRIFFCI_Desc_Arrow;      break;
00934     case CMXSECTION_ARROWHEADS: id = cmxRIFFCI_Desc_Arrowheads; break;
00935     case CMXSECTION_COLOUR:     id = cmxRIFFCI_Desc_Colour;     break;
00936     case CMXSECTION_DOTDASH:    id = cmxRIFFCI_Desc_DotDash;    break;
00937     case CMXSECTION_FONT:       id = cmxRIFFCI_Desc_Font;       break;
00938     case CMXSECTION_OUTLINE:    id = cmxRIFFCI_Desc_Outline;    break;
00939     case CMXSECTION_LINESTYLE:  id = cmxRIFFCI_Desc_LineStyle;  break;
00940     case CMXSECTION_PEN:        id = cmxRIFFCI_Desc_Pen;        break;
00941     case CMXSECTION_LENS:       id = cmxRIFFCI_Desc_Lens;       break;
00942     case CMXSECTION_SCREEN:     id = cmxRIFFCI_Desc_Screen;     break;
00943     case CMXSECTION_IMAGINFO:   id = cmxRIFFCI_ImageInfo;       break;
00944     case CMXSECTION_IMAGDATA:   id = cmxRIFFCI_ImageData;       break;
00945     case CMXSECTION_PROCBITFILL:id = cmxRIFFCI_Procedure;       break;
00946     case CMXSECTION_PREVIEWBITMAP: id = cmxRIFFCI_Thumbnail;    break;
00947     default:
00948         ERROR2(FALSE, "Unknown section type");
00949         break;
00950     }
00951 
00952     // OK, write the RIFF header
00953     RIFFck chdr;
00954     chdr.ckID = IsAList?RIFFTYPE_LIST:id;
00955     chdr.ckSize = 0;
00956     ExportFile->write(&chdr, sizeof(chdr));
00957 
00958     // set the future length
00959     SectionLengthFuture.Init(this, FUTURE_BACKLOC(&chdr, ckSize), sizeof(chdr.ckSize));
00960     SectionLengthFuture.SetLengthStartPos(this, 0 /* - (INT32)sizeof(chdr)*/);
00961 
00962     // write the list type, if we're doing a list
00963     if(IsAList)
00964         ExportFile->write(&id, sizeof(id));
00965 
00966     // note which section type we just did
00967     CurrentSection = Type;
00968     
00969     return TRUE;
00970 }
00971 
00972 
00973 /********************************************************************************************
00974 
00975 >   BOOL CMXExportDC::EndSection(void)
00976 
00977     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
00978     Created:    24/06/96
00979     Inputs:     none
00980     Returns:    success
00981     Purpose:    Finish off writing a section to a CMX file
00982     SeeAlso:    
00983 
00984 ********************************************************************************************/
00985 
00986 BOOL CMXExportDC::EndSection(void)
00987 {
00988     ERROR2IF(CurrentSection == CMXSECTION_NONE, FALSE, "Tried to end a section which didn't exist");
00989 
00990     // write the length
00991     SectionLengthFuture.Write(this);
00992 
00993     // set the section type to none
00994     CurrentSection = CMXSECTION_NONE;
00995 
00996     // word align the file
00997     if((GetFilePosition() & 1) != 0)
00998     {
00999         // put an extra byte in the file
01000         ExportFile->put('\0');
01001     }
01002 
01003     return TRUE;
01004 }
01005 
01006 
01007 /********************************************************************************************
01008 
01009 >   BOOL CMXExportDC::StartRIFFList(INT32 Type)
01010 
01011     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01012     Created:    16/07/96
01013     Inputs:     The type of section to start
01014     Returns:    success
01015     Purpose:    Start writing a section to a CMX file
01016     SeeAlso:    
01017 
01018 ********************************************************************************************/
01019 
01020 BOOL CMXExportDC::StartRIFFList(INT32 Type)
01021 {
01022     ERROR2IF(DoingRIFFList, FALSE, "Tried to start a riff list without ending the previous one");
01023 
01024     // write the riff list header
01025     RIFFck chdr;
01026     chdr.ckID = RIFFTYPE_LIST;
01027     chdr.ckSize = 0;
01028     ExportFile->write(&chdr, sizeof(chdr));
01029 
01030     // set the future length
01031     RIFFListLengthFuture.Init(this, FUTURE_BACKLOC(&chdr, ckSize), sizeof(chdr.ckSize));
01032     RIFFListLengthFuture.SetLengthStartPos(this, 0);
01033 
01034     // write the list type, if we're doing a list
01035     DWORD id = Type;
01036     ExportFile->write(&id, sizeof(id));
01037 
01038     // flag...
01039     DoingRIFFList = TRUE;
01040     
01041     return TRUE;
01042 }
01043 
01044 
01045 /********************************************************************************************
01046 
01047 >   BOOL CMXExportDC::EndRIFFList(void)
01048 
01049     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01050     Created:    16/07/96
01051     Inputs:     none
01052     Returns:    success
01053     Purpose:    Finish off writing a section to a CMX file
01054     SeeAlso:    
01055 
01056 ********************************************************************************************/
01057 
01058 BOOL CMXExportDC::EndRIFFList(void)
01059 {
01060     ERROR2IF(!DoingRIFFList, FALSE, "Tried to end a riff list which didn't exist");
01061 
01062     // write the length
01063     RIFFListLengthFuture.Write(this);
01064 
01065     // word align the file
01066     if((GetFilePosition() & 1) != 0)
01067     {
01068         // put an extra byte in the file
01069         ExportFile->put('\0');
01070     }
01071 
01072     // flag
01073     DoingRIFFList = FALSE;
01074 
01075     return TRUE;
01076 }
01077 
01078 
01079 /********************************************************************************************
01080 
01081 >   BOOL CMXExportDC::StartTag(INT32 Tag)
01082 
01083     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01084     Created:    27/06/96
01085     Inputs:     Tag for the command
01086     Returns:    success
01087     Purpose:    starts writing a tag to the file
01088     SeeAlso:    
01089 
01090 ********************************************************************************************/
01091 
01092 BOOL CMXExportDC::StartTag(INT32 Tag)
01093 {
01094     if(!ThirtyTwoBit)
01095         return TRUE;        // 16 bit files don't have tags
01096 
01097     ERROR2IF(DoingTag == TRUE, FALSE, "already doing a tag");
01098 
01099     // write the tag header
01100     cmxTagHdr hdr;
01101     hdr.ID = (BYTE)Tag;
01102     hdr.Size = 0;
01103     ExportFile->write(&hdr, sizeof(hdr));
01104 
01105     // initialise the future value
01106     TagLengthFuture.Init(this, FUTURE_BACKLOC(&hdr, Size), sizeof(hdr.Size));
01107     TagLengthFuture.SetLengthStartPos(this, 0-(INT32)sizeof(hdr));
01108 
01109     // flag
01110     DoingTag = TRUE;
01111 
01112     return TRUE;
01113 }
01114 
01115     
01116 /********************************************************************************************
01117 
01118 >   BOOL CMXExportDC::EndTag(void)
01119 
01120     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01121     Created:    27/06/96
01122     Inputs:     none
01123     Returns:    success
01124     Purpose:    ends a tag
01125     SeeAlso:    
01126 
01127 ********************************************************************************************/
01128 
01129 BOOL CMXExportDC::EndTag(void)
01130 {
01131     if(!ThirtyTwoBit)
01132         return TRUE;        // 16 bit files don't have tags
01133 
01134     ERROR2IF(DoingTag == FALSE, FALSE, "not doing a tag");
01135     ERROR2IF(NestedTagLevel != 0, FALSE, "tried to end a main tag when nested tags are active");
01136 
01137     // write the length
01138     TagLengthFuture.Write(this);
01139 
01140     // flag
01141     DoingTag = FALSE;
01142 
01143     return TRUE;
01144 }
01145 
01146 
01147 /********************************************************************************************
01148 
01149 >   BOOL CMXExportDC::StartNestedTag(INT32 Tag)
01150 
01151     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01152     Created:    27/06/96
01153     Inputs:     Tag for the command
01154     Returns:    success
01155     Purpose:    starts writing a nested tag to the file
01156     SeeAlso:    
01157 
01158 ********************************************************************************************/
01159 
01160 BOOL CMXExportDC::StartNestedTag(INT32 Tag)
01161 {
01162     if(!ThirtyTwoBit)
01163         return TRUE;        // 16 bit files don't have tags
01164 
01165     ERROR2IF(DoingTag == FALSE, FALSE, "tried to start a nested tag outside a tag");
01166 
01167     // write the tag header
01168     cmxTagHdr hdr;
01169     hdr.ID = (BYTE)Tag;
01170     hdr.Size = 0;
01171     ExportFile->write(&hdr, sizeof(hdr));
01172 
01173     // get one of those nested tag record things
01174     CMXNestedTagRecord *pRec = new CMXNestedTagRecord;
01175     if(pRec == NULL)
01176         return FALSE;
01177 
01178     // initialise the future value
01179     pRec->LengthFuture.Init(this, FUTURE_BACKLOC(&hdr, Size), sizeof(hdr.Size));
01180     pRec->LengthFuture.SetLengthStartPos(this, 0-(INT32)sizeof(hdr));
01181 
01182     // add the record to the list
01183     NestedTagList.AddTail(pRec);
01184 
01185     // flag
01186     NestedTagLevel++;
01187 
01188     return TRUE;
01189 }
01190 
01191     
01192 /********************************************************************************************
01193 
01194 >   BOOL CMXExportDC::EndNestedTag(void)
01195 
01196     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01197     Created:    04/07/96
01198     Inputs:     none
01199     Returns:    success
01200     Purpose:    ends a nested tag
01201     SeeAlso:    
01202 
01203 ********************************************************************************************/
01204 
01205