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
00101 #include "camtypes.h"
00102
00103
00104
00105 #include "page.h"
00106
00107
00108
00109 #include "nodepath.h"
00110 #include "riffform.h"
00111 #include "progress.h"
00112
00113 #include "layer.h"
00114
00115 #include "cdrfiltr.h"
00116
00117 #include "combshps.h"
00118 #include "nodetxts.h"
00119 #include "attrmap.h"
00120
00121 #include "cmxform.h"
00122 #include "cmxifltr.h"
00123 #include "cmxistut.h"
00124 #include "cmxibits.h"
00125
00126 #include "cmxidata.h"
00127 #include "cmxibitm.h"
00128
00129 CC_IMPLEMENT_DYNAMIC(CMXImportFilter, VectorFilter)
00130 CC_IMPLEMENT_DYNAMIC(CMXImportFilterDataSet, CCObject)
00131
00132 #define new CAM_DEBUG_NEW
00133
00134 #ifdef _DEBUG
00135 void CMXImportFilter::FormatErrorBreakingFunction(void)
00136 {
00137 TRACEUSER( "Ben", _T(">>> format error in cmx file\n"));
00138 }
00139 #endif
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 CMXImportFilter::CMXImportFilter()
00155 {
00156
00157 FilterName.Load(_R(IDT_CMXIMPORTFILTER_FILTERNAME));
00158 FilterInfo.Load(_R(IDT_CMXIMPORTFILTER_FILTERINFO));
00159 FilterID = FILTERID_CMXIMPORT;
00160
00161 Flags.CanImport = TRUE;
00162 Flags.CanExport = FALSE;
00163
00164 ImportMsgID = _R(IDT_IMPORTMSG_CMX);
00165
00166 ExportMsgID = _R(IDT_EXPORTMSG_CMX);
00167
00168
00169 CMXIinfo::SetUpInfo();
00170
00171
00172 Data = NULL;
00173
00174
00175 CorelDraw7 = FALSE;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 BOOL CMXImportFilter::Init()
00192 {
00193
00194 pOILFilter = new CMXImportOILFilter(this);
00195 if (pOILFilter == NULL)
00196 return FALSE;
00197
00198
00199 return TRUE;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 INT32 CMXImportFilter::HowCompatible(PathName & FileName, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize)
00221 {
00222
00223 PORTNOTE("byteorder", "TODO: Check byte ordering")
00224 RIFFFile_Header *pHdr = (RIFFFile_Header *)HeaderStart;
00225
00226 if(pHdr->CK.ckID == RIFFTYPE_RIFF)
00227 {
00228 switch(pHdr->FormType)
00229 {
00230 case cmxRIFFFORMTYPE_CMX:
00231
00232 return 10;
00233 break;
00234
00235 case cmxRIFFFORMTYPE_CDR5:
00236 case cmxRIFFFORMTYPE_CDT5:
00237 case cmxRIFFFORMTYPE_CDR6:
00238 case cmxRIFFFORMTYPE_CDT6:
00239
00240
00241 if(CDRFilter::HasCDRFileGotCMXFile(&FileName))
00242 {
00243 return 10;
00244 }
00245 break;
00246
00247 default:
00248 break;
00249 }
00250 }
00251
00252 return 0;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 BOOL CMXImportFilter::DoImport(SelOperation * Op, CCLexFile * pDiskFile,
00282 Document * DestDoc, BOOL AutoChoosen , ImportPosition * Pos,
00283 KernelBitmap** ppImportedBitmap, DocCoord* pPosTranslate, String_256* URL)
00284 {
00285
00286 pFile = pDiskFile;
00287 Is32Bit = FALSE;
00288 StartPosition = 0;
00289 TheDocument = DestDoc;
00290
00291
00292 ERROR3IF(Data != NULL, "CMX data set already created");
00293 Data = new CMXImportFilterDataSet(this);
00294 if(Data == NULL)
00295 return FALSE;
00296
00297
00298 Data->pProgress = new Progress(_R(IDT_CMX_IMPORTMSG), 1, FALSE);
00299 if(Data->pProgress == NULL)
00300 return FALSE;
00301 if(!SetUpCurrentAttrs())
00302 return FALSE;
00303
00304
00305 Data->TextFrameRead = FALSE;
00306
00307 SetTextAttributeIgnore();
00308
00309
00310 Document *pTheDocument = GetDocument();
00311 ERROR2IF(pTheDocument == NULL, FALSE, "no document for filter");
00312 Spread *pSpread = NULL;
00313
00314 if (Pos == NULL)
00315 {
00316
00317 pSpread = GetFirstSpread(DestDoc);
00318 Page *pPage = (Page *) pSpread->FindFirstPageInSpread();
00319 ENSURE(pPage->IsKindOf(CC_RUNTIME_CLASS(Page)),
00320 "MetaFileFilter::DoImport(): Could not find first Page");
00321 }
00322 else
00323 {
00324 pSpread = Pos->pSpread;
00325 }
00326
00327
00328
00329 BOOL EverythingWentSwimmingly = TRUE;
00330 TRY
00331 {
00332 if( !Stage1_ReadHeader(pSpread)
00333 || !Stage2_ReadMasterIndex()
00334 || !Stage3_ConvertDescriptionSections()
00335 || !Stage4_ConvertPage()
00336 || !Stage5_PlaceObjectsInTree(pSpread, Op, Pos) )
00337 EverythingWentSwimmingly = FALSE;
00338 }
00339 CATCH(CFileException, e)
00340 {
00341
00342 CleanUpAfterImport();
00343
00344 return FALSE;
00345 }
00346 END_CATCH
00347
00348 CleanUpAfterImport();
00349
00350 return EverythingWentSwimmingly;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 void CMXImportFilter::CleanUpAfterImport(void)
00367 {
00368
00369
00370 if(Data != NULL)
00371 delete Data;
00372
00373 Data = NULL;
00374
00375
00376 DeleteCurrentAttrs();
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 BOOL CMXImportFilter::LocateRootLevelRIFFSection(DWORD Section)
00394 {
00395
00396 Seek(0);
00397
00398
00399 RIFFFile_Header Hdr;
00400 pFile->read(&Hdr, sizeof(Hdr));
00401
00402 if(Hdr.CK.ckID != RIFFTYPE_RIFF)
00403 return FALSE;
00404
00405 UINT32 loc = sizeof(Hdr);
00406
00407
00408 while(loc < Hdr.CK.ckSize)
00409 {
00410 RIFFck ck;
00411 pFile->read(&ck, sizeof(ck));
00412 loc += sizeof(ck);
00413 if(ck.ckID == Section)
00414 return TRUE;
00415
00416
00417 loc += ck.ckSize;
00418 Seek(loc);
00419 }
00420
00421 return FALSE;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 BOOL CMXImportFilter::Stage1_ReadHeader(Spread *pSpread)
00440 {
00441
00442 if(!LocateRootLevelRIFFSection(cmxRIFFCI_Header))
00443 {
00444
00445 if(LocateRootLevelRIFFSection(cmxRIFFFORMTYPE_cmx1))
00446 {
00447
00448 StartPosition = pFile->tellIn();
00449
00450 if(!LocateRootLevelRIFFSection(cmxRIFFCI_Header))
00451 {
00452 CMXFORMATERROR(FALSE)
00453 }
00454 }
00455 else
00456 {
00457 CMXFORMATERROR(FALSE)
00458 }
00459 }
00460
00461
00462 CI_READDATA(FileHeader, Hdr)
00463
00464
00465 if(strcmp(Hdr.ID, cmxID) != 0)
00466 CMXFORMATERROR(FALSE)
00467
00468
00469 switch(Hdr.CoordSize & 0xf)
00470 {
00471 case cmxCOORDSIZE_32:
00472 TRACEUSER( "Ben", _T("\n\n********************** 32 bit CMX file\n"));
00473 Is32Bit = TRUE;
00474 break;
00475
00476 case cmxCOORDSIZE_16:
00477 TRACEUSER( "Ben", _T("\n\n********************** 16 bit CMX file\n"));
00478 Is32Bit = FALSE;
00479 break;
00480
00481 default:
00482
00483 CMXFORMATERROR(FALSE);
00484 break;
00485 }
00486
00487
00488 Data->IndexFilePosition = Hdr.IndexSection;
00489
00490
00491 Page *pPage = (Page *)pSpread->FindFirstPageInSpread();
00492
00493
00494 DocRect PageRect = pPage->GetPageRect();
00495 DocCoord Origin = DocCoord(PageRect.lo.x + (PageRect.Width() / 2),
00496 PageRect.lo.y + (PageRect.Height() / 2));
00497
00498
00499 double Scale;
00500 if(Is32Bit)
00501 {
00502 Scale = 1 / CAMCOORD_SCALEFACTOR32;
00503 }
00504 else
00505 {
00506 Scale = 72;
00507 }
00508 Matrix TheMat = Matrix((FIXED16)Scale, (FIXED16)Scale);
00509
00510
00511 TheMat *= Matrix(Origin);
00512
00513
00514 Data->BaseMatrix = TheMat;
00515 Data->BaseScaleFactor = Scale;
00516
00517
00518 Data->pCurrentMatrix = &Data->BaseMatrix;
00519
00520 return TRUE;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 BOOL CMXImportFilter::Stage5_PlaceObjectsInTree(Spread *pSpread, SelOperation *pOp, ImportPosition *pPos)
00537 {
00538 Trans2DMatrix Xlate;
00539 BOOL Translate = FALSE;
00540 Coord Offset;
00541
00542
00543 if(GetDragAndDropTranslation(pPos, Data->AllObjectsBoundsRect, &Offset))
00544 {
00545 Translate = TRUE;
00546 Xlate = Trans2DMatrix(Offset.x, Offset.y);
00547 }
00548
00549 BOOL ImportingWithLayers = FALSE;
00550
00551
00552 #ifdef WEBSTER
00553
00554
00555 if (
00556 (!TheDocument->IsImporting() && Filter::OpenWithLayers) ||
00557 (TheDocument->IsImporting() && Filter::ImportWithLayers)
00558 )
00559 ImportingWithLayers = TRUE;
00560 #else
00561
00562
00563
00564 if (TheDocument->IsImporting())
00565 {
00566 Spread * pTheSpread = TheDocument->GetSelectedSpread();
00567 Layer * pFrame = NULL;
00568 if (pTheSpread != NULL)
00569 pFrame = pTheSpread->FindFirstFrameLayer();
00570 if (pFrame != NULL)
00571 ImportingWithLayers = FALSE;
00572 else
00573 ImportingWithLayers = Filter::ImportWithLayers;
00574 }
00575 else
00576 {
00577 ImportingWithLayers = Filter::OpenWithLayers;
00578 }
00579 #endif
00580
00581 NodeGroup *pGroup = NULL;
00582 if(!ImportingWithLayers)
00583 {
00584 if((pGroup = new NodeGroup) == NULL)
00585 return FALSE;
00586 }
00587
00588
00589 CMXImportLayer *pSarah = (CMXImportLayer *)Data->Layers.GetHead();
00590 while(pSarah != NULL)
00591 {
00592 ERROR2IF(!IS_A(pSarah, CMXImportLayer), FALSE, "thingy not a CMX import layer");
00593
00594 if(ImportingWithLayers)
00595 {
00596
00597 Layer *pNewLayer = pSarah->UseSubTreeAsLayer();
00598 if(pNewLayer == NULL)
00599 return FALSE;
00600
00601
00602 if(Translate)
00603 pNewLayer->Transform(Xlate);
00604
00605
00606 if(!pOp->DoInsertNewNode(pNewLayer, (Node *)pSpread, LASTCHILD, TRUE))
00607 {
00608
00609 pNewLayer->CascadeDelete();
00610 delete pNewLayer;
00611 return FALSE;
00612 }
00613
00614
00615 pNewLayer->EnsureUniqueLayerID();
00616
00617
00618 if(!pNewLayer->OptimiseAttributes())
00619 return FALSE;
00620 }
00621 else
00622 {
00623
00624 ERROR3IF(pGroup == NULL, "no group node created");
00625
00626
00627 if(pSarah->GetSubTree() != NULL)
00628 {
00629 Node *pSubTree = pSarah->GetSubTree();
00630
00631 pSubTree->InsertChainSimple(pGroup, LASTCHILD);
00632 }
00633
00634
00635 pSarah->UseSubTree();
00636 }
00637
00638 pSarah = (CMXImportLayer *)Data->Layers.GetNext(pSarah);
00639 }
00640
00641 if(ImportingWithLayers)
00642 {
00643
00644 TheDocument->ResetInsertionPosition();
00645 }
00646 else
00647 {
00648
00649 if (!MakeSureLayerExists(TheDocument))
00650
00651 return FALSE;
00652
00653
00654
00655
00656
00657 NodeRenderableBounded *InsertNode = pGroup;
00658
00659 NodeRenderableBounded *FirstChild = (NodeRenderableBounded *)pGroup->FindFirstChild();
00660
00661 if(FirstChild != 0)
00662 {
00663
00664
00665 if(FirstChild->FindNext() == 0)
00666 InsertNode = FirstChild;
00667 }
00668
00669
00670 if(Translate)
00671 InsertNode->Transform(Xlate);
00672
00673
00674 if(InsertNode != pGroup)
00675 InsertNode->UnlinkNodeFromTree(NULL);
00676
00677
00678 InsertNode->InvalidateBoundingRect();
00679
00680
00681 if (!pOp->DoInsertNewNode(InsertNode, pSpread, TRUE))
00682 {
00683
00684 pGroup->CascadeDelete();
00685 delete pGroup;
00686 return FALSE;
00687 }
00688
00689
00690 if(!InsertNode->OptimiseAttributes())
00691 return FALSE;
00692
00693
00694 if(InsertNode != pGroup)
00695 delete pGroup;
00696 }
00697
00698
00699 if(!AddColoursToDocument())
00700 return FALSE;
00701
00702
00703 TheDocument->PostImport();
00704
00705 return TRUE;
00706 }
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 CMXImportFilterDataSet::CMXImportFilterDataSet(CMXImportFilter *pFilter)
00722 : TransformStack(cmxiSTACKTYPE_TRANSFORM, pFilter)
00723 , ClipperStack(cmxiSTACKTYPE_CLIPPER, pFilter)
00724 {
00725
00726 for(INT32 l = 0; l < cmxMASTERIN_MAXENTRY; l++)
00727 MasterIndexEntries[l] = 0;
00728
00729
00730 pProgress = NULL;
00731 CommandsInPage = -1;
00732 pCurrentLayer = NULL;
00733 pCurrentMatrix = NULL;
00734 pTextStory = NULL;
00735 pTextLine = NULL;
00736 NumColours = 0;
00737 Colours = NULL;
00738 NumOutlines = 0;
00739 Outlines = NULL;
00740 NumPens = 0;
00741 Pens = NULL;
00742 BaseScaleFactor = 0;
00743 NumLineStyles = 0;
00744 LineStyles = NULL;
00745 NumRImages = 0;
00746 RImages = NULL;
00747 NumProcedures = 0;
00748 Procedures = NULL;
00749 NumDotDashes = 0;
00750 DotDashes = NULL;
00751 pClippingPath = NULL;
00752 NumArrowShapes = 0;
00753 ArrowShapes = NULL;
00754 NumArrowheads = 0;
00755 Arrowheads = NULL;
00756 NumBitmaps = 0;
00757 Bitmaps = NULL;
00758 NumFonts = 0;
00759 Fonts = NULL;
00760
00761
00762 NumCharInfo = 0;
00763 CharInfos = new cmxiCharInfo[100];
00764 for(INT32 i = 0 ; i < 100 ; i++)
00765 CharInfos[i].UsageMask = 0;
00766
00767
00768
00769
00770 InPage = FALSE;
00771 RemoveLens = FALSE;
00772 EndSectionFound = FALSE;
00773 HaveFirstObjInBoundsRect = FALSE;
00774
00775
00776 AttributesApproximated = 0;
00777 ObjectsApproximated = 0;
00778 ClippingsApproximated = 0;
00779 }
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 CMXImportFilterDataSet::~CMXImportFilterDataSet()
00796 {
00797
00798 Layers.DeleteAll();
00799
00800
00801 if(pProgress != NULL)
00802 {
00803 delete pProgress;
00804 pProgress = NULL;
00805 }
00806
00807
00808 if(Colours != 0)
00809 delete [] Colours;
00810 if(Outlines != 0)
00811 delete [] Outlines;
00812 if(Pens != 0)
00813 delete [] Pens;
00814 if(LineStyles != 0)
00815 delete [] LineStyles;
00816 if(RImages != 0)
00817 delete [] RImages;
00818 if(Procedures != 0)
00819 delete [] Procedures;
00820 if(DotDashes != 0)
00821 delete [] DotDashes;
00822 if(ArrowShapes != 0)
00823 delete [] ArrowShapes;
00824 if(Arrowheads != 0)
00825 delete [] Arrowheads;
00826 if(Bitmaps != 0)
00827 delete [] Bitmaps;
00828 if(Fonts != 0)
00829 delete [] Fonts;
00830 if(CharInfos != 0)
00831 delete [] CharInfos;
00832 }
00833
00834
00835
00836 void CMXImportFilter::AttributeApproximated(void) {Data->AttributesApproximated++;}
00837 void CMXImportFilter::ClippingApproximated(void) {Data->ClippingsApproximated++;}
00838 void CMXImportFilter::ObjectApproximated(void) {Data->ObjectsApproximated++;}
00839 Matrix *CMXImportFilter::GetBaseMatrix(void) {return &Data->BaseMatrix;};
00840 Matrix *CMXImportFilter::GetCurrentMatrix(void) {return Data->pCurrentMatrix;};
00841 void CMXImportFilter::SetMatrix(Matrix *pNewMatrix) {Data->pCurrentMatrix = pNewMatrix;};
00842 void CMXImportFilter::SetClippingPath(Path *pClipper) {Data->pClippingPath = pClipper;};
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 BOOL CMXImportFilter::TransformNode(Node *pNode)
00859 {
00860 ERROR2IF(Data->pCurrentMatrix == NULL, FALSE, "No matrix to transform by");
00861
00862
00863 Trans2DMatrix Transform(*Data->pCurrentMatrix);
00864 NodeRenderableBounded *pBN = (NodeRenderableBounded *)pNode;
00865 ERROR3IF(!pBN->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)), "not a transformable node passed to TransformNode");
00866 pBN->Transform(Transform);
00867
00868
00869 DocRect BBox = pBN->GetBoundingRect(TRUE, FALSE);
00870 if(Data->HaveFirstObjInBoundsRect == FALSE)
00871 {
00872
00873 Data->HaveFirstObjInBoundsRect = TRUE;
00874 Data->AllObjectsBoundsRect = BBox;
00875 }
00876 else
00877 {
00878 Data->AllObjectsBoundsRect = Data->AllObjectsBoundsRect.Union(BBox);
00879 }
00880
00881
00882 return TRUE;
00883 }
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 #define MAXLINEWIDTH (720000 * 2) // sounds reasonable
00900
00901 BOOL CMXImportFilter::SetAttributesForNode(Node *pNode, void *pvAttr, BOOL DeleteStuff)
00902 {
00903 cmxiRenderAttr *pAttr = (cmxiRenderAttr *)pvAttr;
00904
00905
00906 if(Data->RemoveLens)
00907 {
00908 Data->RemoveLens = FALSE;
00909 if(!SetNoTranspFill())
00910 return FALSE;
00911 }
00912
00913 BOOL DoFillStuff = TRUE;
00914
00915
00916 if((pAttr->Mask & cmxRENDATTRMASK_LENS) != 0)
00917 {
00918
00919 if(pAttr->LensSpec.Type == cmxLENSTYPE_GLASS)
00920 {
00921 UINT32 Type;
00922
00923
00924 switch(pAttr->LensSpec.Glass.TintMethod)
00925 {
00926 case cmxLENSTINTMETH_SUBTRACT:
00927 Type = TT_StainGlass;
00928 break;
00929
00930 case cmxLENSTINTMETH_ADD:
00931 Type = TT_Bleach;
00932 break;
00933
00934 case cmxLENSTINTMETH_AVERAGE:
00935 Type = TT_Mix;
00936 break;
00937
00938 default:
00939 Type = TT_Mix;
00940 AttributeApproximated();
00941 break;
00942 }
00943
00944
00945 UINT32 Percent = 255 - ((pAttr->LensSpec.Glass.UniformRate * 255) / 1000);
00946
00947
00948 if(!SetFlatTranspFill(Type, Percent))
00949 return FALSE;
00950
00951
00952 DocColour *pColour = GetColourFromReference(pAttr->LensSpec.Glass.ColourRef);
00953 if(pColour == NULL)
00954 return FALSE;
00955
00956 if(!SetFillColour(*pColour))
00957 return FALSE;
00958
00959 Data->RemoveLens = TRUE;
00960 DoFillStuff = FALSE;
00961 }
00962 else
00963 {
00964 AttributeApproximated();
00965 }
00966 }
00967
00968
00969 if(DoFillStuff)
00970 {
00971 if((pAttr->Mask & cmxRENDATTRMASK_FILL) != 0)
00972 {
00973
00974 Data->ObjFilled = TRUE;
00975 SetPathFilled(TRUE);
00976
00977
00978 BOOL UnknownFill = FALSE;
00979
00980 TRACEUSER( "Ben", _T(" fill type is %d\n"), pAttr->FillSpec.FillID);
00981
00982
00983 switch(pAttr->FillSpec.FillID)
00984 {
00985 case cmxFILLID_UNIFORM:
00986 {
00987
00988 DocColour *pColour = GetColourFromReference(pAttr->FillSpec.Spec.Uniform.ColourReference);
00989 if(pColour == NULL)
00990 return FALSE;
00991
00992 if(!SetFillColour(*pColour))
00993 return FALSE;
00994 }
00995 break;
00996
00997 case cmxFILLID_FOUNTAIN:
00998 if(!SetAttributesFountain(pNode, &pAttr->FillSpec))
00999 {
01000 if(DeleteStuff) delete pAttr->FillSpec.Spec.Fountain.pColours;
01001 return FALSE;
01002 }
01003
01004 if(DeleteStuff) delete pAttr->FillSpec.Spec.Fountain.pColours;
01005 break;
01006
01007 case cmxFILLID_PS:
01008 if(DeleteStuff) delete pAttr->FillSpec.Spec.Postscript.UserFunction;
01009 break;
01010
01011 case cmxFILLID_COLPATTERN:
01012 if(!SetAttributesTwoColourBitmapFill(pNode, &pAttr->FillSpec))
01013 return FALSE;
01014 break;
01015
01016 case cmxFILLID_BITMAPFILL:
01017 case cmxFILLID_BITMAPFILL16:
01018
01019 if(!SetAttributesBitmapFill(pNode, pAttr->FillSpec.Spec.Bitmap.VectorFillReference, &pAttr->FillSpec.Spec.Bitmap.Tile))
01020 return FALSE;
01021 break;
01022
01023 case cmxFILLID_TEXTURE:
01024 if(!SetAttributesBitmapFill(pNode, pAttr->FillSpec.Spec.Texture.VectorFillReference, &pAttr->FillSpec.Spec.Texture.Tile))
01025 return FALSE;
01026 break;
01027
01028 default:
01029
01030 UnknownFill = TRUE;
01031 break;
01032 }
01033
01034 if(UnknownFill)
01035 {
01036
01037 AttributeApproximated();
01038 if(!SetNoFill(pNode))
01039 return FALSE;
01040 }
01041 }
01042 else
01043 {
01044 Data->ObjFilled = FALSE;
01045
01046
01047 if(!SetNoFill(pNode))
01048 return FALSE;
01049 }
01050 }
01051
01052
01053 if((pAttr->Mask & cmxRENDATTRMASK_OUTLINE) != 0)
01054 {
01055
01056 CMXImportOutline *pOut;
01057 if(pAttr->OutlineReference <= 0 || pAttr->OutlineReference > Data->NumOutlines)
01058 CMXFORMATERROR(FALSE)
01059
01060 pOut = &Data->Outlines[pAttr->OutlineReference - 1];
01061
01062 if(pOut->NoStroke)
01063 {
01064 if(!SetNoStroke(pNode))
01065 return FALSE;
01066 }
01067 else
01068 {
01069
01070
01071
01072 DocColour *pCol = GetColourFromReference(pOut->ColourReference);
01073 if(pCol == NULL)
01074 return FALSE;
01075
01076
01077 if(!SetLineColour(*pCol))
01078 return FALSE;
01079
01080
01081 double LineWidth = pOut->Width * Data->BaseScaleFactor;
01082 if(LineWidth > MAXLINEWIDTH) LineWidth = MAXLINEWIDTH;
01083 if(!SetLineWidth((MILLIPOINT)LineWidth))
01084 return FALSE;
01085
01086
01087 DashRec Dash;
01088 if(pOut->pDots != NULL && pOut->pDots->NDots != 0)
01089 {
01090
01091 Dash.Elements = pOut->pDots->NDots;
01092 Dash.DashStart = 0;
01093 Dash.ElementData = pOut->pDots->pElements;
01094 Dash.LineWidth = 1;
01095 Dash.ScaleWithLineWidth = TRUE;
01096 Dash.DashID = -1;
01097 }
01098 else
01099 {
01100
01101 Dash = SD_SOLID;
01102 }
01103
01104
01105 if(!SetLineCap(pOut->Cap)
01106 || !SetJoinType(pOut->Join)
01107 || !SetDashPattern(Dash))
01108 return FALSE;
01109
01110
01111 if(pOut->pArrowheads != NULL)
01112 {
01113
01114
01115 if(pOut->pArrowheads->pStart != NULL)
01116 {
01117 if(!SetStartArrow(pOut->pArrowheads->pStart->Arrow))
01118 return FALSE;
01119 }
01120 else
01121 {
01122 ArrowRec NullArrow;
01123 if(!SetStartArrow(NullArrow))
01124 return FALSE;
01125 }
01126
01127
01128 if(pOut->pArrowheads->pEnd != NULL)
01129 {
01130 if(!SetEndArrow(pOut->pArrowheads->pEnd->Arrow))
01131 return FALSE;
01132 }
01133 else
01134 {
01135 ArrowRec NullArrow;
01136 if(!SetEndArrow(NullArrow))
01137 return FALSE;
01138 }
01139 }
01140 else
01141 {
01142
01143 ArrowRec NullArrow;
01144 if(!SetStartArrow(NullArrow)
01145 || !SetEndArrow(NullArrow))
01146 return FALSE;
01147 }
01148 }
01149 }
01150 else
01151 {
01152 if(!SetNoStroke(pNode))
01153 return FALSE;
01154 }
01155
01156 return TRUE;
01157 }
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173 BOOL CMXImportFilter::SetNoFill(Node *pNode)
01174 {
01175 if(pNode->IsKindOf(CC_RUNTIME_CLASS(NodePath)))
01176 {
01177 NodePath *pPath = (NodePath *)pNode;
01178
01179
01180 }
01181
01182 Data->ObjFilled = FALSE;
01183
01184 SetFillColour(DocColour(COLOUR_TRANS));
01185
01186 return SetPathFilled(FALSE);
01187 }
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203 BOOL CMXImportFilter::SetNoStroke(Node *pNode)
01204 {
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 SetLineColour(DocColour(COLOUR_TRANS));
01216
01217 return TRUE;
01218 }
01219
01220
01221 class CMXBecomeA : public BecomeA
01222 {
01223 public:
01224 CMXBecomeA(BecomeAReason ThisReason, CCRuntimeClass* pClass, UndoableOperation* pOp, BOOL sel=TRUE)
01225 : BecomeA(ThisReason, pClass, pOp, sel) {};
01226
01227 BOOL PassBack(NodeRenderableInk* pNewNode,NodeRenderableInk* pCreatedByNode,CCAttrMap* pAttrMap=NULL);
01228
01229 NodePath *pPath;
01230 };
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 BOOL CMXBecomeA::PassBack(NodeRenderableInk* pNewNode,NodeRenderableInk* pCreatedByNode,CCAttrMap* pAttrMap)
01246 {
01247 pPath = (NodePath *)pNewNode;
01248
01249 if(pAttrMap != NULL)
01250 {
01251
01252 for (POSITION Pos = pAttrMap->GetStartPosition(); Pos != NULL;)
01253 {
01254 void *pType,*pVal;
01255 pAttrMap->GetNextAssoc(Pos,pType,pVal);
01256
01257
01258 NodeAttribute* pAttr = (NodeAttribute*)pVal;
01259
01260
01261 pAttr->AttachNode(pNewNode, LASTCHILD);
01262 }
01263 }
01264
01265 return TRUE;
01266 }
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 BOOL CMXImportFilter::ClipNode(Node **pNode)
01283 {
01284 if(Data->pClippingPath == NULL)
01285 return TRUE;
01286
01287 NodePath *pPath = NULL;
01288
01289
01290 if(!IS_A(*pNode, NodePath))
01291 {
01292 CMXBecomeA ParamBecomeA(BECOMEA_PASSBACK,
01293 CC_RUNTIME_CLASS(NodePath),
01294 NULL, FALSE);
01295
01296 if((*pNode)->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)))
01297 {
01298 if ((*pNode)->CanBecomeA(&ParamBecomeA))
01299 {
01300
01301 if((*pNode)->IsKindOf(CC_RUNTIME_CLASS(TextStory)))
01302 {
01303
01304 ((TextStory *)*pNode)->FormatAndChildren();
01305 }
01306
01307 if (!(*pNode)->DoBecomeA(&ParamBecomeA))
01308 {
01309 return FALSE;
01310 }
01311
01312
01313 if(!IS_A(ParamBecomeA.pPath, NodePath))
01314 {
01315
01316 delete ParamBecomeA.pPath;
01317 return TRUE;
01318 }
01319
01320
01321 (*pNode)->CascadeDelete();
01322 delete *pNode;
01323 *pNode = ParamBecomeA.pPath;
01324 pPath = ParamBecomeA.pPath;
01325 }
01326 }
01327 }
01328 else
01329 {
01330 pPath = (NodePath *)*pNode;
01331 }
01332 ERROR2IF(pPath == NULL, FALSE, "no path, even though we tried really really hard");
01333
01334
01335 Path *pOutputPath = new Path;
01336 if(pOutputPath == NULL || !pOutputPath->Initialise())
01337 return FALSE;
01338
01339
01340 if(Data->pClippingPath->ClipPathToPath(pPath->InkPath, pOutputPath, 2 ) > 0)
01341 {
01342
01343
01344 if(!pPath->InkPath.CloneFrom(*pOutputPath))
01345 return FALSE;
01346 }
01347 else
01348 {
01349
01350 pPath->CascadeDelete();
01351 delete pPath;
01352
01353
01354 (*pNode) = NULL;
01355 }
01356
01357
01358 delete pOutputPath;
01359
01360 return TRUE;
01361 }
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376 BOOL CMXImportFilter::GetCorelBBox(NodeRenderableBounded *pNode, DocRect *BBox)
01377 {
01378 if(pNode->IsKindOf(CC_RUNTIME_CLASS(NodePath)))
01379 {
01380
01381
01382
01383 NodePath *pNodePath = (NodePath *)pNode;
01384
01385
01386 INT32 NCoords = pNodePath->InkPath.GetNumCoords();
01387 DocCoord *Coords = pNodePath->InkPath.GetCoordArray();
01388
01389 ERROR3IF(NCoords < 1, "Awooga! Trying to find a corel bbox of a path with less than one coord.");
01390
01391 INT32 c;
01392
01393 INT32 x0, y0, x1, y1;
01394
01395
01396 x0 = x1 = Coords[0].x;
01397 y0 = y1 = Coords[0].y;
01398
01399 for(c = 1; c < NCoords; c++)
01400 {
01401
01402 if(Coords[c].x < x0) x0 = Coords[c].x;
01403 if(Coords[c].y < y0) y0 = Coords[c].y;
01404 if(Coords[c].x > x1) x1 = Coords[c].x;
01405 if(Coords[c].y > y1) y1 = Coords[c].y;
01406 }
01407
01408
01409 BBox->lo.x = x0;
01410 BBox->lo.y = y0;
01411 BBox->hi.x = x1;
01412 BBox->hi.y = y1;
01413 } else {
01414
01415
01416 *BBox = pNode->GetBoundingRect();
01417 }
01418
01419 return TRUE;
01420 }
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435 BOOL CMXImportFilter::ApplyAttributesToNode(Node *pNode)
01436 {
01437
01438
01439
01440 if(pNode == NULL)
01441 return TRUE;
01442
01443
01444
01445 if(Data->ObjFilled == FALSE)
01446 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
01447
01448
01449 BOOL Result = AttributeManager::ApplyBasedOnDefaults(pNode, CurrentAttrs);
01450
01451
01452 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
01453
01454 return Result;
01455 }
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476 BOOL CMXImportFilter::GotoSectionFromIndex(INT32 MasterIndexEntry, DWORD PredictedRIFFType,
01477 BOOL NonExistanceIsFormatError, BOOL *Found, INT32 *Size)
01478 {
01479 if(Found != 0)
01480 (*Found) = FALSE;
01481
01482 if(Data->MasterIndexEntries[MasterIndexEntry] == 0)
01483 {
01484
01485 if(NonExistanceIsFormatError)
01486 CMXFORMATERROR(FALSE)
01487
01488
01489 return TRUE;
01490 }
01491
01492 if(Found != 0)
01493 (*Found) = TRUE;
01494
01495 TRACEUSER( "Ben", _T("index entry %d at %d\n"), MasterIndexEntry, Data->MasterIndexEntries[MasterIndexEntry]);
01496 Seek(Data->MasterIndexEntries[MasterIndexEntry]);
01497 RIFFck chdr;
01498 pFile->read(&chdr, sizeof(chdr));
01499 if(chdr.ckID != PredictedRIFFType)
01500 CMXFORMATERROR(FALSE)
01501
01502 if(Size != 0)
01503 (*Size) = chdr.ckSize;
01504
01505 return TRUE;
01506 }
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523 BOOL CMXImportFilter::SetAttributesFountain(Node *pNode, cmxiFillSpec *Fill)
01524 {
01525
01526 DocRect BBox;
01527 if(!GetCorelBBox((NodeRenderableBounded *)pNode, &BBox))
01528 return FALSE;
01529
01530
01531 DocColour *pStartColour = GetColourFromReference(Fill->Spec.Fountain.pColours->GetColourRefClosestToPosition(0));
01532 DocColour *pEndColour = GetColourFromReference(Fill->Spec.Fountain.pColours->GetColourRefClosestToPosition(100));
01533
01534
01535
01536 BOOL NormalRainbow = TRUE;
01537 if(Fill->Spec.Fountain.FillMode == cmxFILLMODE_HSB_CW ||
01538 Fill->Spec.Fountain.FillMode == cmxFILLMODE_HSB_CCW)
01539 {
01540
01541 ColourContext *Conv = ColourContext::GetGlobalDefault(COLOURMODEL_HSVT);
01542
01543 ColourHSVT StartC;
01544 ColourHSVT EndC;
01545
01546 Conv->ConvertColour(pStartColour, (ColourGeneric *)&StartC);
01547 Conv->ConvertColour(pEndColour, (ColourGeneric *)&EndC);
01548
01549
01550 ColourValue Difference;
01551
01552 if(EndC.Hue > StartC.Hue)
01553 {
01554 Difference = EndC.Hue - StartC.Hue;
01555 } else {
01556 Difference = 1.0 - (StartC.Hue - EndC.Hue);
01557 }
01558
01559
01560 if(Difference > fixed24(0.5))
01561 NormalRainbow = FALSE;
01562 }
01563
01564
01565 switch(Fill->Spec.Fountain.FillMode)
01566 {
01567 case cmxFILLMODE_RGB:
01568 case cmxFILLMODE_CUSTOM:
01569 default:
01570 SetFadeFillEffect();
01571 break;
01572
01573 case cmxFILLMODE_HSB_CCW:
01574 if(NormalRainbow)
01575 SetRainbowFillEffect();
01576 else
01577 SetAltRainbowFillEffect();
01578 break;
01579
01580 case cmxFILLMODE_HSB_CW:
01581 if(NormalRainbow)
01582 SetAltRainbowFillEffect();
01583 else
01584 SetRainbowFillEffect();
01585 break;
01586 }
01587
01588
01589 switch(Fill->Spec.Fountain.Type)
01590 {
01591 case cmxFOUNTAINTYPE_LINEAR:
01592 if(!SetAttributesLinearGrad(pNode, Fill, BBox, pStartColour, pEndColour))
01593 return FALSE;
01594 break;
01595
01596 case cmxFOUNTAINTYPE_RADIAL:
01597 if(!SetAttributesRadialGrad(pNode, Fill, BBox, pStartColour, pEndColour))
01598 return FALSE;
01599 break;
01600
01601 case cmxFOUNTAINTYPE_SQUARE:
01602 if(!SetAttributesRadialGrad(pNode, Fill, BBox, pStartColour, pEndColour, TRUE))
01603 return FALSE;
01604 break;
01605
01606 case cmxFOUNTAINTYPE_CONICAL:
01607 if(!SetAttributesConicalGrad(pNode, Fill, BBox, pStartColour, pEndColour))
01608 return FALSE;
01609 break;
01610
01611 default:
01612 return SetNoFill(pNode);
01613 break;
01614 }
01615
01616 return TRUE;
01617 }
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 BOOL CMXImportFilter::SetAttributesLinearGrad(Node *pNode, cmxiFillSpec *GFill, DocRect &BBox, DocColour *StartColour, DocColour *EndColour)
01635 {
01636
01637
01638
01639
01640
01641 DocCoord Start, End;
01642
01643
01644 MILLIPOINT Width = BBox.Width();
01645 MILLIPOINT Height = BBox.Height();
01646
01647
01648 if(Width < 16)
01649 Width = 16;
01650
01651 if(Height < 16)
01652 Height = 16;
01653
01654
01655 DocCoord Centre;
01656 Centre.x = BBox.lo.x + (Width / 2);
01657 Centre.y = BBox.lo.y + (Height / 2);
01658
01659
01660 double TotalArea = (double) Width * (double) Height;
01661
01662
01663 BOOL Mirror = FALSE;
01664 double Angle = GFill->Spec.Fountain.Angle;
01665
01666 if (Angle >= PI)
01667 {
01668 Angle -= PI;
01669 Mirror = TRUE;
01670 }
01671 else if (Angle < 0)
01672 {
01673 Angle += PI;
01674 Mirror = TRUE;
01675 }
01676
01677 Angle += (PI/2);
01678
01679 if (Angle >= PI)
01680 {
01681 Angle -= PI;
01682 }
01683
01684
01685 INT32 EdgePad = GFill->Spec.Fountain.Padding;
01686
01687
01688 double TanTheta;
01689 if (Angle == (PI/2))
01690 {
01691
01692
01693
01694 Start.x = BBox.lo.x;
01695 Start.y = Centre.y;
01696 End.x = BBox.hi.x;
01697 End.y = Centre.y;
01698
01699
01700 INT32 Padding = (Width * EdgePad) / 100;
01701 Start.x += Padding;
01702 End.x -= Padding;
01703 }
01704 else if (Angle == 0)
01705 {
01706
01707
01708
01709 Start.x = Centre.x;
01710 Start.y = BBox.lo.y;
01711 End.x = Centre.x;
01712 End.y = BBox.hi.y;
01713
01714
01715 INT32 Padding = (Height * EdgePad) / 100;
01716 Start.y += Padding;
01717 End.y -= Padding;
01718 }
01719 else
01720 {
01721 TanTheta = tan(Angle);
01722
01723
01724
01725
01726 MILLIPOINT TriWidth = (MILLIPOINT) ((double) Height / TanTheta);
01727
01728
01729 if (TriWidth < 0)
01730 TriWidth = -TriWidth;
01731 if (TriWidth > Width)
01732 TriWidth = Width;
01733
01734
01735 MILLIPOINT TriHeight = (MILLIPOINT) ((double) Width * TanTheta);
01736
01737
01738 if (TriHeight < 0)
01739 TriHeight = -TriHeight;
01740 if (TriHeight > Height)
01741 TriHeight = Height;
01742
01743
01744 MILLIPOINT StartC, EndC;
01745
01746
01747
01748 double Percentage = (50.0 * (double) TriWidth * (double) TriHeight) / TotalArea;
01749
01750 INT32 Diff = 0;
01751
01752
01753 if (((INT32) Percentage) >= EdgePad)
01754 {
01755
01756 TriHeight = (MILLIPOINT) sqrt(ABS(((double) EdgePad * TotalArea * TanTheta) / 100.0));
01757
01758 TriWidth = (MILLIPOINT) ((double) TriHeight / TanTheta);
01759 if (TriWidth < 0)
01760 TriWidth = -TriWidth;
01761
01762 ENSURE(TriWidth < Width, "Error in Corel Grad fill decoding logic");
01763 }
01764 else
01765 {
01766
01767 Percentage = (EdgePad - Percentage) / 2;
01768
01769
01770 if (TriWidth == Width)
01771 {
01772
01773 Diff = (MILLIPOINT) ((Percentage * Height) / 100.0);
01774 }
01775 else
01776 {
01777
01778 Diff = (MILLIPOINT) ((Percentage * Width) / 100.0);
01779 Diff = (MILLIPOINT) (Diff / tan(PI - Angle));
01780 Diff = ABS(Diff);
01781 }
01782 }
01783
01784
01785
01786 if (Angle == (PI/2))
01787 {
01788
01789 }
01790 else if (Angle < (PI/2))
01791 {
01792 StartC = (MILLIPOINT) (BBox.lo.y - ((BBox.hi.x - TriWidth) * TanTheta));
01793 EndC = (MILLIPOINT) (BBox.hi.y - ((BBox.lo.x + TriWidth) * TanTheta));
01794 }
01795 else
01796 {
01797 StartC = (MILLIPOINT) (BBox.lo.y - ((BBox.lo.x + TriWidth) * TanTheta));
01798 EndC = (MILLIPOINT) (BBox.hi.y - ((BBox.hi.x - TriWidth) * TanTheta));
01799 }
01800
01801
01802 StartC += Diff;
01803 EndC -= Diff;
01804
01805
01806
01807
01808
01809 double FillM = -1.00 / TanTheta;
01810 MILLIPOINT FillC = (MILLIPOINT) (Centre.y - (Centre.x * FillM));
01811
01812
01813
01814 Start.x = (MILLIPOINT) ( (FillC - StartC) / (TanTheta + (1.00 / TanTheta)) );
01815 Start.y = (MILLIPOINT) ((FillM * Start.x) + FillC);
01816
01817 End.x = (MILLIPOINT) ( (FillC - EndC) / (TanTheta + (1.00 / TanTheta)) );
01818 End.y = (MILLIPOINT) ((FillM * End.x) + FillC);
01819 }
01820
01821 if (Mirror)
01822 {
01823
01824 DocCoord Tmp = Start;
01825 Start = End;
01826 End = Tmp;
01827 }
01828
01829
01830 return SetLinearFill(*StartColour, *EndColour, Start, End);
01831 }
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846 BOOL CMXImportFilter::SetAttributesConicalGrad(Node *pNode, cmxiFillSpec *GFill, DocRect &BBox, DocColour *StartColour, DocColour *EndColour)
01847 {
01848
01849 DocCoord Start, End;
01850
01851
01852 MILLIPOINT Width = BBox.Width();
01853 MILLIPOINT Height = BBox.Height();
01854
01855
01856
01857
01858 Start.x = BBox.lo.x + (Width / 2);
01859 Start.y = BBox.lo.y + (Height / 2);
01860 Start.x += ((GFill->Spec.Fountain.Offset.x * Width) / 100);
01861 Start.y += ((GFill->Spec.Fountain.Offset.y * Height) / 100);
01862
01863
01864 double Radius = Width / 2;
01865 double Theta = GFill->Spec.Fountain.Angle;
01866
01867
01868 Theta = 0 - Theta;
01869
01870
01871 Theta -= PI / 2;
01872
01873
01874 while(Theta < 0)
01875 Theta += (2 * PI);
01876
01877
01878 double dx, dy;
01879
01880 dx = Radius * sin(Theta);
01881 dy = Radius * cos(Theta);
01882
01883 End.x = Start.x + (INT32)dx;
01884 End.y = Start.y + (INT32)dy;
01885
01886
01887
01888
01889 return SetConicalFill(*EndColour, *StartColour, Start, End);
01890 }
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905 BOOL CMXImportFilter::SetAttributesRadialGrad(Node *pNode, cmxiFillSpec *GFill, DocRect &BBox, DocColour *StartColour, DocColour *EndColour, BOOL IsSquare)
01906 {
01907
01908 DocCoord Start, End, End2;
01909
01910
01911 MILLIPOINT Width = BBox.Width();
01912 MILLIPOINT Height = BBox.Height();
01913
01914
01915
01916 double dWidth = Width;
01917 double dHeight = Height;
01918 INT32 Diagonal = (INT32)sqrt(dWidth*dWidth + dHeight*dHeight);
01919
01920
01921
01922 INT32 Edge = (Diagonal * (100 - (GFill->Spec.Fountain.Padding * 2))) / 100;
01923
01924
01925
01926
01927 DocCoord Centre = DocCoord(BBox.lo.x + (Width / 2), BBox.lo.y + (Height / 2));
01928 INT32 OffX = (GFill->Spec.Fountain.Offset.x * Width) / 100;
01929 INT32 OffY = (GFill->Spec.Fountain.Offset.y * Height) / 100;
01930 Start.x = Centre.x + OffX;
01931 Start.y = Centre.y + OffY;
01932
01933
01934 double Radius = Edge / 2;
01935
01936
01937 double dOffX = OffX;
01938 double dOffY = OffY;
01939 double Dist = (INT32)sqrt(dOffX*dOffX + dOffY*dOffY);
01940
01941
01942 double BodgeFactor = 1 + (Dist / (double)(Diagonal / 2));
01943 Radius *= BodgeFactor;
01944
01945
01946 if(IsSquare)
01947 {
01948
01949 double Theta = GFill->Spec.Fountain.Angle;
01950 End.x = Start.x + ((MILLIPOINT)(Radius * cos(Theta)));
01951 End.y = Start.y + ((MILLIPOINT)(Radius * sin(Theta)));
01952 End2.x = Start.x + ((MILLIPOINT)(Radius * cos(Theta + PI/2)));
01953 End2.y = Start.y + ((MILLIPOINT)(Radius * sin(Theta + PI/2)));
01954 }
01955 else
01956 {
01957
01958 End.x = Start.x + ((MILLIPOINT) Radius);
01959 End.y = Start.y;
01960 }
01961
01962
01963
01964
01965 BOOL ok;
01966 if(IsSquare)
01967 ok = SetSquareFill(*EndColour, *StartColour, Start, End, End2);
01968
01969 else
01970 ok = SetRadialFill(*EndColour, *StartColour, Start, End);
01971
01972 return ok;
01973 }
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988 BOOL CMXImportFilter::SetAttributesBitmapFill(Node *pNode, INT32 VectorReference, cmxiTiling *Tile)
01989 {
01990
01991 if(VectorReference <= 0 || VectorReference > Data->NumProcedures)
01992 return SetNoFill(pNode);
01993
01994
01995 INT32 Position = Data->Procedures[VectorReference-1].Position;
01996 if(Position <= 0)
01997 return SetNoFill(pNode);
01998
01999
02000 INT32 StartFilePos = Tell();
02001
02002
02003 Seek(Position);
02004
02005
02006 INT32 Jenny = -1;
02007
02008
02009 RIFFck hdr;
02010 pFile->read(&hdr, sizeof(hdr));
02011
02012
02013 BOOL EndProcLoc = Tell() + hdr.ckSize;
02014
02015
02016 TRACEUSER( "Ben", _T("searching commands in vector fill procedure:\n"));
02017 BOOL Done = FALSE;
02018 while(Done == FALSE)
02019 {
02020
02021
02022 INT32 CommandEndFilePos = Tell();
02023
02024
02025 CI_READDATA(CommandHeader, ch)
02026
02027
02028 if(ch.Code < 0 && !Is32Bit)
02029 ch.Code = 0 - ch.Code;
02030
02031 CommandEndFilePos += ch.Size;
02032
02033
02034 if(ch.Code == cmxINSTR_DrawImage)
02035 {
02036
02037 CI_READDATA(DrawImage, di)
02038
02039 if(di.ImageFileReference1 > 0 && di.ImageFileReference1 <= Data->NumRImages)
02040 {
02041
02042 Jenny = di.ImageFileReference1;
02043 break;
02044 }
02045 }
02046 else if(ch.Code == cmxINSTR_EndSection)
02047 {
02048
02049 break;
02050 }
02051
02052
02053 if(Tell() != CommandEndFilePos)
02054 Seek(CommandEndFilePos);
02055
02056 if(CommandEndFilePos >= EndProcLoc)
02057 break;
02058 }
02059 TRACEUSER( "Ben", _T("finished searching commands, ref = %d\n"), Jenny);
02060
02061
02062 Seek(StartFilePos);
02063
02064
02065 if(Jenny <= 0)
02066 return SetNoFill(pNode);
02067
02068
02069 DocRect BBox;
02070 if(!GetCorelBBox((NodeRenderableBounded *)pNode, &BBox))
02071 return FALSE;
02072
02073
02074 DocCoord StartPoint, EndPoint, EndPoint2;
02075 if(!GetTilingPoints(&BBox, Tile, &StartPoint, &EndPoint, &EndPoint2))
02076 return FALSE;
02077
02078
02079 if(!Data->RImages[Jenny-1].IsRImage())
02080 return SetNoFill(pNode);
02081 KernelBitmap *pBitmap = Data->RImages[Jenny-1].GetBitmap(this);
02082 if(pBitmap == 0)
02083 return SetNoFill(pNode);
02084
02085
02086 return SetBitmapFill(pBitmap, StartPoint, EndPoint, EndPoint2);
02087 }
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102 BOOL CMXImportFilter::SetAttributesTwoColourBitmapFill(Node *pNode, cmxiFillSpec *pFill)
02103 {
02104
02105 DocRect BBox;
02106 if(!GetCorelBBox((NodeRenderableBounded *)pNode, &BBox))
02107 return FALSE;
02108
02109
02110 DocCoord StartPoint, EndPoint, EndPoint2;
02111 if(!GetTilingPoints(&BBox, &pFill->Spec.TwoColourBitmap.Tile, &StartPoint, &EndPoint, &EndPoint2))
02112 return FALSE;
02113
02114
02115 INT32 y0 = StartPoint.y;
02116 INT32 y1 = EndPoint2.y;
02117 StartPoint.y = y1;
02118 EndPoint2.y = y0;
02119 EndPoint.y = y1;
02120
02121
02122 if(pFill->Spec.TwoColourBitmap.BitmapReference <= 0 || pFill->Spec.TwoColourBitmap.BitmapReference > Data->NumBitmaps)
02123 return SetNoFill(pNode);
02124
02125
02126 DocColour *pStartColour = GetColourFromReference(pFill->Spec.TwoColourBitmap.ForeColourReference);
02127 DocColour *pEndColour = GetColourFromReference(pFill->Spec.TwoColourBitmap.BackColourReference);
02128
02129
02130 KernelBitmap *pBitmap = Data->Bitmaps[pFill->Spec.TwoColourBitmap.BitmapReference - 1].CreateColouredCopy(this, pStartColour, pEndColour);
02131 if(pBitmap == 0)
02132 return SetNoFill(pNode);
02133
02134
02135 return SetBitmapFill(pBitmap, StartPoint, EndPoint, EndPoint2);
02136 }
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151 BOOL CMXImportFilter::GetTilingPoints(DocRect *BBox, cmxiTiling *Tile, DocCoord *StartPoint, DocCoord *EndPoint, DocCoord *EndPoint2)
02152 {
02153 if(Tile != 0)
02154 {
02155
02156 INT32 SizeX = (INT32)(Tile->Width * Data->BaseScaleFactor);
02157 INT32 SizeY = (INT32)(Tile->Height * Data->BaseScaleFactor);
02158
02159
02160 INT32 XPos = BBox->lo.x + ((SizeX * Tile->XOffset) / 100);
02161 INT32 YPos = BBox->hi.y - SizeY - ((SizeY * Tile->YOffset) / 100);
02162
02163
02164 *StartPoint = DocCoord(XPos, YPos);
02165 *EndPoint = DocCoord(XPos + SizeX, YPos);
02166 *EndPoint2 = DocCoord(XPos, YPos + SizeY);
02167 }
02168 else
02169 {
02170
02171 *StartPoint = DocCoord(BBox->lo.x, BBox->lo.y);
02172 *EndPoint = DocCoord(BBox->hi.x, BBox->lo.y);
02173 *EndPoint2 = DocCoord(BBox->lo.x, BBox->hi.y);
02174 }
02175
02176 return TRUE;
02177 }
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194 BOOL CMXImportFilter::SkipToPreviewBitmap(CCLexFile * pFile)
02195 {
02196
02197 pFile->seekIn(0);
02198
02199
02200 RIFFFile_Header hdr;
02201 pFile->read(&hdr, sizeof(hdr));
02202
02203
02204 if(hdr.CK.ckID != RIFFTYPE_RIFF)
02205 return FALSE;
02206
02207 INT32 FileEnd = hdr.CK.ckSize;
02208 INT32 where = sizeof(hdr);
02209
02210
02211 for(INT32 togo = 4; togo > 0 && where < FileEnd; togo--)
02212 {
02213
02214 RIFFck ck;
02215 pFile->read(&ck, sizeof(ck));
02216
02217 where += sizeof(ck) + ck.ckSize;
02218
02219
02220 if(ck.ckID == cmxRIFFCI_Thumbnail)
02221 {
02222
02223 DWORD clipboardformat;
02224 pFile->read(&clipboardformat, sizeof(clipboardformat));
02225
02226 return TRUE;
02227 }
02228
02229
02230 pFile->seekIn(where);
02231 }
02232
02233
02234 return FALSE;
02235 }
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253 void CMXImportFilter::SetNonTextAttributeIgnore()
02254 {
02255 CurrentAttrs[ATTR_BAD_ID].Ignore = TRUE;
02256 CurrentAttrs[ATTR_STROKECOLOUR].Ignore = TRUE;
02257 CurrentAttrs[ATTR_STROKETRANSP].Ignore = TRUE;
02258 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
02259 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Ignore = TRUE;
02260 CurrentAttrs[ATTR_FILLMAPPING].Ignore = TRUE;
02261 CurrentAttrs[ATTR_TRANSPFILLMAPPING].Ignore = TRUE;
02262 CurrentAttrs[ATTR_FILLEFFECT].Ignore = TRUE;
02263 CurrentAttrs[ATTR_LINEWIDTH].Ignore = TRUE;
02264 CurrentAttrs[ATTR_WINDINGRULE].Ignore = TRUE;
02265 CurrentAttrs[ATTR_JOINTYPE].Ignore = TRUE;
02266 CurrentAttrs[ATTR_QUALITY].Ignore = TRUE;
02267 CurrentAttrs[ATTR_DASHPATTERN].Ignore = TRUE;
02268 CurrentAttrs[ATTR_STARTCAP].Ignore = TRUE;
02269 CurrentAttrs[ATTR_STARTARROW].Ignore = TRUE;
02270 CurrentAttrs[ATTR_ENDARROW].Ignore = TRUE;
02271 CurrentAttrs[ATTR_MITRELIMIT].Ignore = TRUE;
02272 CurrentAttrs[ATTR_TXTFONTTYPEFACE].Ignore = TRUE;
02273 CurrentAttrs[ATTR_OVERPRINTLINE].Ignore = TRUE;
02274 CurrentAttrs[ATTR_OVERPRINTFILL].Ignore = TRUE;
02275 CurrentAttrs[ATTR_PRINTONALLPLATES].Ignore = TRUE;
02276 CurrentAttrs[ATTR_FIRST_FREE_ID].Ignore = TRUE;
02277 CurrentAttrs[ATTR_MOULD].Ignore = TRUE;
02278 CurrentAttrs[ATTR_ENDCAP].Ignore = TRUE;
02279 }
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293 void CMXImportFilter::SetNonTextAttributeNotIgnore()
02294 {
02295 CurrentAttrs[ATTR_BAD_ID].Ignore = FALSE;
02296 CurrentAttrs[ATTR_STROKECOLOUR].Ignore = FALSE;
02297 CurrentAttrs[ATTR_STROKETRANSP].Ignore = FALSE;
02298 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
02299 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Ignore = FALSE;
02300 CurrentAttrs[ATTR_FILLMAPPING].Ignore = FALSE;
02301 CurrentAttrs[ATTR_TRANSPFILLMAPPING].Ignore = FALSE;
02302 CurrentAttrs[ATTR_FILLEFFECT].Ignore = FALSE;
02303 CurrentAttrs[ATTR_LINEWIDTH].Ignore = FALSE;
02304 CurrentAttrs[ATTR_WINDINGRULE].Ignore = FALSE;
02305 CurrentAttrs[ATTR_JOINTYPE].Ignore = FALSE;
02306 CurrentAttrs[ATTR_QUALITY].Ignore = FALSE;
02307 CurrentAttrs[ATTR_DASHPATTERN].Ignore = FALSE;
02308 CurrentAttrs[ATTR_STARTCAP].Ignore = FALSE;
02309 CurrentAttrs[ATTR_STARTARROW].Ignore = FALSE;
02310 CurrentAttrs[ATTR_ENDARROW].Ignore = FALSE;
02311 CurrentAttrs[ATTR_MITRELIMIT].Ignore = FALSE;
02312 CurrentAttrs[ATTR_TXTFONTTYPEFACE].Ignore = FALSE;
02313 CurrentAttrs[ATTR_OVERPRINTLINE].Ignore = FALSE;
02314 CurrentAttrs[ATTR_OVERPRINTFILL].Ignore = FALSE;
02315 CurrentAttrs[ATTR_PRINTONALLPLATES].Ignore = FALSE;
02316 CurrentAttrs[ATTR_FIRST_FREE_ID].Ignore = FALSE;
02317 CurrentAttrs[ATTR_MOULD].Ignore = FALSE;
02318 CurrentAttrs[ATTR_ENDCAP].Ignore = FALSE;
02319 }
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332 void CMXImportFilter::SetTextAttributeIgnore()
02333 {
02334 CurrentAttrs[ATTR_TXTFONTTYPEFACE].Ignore = TRUE;
02335 CurrentAttrs[ATTR_TXTBOLD].Ignore = TRUE;
02336 CurrentAttrs[ATTR_TXTITALIC].Ignore = TRUE;
02337 CurrentAttrs[ATTR_TXTASPECTRATIO].Ignore = TRUE;
02338 CurrentAttrs[ATTR_TXTJUSTIFICATION].Ignore = TRUE;
02339 CurrentAttrs[ATTR_TXTTRACKING].Ignore = TRUE;
02340 CurrentAttrs[ATTR_TXTUNDERLINE].Ignore = TRUE;
02341 CurrentAttrs[ATTR_TXTFONTSIZE].Ignore = TRUE;
02342 CurrentAttrs[ATTR_TXTSCRIPT].Ignore = TRUE;
02343 CurrentAttrs[ATTR_TXTBASELINE].Ignore = TRUE;
02344 CurrentAttrs[ATTR_TXTLINESPACE].Ignore = TRUE;
02345
02346 }
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360 void CMXImportFilter::SetTextAttributeNotIgnore()
02361 {
02362 CurrentAttrs[ATTR_TXTFONTTYPEFACE].Ignore = FALSE;
02363 CurrentAttrs[ATTR_TXTBOLD].Ignore = FALSE;
02364 CurrentAttrs[ATTR_TXTITALIC].Ignore = FALSE;
02365 CurrentAttrs[ATTR_TXTASPECTRATIO].Ignore = FALSE;
02366 CurrentAttrs[ATTR_TXTJUSTIFICATION].Ignore = FALSE;
02367 CurrentAttrs[ATTR_TXTTRACKING].Ignore = FALSE;
02368 CurrentAttrs[ATTR_TXTUNDERLINE].Ignore = FALSE;
02369 CurrentAttrs[ATTR_TXTFONTSIZE].Ignore = FALSE;
02370 CurrentAttrs[ATTR_TXTSCRIPT].Ignore = FALSE;
02371 CurrentAttrs[ATTR_TXTBASELINE].Ignore = FALSE;
02372 CurrentAttrs[ATTR_TXTLINESPACE].Ignore = FALSE;
02373
02374 }