00001 // $Id: cmxfiltr.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // CMX (Corel Metafile) Filter 00099 00100 /* 00101 */ 00102 00103 00104 #include "camtypes.h" 00105 #include "cmxfiltr.h" 00106 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 //#include "filtrres.h" 00108 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 #include "cmxexdc.h" 00110 #include "cmxrendr.h" 00111 #include "page.h" 00112 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 //#include "tim.h" 00114 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 #include "nodepath.h" 00116 //#include "cmxres.h" 00117 00118 DECLARE_SOURCE("$Revision: 1282 $"); 00119 00120 CC_IMPLEMENT_DYNAMIC(CMXFilter, VectorFilter) 00121 CC_IMPLEMENT_DYNAMIC(CMXFilter16, CMXFilter) 00122 CC_IMPLEMENT_DYNAMIC(CMXFilter32, CMXFilter) 00123 00124 /******************************************************************************************** 00125 00126 > CMXFilter::CMXFilter() 00127 00128 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00129 Created: 17/6/96 00130 Inputs: None 00131 Returns: None 00132 Purpose: Constructor for class CMXFilter 00133 SeeAlso: class VectorFilter 00134 00135 ********************************************************************************************/ 00136 00137 CMXFilter::CMXFilter() 00138 { 00139 // Set up filter descriptions. 00140 FilterName.Load(_R(IDT_CMXFILTER_FILTERNAME)); 00141 FilterInfo.Load(_R(IDT_CMXFILTER_FILTERINFO)); 00142 FilterID = FILTERID_NONE; 00143 00144 Flags.CanImport = FALSE; 00145 Flags.CanExport = FALSE; 00146 00147 #ifdef DO_EXPORT 00148 //WEBSTER-Martin-27/01/97 00149 #ifndef WEBSTER 00150 Flags.CanExport = TRUE; 00151 #endif //WEBSTER 00152 #endif 00153 00154 ImportMsgID = _R(IDT_IMPORTMSG_CMX); 00155 00156 ExportDC = NULL; 00157 ExportRegion = NULL; 00158 ExportMsgID = _R(IDT_EXPORTMSG_CMX); 00159 00160 IsDoingClipboardExport = FALSE; 00161 } 00162 00163 /******************************************************************************************** 00164 00165 > CMXFilter16::CMXFilter16() 00166 00167 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00168 Created: 19/6/96 00169 Inputs: None 00170 Returns: None 00171 Purpose: Constructor for class CMXFilter16 00172 SeeAlso: class CMXFilter 00173 00174 ********************************************************************************************/ 00175 00176 CMXFilter16::CMXFilter16() 00177 { 00178 // Set up filter descriptions. 00179 FilterID = FILTERID_CMX16; 00180 } 00181 00182 /******************************************************************************************** 00183 00184 > CMXFilter32::CMXFilter32() 00185 00186 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00187 Created: 19/6/96 00188 Inputs: None 00189 Returns: None 00190 Purpose: Constructor for class CMXFilter16 00191 SeeAlso: class CMXFilter 00192 00193 ********************************************************************************************/ 00194 00195 CMXFilter32::CMXFilter32() 00196 { 00197 // Set up filter descriptions. 00198 FilterID = FILTERID_CMX32; 00199 } 00200 00201 /******************************************************************************************** 00202 00203 > BOOL CMXFilter16::Init() 00204 00205 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00206 Created: 17/6/96 00207 Inputs: None 00208 Returns: BOOL, propably saying whether we succeeded or not, buts it not documented 00209 Purpose: Initialiser for class CMXFilter 00210 SeeAlso: Filter 00211 00212 ********************************************************************************************/ 00213 00214 BOOL CMXFilter16::Init() 00215 { 00216 // Get the OILFilter object 00217 pOILFilter = new CMX16OILFilter(this); 00218 if (pOILFilter == NULL) 00219 return FALSE; 00220 00221 return TRUE; 00222 } 00223 00224 /******************************************************************************************** 00225 00226 > BOOL CMXFilter32::Init() 00227 00228 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00229 Created: 17/6/96 00230 Inputs: None 00231 Returns: BOOL, propably saying whether we succeeded or not, buts it not documented 00232 Purpose: Initialiser for class CMXFilter 00233 SeeAlso: Filter 00234 00235 ********************************************************************************************/ 00236 00237 BOOL CMXFilter32::Init() 00238 { 00239 // Get the OILFilter object 00240 pOILFilter = new CMX32OILFilter(this); 00241 if (pOILFilter == NULL) 00242 return FALSE; 00243 00244 00245 return TRUE; 00246 } 00247 00248 /******************************************************************************************** 00249 00250 > INT32 CMXFilter::HowCOmpatible(PathName& Filename, 00251 ADDR HeaderStart, 00252 UINT32 HeaderSize, 00253 UINT32 FileSize); 00254 00255 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00256 Created: 17/6/96 00257 Inputs: Filename - filename of file to check 00258 HeaderStart, HeaderSize, - infomation on header of file loaded into memory 00259 FileSize - length of file (bytes) 00260 Returns: 0 to 10. 0 means I know nothing about this file, 10 means its definitly mine 00261 Purpose: Looks at the start of the file to see if we recognise it as one of ours 00262 SeeAlso: class Filters, class CDRFilter 00263 00264 ********************************************************************************************/ 00265 00266 INT32 CMXFilter::HowCompatible(PathName & FileName, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize) 00267 { 00268 return 0; 00269 } 00270 00271 /******************************************************************************************** 00272 00273 > BOOL CMXFilter::DoImport(SelOperation * Op, CCLexFile * pDiskFile, 00274 Document * DestDoc, BOOL AutoChoosen , ImportPosition * Pos, 00275 KernelBitmap** ppImportedBitmap,DocCoord* pPosTranslate, String_256* URL) 00276 00277 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00278 Created: 17/6/96 00279 Inputs: Op - pointer to the operatioj that this input process is associated with, 00280 pDiskFile - the CMX file to be loaded 00281 DestDoc - the document object whcih should hold the data read in from this file 00282 URL - original URL of the imported file 00283 Returns: TRUE is the input operation worked, FALSE if not 00284 Purpose: Read an CMX format file and convert it into Camelot tree data structures. When 00285 the file is loaded we force a redraw for the area affected by the new data 00286 At the moment the data is just put on the first layer of the first spread 00287 of the first chapter in the document, and this is a bodge. 00288 The operation is terminated (i.e. its End() function is called) if the 00289 operation completed successfully. 00290 Errors: Fails (returns FALSE) if the document structure is incorrect, if the CMX file 00291 contains a syntax error, of the CMX file cannot be found/opened or if its 00292 not actually an CMX file. 00293 SeeAlso: CMXFilter::HowCompatible 00294 00295 ********************************************************************************************/ 00296 00297 BOOL CMXFilter::DoImport(SelOperation * Op, CCLexFile * pDiskFile, 00298 Document * DestDoc, BOOL AutoChoosen , ImportPosition * Pos, 00299 KernelBitmap** ppImportedBitmap,DocCoord* pPosTranslate, String_256* URL) 00300 { 00301 return FALSE; 00302 } 00303 00304 /******************************************************************************************** 00305 00306 > BOOL CMXFilter::DoExport(Operation *, CCLexFile *, PathName *, Document * ); 00307 00308 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00309 Created: 17/6/96 00310 Inputs: 00311 Returns: 00312 Purpose: does the exportness 00313 SeeAlso: 00314 00315 ********************************************************************************************/ 00316 00317 BOOL CMXFilter::DoExport(Operation* pOp, CCLexFile* pFile, PathName* pPath, Document* pDoc, 00318 BOOL ShowOptions) 00319 { 00320 #ifdef DO_EXPORT 00321 // Used to open the file up before starting DoExport. But this meant a cancel on the export 00322 // options dialog had filled the file, if it was already present. So now up up here if 00323 // not open already. 00324 BOOL ok; 00325 if (!pFile->isOpen()) 00326 { 00327 if (pFile->IsKindOf(CC_RUNTIME_CLASS(CCDiskFile))) 00328 { 00329 ok = OpenExportFile((CCDiskFile*) pFile, pPath); 00330 if (!ok) return FALSE; 00331 } 00332 else 00333 { 00334 TRACEUSER( "JustinF", _T("Tried to open non-CCDiskFile in CMXFilter::DoExport\n")); 00335 return FALSE; 00336 } 00337 } 00338 00339 // Set up document pointer 00340 TheDocument = pDoc; 00341 00342 // set a nice flag 00343 DisplaySquishyWarning = FALSE; 00344 00345 // Get pointer to the spread to export. 00346 Spread *pSpread = GetFirstSpread(pDoc); 00347 00348 // Set up device context and render region for this export. 00349 if (!PrepareToExport(pFile, pSpread)) 00350 { 00351 CleanUpAfterExport(); 00352 return FALSE; 00353 } 00354 00355 // Graeme (15-2-00) - Ben's original code used the spread's bounding box, which appears 00356 // to line in the range +/- 10,000,000. This was giving the wrong results, so I've 00357 // now modified the code to create the PageBBox from the page's bounding box. 00358 Page *pPage = ( Page * ) pSpread->FindFirstPageInSpread (); 00359 DocRect PageBBox = pPage->GetPageRect (); 00360 00361 ExportDC->SetInfo(pOp, pPath, pDoc); 00362 00363 // write the header 00364 if(!ExportDC->CreateHeader(&PageBBox)) 00365 return FALSE; 00366 00367 // preview bitmap... 00368 if(!IsDoingClipboardExport) 00369 { 00370 if(!ExportDC->WritePreviewBitmap()) 00371 return FALSE; 00372 } 00373 00374 // start the page 00375 if(!ExportDC->StartPage(&PageBBox)) 00376 return FALSE; 00377 00378 // Export the data to the file 00379 if (!ExportRender(ExportRegion)) 00380 { 00381 CleanUpAfterExport(); 00382 return FALSE; 00383 } 00384 00385 // end the page 00386 if(!ExportDC->EndPage()) 00387 return FALSE; 00388 00389 // write the reference list 00390 if(!ExportDC->WriteReferenceList()) 00391 return FALSE; 00392 00393 // write the description sections 00394 if(!ExportDC->WriteDescriptionSections()) 00395 return FALSE; 00396 00397 // write any other sections 00398 if(!ExportDC->WriteReferSections()) 00399 return FALSE; 00400 00401 // write the index 00402 if(!ExportDC->WriteIndex()) 00403 return FALSE; 00404 00405 if(!FinishExport()) 00406 return FALSE; 00407 00408 // All done - deallocate dynamic objects and return success. 00409 CleanUpAfterExport(); 00410 00411 // Detach document 00412 TheDocument = NULL; 00413 00414 if(DisplaySquishyWarning) 00415 { 00416 Error::SetError(_R(IDT_CMXFILTER_SQUISHWARNING), 0); 00417 InformWarning(); 00418 Error::ClearError(); 00419 } 00420 00421 return TRUE; 00422 #else 00423 return FALSE; 00424 #endif 00425 } 00426 00427 /******************************************************************************************** 00428 00429 > Matrix CMXFilter16::GetExportTransform ( Spread *pSpread ) 00430 00431 Author: Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com> 00432 Created: 14/2/00 00433 Inputs: pSpread - A pointer to the spread that is being exported. 00434 Returns: Matrix - A transformation matrix to covert Camelot co-ordinate spaces into 00435 CMX co-ordinate spaces. 00436 Purpose: Creates a transformation matrix that provides the mapping between a Camelot 00437 document's co-ordinate system, and that used within the CMX file. 00438 SeeAlso: 00439 00440 ********************************************************************************************/ 00441 00442 Matrix CMXFilter16::GetExportTransform(Spread *pSpread) 00443 { 00444 #ifdef DO_EXPORT 00445 00446 // Work out where the origin is... 00447 Page *pPage = ( Page * ) pSpread->FindFirstPageInSpread (); 00448 00449 // Use the centre of the page as the origin. 00450 DocCoord CMXOrigin = ( pPage->GetPageRect () ).Centre (); 00451 00452 // CMXOrigin is the origin of the page in CMX coords... 00453 Matrix Mat ( -CMXOrigin.x, -CMXOrigin.y ); 00454 00455 // Fiddle with the scale factor 00456 Mat *= Matrix ( FIXED16 ( CAMCOORD_SCALEFACTOR16 ), FIXED16 ( CAMCOORD_SCALEFACTOR16 ) ); 00457 00458 return Mat; 00459 #else 00460 return Matrix (); 00461 #endif 00462 } 00463 00464 00465 /******************************************************************************************** 00466 00467 > Matrix &CMXFilter32::GetExportTransform(Spread *pSpread) 00468 00469 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00470 Created: 27/06/96 00471 Inputs: none 00472 Returns: whether it fell over or not, really. 00473 Purpose: get everything ready for the old exporting business -- basically 00474 set up one of our nice render regions, write a little header 00475 and get everything under way. 00476 SeeAlso: 00477 00478 ********************************************************************************************/ 00479 00480 Matrix CMXFilter32::GetExportTransform(Spread *pSpread) 00481 { 00482 #ifdef DO_EXPORT 00483 // Work out where the origin is... 00484 Page *pPage = ( Page * ) pSpread->FindFirstPageInSpread (); 00485 00486 // Use the centre of the page as the origin. 00487 DocCoord CMXOrigin = ( pPage->GetPageRect () ).Centre (); 00488 00489 // CMXOrigin is the origin of the page in CMX coords... 00490 Matrix Mat ( -CMXOrigin.x, -CMXOrigin.y ); 00491 00492 // Fiddle with the scale factor 00493 Mat *= Matrix(FIXED16(CAMCOORD_SCALEFACTOR32), FIXED16(CAMCOORD_SCALEFACTOR32)); 00494 00495 return Mat; 00496 #else 00497 return Matrix(); 00498 #endif 00499 } 00500 00501 00502 /******************************************************************************************** 00503 00504 > BOOL CMXFilter::PrepareToExport(CCLexFile*, Spread* pSpread) 00505 00506 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00507 Created: 18/6/96 00508 Inputs: disk file to pop things out to, spread to do funky things to 00509 Returns: whether it fell over or not, really. 00510 Purpose: get everything ready for the old exporting business -- basically 00511 set up one of our nice render regions, write a little header 00512 and get everything under way. 00513 SeeAlso: 00514 00515 ********************************************************************************************/ 00516 00517 BOOL CMXFilter::PrepareToExport(CCLexFile* pFile, Spread* pSpread) 00518 { 00519 #ifdef DO_EXPORT 00520 // Get the position of the first page, and use this to set the origin. 00521 Page *pPage = pSpread->FindFirstPageInSpread(); 00522 ENSURE(pPage != NULL, "Spread has no pages"); 00523 ERRORIF(pPage == NULL, _R(IDT_DOC_BADSTRUCTURE), FALSE); 00524 00525 // Create a new render region to export to: 00526 Matrix Mat = GetExportTransform(pSpread); 00527 ExportRegion = CreateRenderRegion(&Mat); 00528 00529 if (ExportRegion == NULL) 00530 return FALSE; 00531 00532 // Created the 'file' DC for rendering and try to open the specified file. 00533 ExportDC = CreateExportDC(); 00534 00535 if (ExportDC == NULL) 00536 return FALSE; 00537 00538 TRY 00539 { 00540 ExportDC->Init(pFile, ExportRegion, IS_A(this, CMXFilter16)?FALSE:TRUE, IsDoingClipboardExport); 00541 } 00542 CATCH(CFileException, e) 00543 { 00544 // Could not open the export file - return error 00545 return FALSE; 00546 } 00547 END_CATCH 00548 00549 // Attach to the right device. 00550 View* pView = View::GetCurrent(); 00551 ERROR2IF(!pView, FALSE, "No current View to attach in CMXFilter::PrepareForExport"); 00552 ExportRegion->AttachDevice(pView, ExportDC, pSpread); 00553 00554 // All ok 00555 return TRUE; 00556 #else 00557 return FALSE; 00558 #endif 00559 } 00560 00561 00562 /******************************************************************************************** 00563 00564 > BOOL CMXFilter::FinishExport(void) 00565 00566 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00567 Created: 24/06/96 00568 Inputs: nothin' 00569 Returns: success 00570 Purpose: Finish off the export operation -- finishes header and all that 00571 SeeAlso: 00572 00573 ********************************************************************************************/ 00574 00575 BOOL CMXFilter::FinishExport(void) 00576 { 00577 #ifdef DO_EXPORT 00578 if(!ExportDC->PolishOffThatFile()) 00579 return FALSE; 00580 return TRUE; 00581 #else 00582 return FALSE; 00583 #endif 00584 } 00585 00586 00587 /******************************************************************************************** 00588 00589 > void CMXFilter::CleanUpAfterExport() 00590 00591 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00592 Created: 18/6/96 00593 Inputs: nothin' 00594 Returns: nothin' 00595 Purpose: Sorts everything out when something went wrong, or we finished normally 00596 SeeAlso: 00597 00598 ********************************************************************************************/ 00599 00600 void CMXFilter::CleanUpAfterExport() 00601 { 00602 #ifdef DO_EXPORT 00603 ExportDC->CleanUp(); 00604 00605 // get rid of that render region 00606 delete ExportRegion; 00607 #endif 00608 } 00609 00610 00611 /******************************************************************************************** 00612 00613 > CMXExportDC* CMXFilter::CreateExportDC(); 00614 00615 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00616 Created: 18/6/96 00617 Inputs: nothin' 00618 Returns: the device context to use when exporting CMX files 00619 Purpose: Get a device context up and running. 00620 SeeAlso: 00621 00622 ********************************************************************************************/ 00623 00624 CMXExportDC* CMXFilter::CreateExportDC() 00625 { 00626 #ifdef DO_EXPORT 00627 // Create and return a DC 00628 return new CMXExportDC(this); 00629 #else 00630 return NULL; 00631 #endif 00632 } 00633 00634 00635 /******************************************************************************************** 00636 00637 > CMXRenderRegion *CMXFilter::CreateRenderRegion(Matrix *pM) 00638 00639 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00640 Created: 19/6/96 00641 Inputs: nothin' 00642 Returns: render region or 0 00643 Purpose: create a 32 bit render region for CMX export. 00644 SeeAlso: 00645 00646 ********************************************************************************************/ 00647 00648 CMXRenderRegion *CMXFilter::CreateRenderRegion(Matrix *pM) 00649 { 00650 #ifdef DO_EXPORT 00651 // Don't care about clip regions when exporting - create a null region. 00652 DocRect NullClipRect; 00653 NullClipRect.MakeEmpty(); 00654 00655 // Don't use view scale; set to 1 00656 FIXED16 Scale(1); 00657 00658 // Create the region 00659 return new CMXRenderRegion(NullClipRect, *pM, Scale); 00660 #else 00661 // Ne yuk yuk... No cmx export for you pesky ralphs... 00662 return NULL; 00663 #endif 00664 } 00665 00666