00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 #include <math.h>
00101 #include "camtypes.h"
00102
00103 #include "cmxexdc.h"
00104 #include "cmxform.h"
00105 #include "riffform.h"
00106
00107 #include "colormgr.h"
00108
00109 #include "camelot.h"
00110 #include "cversion.h"
00111 #include "prvwflt.h"
00112
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
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 CMXFutureUpdater::CMXFutureUpdater()
00157 {
00158 AbsPosition = -1;
00159 DataSize = 0;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
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
00186
00187
00188
00189
00190
00191
00192
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
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 BOOL CMXFutureUpdater::WriteValue(CMXExportDC *pDC, INT32 Value)
00225 {
00226 ERROR2IF(pDC == 0, FALSE, "No pDC, chaps");
00227
00228
00229 if(!pDC->WriteNumber(AbsPosition, DataSize, Value))
00230 return FALSE;
00231
00232
00233 AbsPosition = -1;
00234 DataSize = 0;
00235 Reset();
00236
00237 return TRUE;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 CMXFutureLength::CMXFutureLength()
00255 {
00256 StartPos = -1;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
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
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 void CMXFutureLength::Reset(void)
00296 {
00297 StartPos = -1;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
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
00330
00331
00332
00333
00334
00335
00336
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
00351
00352
00353
00354
00355
00356
00357
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
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 CMXReferListItemOffset::CMXReferListItemOffset(CMXExportDC *pDC)
00382 : CMXReferListItem(pDC)
00383 {
00384 Offset = pDC->GetFilePosition();
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
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
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 BOOL CMXReferLayer::WriteInReferenceList(CMXExportDC *pDC)
00422 {
00423 ERROR2IF(pDC == 0, FALSE, "no DC");
00424
00425
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
00442
00443
00444
00445
00446
00447
00448
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
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 BOOL CMXReferLayer::WriteInIndex(CMXExportDC *pDC)
00476 {
00477
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
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 BOOL CMXReferPage::WriteInIndex(CMXExportDC *pDC)
00506 {
00507
00508
00509 cmxPageIndexEntry pe;
00510
00511
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
00529
00530
00531
00532
00533
00534
00535
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
00564
00565
00566
00567
00568
00569
00570
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
00589
00590
00591
00592
00593
00594
00595
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;
00607
00608
00609
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
00630 OutputModel = COLOURMODEL_RGBT;
00631 ColH.ColType = cmxCOLMODEL_RGB;
00632 break;
00633 }
00634
00635
00636 if(!pDC->WriteTag(cmxTAG_DescrSection_Color_Base, &ColH, sizeof(ColH)))
00637 return FALSE;
00638
00639
00640 ColourContext *OutputCC = ColourManager::GetColourContext(OutputModel);
00641 ERROR3IF(OutputCC == NULL, "Can't find a colour context");
00642
00643
00644 ColourPacked Result;
00645 OutputCC->ConvertColour(&Colour, &Result);
00646
00647
00648 if(!pDC->StartTag(cmxTAG_DescrSection_Color_ColorDescr))
00649 return FALSE;
00650
00651
00652 switch (OutputModel)
00653 {
00654 case COLOURMODEL_HSVT:
00655 {
00656
00657
00658
00659
00660
00661
00662
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
00696 if(!pDC->EndTag())
00697 return FALSE;
00698
00699
00700 if(!pDC->WriteMinEndTag())
00701 return FALSE;
00702
00703 return TRUE;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 BOOL CMXReferMasterIndex::WriteInIndex(CMXExportDC *pDC)
00721 {
00722
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
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 BOOL CMXReferMasterLayer::WriteInIndex(CMXExportDC *pDC)
00751 {
00752
00753 if(pDC->IsThirtyTwoBit())
00754 {
00755 cmxMasterLayerEntry32 le;
00756
00757 le.TableType = cmxMASTERIN_MASTERLAYER;
00758 le.SizeInFile = sizeof(DWORD);
00759 le.ID = 1;
00760 le.Offset = Offset;
00761
00762 if(!pDC->WriteData(&le, sizeof(le)))
00763 return FALSE;
00764 }
00765 else
00766 {
00767 cmxMasterLayerEntry16 le;
00768
00769 le.TableType = cmxMASTERIN_MASTERLAYER;
00770 le.ID = 1;
00771 le.Offset = Offset;
00772
00773 if(!pDC->WriteData(&le, sizeof(le)))
00774 return FALSE;
00775 }
00776
00777 return TRUE;
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 CMXExportDC::CMXExportDC(Filter *Parent) : ExportDC(Parent)
00793 {
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 BOOL CMXExportDC::Init(CCLexFile* pFile, CMXRenderRegion *pReg, BOOL bThirtyTwoBit, BOOL ClipboardExport)
00813 {
00814
00815 if (!ExportDC::Init(pFile)) return FALSE;
00816
00817
00818
00819 ExportFile->SetThrowExceptions(TRUE);
00820 ExportFile->SetReportErrors(FALSE);
00821
00822
00823 ThirtyTwoBit = bThirtyTwoBit;
00824
00825
00826 CurrentSection = CMXSECTION_NONE;
00827
00828
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
00842 if(!ClipboardExport)
00843 {
00844
00845 AreIgnoreingOverlappedLenses = FALSE;
00846 OverlappedLensesHaveBeenIgnored = FALSE;
00847 HaveAskedUserAboutLenses = FALSE;
00848 }
00849 else
00850 {
00851
00852 AreIgnoreingOverlappedLenses = TRUE;
00853 OverlappedLensesHaveBeenIgnored = FALSE;
00854 HaveAskedUserAboutLenses = TRUE;
00855 }
00856
00857 for(INT32 i = 0 ; i < CMXFUTUREVALUECACHESIZE ; i++)
00858 {
00859
00860 FutureDataCache[i].Location = INT32_MAX;
00861 FutureDataCache[i].Data = 0;
00862 FutureDataCache[i].DataSize = 0;
00863 }
00864
00865
00866 CMXReferDefaultScreen *pDefScreen = new CMXReferDefaultScreen(this);
00867 if(pDefScreen == NULL) return FALSE;
00868
00869
00870 ReferList.AddTail(pDefScreen);
00871
00872
00873 CMXReferDefaultDotDash *pDefdd = new CMXReferDefaultDotDash(this);
00874 if(pDefdd == NULL) return FALSE;
00875
00876
00877 ReferList.AddTail(pDefdd);
00878 return TRUE;
00879 }
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 void CMXExportDC::CleanUp(void)
00895 {
00896 WriteFutureDataCache();
00897 ReferList.DeleteAll();
00898 LensBBoxes.DeleteAll();
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
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
00920
00921 DWORD id;
00922 BOOL IsAList = FALSE;
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
00953 RIFFck chdr;
00954 chdr.ckID = IsAList?RIFFTYPE_LIST:id;
00955 chdr.ckSize = 0;
00956 ExportFile->write(&chdr, sizeof(chdr));
00957
00958
00959 SectionLengthFuture.Init(this, FUTURE_BACKLOC(&chdr, ckSize), sizeof(chdr.ckSize));
00960 SectionLengthFuture.SetLengthStartPos(this, 0 );
00961
00962
00963 if(IsAList)
00964 ExportFile->write(&id, sizeof(id));
00965
00966
00967 CurrentSection = Type;
00968
00969 return TRUE;
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
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
00991 SectionLengthFuture.Write(this);
00992
00993
00994 CurrentSection = CMXSECTION_NONE;
00995
00996
00997 if((GetFilePosition() & 1) != 0)
00998 {
00999
01000 ExportFile->put('\0');
01001 }
01002
01003 return TRUE;
01004 }
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
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
01025 RIFFck chdr;
01026 chdr.ckID = RIFFTYPE_LIST;
01027 chdr.ckSize = 0;
01028 ExportFile->write(&chdr, sizeof(chdr));
01029
01030
01031 RIFFListLengthFuture.Init(this, FUTURE_BACKLOC(&chdr, ckSize), sizeof(chdr.ckSize));
01032 RIFFListLengthFuture.SetLengthStartPos(this, 0);
01033
01034
01035 DWORD id = Type;
01036 ExportFile->write(&id, sizeof(id));
01037
01038
01039 DoingRIFFList = TRUE;
01040
01041 return TRUE;
01042 }
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
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
01063 RIFFListLengthFuture.Write(this);
01064
01065
01066 if((GetFilePosition() & 1) != 0)
01067 {
01068
01069 ExportFile->put('\0');
01070 }
01071
01072
01073 DoingRIFFList = FALSE;
01074
01075 return TRUE;
01076 }
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 BOOL CMXExportDC::StartTag(INT32 Tag)
01093 {
01094 if(!ThirtyTwoBit)
01095 return TRUE;
01096
01097 ERROR2IF(DoingTag == TRUE, FALSE, "already doing a tag");
01098
01099
01100 cmxTagHdr hdr;
01101 hdr.ID = (BYTE)Tag;
01102 hdr.Size = 0;
01103 ExportFile->write(&hdr, sizeof(hdr));
01104
01105
01106 TagLengthFuture.Init(this, FUTURE_BACKLOC(&hdr, Size), sizeof(hdr.Size));
01107 TagLengthFuture.SetLengthStartPos(this, 0-(INT32)sizeof(hdr));
01108
01109
01110 DoingTag = TRUE;
01111
01112 return TRUE;
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129 BOOL CMXExportDC::EndTag(void)
01130 {
01131 if(!ThirtyTwoBit)
01132 return TRUE;
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
01138 TagLengthFuture.Write(this);
01139
01140
01141 DoingTag = FALSE;
01142
01143 return TRUE;
01144 }
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160 BOOL CMXExportDC::StartNestedTag(INT32 Tag)
01161 {
01162 if(!ThirtyTwoBit)
01163 return TRUE;
01164
01165 ERROR2IF(DoingTag == FALSE, FALSE, "tried to start a nested tag outside a tag");
01166
01167
01168 cmxTagHdr hdr;
01169 hdr.ID = (BYTE)Tag;
01170 hdr.Size = 0;
01171 ExportFile->write(&hdr, sizeof(hdr));
01172
01173
01174 CMXNestedTagRecord *pRec = new CMXNestedTagRecord;
01175 if(pRec == NULL)
01176 return FALSE;
01177
01178
01179 pRec->LengthFuture.Init(this, FUTURE_BACKLOC(&hdr, Size), sizeof(hdr.Size));
01180 pRec->LengthFuture.SetLengthStartPos(this, 0-(INT32)sizeof(hdr));
01181
01182
01183 NestedTagList.AddTail(pRec);
01184
01185
01186 NestedTagLevel++;
01187
01188 return TRUE;
01189 }
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205 BOOL CMXExportDC::EndNestedTag(void)
01206 {
01207 if(!ThirtyTwoBit)
01208 return TRUE;
01209
01210 ERROR2IF(DoingTag == FALSE, FALSE, "not doing a tag");
01211 ERROR2IF(NestedTagLevel <= 0, FALSE, "not doing a nested tag");
01212
01213
01214 CMXNestedTagRecord *pRec = (CMXNestedTagRecord *)NestedTagList.GetTail();
01215
01216
01217 ERROR2IF(!IS_A(pRec, CMXNestedTagRecord), FALSE, "tag record not a tag record");
01218
01219
01220 pRec->LengthFuture.Write(this);
01221
01222
01223 delete NestedTagList.RemoveTail();
01224
01225
01226 NestedTagLevel--;
01227
01228 return TRUE;
01229 }
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 BOOL CMXExportDC::DoWriteTag(INT32 Tag, void *Data, UINT32 Size, BOOL Nested)
01246 {
01247 if(!Nested)
01248 {
01249 ERROR2IF(DoingTag == TRUE, FALSE, "already doing a tag");
01250 }
01251
01252
01253 if(ThirtyTwoBit)
01254 {
01255
01256 cmxTagHdr hdr;
01257 hdr.ID = (BYTE)Tag;
01258 hdr.Size = sizeof(hdr)+Size;
01259 ExportFile->write(&hdr, sizeof(hdr));
01260 }
01261
01262
01263 if(Size != 0)
01264 ExportFile->write(Data, Size);
01265
01266 return TRUE;
01267 }
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 BOOL CMXExportDC::WriteCommand(UINT32 Tag, void *Data, UINT32 Size)
01285 {
01286 ERROR2IF(DoingCommand != FALSE, FALSE, "Already writing a command");
01287
01288
01289 cmxInstrHdr hdr = {Size + sizeof(hdr), ThirtyTwoBit?Tag:(0 - (SWORD)Tag)};
01290
01291
01292 if((hdr.Size & 1) != 0)
01293 hdr.Size++;
01294
01295 ExportFile->write(&hdr, sizeof(hdr));
01296
01297 if(Size != 0)
01298 {
01299 ERROR2IF(Data == 0, FALSE, "didn't get some data");
01300
01301
01302 ExportFile->write(Data, Size);
01303 }
01304
01305 Tally++;
01306 PageInstructionCount++;
01307 LayerInstructionCount++;
01308
01309
01310 if(( Size & 1) != 0)
01311 {
01312
01313 ExportFile->put('\0');
01314 }
01315
01316 return TRUE;
01317 }
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334 BOOL CMXExportDC::StartCommand(UINT32 Tag)
01335 {
01336 ERROR2IF(DoingCommand != FALSE, FALSE, "Already writing a command");
01337
01338
01339 CurrentInstrFilePosition = GetFilePosition();
01340
01341
01342 cmxInstrHdr hdr = {0, ThirtyTwoBit?Tag:(0 - (SWORD)Tag)};
01343 ExportFile->write(&hdr, sizeof(hdr));
01344
01345 Tally++;
01346 PageInstructionCount++;
01347 LayerInstructionCount++;
01348
01349
01350 CommandLengthFuture.Init(this, FUTURE_BACKLOC(&hdr, Size), sizeof(hdr.Size));
01351 CommandLengthFuture.SetLengthStartPos(this, 0 - (INT32)sizeof(hdr));
01352
01353
01354 DoingCommand = TRUE;
01355
01356 return TRUE;
01357 }
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373 BOOL CMXExportDC::EndCommand(void)
01374 {
01375 ERROR2IF(DoingCommand != TRUE, FALSE, "Already writing a command");
01376
01377
01378 if((GetFilePosition() & 1) != 0)
01379 {
01380
01381 ExportFile->put('\0');
01382 }
01383
01384 CommandLengthFuture.Write(this);
01385
01386 DoingCommand = FALSE;
01387
01388 CurrentInstrFilePosition = -1;
01389
01390 return TRUE;
01391 }
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412 BOOL CMXExportDC::CreateHeader(DocRect *pFileBBox)
01413 {
01414 ERROR2IF(pMatrix == NULL, FALSE, "No matrix yet");
01415
01416
01417 RIFFFile_Header rhdr;
01418 rhdr.CK.ckID = RIFFTYPE_RIFF;
01419 rhdr.CK.ckSize = 0;
01420 rhdr.FormType = cmxRIFFFORMTYPE_CMX;
01421
01422 ExportFile->write(&rhdr, sizeof(rhdr));
01423
01424
01425 FileLengthFuture.Init(this, FUTURE_BACKLOC(&rhdr, CK.ckSize), sizeof(rhdr.CK.ckSize));
01426 FileLengthFuture.SetLengthStartPos(this, -(INT32)sizeof(DWORD));
01427
01428
01429 if(!StartSection(CMXSECTION_HEADER))
01430 return FALSE;
01431
01432
01433 cmxHeader fhdr;
01434 memset(&fhdr, 0, sizeof(fhdr));
01435 camStrcpy((char *)fhdr.Id, cmxID);
01436 camStrcpy((char *)fhdr.OS, cmxOS);
01437 fhdr.ByteOrder = cmxBYTEORDER_INTEL | 0x30;
01438 if(ThirtyTwoBit)
01439 {
01440 fhdr.CoordSize = cmxCOORDSIZE_32 | 0x30;
01441 fhdr.Major = cmxMAJOR_32 | 0x30;
01442 fhdr.Factor = cmxFACTOR_32;
01443 fhdr.Unit = cmxUNIT_MILLIMETER;
01444 }
01445 else
01446 {
01447 fhdr.CoordSize = cmxCOORDSIZE_16 | 0x30;
01448 fhdr.Major = cmxMAJOR_16 | 0x30;
01449 fhdr.Factor = cmxFACTOR_16;
01450 fhdr.Unit = cmxUNIT_INCH;
01451 }
01452 fhdr.Minor = cmxMINOR | 0x30;
01453
01454
01455 DocRect bb = *pFileBBox;
01456 pMatrix->TransformBounds(&bb);
01457
01458 fhdr.IBBLeft = bb.lo.x;
01459 fhdr.IBBTop = bb.hi.y;
01460 fhdr.IBBRight = bb.hi.x;
01461 fhdr.IBBBottom = bb.lo.y;
01462 fhdr.IThumbnail = -1;
01463
01464 ExportFile->write(&fhdr, sizeof(fhdr));
01465
01466
01467 Tally.Init(this, FUTURE_BACKLOC(&fhdr, ITally), sizeof(fhdr.ITally));
01468 Tally = 0;
01469 IndexSectionFuture.Init(this, FUTURE_BACKLOC(&fhdr, IIndexSection), sizeof(fhdr.IIndexSection));
01470 TrailerIndexFuture.Init(this, FUTURE_BACKLOC(&fhdr, IInfoSection), sizeof(fhdr.IInfoSection));
01471 ThumbnailIndexFuture.Init(this, FUTURE_BACKLOC(&fhdr, IThumbnail), sizeof(fhdr.IThumbnail));
01472
01473
01474 if(!EndSection())
01475 return FALSE;
01476
01477 return TRUE;
01478 }
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 BOOL CMXExportDC::PolishOffThatFile()
01495 {
01496 ERROR2IF(CurrentSection != CMXSECTION_NONE, FALSE, "Didn't end the section before ending the file");
01497
01498
01499
01500 if(!Tally.Write(this))
01501 return FALSE;
01502
01503
01504 if(!TrailerIndexFuture.Write(this))
01505 return FALSE;
01506 if(!StartSection(CMXSECTION_TRAILER))
01507 return FALSE;
01508 if(!EndSection())
01509 return FALSE;
01510
01511
01512 if(!FileLengthFuture.Write(this))
01513 return FALSE;
01514
01515
01516 WriteFutureDataCache();
01517
01518
01519 return TRUE;
01520 }
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535 INT32 CMXExportDC::GetFilePosition()
01536 {
01537 return ExportFile->tell();
01538 }
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553 BOOL CMXExportDC::WriteBBox(DocRect *BBox, BOOL Transform)
01554 {
01555 ERROR2IF(pMatrix == NULL, FALSE, "No matrix");
01556
01557 if(ThirtyTwoBit)
01558 {
01559 DocRect bb = *BBox;
01560 if(Transform)
01561 pMatrix->TransformBounds(&bb);
01562
01563 cmxBBox32 b = {bb.lo.x, bb.hi.y, bb.hi.x, bb.lo.y};
01564
01565 ExportFile->write(&b, sizeof(b));
01566 }
01567 else
01568 {
01569 DocRect bb = *BBox;
01570 if(Transform)
01571 pMatrix->TransformBounds(&bb);
01572
01573 cmxBBox16 b = {(SWORD)bb.lo.x, (SWORD)bb.hi.y, (SWORD)bb.hi.x, (SWORD)bb.lo.y};
01574
01575 ExportFile->write(&b, sizeof(b));
01576 }
01577
01578 return TRUE;
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595 void CMXExportDC::WriteAngle ( double theta )
01596 {
01597
01598 theta = ( theta * 360.0 ) / ( 2.0 * PI );
01599
01600
01601 if(ThirtyTwoBit)
01602 {
01603 INT32 Angle32 = ( INT32 ) ( theta * 1000000.0 );
01604 ExportFile->write ( &Angle32, sizeof ( Angle32 ) );
01605 }
01606 else
01607 {
01608 short Angle16 = ( short ) ( theta * 10.0);
01609 ExportFile->write ( &Angle16, sizeof ( Angle16 ) );
01610 }
01611 }
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626 BOOL CMXExportDC::WriteString(StringBase *Str)
01627 {
01628 INT32 StrLen = Str->Length();
01629
01630 cmxString h;
01631 h.Length = (WORD)StrLen;
01632 ExportFile->write(&h, sizeof(h));
01633
01634 ExportFile->write((TCHAR *)(*Str), StrLen);
01635
01636 return TRUE;
01637 }
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652 BOOL CMXExportDC::WriteMatrix(Matrix *pMatrix)
01653 {
01654 if(pMatrix == NULL)
01655 {
01656
01657 WORD MatrixType = cmxMATRIXTYPE_IDENTITY;
01658 ExportFile->write(&MatrixType, sizeof(MatrixType));
01659 }
01660 else
01661 {
01662
01663 cmxMatrix Thingy;
01664 FIXED16 abcd[4];
01665 INT32 ef[2];
01666 pMatrix->GetComponents((FIXED16 *)(&abcd), (INT32 *)(&ef));
01667 Thingy.Type = cmxMATRIXTYPE_GENERAL;
01668 Thingy.a = abcd[0].MakeDouble();
01669 Thingy.b = abcd[1].MakeDouble();
01670 Thingy.c = abcd[2].MakeDouble();
01671 Thingy.d = abcd[3].MakeDouble();
01672 Thingy.e = (DOUBLE)ef[0];
01673 Thingy.f = (DOUBLE)ef[1];
01674
01675 ExportFile->write(&Thingy, sizeof(Thingy));
01676 }
01677
01678 return TRUE;
01679 }
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697 BOOL CMXExportDC::WriteNumber(INT32 Position, UINT32 DataSize, INT32 Value)
01698 {
01699 TRACEUSER( "Claude", _T("Writing number %x at %d, size %d\n"), Value, Position, DataSize);
01700
01701
01702 if(NumberOfEntriesUsedInCache >= (CMXFUTUREVALUECACHESIZE - 1))
01703 WriteFutureDataCache();
01704
01705
01706 INT32 theEntryInCache = 0;
01707
01708
01709
01710 while((theEntryInCache < NumberOfEntriesUsedInCache) && (Position > FutureDataCache[theEntryInCache].Location))
01711 theEntryInCache++;
01712
01713 TRACEUSER( "Claude", _T("Writing entry %d"), theEntryInCache);
01714
01715 if(theEntryInCache < NumberOfEntriesUsedInCache)
01716 {
01717
01718
01719
01720
01721
01722 for(INT32 entrySorting = NumberOfEntriesUsedInCache;
01723 entrySorting >= theEntryInCache; entrySorting--)
01724 {
01725
01726 FutureDataCache[entrySorting+1] = FutureDataCache[entrySorting];
01727 }
01728 }
01729
01730
01731 FutureDataCache[theEntryInCache].Location = Position;
01732 FutureDataCache[theEntryInCache].Data = Value;
01733 FutureDataCache[theEntryInCache].DataSize = DataSize;
01734
01735 TRACEUSER( "Claude", _T("Writing number %x at %d, size %d\n"),
01736 FutureDataCache[theEntryInCache].Data,
01737 FutureDataCache[theEntryInCache].Location,
01738 FutureDataCache[theEntryInCache].DataSize);
01739
01740 NumberOfEntriesUsedInCache++;
01741
01742 return TRUE;
01743 }
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758 BOOL CMXExportDC::WriteFutureDataCache()
01759 {
01760
01761 INT32 here = ExportFile->tell();
01762
01763 for(INT32 i = 0 ; i < NumberOfEntriesUsedInCache ; i++)
01764 {
01765
01766 TRACEUSER( "Claude", _T("Writing cache %x at %d, size %d\n"),
01767 FutureDataCache[i].Data,
01768 FutureDataCache[i].Location,
01769 FutureDataCache[i].DataSize);
01770
01771
01772 ExportFile->seek(FutureDataCache[i].Location);
01773
01774 if(FutureDataCache[i].DataSize != 0)
01775 {
01776
01777 switch(FutureDataCache[i].DataSize)
01778 {
01779 case sizeof(BYTE):
01780 {
01781 BYTE Num = (BYTE)FutureDataCache[i].Data;
01782 ExportFile->write(&Num, sizeof(Num));
01783 }
01784 break;
01785
01786 case sizeof(WORD):
01787 {
01788 WORD Num = (WORD)FutureDataCache[i].Data;
01789 ExportFile->write(&Num, sizeof(Num));
01790 }
01791 break;
01792
01793 case sizeof(INT32):
01794 {
01795 INT32 Num = FutureDataCache[i].Data;
01796 ExportFile->write(&Num, sizeof(Num));
01797 }
01798 break;
01799
01800 default:
01801
01802 ERROR3("OOOKK! Non supported data size");
01803 break;
01804 }
01805
01806 FutureDataCache[i].Location = INT32_MAX;
01807 FutureDataCache[i].Data = 0;
01808 FutureDataCache[i].DataSize = 0;
01809 }
01810 }
01811
01812 ExportFile->seek(here);
01813
01814
01815 NumberOfEntriesUsedInCache = 0;
01816
01817 return TRUE;
01818 }
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833 BOOL CMXExportDC::StartPage(DocRect *BBox, BOOL IsProcedure)
01834 {
01835 ERROR2IF(DoingPage == TRUE, FALSE, "Already doing a page");
01836
01837 if(!IsProcedure)
01838 {
01840
01841
01842 PageRefer = new CMXReferPage(this);
01843 if(PageRefer == NULL)
01844 return FALSE;
01845 ReferList.AddTail(PageRefer);
01846
01847
01848 StartSection(CMXSECTION_PAGE);
01849
01850
01851 StartCommand(cmxINSTR_BeginPage);
01852
01853
01854 if(!StartTag(cmxTAG_BeginPage_PageSpecification))
01855 return FALSE;
01856
01857 cmxInstrPage1 phdr1;
01858 phdr1.PageNumber = 1;
01859 phdr1.Flags = 0;
01860 ExportFile->write(&phdr1, sizeof(phdr1));
01861
01862
01863 PageFlags.Init(this, FUTURE_BACKLOC(&phdr1, Flags), sizeof(phdr1.Flags));
01864 PageFlags = 0;
01865
01866
01867 WriteBBox(BBox);
01868
01869
01870 cmxInstrPage2 phdr2;
01871 phdr2.EndPageOffset = 0;
01872 phdr2.GroupCount = 0;
01873 phdr2.InstructionCount = 0;
01874 ExportFile->write(&phdr2, sizeof(phdr2));
01875
01876
01877 PageEndIndexFuture.Init(this, FUTURE_BACKLOC(&phdr2, EndPageOffset), sizeof(phdr2.EndPageOffset));
01878 PageGroupCount.Init(this, FUTURE_BACKLOC(&phdr2, GroupCount), sizeof(phdr2.GroupCount));
01879 PageGroupCount = 0;
01880 PageInstructionCount.Init(this, FUTURE_BACKLOC(&phdr2, InstructionCount), sizeof(phdr2.InstructionCount));
01881 PageInstructionCount = 1;
01882
01883
01884 if(!EndTag())
01885 return FALSE;
01886
01887
01888 if(!StartTag(cmxTAG_BeginPage_Matrix))
01889 return FALSE;
01890
01891
01892 if(!WriteMatrix())
01893 return FALSE;
01894
01895
01896 if(!EndTag())
01897 return FALSE;
01898
01899
01900 BYTE MapMode = 0;
01901 if(!WriteTag(cmxTAG_BeginPage_MappingMode, &MapMode, sizeof(MapMode)))
01902 return FALSE;
01903
01904
01905 if(!WriteMinEndTag())
01906 return FALSE;
01907
01908
01909 EndCommand();
01910
01911
01912 PageIsProc = FALSE;
01913 }
01914 else
01915 {
01917
01918
01919 StartCommand(cmxINSTR_BeginProcedure);
01920
01921
01922 if(!StartTag(cmxTAG_BeginProcedure_ProcedureSpecification))
01923 return FALSE;
01924
01925 cmxInstrProc1 phdr1;
01926 phdr1.Flags = 0;
01927 ExportFile->write(&phdr1, sizeof(phdr1));
01928
01929
01930 PageFlags.Init(this, FUTURE_BACKLOC(&phdr1, Flags), sizeof(phdr1.Flags));
01931 PageFlags = 0;
01932
01933
01934 WriteBBox(BBox, FALSE);
01935
01936
01937 cmxInstrProc2 phdr2;
01938 phdr2.EndPageOffset = 0;
01939 phdr2.GroupCount = 0;
01940 phdr2.InstructionCount = 0;
01941 ExportFile->write(&phdr2, sizeof(phdr2));
01942
01943
01944 PageEndIndexFuture.Init(this, FUTURE_BACKLOC(&phdr2, EndPageOffset), sizeof(phdr2.EndPageOffset));
01945 PageGroupCount.Init(this, FUTURE_BACKLOC(&phdr2, GroupCount), sizeof(phdr2.GroupCount));
01946 PageGroupCount = 0;
01947 PageInstructionCount.Init(this, FUTURE_BACKLOC(&phdr2, InstructionCount), sizeof(phdr2.InstructionCount));
01948 PageInstructionCount = 1;
01949
01950
01951 if(!EndTag())
01952 return FALSE;
01953
01954
01955 if(!WriteMinEndTag())
01956 return FALSE;
01957
01958
01959 EndCommand();
01960
01961
01962 PageIsProc = TRUE;
01963 }
01964
01965 DoingPage = TRUE;
01966 LayerNumber = 0;
01967
01968
01969 if(!IsProcedure)
01970 FirstInstrFilePosition = GetFilePosition();
01971
01972
01973
01974 return TRUE;
01975 }
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991 BOOL CMXExportDC::EndPage(void)
01992 {
01993 ERROR2IF(DoingPage == FALSE, FALSE, "Not doing a page");
01994
01995
01996 PageEndIndexFuture.Write(this);
01997
01998
01999 if(!PageIsProc)
02000 WriteCommand(cmxINSTR_EndPage);
02001 else
02002 WriteCommand(cmxINSTR_EndSection);
02003
02004
02005 PageFlags.Write(this);
02006 PageInstructionCount.Write(this);
02007 PageGroupCount.Write(this);
02008
02009
02010 if(!PageIsProc)
02011 EndSection();
02012
02013 DoingPage = FALSE;
02014
02015 return TRUE;
02016 }
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032 BOOL CMXExportDC::StartLayer(String_256 &Name)
02033 {
02034 ERROR2IF(DoingPage == FALSE, FALSE, "Layers should be in pages");
02035 ERROR2IF(DoingLayer == TRUE, FALSE, "Already doing a layer");
02036
02037 LayerNumber++;
02038
02039
02040 CMXReferLayer *pRL = new CMXReferLayer(this);
02041 if(pRL == NULL)
02042 return FALSE;
02043 pRL->SetLayerDetails(LayerNumber, &Name);
02044 ReferList.AddTail(pRL);
02045
02046
02047 StartCommand(cmxINSTR_BeginLayer);
02048
02049
02050 if(!StartTag(cmxTAG_BeginLayer_LayerSpecification))
02051 return FALSE;
02052
02053
02054 cmxInstrLayer1 chdr1;
02055 chdr1.PageNumber = 1;
02056 chdr1.LayerNumber = (WORD)LayerNumber;
02057 chdr1.LayerFlags = 0;
02058 chdr1.InstructionCount = 0;
02059 ExportFile->write(&chdr1, sizeof(chdr1));
02060
02061
02062 LayerInstructionCount.Init(this, FUTURE_BACKLOC(&chdr1, InstructionCount), sizeof(chdr1.InstructionCount));
02063 LayerFlags.Init(this, FUTURE_BACKLOC(&chdr1, LayerFlags), sizeof(chdr1.LayerFlags));
02064 LayerFlags = 0;
02065
02066
02067 WriteString(&Name);
02068
02069
02070 if(!EndTag())
02071 return FALSE;
02072
02073
02074 if(!StartTag(cmxTAG_BeginLayer_Matrix))
02075 return FALSE;
02076 if(!WriteMatrix())
02077 return FALSE;
02078 if(!EndTag())
02079 return FALSE;
02080
02081
02082 BYTE MapMode = 0;
02083 if(!WriteTag(cmxTAG_BeginLayer_MappingMode, &MapMode, sizeof(MapMode)))
02084 return FALSE;
02085
02086
02087 if(!WriteMinEndTag())
02088 return FALSE;
02089
02090
02091 EndCommand();
02092
02093 LayerInstructionCount = 1;
02094
02095 DoingLayer = TRUE;
02096
02097 return TRUE;
02098 }
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114 BOOL CMXExportDC::EndLayer(void)
02115 {
02116 ERROR2IF(DoingLayer == FALSE, FALSE, "Already doing a layer");
02117
02118
02119 WriteCommand(cmxINSTR_EndLayer);
02120
02121
02122 LayerInstructionCount.Write(this);
02123 LayerFlags.Write(this);
02124
02125 DoingLayer = FALSE;
02126
02127 return TRUE;
02128 }
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145 BOOL CMXExportDC::StartGroup(DocRect *BBox, BOOL TransformBBox)
02146 {
02147 ERROR2IF(DoingLayer == FALSE && !PageIsProc, FALSE, "Groups should be in layers");
02148
02149
02150 PageGroupCount++;
02151
02152
02153 if(!StartCommand(cmxINSTR_BeginGroup))
02154 return FALSE;
02155
02156
02157 if(!StartTag(cmxTAG_BeginGroup_GroupSpecification))
02158 return FALSE;
02159
02160
02161 if(!WriteBBox(BBox, TransformBBox))
02162 return FALSE;
02163
02164
02165 CMXGroupRecord *pGRec = new CMXGroupRecord(this);
02166 if(pGRec == NULL)
02167 return FALSE;
02168
02169
02170 GroupList.AddTail(pGRec);
02171
02172
02173 cmxGroupInfo gi = {0,0,0};
02174 ExportFile->write(&gi, sizeof(gi));
02175
02176 if(!EndTag())
02177 return FALSE;
02178
02179 if(!WriteMinEndTag())
02180 return FALSE;
02181
02182
02183 if(!EndCommand())
02184 return FALSE;
02185
02186 return TRUE;
02187 }
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203 BOOL CMXExportDC::EndGroup(void)
02204 {
02205
02206 CMXGroupRecord *pGRec = (CMXGroupRecord *)GroupList.GetTail();
02207
02208
02209 if(!pGRec->Write(this))
02210 return FALSE;
02211
02212
02213 delete GroupList.RemoveTail();
02214
02215
02216 if(!WriteCommand(cmxINSTR_EndGroup))
02217 return FALSE;
02218
02219 return TRUE;
02220 }
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236 CMXGroupRecord::CMXGroupRecord(CMXExportDC *pDC)
02237 {
02238 Offset = pDC->GetFilePosition();
02239 TallyAtStart = pDC->GetInstructionTally();
02240 GroupCountAtStart = pDC->GetGroupCount();
02241 }
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257 BOOL CMXGroupRecord::Write(CMXExportDC *pDC)
02258 {
02259
02260 if(!pDC->WriteNumber(Offset, sizeof(WORD), pDC->GetGroupCount() - GroupCountAtStart))
02261 return FALSE;
02262
02263 if(!pDC->WriteNumber(Offset + sizeof(WORD), sizeof(DWORD), pDC->GetInstructionTally() - TallyAtStart))
02264 return FALSE;
02265
02266 if(!pDC->WriteNumber(Offset + sizeof(WORD) + sizeof(DWORD), sizeof(DWORD), pDC->GetFilePosition()))
02267 return FALSE;
02268
02269 return TRUE;
02270 }
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286 BOOL CMXExportDC::WriteReferenceList(void)
02287 {
02288
02289 WORD RefListEntries = 0;
02290 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
02291 while(pEn != 0)
02292 {
02293 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "Entry in the refer list isn't a correct list item");
02294
02295 if(pEn->IsInReferenceList())
02296 RefListEntries++;
02297
02298 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02299 }
02300
02301
02302 ERROR2IF(PageRefer == NULL, FALSE, "no page reference item");
02303 PageRefer->SetRefListOffset(GetFilePosition());
02304 RefListOffset = GetFilePosition();
02305
02306
02307 if(!StartSection(CMXSECTION_REFLIST))
02308 return FALSE;
02309
02310
02311 ExportFile->write(&RefListEntries, sizeof(RefListEntries));
02312
02313
02314 pEn = (CMXReferListItem *)ReferList.GetHead();
02315 while(pEn != 0)
02316 {
02317 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "Entry in the refer list isn't a correct list item");
02318
02319 if(!pEn->WriteInReferenceList(this))
02320 return FALSE;
02321
02322 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02323 }
02324
02325
02326 if(!EndSection())
02327 return FALSE;
02328
02329 return TRUE;
02330 }
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346 BOOL CMXExportDC::WriteIndex(void)
02347 {
02348
02349 if(!StartSection(CMXSECTION_INDEX))
02350 return FALSE;
02351
02352
02353 if(!WriteAnIndex(cmxINDEX_LAYER))
02354 return FALSE;
02355
02356
02357 if(!WriteAnIndex(cmxINDEX_MASTERLAYER))
02358 return FALSE;
02359
02360
02361 if(!WriteAnIndex(cmxINDEX_PAGE))
02362 return FALSE;
02363
02364
02365 if(!WriteAnIndex(cmxINDEX_PROCEDURE))
02366 return FALSE;
02367
02368
02369 if(!WriteAnIndex(cmxINDEX_EMBEDFILE))
02370 return FALSE;
02371
02372
02373 if(!WriteAnIndex(cmxINDEX_ARROW))
02374 return FALSE;
02375
02376
02377 if(!WriteAnIndex(cmxINDEX_MASTERINDEX))
02378 return FALSE;
02379
02380
02381 if(!EndSection())
02382 return FALSE;
02383
02384 return TRUE;
02385 }
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401 BOOL CMXExportDC::WriteCamComment(void)
02402 {
02403 if(PageIsProc)
02404 return TRUE;
02405
02406 CCamApp* Application;
02407 String_64 Text;
02408 String_256 TheText = String_256("saved from " PRODUCT_NAME " ");
02409
02410
02411 Application = (CCamApp*) AfxGetApp();
02412
02413 Application->GetCamelotVersion(&Text);
02414 Text += TEXT("(v");
02415 Text += TEXT(PRODUCT_VERSION_NO);
02416 Text += TEXT(")");
02417 TheText += Text;
02418
02419
02420
02421 Text._MakeMsg(TEXT(" (#1%d) "), (INT32) CAMELOT_VERSION_MINOR);
02422 TheText += Text;
02423
02424 Application->GetCamelotType(&Text);
02425 TheText += Text;
02426
02427 TheText += " on ";
02428 Application->GetHostOSName(&Text);
02429 TheText += Text;
02430
02431 TRACEUSER( "Ben", _T("setting comment = %s\n"), (TCHAR *)TheText);
02432
02433
02434 if(!StartCommand(cmxINSTR_Comment) || !StartTag(cmxTAG_Comment_CommentSpecification))
02435 return FALSE;
02436
02437 WORD Size = TheText.Length();
02438
02439 ExportFile->write(&Size, sizeof(Size));
02440
02441 ExportFile->write((TCHAR *)TheText, Size);
02442
02443
02444 if(!EndTag() || !WriteMinEndTag() || !EndCommand())
02445 return FALSE;
02446
02447 return TRUE;
02448 }
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464 BOOL CMXExportDC::WriteReferSections(void)
02465 {
02466
02467 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
02468 while(pEn != 0)
02469 {
02470 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02471
02472 if(pEn->IsASection())
02473 {
02474 if(!pEn->WriteSection(this))
02475 return FALSE;
02476 }
02477
02478 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02479 }
02480
02481 return TRUE;
02482 }
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498 BOOL CMXExportDC::WriteAnIndex(INT32 Which)
02499 {
02500
02501 INT32 TableSize = sizeof(WORD);
02502
02503
02504
02505 INT32 id;
02506 CMXReferMasterIndex *pMIE = new CMXReferMasterIndex(this);
02507 if(pMIE == NULL)
02508 return FALSE;
02509 BOOL NoMIE = FALSE;
02510 switch(Which)
02511 {
02512 case cmxINDEX_LAYER:
02513 {
02514 ERROR2IF(PageRefer == NULL, FALSE, "no page refer set up");
02515 PageRefer->SetLayerTableOffset(GetFilePosition());
02516
02517 id = cmxRIFFCI_LayerIndex;
02518 NoMIE = TRUE;
02519 TableSize += sizeof(WORD);
02520
02521
02522 CMXReferMasterLayer *pML = new CMXReferMasterLayer(this);
02523 if(pML == NULL)
02524 return FALSE;
02525 ReferList.AddTail(pML);
02526 }
02527 break;
02528
02529 case cmxINDEX_PAGE:
02530 id = cmxRIFFCI_PageIndex;
02531 pMIE->SetType(cmxMASTERIN_PAGE);
02532 break;
02533
02534 case cmxINDEX_MASTERINDEX:
02535
02536 IndexSectionFuture.Write(this);
02537
02538 TableSize += sizeof(cmxMasterIndexHeader);
02539 id = cmxRIFFCI_MasterIndex;
02540 pMIE->SetType(cmxMASTERIN_MASTERIN);
02541 break;
02542
02543 case cmxINDEX_MASTERLAYER:
02544 id = cmxRIFFCI_MasterLayerIndex;
02545 pMIE->SetType(cmxMASTERIN_MASTERLAYER);
02546 break;
02547
02548 case cmxINDEX_PROCEDURE:
02549 id = cmxRIFFCI_ProcIndex;
02550 pMIE->SetType(cmxMASTERIN_PROCEDURE);
02551 break;
02552
02553 case cmxINDEX_EMBEDFILE:
02554 id = cmxRIFFCI_EmbeddedFileIndex;
02555 pMIE->SetType(cmxMASTERIN_EMBEDFILE);
02556 break;
02557
02558 case cmxINDEX_ARROW:
02559 id = cmxRIFFCI_ArrowIndex;
02560 pMIE->SetType(cmxMASTERIN_ARROW);
02561 TableSize += sizeof(cmxArrowIndexHeader) + (ThirtyTwoBit?sizeof(WORD):0);
02562 break;
02563
02564 default:
02565 ERROR3("Don't know what type of index to write!");
02566 }
02567
02568 if(NoMIE)
02569 {
02570 delete pMIE;
02571 }
02572 else
02573 {
02574 ReferList.AddTail(pMIE);
02575 }
02576
02577
02578 WORD Entries = 0;
02579 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
02580 while(pEn != 0)
02581 {
02582 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02583
02584 if(pEn->IsInWhichIndex() == Which)
02585 {
02586 Entries++;
02587 TableSize += pEn->IndexEntrySize(this);
02588 }
02589
02590 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02591 }
02592
02593 if(Entries == 0)
02594 {
02595
02596 delete ReferList.RemoveItem(pMIE);
02597 return TRUE;
02598 }
02599
02600
02601 RIFFck ck;
02602 ck.ckID = id;
02603 ck.ckSize = TableSize;
02604 ExportFile->write(&ck, sizeof(ck));
02605
02606 if(Which == cmxINDEX_MASTERINDEX)
02607 {
02608
02609 cmxMasterIndexHeader mih = {cmxMASTERIN_MASTERIN, ThirtyTwoBit?0xfff:0x18};
02610 ExportFile->write(&mih, sizeof(mih));
02611 }
02612
02613 ExportFile->write(&Entries, sizeof(Entries));
02614
02615
02616 switch(Which)
02617 {
02618 case cmxINDEX_LAYER:
02619 {
02620 WORD PageNumber = 1;
02621 ExportFile->write(&PageNumber, sizeof(PageNumber));
02622 }
02623 break;
02624
02625 case cmxINDEX_ARROW:
02626 {
02627 cmxArrowIndexHeader aih;
02628 WriteSizeInFile(sizeof(cmxArrowIndexEntry));
02629 aih.Type = cmxARROWINDEXTYPE;
02630 ExportFile->write(&aih, sizeof(aih));
02631 }
02632 break;
02633
02634 default:
02635 break;
02636 }
02637
02638
02639 pEn = (CMXReferListItem *)ReferList.GetHead();
02640 while(pEn != 0)
02641 {
02642 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02643
02644 if(pEn->IsInWhichIndex() == Which)
02645 {
02646 if(!pEn->WriteInIndex(this))
02647 return FALSE;
02648 }
02649
02650 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02651 }
02652
02653
02654 if((GetFilePosition() & 1) != 0)
02655 {
02656
02657 ExportFile->put('\0');
02658 }
02659
02660
02661 return TRUE;
02662 }
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677 void CMXExportDC::SetCMXFlag(INT32 flag)
02678 {
02679 PageFlags = ((INT32)PageFlags) | flag;
02680 LayerFlags = ((INT32)LayerFlags) | flag;
02681 }
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697 #define WRITEDESC(h) if(!WriteADesc(h)) return FALSE;
02698
02699 BOOL CMXExportDC::WriteDescriptionSections(void)
02700 {
02701 WRITEDESC(cmxDESC_ARROW)
02702 WRITEDESC(cmxDESC_ARROWHEADS)
02703 WRITEDESC(cmxDESC_DOTDASH)
02704 WRITEDESC(cmxDESC_FONT)
02705 WRITEDESC(cmxDESC_OUTLINE)
02706 WRITEDESC(cmxDESC_LINESTYLE)
02707 WRITEDESC(cmxDESC_PEN)
02708 WRITEDESC(cmxDESC_SCREEN)
02709 WRITEDESC(cmxDESC_COLOUR)
02710
02711 return TRUE;
02712 }
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728 BOOL CMXExportDC::WriteADesc(INT32 Which)
02729 {
02730
02731
02732 INT32 Section;
02733 CMXReferMasterIndex *pMIE = new CMXReferMasterIndex(this);
02734 if(pMIE == NULL)
02735 return FALSE;
02736 BOOL NoMIE = FALSE;
02737 BOOL HasRecordCount = TRUE;
02738 BOOL CanOmit = FALSE;
02739 switch(Which)
02740 {
02741 case cmxDESC_ARROW:
02742 Section = CMXSECTION_ARROW;
02743 CanOmit = TRUE;
02744 pMIE->SetType(cmxMASTERIN_ARROW);
02745 HasRecordCount = FALSE;
02746 break;
02747
02748 case cmxDESC_ARROWHEADS:
02749 Section = CMXSECTION_ARROWHEADS;
02750 pMIE->SetType(cmxMASTERIN_ARROWHEADS);
02751 break;
02752
02753 case cmxDESC_COLOUR:
02754 Section = CMXSECTION_COLOUR;
02755 pMIE->SetType(cmxMASTERIN_COLOUR);
02756 break;
02757
02758 case cmxDESC_DOTDASH:
02759 Section = CMXSECTION_DOTDASH;
02760 pMIE->SetType(cmxMASTERIN_DOTDASH);
02761 break;
02762
02763 case cmxDESC_FONT:
02764 Section = CMXSECTION_FONT;
02765 pMIE->SetType(cmxMASTERIN_FONT);
02766 CanOmit = TRUE;
02767 HasRecordCount = FALSE;
02768 break;
02769
02770
02771
02772
02773
02774
02775
02776
02777 case cmxDESC_OUTLINE:
02778 Section = CMXSECTION_OUTLINE;
02779 pMIE->SetType(cmxMASTERIN_OUTLINE);
02780 break;
02781
02782 case cmxDESC_LINESTYLE:
02783 Section = CMXSECTION_LINESTYLE;
02784 pMIE->SetType(cmxMASTERIN_LINESTYLE);
02785 break;
02786
02787 case cmxDESC_PEN:
02788 Section = CMXSECTION_PEN;
02789 pMIE->SetType(cmxMASTERIN_PEN);
02790 break;
02791
02792 case cmxDESC_SCREEN:
02793 Section = CMXSECTION_SCREEN;
02794 pMIE->SetType(cmxMASTERIN_SCREEN);
02795 break;
02796
02797 default:
02798 ERROR3("Don't know what type of desc to write!");
02799 }
02800
02801
02802 WORD Entries = 0;
02803 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
02804 while(pEn != 0)
02805 {
02806 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02807
02808 if(pEn->IsInWhichDesc() == Which)
02809 {
02810 Entries++;
02811 }
02812
02813 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02814 }
02815
02816
02817 if(Entries == 0 && CanOmit)
02818 {
02819 delete pMIE;
02820 return TRUE;
02821 }
02822
02823
02824 if(NoMIE)
02825 {
02826 delete pMIE;
02827 }
02828 else
02829 {
02830 ReferList.AddTail(pMIE);
02831 }
02832
02833
02834 if(!StartSection((CMXExportDC::CMXSectionType)Section))
02835 return FALSE;
02836 if(HasRecordCount)
02837 ExportFile->write(&Entries, sizeof(Entries));
02838
02839
02840 pEn = (CMXReferListItem *)ReferList.GetHead();
02841 while(pEn != 0)
02842 {
02843 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
02844
02845 if(pEn->IsInWhichDesc() == Which)
02846 {
02847 if(!pEn->WriteInDesc(this))
02848 return FALSE;
02849 }
02850
02851 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
02852 }
02853
02854
02855 if(!EndSection())
02856 return FALSE;
02857
02858
02859 return TRUE;
02860 }
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876 BOOL CMXReferDotDash::WriteInDesc(CMXExportDC *pDC)
02877 {
02878 pDash->CheckAndFix();
02879
02880
02881 if(!pDC->StartTag(cmxTAG_DescrSection_Dash))
02882 return FALSE;
02883
02884
02885 WORD DotCount = (WORD)pDash->Elements;
02886 if(!pDC->WriteData(&DotCount, sizeof(DotCount)))
02887 return FALSE;
02888
02889
02890 for(INT32 l = 0; l < pDash->Elements; l++)
02891 {
02892 WORD Element = (WORD)((pDash->ElementData[l] + 4) / pDash->LineWidth);
02893 if(Element <= 0) Element = 1;
02894 Element *= 4;
02895 if(!pDC->WriteData(&Element, sizeof(Element)))
02896 return FALSE;
02897 }
02898
02899
02900 if(!pDC->EndTag() || !pDC->WriteMinEndTag())
02901 return FALSE;
02902
02903 return TRUE;
02904 }
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920 BOOL CMXReferArrow::WriteInDesc(CMXExportDC *pDC)
02921 {
02922
02923 ArrowFilePosition = pDC->GetFilePosition();
02924
02925
02926 if(!pDC->StartTag(cmxTAG_DescrSection_Arrow))
02927 return FALSE;
02928
02929
02930 Path *pPath = pArrow->GetArrowPath();
02931 ERROR2IF(pPath == NULL, FALSE, "no arrow path");
02932 INT32 NumCoords = pPath->GetNumCoords();
02933 DocCoord *Coords = pPath->GetCoordArray();
02934 PathVerb *Verbs = pPath->GetVerbArray();
02935 DocRect ArrowBBox;
02936 pDC->CalcCorelBBox(Coords, NumCoords, &ArrowBBox);
02937
02938
02939 DocCoord ArrowCentre = pArrow->GetArrowCentre();
02940
02941 INT32 dl = abs(ArrowCentre.x - ArrowBBox.lo.x);
02942 INT32 dr = abs(ArrowBBox.hi.x - ArrowCentre.x);
02943 INT32 db = abs(ArrowCentre.y - ArrowBBox.lo.y);
02944 INT32 dt = abs(ArrowBBox.hi.y - ArrowCentre.y);
02945 INT32 maxdist = (dl > dr)?dl:dr;
02946 maxdist = (maxdist > db)?maxdist:db;
02947 maxdist = (maxdist > dt)?maxdist:dt;
02948
02949
02950 double ScaleFactor =
02951 ((double)(pDC->IsThirtyTwoBit()?cmxARROWDEF_MAXCOORD32:cmxARROWDEF_MAXCOORD16))
02952 / ((double)maxdist);
02953 Matrix Mat((FIXED16)ScaleFactor, 0, 0, (FIXED16)ScaleFactor, - ArrowCentre.x, - ArrowCentre.y);
02954
02955
02956
02957
02958 BOOL BungInExtraPoint = FALSE;
02959 if(Coords[0] != Coords[NumCoords - 1])
02960 BungInExtraPoint = TRUE;
02961
02962
02963 WORD Count = (WORD)NumCoords + (BungInExtraPoint?1:0);
02964 pDC->WriteData(&Count, sizeof(Count));
02965
02966
02967 INT32 l;
02968 for(l = 0; l < NumCoords; l++)
02969 {
02970 DocCoord Coord = Coords[l];
02971 Mat.transform(&Coord);
02972
02973
02974 if(pDC->IsThirtyTwoBit())
02975 {
02976 cmxPoint32 p = {Coord.x, Coord.y};
02977 pDC->WriteData(&p, sizeof(p));
02978 }
02979 else
02980 {
02981 cmxPoint16 p = {(SWORD)Coord.x, (SWORD)Coord.y};
02982 pDC->WriteData(&p, sizeof(p));
02983 }
02984 }
02985
02986 if(BungInExtraPoint)
02987 {
02988 DocCoord Coord = Coords[0];
02989 Mat.transform(&Coord);
02990
02991
02992 if(pDC->IsThirtyTwoBit())
02993 {
02994 cmxPoint32 p = {Coord.x, Coord.y};
02995 pDC->WriteData(&p, sizeof(p));
02996 }
02997 else
02998 {
02999 cmxPoint16 p = {(SWORD)Coord.x, (SWORD)Coord.y};
03000 pDC->WriteData(&p, sizeof(p));
03001 }
03002 }
03003
03004
03005 INT32 BezCount = 0;
03006 for(l = 0; l < NumCoords; l++)
03007 {
03008 BYTE Type;
03009
03010 switch(Verbs[l] & (PT_LINETO | PT_MOVETO | PT_BEZIERTO))
03011 {
03012 case PT_MOVETO:
03013 {
03014 Type = CMXNODETYPE_TYPE_MOVE | CMXNODETYPE_USER;
03015
03016
03017 for(INT32 lp = l + 1; lp < NumCoords; lp++)
03018 {
03019
03020 if((Verbs[lp] & (PT_LINETO | PT_MOVETO | PT_BEZIERTO)) == PT_MOVETO)
03021 break;
03022
03023
03024 if((Verbs[lp] & PT_CLOSEFIGURE) != 0)
03025 {
03026 Type |= CMXNODETYPE_CLOSED;
03027 break;
03028 }
03029 }
03030 }
03031 BezCount = 0;
03032 break;
03033
03034 case PT_LINETO:
03035 Type = CMXNODETYPE_TYPE_LINE | CMXNODETYPE_USER;
03036 BezCount = 0;
03037 break;
03038
03039 case PT_BEZIERTO:
03040
03041
03042 if(BezCount == 2)
03043 {
03044 Type = CMXNODETYPE_TYPE_CURVE | CMXNODETYPE_USER;
03045 }
03046 else
03047 {
03048 Type = CMXNODETYPE_TYPE_ARC;
03049 }
03050 BezCount++;
03051 if(BezCount > 2)
03052 BezCount = 0;
03053 break;
03054
03055 default:
03056 ERROR3("Unknown node type");
03057 break;
03058 }
03059
03060 if((Verbs[l] & PT_CLOSEFIGURE) != 0)
03061 {
03062 if(!BungInExtraPoint || l != (NumCoords - 1))
03063 Type |= CMXNODETYPE_CLOSED;
03064 }
03065
03066 if(l == (NumCoords - 1) && !BungInExtraPoint)
03067 Type |= CMXNODETYPE_CLOSED;
03068
03069 pDC->WriteData(&Type, sizeof(Type));
03070 }
03071
03072 if(BungInExtraPoint)
03073 {
03074 BYTE Type = CMXNODETYPE_TYPE_LINE | CMXNODETYPE_USER | CMXNODETYPE_CLOSED;
03075 pDC->WriteData(&Type, sizeof(Type));
03076 }
03077
03078
03079 DWORD LineOffset = 0;
03080 if(!pDC->WriteData(&LineOffset, sizeof(LineOffset)))
03081 return FALSE;
03082
03083
03084 if(!pDC->EndTag() || !pDC->WriteMinEndTag())
03085 return FALSE;
03086
03087 return TRUE;
03088 }
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104 BOOL CMXReferArrow::WriteInIndex(CMXExportDC *pDC)
03105 {
03106
03107 cmxArrowIndexEntry En;
03108 En.FilePosition = ArrowFilePosition;
03109
03110
03111 return pDC->WriteData(&En, sizeof(En));
03112 }
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128 BOOL CMXExportDC::WritePreviewBitmap(void)
03129 {
03130 Filter* pFilter = NULL;
03131 pFilter = Filter::GetFirst();
03132 while ((pFilter != NULL) && (pFilter->FilterID != FILTERID_PREVIEW_BMP))
03133 {
03134
03135 pFilter = Filter::GetNext(pFilter);
03136 }
03137
03138
03139 if ((pFilter != NULL) && (pFilter->IS_KIND_OF(BaseBitmapFilter)))
03140 {
03141
03142 ThumbnailIndexFuture.Write(this);
03143
03144
03145 if(!StartSection(CMXSECTION_PREVIEWBITMAP))
03146 return FALSE;
03147
03148
03149 DWORD Eight = 8;
03150 Eight = NativetoLE(Eight);
03151 ExportFile->write(&Eight, sizeof(Eight));
03152
03153
03154 INT32 Start = ExportFile->tell();
03155 BITMAPFILEHEADER hdr;
03156 ExportFile->seek(Start - sizeof(hdr));
03157 ExportFile->read(&hdr, sizeof(hdr));
03158 ExportFile->seek(Start - sizeof(hdr));
03159
03160
03161
03162 INT32 OldPreviewSize = PreviewFilter::PreviewBitmapSize;
03163
03164 PreviewFilter::PreviewBitmapSize = 96000;
03165
03166
03167 BaseBitmapFilter* pBitmapFilter = (BaseBitmapFilter*) pFilter;
03168 pBitmapFilter->SetPreviewBitmap(TRUE);
03169
03170
03171 BOOL ok = pFilter->DoExport(pOp, ExportFile, pPath, TheDocument);
03172
03173
03174
03175 pBitmapFilter->SetPreviewBitmap(FALSE);
03176
03177 PreviewFilter::PreviewBitmapSize = OldPreviewSize;
03178
03179
03180 INT32 Here = ExportFile->tell();
03181 ExportFile->seek(Start - sizeof(hdr));
03182 ExportFile->write(&hdr, sizeof(hdr));
03183 ExportFile->seek(Here);
03184
03185
03186 if(!EndSection())
03187 return FALSE;
03188
03189 return ok;
03190 }
03191
03192 return TRUE;
03193 }
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207 double CMXExportDC::Round ( double ToRound )
03208 {
03209
03210 return floor ( ToRound + 0.5 );
03211 }