00001 // $Id: filters.cpp 1760 2006-09-22 10:13:32Z luke $ 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 00099 00100 #include "camtypes.h" 00101 00102 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00103 #include "epsfiltr.h" 00104 //#include "coreleps.h" 00105 #include "aw_eps.h" 00106 #include "cameleps.h" 00107 #include "ai_eps.h" 00108 #include "ai5_eps.h" 00109 #include "ai8_eps.h" 00110 //#include "drawfltr.h" 00111 //#include "textfltr.h" 00112 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 //#include "tim.h" 00115 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 #include "progress.h" 00119 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00120 #include "chapter.h" 00121 //#include "group.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00122 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00123 #include "bmpfiltr.h" 00124 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00125 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00126 #include "native.h" // The new designed native filter, used for v2 00127 #include "nativeps.h" // The old style EPS native filter, used in v1.1 00128 #include "layer.h" 00129 //#include "nev.h" 00130 //#include "coplfilr.h" 00131 //#include "cdrfiltr.h" 00132 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00133 //#include "ben.h" 00134 #include "freeeps.h" 00135 //#include "rik.h" 00136 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00137 #include "fontman.h" 00138 //#include "peter.h" 00139 #include "sgliboil.h" // FileExists 00140 #include "cmxfiltr.h" 00141 //#include "will2.h" 00142 //#include "filtrres.h" 00143 //#include "cmxifltr.h" 00144 #include "exjpeg.h" // JPEGExportFilter 00145 #include "filtimag.h" // Imagemap filter 00146 #include "pngfiltr.h" // for PNG filter class 00147 #include "imjpeg.h" // for JPEGImportFilter 00148 #include "swffiltr.h" // For the SWF export filter. 00149 //#include "extfilts.h" // For the TIFF filter. 00150 #include "kerneldc.h" 00151 #include "xsepsops.h" 00152 00153 #include "giffiltr.h" // Transparent and interlaced GIF filter`` 00154 #include "htmlfltr.h" // HTML filter 00155 #include "lineattr.h" 00156 00157 //#include "andy.h" //For _R(IDM_OVERWRITE) 00158 //#include "resource.h" //For _R(IDS_CANCEL) 00159 #include "helpuser.h" //For SetNextMsgHelpContext() 00160 //#include "resimmap.h" //For _R(IDM_EXPORT_OVERWRITE) 00161 #include "imgmgkft.h" 00162 00163 #include "webfiltr.h" // The new web filter which is the minimilistic form of the new native filter 00164 #include "ftfilter.h" 00165 #include "hardwaremanager.h" 00166 using namespace oilHardwareManager; 00167 00168 // Ralph's CDR / CMX import state is currently in limbo land... To put 00169 // the filters back in, undefine NOCDRCMX and also add back the relevant 00170 // bits in winoil and kernel.mak 00171 #ifdef RALPH 00172 //#define NOCDRCMX 1 00173 #endif 00174 00175 CC_IMPLEMENT_DYNAMIC(Filter, CCObject) 00176 00177 CC_IMPLEMENT_DYNAMIC(VectorFilter, Filter) 00178 CC_IMPLEMENT_DYNAMIC(BitmapFilter, Filter) 00179 CC_IMPLEMENT_DYNAMIC(FilterFamily, Filter) 00180 CC_IMPLEMENT_DYNAMIC(GenericFilter, FilterFamily) 00181 CC_IMPLEMENT_DYNAMIC(VectorFilterFamily, FilterFamily) 00182 CC_IMPLEMENT_DYNAMIC(BitmapFilterFamily, FilterFamily) 00183 CC_IMPLEMENT_DYNAMIC(GenericEPSFilter, FilterFamily) 00184 #ifndef NOCDRCMX 00185 CC_IMPLEMENT_DYNAMIC(PaletteFilterFamily, FilterFamily) 00186 #endif 00187 00188 #if BUILD_TEXT_FILTERS 00189 CC_IMPLEMENT_DYNAMIC(TextFilter, Filter) 00190 CC_IMPLEMENT_DYNAMIC(TextFilterFamily, FilterFamily) 00191 #endif 00192 00193 CC_IMPLEMENT_MEMDUMP(SnapShotList, CC_CLASS_MEMDUMP); 00194 CC_IMPLEMENT_MEMDUMP(SnapShotItem, ListItem); 00195 CC_IMPLEMENT_MEMDUMP(AttrRecordList, CC_CLASS_MEMDUMP); 00196 CC_IMPLEMENT_MEMDUMP(AttrRecordItem, ListItem); 00197 00198 00199 // Declare smart memory handling in Debug builds 00200 #define new CAM_DEBUG_NEW 00201 00202 00203 // Initialised to "no override". 00204 UINT32 Filter::m_nForcedStatusExportMessage = 0; 00205 00206 ID Filter::m_NextFilterID = FILTERID_ALDUS_END + 1; 00207 00208 00209 /******************************************************************************************** 00210 00211 > BOOL FilterFlags::operator==(const FilterFlags Flags) 00212 00213 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00214 Created: 29/03/94 00215 Inputs: Flags - the flags to test against. 00216 Returns: TRUE or FALSE! 00217 Purpose: Test FilterFlags for equality! 00218 00219 ********************************************************************************************/ 00220 00221 BOOL FilterFlags::operator==(const FilterFlags Flags) 00222 { 00223 return (CanImport == Flags.CanImport) && (CanExport == Flags.CanExport) && 00224 (ShowFilter == Flags.ShowFilter) && (CanExportMultipleImages == Flags.CanExportMultipleImages); 00225 } 00226 00227 00228 00229 00230 // The global list of installed filters. 00231 List Filter::FilterList; 00232 00233 // Er..dunno actually 00234 GenericFilter *Filter::pGenericFilter = NULL; 00235 00236 // 00237 // Variables used for progress display update... 00238 // 00239 00240 // The number of nodes saved out so far (also used for accumulating total 00241 // while scanning the tree. 00242 UINT32 Filter::NumNodes = 0; 00243 00244 // Indicates how many 'nodes' should be saved before we update the progress bar. 00245 UINT32 Filter::UpdateEvery = 1; 00246 00247 // The last time we updated the progress bar (in terms of nodes saved out). 00248 UINT32 Filter::LastExportProgressUpdate = 0; 00249 00250 // The maximum limit on the current export sub-operation - i.e. this ensures that 00251 // incorrect exporting code cannot screw up the rest of the progress bar system. 00252 UINT32 Filter::CurrentProgressLimit = 0; 00253 00254 // Allows a ExportRenderer to cope with rendering in strips where mulit-pass rendering 00255 // will be happening. If the progress is started with NumNodes * number of strips we 00256 // we need to have an offset for the start of each strip. This allows this to happen. 00257 UINT32 Filter::ProgressOffset = 0; 00258 00259 UINT32 Filter::m__StripStart = 0; 00260 00261 // Preference settings 00262 00263 /******************************************************************************************** 00264 00265 Preference: MinLineWidth 00266 Section: Filters 00267 Range: Between 0 and 10,000. 00268 Purpose: Controls how line widths are handled - if a line width thinner than the 00269 value of this preference is found, then the line width is forced to be 00270 this width. E.g. set it to 500 to make all imported lines be at least 00271 0.5 points wide. (It defaults to 0.25pt) 00272 SeeAlso: AddUnnamedColours 00273 00274 ********************************************************************************************/ 00275 00276 INT32 Filter::MinLineWidth = 250; 00277 00278 /******************************************************************************************** 00279 00280 Preference: ImportWithLayers 00281 Section: Filters 00282 Range: TRUE or FALSE. 00283 Purpose: Controls how files are imported: 00284 TRUE => Layers are imported/created as necessary when importing. 00285 FALSE => Layers are ignore when importing, and the whole imported 00286 file is placed in the document as a group. 00287 SeeAlso: Filter 00288 00289 ********************************************************************************************/ 00290 #ifdef WEBSTER 00291 // Layers are bad in Webster as it conflicts with frames 00292 INT32 Filter::ImportWithLayers = 0; // dont import layers 00293 #else 00294 INT32 Filter::ImportWithLayers = 2; // import layers with the names they were given 00295 #endif // WEBSTER 00296 00297 /******************************************************************************************** 00298 00299 Preference: OpenWithLayers 00300 Section: Filters 00301 Range: TRUE or FALSE. 00302 Purpose: Controls how files are opened: 00303 TRUE => Layers are imported/created as necessary when opening a file. 00304 FALSE => Layers are ignore when importing, and the whole opened 00305 file is placed in the document as a group. 00306 Note: Does not affect v2 Native file formats such as xar and web. 00307 00308 ********************************************************************************************/ 00309 #ifdef WEBSTER 00310 // Layers are bad in Webster as it conflicts with frames 00311 BOOL Filter::OpenWithLayers = FALSE; 00312 #else 00313 BOOL Filter::OpenWithLayers = TRUE; 00314 #endif // WEBSTER 00315 00316 /******************************************************************************************** 00317 00318 Preference: ImportBitmapsOntoLayers 00319 Section: Filters 00320 Range: TRUE or FALSE. 00321 Purpose: Controls how bitmap files are opened/imported: 00322 TRUE => each bitmap is placed on a new layer. 00323 FALSE => each bitmaps is placed on the current layer. 00324 Applies to multiple format bitmaps such as animated GIFs 00325 00326 ********************************************************************************************/ 00327 00328 BOOL Filter::ImportBitmapsOntoLayers = TRUE; 00329 00330 /******************************************************************************************** 00331 00332 Preference: bDontWarnBitmapNonMixTransp 00333 Section: Filters 00334 Range: TRUE or FALSE. 00335 Purpose: Controls how bitmap files are opened/imported: 00336 TRUE => each bitmap is placed on a new layer. 00337 FALSE => each bitmaps is placed on the current layer. 00338 Applies to multiple format bitmaps such as animated GIFs 00339 00340 ********************************************************************************************/ 00341 00342 BOOL Filter::bDontWarnBitmapNonMixTransp = FALSE; 00343 00344 /******************************************************************************************** 00345 00346 Preference: AddUnnamedColours 00347 Section: Filters 00348 Range: TRUE or FALSE 00349 Purpose: If it is TRUE then any colours used in the imported file but not explicitly 00350 named by whatever colour table structure the file uses will be created 00351 as named colours (usu. of the form Unnamed 1, Unnamed 2 and so on). 00352 If FALSE, immediate colours will be used, and will not appear on the 00353 document's colour bar. 00354 Defaults to FALSE. 00355 SeeAlso: MinLineWidth 00356 00357 ********************************************************************************************/ 00358 00359 BOOL Filter::AddUnnamedColours = FALSE; 00360 00361 /******************************************************************************************** 00362 00363 > Filter::Filter () 00364 00365 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00366 Created: 22/02/94 00367 Purpose: Set the Filter object up to be in a clean state. 00368 SeeAlso: Filter; Filter::~Filter; OILFilter 00369 00370 ********************************************************************************************/ 00371 00372 Filter::Filter () 00373 { 00374 // Ensure destructor will not corrupt heap 00375 pOILFilter = NULL; 00376 CurrentAttrs = NULL; 00377 FillAttr.pAttr = NULL; 00378 FillAttr.Temp = FALSE; 00379 FillAttr.Ignore = FALSE; 00380 00381 // Set default of no export message 00382 ExportMsgID = 0; 00383 00384 // Set default message of none (use default message) 00385 StopExportMsgID = 0; 00386 00387 // Set default of no import message 00388 ImportMsgID = 0; 00389 00390 // No document yet... 00391 TheDocument = NULL; 00392 00393 // No Preview Bitmap Please 00394 WantPreviewBmp = FALSE; 00395 00396 // Ensure these are at known states, set them to do nothing so people have to change them 00397 Flags.CanImport = FALSE; 00398 Flags.CanExport = FALSE; 00399 Flags.CanExportMultipleImages = FALSE; 00400 00401 // Want to show filters by default, unless the user specificaly requests otherwise 00402 Flags.ShowFilter = TRUE; 00403 00404 // set the path filled flag to a sensible state 00405 PathFilled = TRUE; 00406 00407 // Don't save attributes as default. 00408 SaveAttributes = FALSE; 00409 00410 m_pSoleLayer = NULL; 00411 } 00412 00413 /******************************************************************************************** 00414 00415 > Filter::~Filter() 00416 00417 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00418 Created: 22/02/94 00419 Purpose: Destroys the OILFilter object and the current attribute array/values 00420 associated with this Filter. 00421 SeeAlso: Filter; OILFilter 00422 00423 ********************************************************************************************/ 00424 00425 Filter::~Filter() 00426 { 00427 // Destroy the associated OILFilter object 00428 delete pOILFilter; 00429 00430 // Destory any temporary saved fill attribute 00431 if (FillAttr.Temp) 00432 delete FillAttr.pAttr; 00433 } 00434 00435 00436 /******************************************************************************************** 00437 00438 > virtual BOOL Filter::DeclareFilterPreferenceSection() 00439 00440 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00441 Created: 30/10/96 00442 Returns: TRUE if the preference section was declared correctly 00443 FALSE otherwise 00444 Purpose: Ensures all filter related preferences go to the same section 00445 00446 ********************************************************************************************/ 00447 BOOL Filter::DeclareFilterPreferenceSection() 00448 { 00449 return( Camelot.DeclareSection( _T("Filters"), 10 ) ); 00450 } 00451 00452 00453 /******************************************************************************************** 00454 00455 > virtual BOOL Filter::CanIncludePreviewBmp() 00456 00457 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00458 Created: 2/2/95 00459 Returns: TRUE if the filter is capable of having a preview bitmap put in it somehow. 00460 FALSE if it can't. Most filters can not do this. 00461 Purpose: Allows you to find out if a particular filter can produce a Preview Bitmap 00462 in it. 00463 00464 ********************************************************************************************/ 00465 00466 BOOL Filter::CanIncludePreviewBmp() 00467 { 00468 // Say no. Filters that can will have to say yes 00469 return FALSE; 00470 } 00471 00472 00473 /******************************************************************************************** 00474 00475 > void Filter::IncludePreviewBmp(BOOL WantBmp) 00476 00477 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00478 Created: 2/2/95 00479 Inputs: WantBmp - TRUE if you want the filter to Include a Preview Bitmap. 00480 FALSE if not. 00481 Purpose: Asks the filter to include a Preview bitmap or not. NOTE: This only has 00482 any effect if the Filter answered TRUE to a call to CanIncludePreviewBmp. 00483 NOTE2: All the filters hang around even if they are not doing any filtering, 00484 so if you set this flag one way it will stay like that for all future uses of 00485 the filter until it is set again. The best method will be to swtich it on if 00486 required, do the import and then switch it off again immediatly afterwards. 00487 SeeAlso: Filter::CanIncludePreviewBmp 00488 00489 ********************************************************************************************/ 00490 00491 void Filter::IncludePreviewBmp(BOOL WantBmp) 00492 { 00493 // Set the internal Flag 00494 WantPreviewBmp = WantBmp; 00495 } 00496 00497 00498 00499 /******************************************************************************************** 00500 00501 > BOOL Filter::SetUpCurrentAttrs() 00502 00503 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00504 Created: 13/04/94 00505 Returns: TRUE if attributes set up ok; 00506 FALSE otherwise. 00507 Purpose: Obtains an attribute array from the attribute manager. This array is the 00508 set of default attributes - the filter should use them to maintain its 00509 set of current attributes while importing. It then asks the attribute 00510 manager to add the correct attributes to each node based on this array. 00511 This should be called when importing, not when intialising, otherwise 00512 all filters will have this array hanging around all the time, which is bad. 00513 Errors: Out of memory. 00514 SeeAlso: AttributeManager; AttributeManager::ApplyBasedOnDefaults 00515 00516 ********************************************************************************************/ 00517 00518 BOOL Filter::SetUpCurrentAttrs() 00519 { 00520 // Sanity check 00521 ENSURE(CurrentAttrs == NULL, "Filter::SetUpCurrentAttrs called unnecessarily!"); 00522 00523 // Get the array of default attributes to use as our current attributes. 00524 CurrentAttrs = AttributeManager::GetDefaultAttributes(); 00525 if (CurrentAttrs == NULL) 00526 return FALSE; 00527 00528 // Clear the 'ignore' flag on all attributes. 00529 INT32 NumAttrs = AttributeManager::GetNumAttributes(); 00530 for (INT32 i = 0; i < NumAttrs; i++) 00531 CurrentAttrs[i].Ignore = FALSE; 00532 00533 // All done 00534 return TRUE; 00535 } 00536 00537 /******************************************************************************************** 00538 00539 > void Filter::DeleteCurrentAttrs() 00540 00541 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00542 Created: 13/04/94 00543 Purpose: Deallocates any objects used to hold the current attributes for the filter. 00544 Should be called after import has finished, so the attribute table isn't 00545 hanging around all the time. 00546 SeeAlso: Filter::SetUpCurrentAttrs 00547 00548 ********************************************************************************************/ 00549 00550 void Filter::DeleteCurrentAttrs() 00551 { 00552 // Delete any attribute values we created 00553 if (CurrentAttrs != NULL) 00554 { 00555 DeleteAttributeList(CurrentAttrs); 00556 // Lose the attribute value array 00557 CCFree(CurrentAttrs); 00558 CurrentAttrs = NULL; 00559 } 00560 } 00561 00562 /******************************************************************************************** 00563 00564 void Filter::DeleteAttributeList(AttributeEntry* pAttrList) 00565 00566 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00567 Created: 16/10/95 00568 Inputs: pAttrList = A pointer to the first item in the attribute list 00569 Returns: - 00570 Purpose: This function removes all temp attributes from the attribute list provided 00571 All temp attributes will have their list entries updated with NULL pointers. 00572 00573 *********************************************************************************************/ 00574 00575 void Filter::DeleteAttributeList(AttributeEntry* pAttrList) 00576 { 00577 // Delete any attribute values we created 00578 INT32 NumAttrs = AttributeManager::GetNumAttributes(); 00579 for (INT32 i=0; i<NumAttrs; i++) 00580 { 00581 // Delete the object if it is temporary. 00582 if (pAttrList[i].Temp) 00583 { 00584 delete pAttrList[i].pAttr; 00585 pAttrList[i].pAttr = NULL; 00586 pAttrList[i].Temp = FALSE; 00587 } 00588 } 00589 } 00590 00591 00592 00593 /******************************************************************************************** 00594 00595 > BOOL Filter::SnapShotCurrentAttrs() 00596 00597 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00598 Created: 16/10/95 00599 Inputs: - 00600 Returns: TRUE if the currentattrs list has been copied 00601 FALSE if nothing has been copied 00602 Purpose: This function grabs a snap shot of the filter managers current attributes. 00603 It simply makes a new List identical to that of CurrentAttrs. 00604 00605 *********************************************************************************************/ 00606 00607 BOOL Filter::SnapShotCurrentAttrs() 00608 { 00609 return FilterSnapShot.CreateSnapShot(CurrentAttrs); 00610 } 00611 00612 /******************************************************************************************** 00613 00614 > void Filter::DeleteSnapShot() 00615 00616 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00617 Created: 16/10/95 00618 Inputs: - 00619 Returns: - 00620 Purpose: This function removes the snap shot list allocated during SnapShotCurrentAttrs(). 00621 It should be called to match any successfull return of its sister function. 00622 ie SnapShotCurrentAttrs() and DeleteSnapShot() should be paired. 00623 Note, the calls are not recursive. ie a 00624 SnapShot 00625 SnapShot 00626 Delete 00627 Delete 00628 is not currently supported 00629 SeeAlso: SnapShotCurrentAttrs() 00630 00631 *********************************************************************************************/ 00632 00633 void Filter::DeleteSnapShot() 00634 { 00635 FilterSnapShot.DestroySnapShot(); 00636 } 00637 00638 00639 /******************************************************************************************** 00640 00641 > BOOL Filter::ApplyChangedAttrs(Node* pNode) 00642 00643 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00644 Created: 16/10/95 00645 Inputs: - 00646 Returns: TRUE if the changed attributes have been applied to pNode 00647 FALSE if nothing has been applied 00648 Purpose: This function uses the snapshot facility to work out which of the 00649 current attributes have changed. Obviously it expects a snap shot to have 00650 been taken some time earlier. Only those attributes that have changes will be 00651 applied to the node described on entry. Note, any changed attributes which 00652 now match defaults will not be applied as the function calls 00653 ApplyBasedOnDefaults() with the changes list. 00654 00655 *********************************************************************************************/ 00656 00657 BOOL Filter::ApplyChangedAttrs(Node* pNode) 00658 { 00659 return FilterSnapShot.ApplyChangedAttrs(pNode,CurrentAttrs); 00660 } 00661 00662 00663 00664 /******************************************************************************************** 00665 00666 > void Filter::PushCurrentAttrsBasedOnSnapShot() 00667 00668 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00669 Created: 16/10/95 00670 Inputs: - 00671 Returns: - 00672 Purpose: This function uses the snap shot facility. It checks the snap shot list 00673 against the current attribute list to find attributes which differ. Those 00674 that do are obviously new attributes. ie attributes which have been parsed 00675 by the filter after the snap shot was taken. This function takes the current 00676 attrubute list and removes all those attributes which have changed in this 00677 way. It resets them to their default none temp attribute types. 00678 00679 *********************************************************************************************/ 00680 00681 void Filter::PushCurrentAttrsBasedOnSnapShot() 00682 { 00683 FilterSnapShot.PushAttrsBasedOnSnapShot(CurrentAttrs); 00684 } 00685 00686 00687 /******************************************************************************************** 00688 00689 > void Filter::PopCurrentAttrsBasedOnSnapShot() 00690 00691 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00692 Created: 16/10/95 00693 Inputs: - 00694 Returns: - 00695 Purpose: This function uses the snap shot facility. It checks the snap shot list 00696 against the current attribute list to find attributes which differ. Those 00697 that do are obviously new attributes. ie attributes which have been parsed 00698 by the filter after the snap shot was taken. This function takes the current 00699 attrubute list and removes all those attributes which have changed in this 00700 way. It resets them to their default none temp attribute types. 00701 00702 *********************************************************************************************/ 00703 00704 void Filter::PopCurrentAttrsBasedOnSnapShot() 00705 { 00706 FilterSnapShot.PopAttrsBasedOnSnapShot(CurrentAttrs); 00707 } 00708 00709 00710 00711 00712 00713 00714 #define ADD_FILTER(Classname) \ 00715 /* Create, initialise and install the Generic import filter */ \ 00716 pFilter = new Classname; \ 00717 if (pFilter == NULL) return FALSE; \ 00718 \ 00719 if (!pFilter->Init()) \ 00720 { \ 00721 /* Error occured - report it and stop trying to initialise filters. */ \ 00722 InformError(); \ 00723 return TRUE; \ 00724 } \ 00725 \ 00726 FilterList.AddTail(pFilter); 00727 00728 /******************************************************************************************** 00729 00730 > BOOL Filter::InitFilters() 00731 00732 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00733 Created: 22/02/94 00734 Returns: TRUE if initialised ok, FALSE if not. 00735 Purpose: Scans all filters to find out which filters are available for use, and 00736 instantiates one of each, and holds them in a list. 00737 Errors: Out of memory (if a filter fails to initialise for other reasons then an 00738 error is reported, but Camelot will still start up ok, i.e. TRUE is 00739 returned). 00740 SeeAlso: Filter 00741 00742 ********************************************************************************************/ 00743 00744 BOOL Filter::InitFilters() 00745 { 00746 // Find the filters - the kernel ones are hard-wired. 00747 Filter* pFilter; 00748 00749 // Create, initialise and install the Generic import filter 00750 ADD_FILTER(GenericFilter) 00751 00752 // Keep a pointer to this one, for handling drag'n'drop 00753 pGenericFilter = (GenericFilter *) pFilter; 00754 00755 // Create, initialise and install the generic vector and bitmap filters 00756 ADD_FILTER(VectorFilterFamily) 00757 ADD_FILTER(BitmapFilterFamily) 00758 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00759 #if BUILD_TEXT_FILTERS 00760 ADD_FILTER(TextFilterFamily) 00761 #endif 00762 #endif 00763 // Create, initialise and install the Generic EPS import filter 00764 #ifndef STANDALONE 00765 ADD_FILTER(GenericEPSFilter) 00766 #endif 00767 00768 #ifndef EXCLUDE_FROM_XARALX 00769 // Remove this next line to add the CDR / CMX filters... 00770 #ifndef NOCDRCMX 00771 ADD_FILTER(PaletteFilterFamily) 00772 #endif 00773 #endif 00774 00775 // Create, initialise and install the other supported filters: 00776 // This must be the first filter that uses .xar or "Save as" wont work 00777 ADD_FILTER(CamelotNativeFilter) // The new designed native filter, used for v2 00778 PORTNOTETRACE("filter","Removed CamelotWebFilter usage"); 00779 #ifndef EXCLUDE_FROM_XARALX 00780 ADD_FILTER(CamelotWebFilter) // The minimalistic form of the v2 native filter 00781 #endif 00782 ADD_FILTER(CamelotEPSFilter) 00783 ADD_FILTER(CamelotNativeEPSFilter) // The old style EPS native filter, used in v1.1 00784 // Winoil filters are initialised here to prevent the drop-down list from being 00785 // mis-ordered. 00786 00787 // Graeme (25-9-00) - Primary filters, in the order that Mark requested. 00788 ADD_FILTER(JPEGExportFilter) 00789 ADD_FILTER(JPEGImportFilter) 00790 00791 ADD_FILTER(PNGFilter) 00792 00793 if (ImageMagickFilter::CheckPath()) 00794 { 00795 // Most of these commented out whilst we have no useful interface for 00796 // filter selection 00797 ADD_FILTER(ImageMagickFilterBMP) 00798 //ADD_FILTER(ImageMagickFilterCUR) 00799 //ADD_FILTER(ImageMagickFilterCUT) 00800 //ADD_FILTER(ImageMagickFilterDCM) 00801 //ADD_FILTER(ImageMagickFilterDCX) 00802 //ADD_FILTER(ImageMagickFilterDIB) 00803 //ADD_FILTER(ImageMagickFilterDNG) 00804 //ADD_FILTER(ImageMagickFilterEPDF) 00805 //ADD_FILTER(ImageMagickFilterEPI) 00806 //ADD_FILTER(ImageMagickFilterEPS) 00807 //ADD_FILTER(ImageMagickFilterEPS2) 00808 //ADD_FILTER(ImageMagickFilterEPS3) 00809 //ADD_FILTER(ImageMagickFilterEPSF) 00810 //ADD_FILTER(ImageMagickFilterEPSI) 00811 //ADD_FILTER(ImageMagickFilterEPT) 00812 //ADD_FILTER(ImageMagickFilterFAX) 00813 //ADD_FILTER(ImageMagickFilterFITS) 00814 ADD_FILTER(ImageMagickFilterICO) 00815 //ADD_FILTER(ImageMagickFilterJNG) 00816 //ADD_FILTER(ImageMagickFilterMIFF) 00817 //ADD_FILTER(ImageMagickFilterMPC) 00818 //ADD_FILTER(ImageMagickFilterOTB) 00819 //ADD_FILTER(ImageMagickFilterP7) 00820 //ADD_FILTER(ImageMagickFilterPALM) 00821 //ADD_FILTER(ImageMagickFilterPAM) 00822 //ADD_FILTER(ImageMagickFilterPBM) 00823 ADD_FILTER(ImageMagickFilterPCD) 00824 //ADD_FILTER(ImageMagickFilterPCDS) 00825 //ADD_FILTER(ImageMagickFilterPCL) 00826 //ADD_FILTER(ImageMagickFilterPCX) 00827 //ADD_FILTER(ImageMagickFilterPDB) 00828 ADD_FILTER(ImageMagickFilterPDF) 00829 //ADD_FILTER(ImageMagickFilterPGM) 00830 ADD_FILTER(ImageMagickFilterPICT) 00831 //ADD_FILTER(ImageMagickFilterPIX) 00832 ADD_FILTER(ImageMagickFilterPNM) 00833 ADD_FILTER(ImageMagickFilterPPM) 00834 //ADD_FILTER(ImageMagickFilterPS) 00835 //ADD_FILTER(ImageMagickFilterPS2) 00836 //ADD_FILTER(ImageMagickFilterPS3) 00837 ADD_FILTER(ImageMagickFilterPSD) 00838 //ADD_FILTER(ImageMagickFilterPTIF) 00839 //ADD_FILTER(ImageMagickFilterPWP) 00840 //ADD_FILTER(ImageMagickFilterRLA) 00841 //ADD_FILTER(ImageMagickFilterRLE) 00842 //ADD_FILTER(ImageMagickFilterSCT) 00843 //ADD_FILTER(ImageMagickFilterSFW) 00844 //ADD_FILTER(ImageMagickFilterSUN) 00845 // // ADD_FILTER(ImageMagickFilterSVG) - removed per NeilH 19/07/2006 so it doesn't clash with vector SVG import 00846 //ADD_FILTER(ImageMagickFilterTGA) 00847 ADD_FILTER(ImageMagickFilterTIFF) 00848 //ADD_FILTER(ImageMagickFilterTIM) 00849 //ADD_FILTER(ImageMagickFilterTTF) 00850 //ADD_FILTER(ImageMagickFilterVICAR) 00851 //ADD_FILTER(ImageMagickFilterVIFF) 00852 //ADD_FILTER(ImageMagickFilterWBMP) 00853 //ADD_FILTER(ImageMagickFilterWPG) 00854 //ADD_FILTER(ImageMagickFilterXBM) 00855 //ADD_FILTER(ImageMagickFilterXCF) 00856 ADD_FILTER(ImageMagickFilterXPM) 00857 //ADD_FILTER(ImageMagickFilterXWD) 00858 } 00859 00860 ADD_FILTER(TI_GIFFilter) 00861 PORTNOTETRACE("filter","Removed TIFFFilter"); 00862 #ifndef EXCLUDE_FROM_XARALX 00863 ADD_FILTER(TIFFFilter) 00864 #endif 00865 00866 #if !defined(EXCLUDE_FROM_XARALX) && !defined(PROD_XS) 00867 // disabled for XS builds 00868 OILFilter::InitPluginFilters(FilterList); 00869 #endif 00870 00871 PORTNOTE("filter","Removed Flash filter for 0.7") 00872 #if defined(_DEBUG) 00873 ADD_FILTER(FlashFilter) 00874 #endif 00875 00876 #ifndef STANDALONE 00877 // Other filters in alphabetical order. 00878 PORTNOTE("filter","Removed filters usage") 00879 #ifndef EXCLUDE_FROM_XARALX 00880 ADD_FILTER(AcornDrawFilter) 00881 #endif 00882 // Adobe AI / EPS filters. 00883 ADD_FILTER(AIEPSFilter) 00884 ADD_FILTER(AI5EPSFilter) 00885 ADD_FILTER(AI8EPSFilter) 00886 00887 ADD_FILTER(PhotoShopEPSFilter) 00888 00889 ADD_FILTER(ArtWorksEPSFilter) 00890 PORTNOTE("filter","Removed filters usage") 00891 #ifndef EXCLUDE_FROM_XARALX 00892 00893 // ADD_FILTER(BMPFilter) 00894 00895 // These filters are not shown in the drop-down menu. 00896 // ADD_FILTER(AdobeColourSwatchFilter) 00897 // ADD_FILTER(AdobeColourTableFilter) 00898 // ADD_FILTER(JCWColourFilter) 00899 00900 // Remove this next line to add the CDR / CMX filters... 00901 #ifndef NOCDRCMX 00902 00903 // Corel native filters. (CMX and CDR.) 00904 ADD_FILTER(CDRFilter) 00905 ADD_FILTER(CMXImportFilter) 00906 PORTNOTE("filter","Removed CMXFilterX usage") 00907 ADD_FILTER(CMXFilter16) 00908 ADD_FILTER(CMXFilter32) 00909 00910 #endif //NOCDRCMX 00911 00912 00913 // Corel EPS filters. 00914 PORTNOTE("filter","Removed Corel EPS filters usage") 00915 ADD_FILTER(Corel3EPSFilter) 00916 ADD_FILTER(Corel4EPSFilter) 00917 00918 ADD_FILTER(CorelPaletteFilter) 00919 #endif 00920 ADD_FILTER(FreeHandEPSFilter) 00921 00922 PORTNOTE("filter","Removed filters usage") 00923 #ifndef EXCLUDE_FROM_XARALX 00924 // HTML based filters. 00925 PORTNOTE("filter","Removed HTMLFilter usage") 00926 ADD_FILTER(HTMLFilter) // the HTML filter 00927 ADD_FILTER(ImagemapFilter) 00928 #endif //EXCLUDE_FROM_XARALX 00929 00930 00931 #if BUILD_OTHER_TEXT_FILTERS 00932 00933 // The text filters don't appear in the drop-down menu. 00934 ADD_FILTER(ANSITextFilter) 00935 ADD_FILTER(UnicodeTextFilter) 00936 ADD_FILTER(RTFTextFilter) 00937 00938 #endif 00939 00940 #endif 00941 00942 #ifdef _DEBUG 00943 ADD_FILTER(FlareTemplateFilter) // The text version 00944 #endif 00945 00946 // Initialise the OIL filters (but they are still objects of class "Filter") 00947 // This can include filters specific to one platform. 00948 OILFilter::InitFilters(FilterList); 00949 00950 #if !defined(EXCLUDE_FROM_RALPH) 00951 // Register our preference for minimum line widths, and whether or not we import 00952 // unnamed colours into the document colour list. 00953 Camelot.DeclareSection(_T("Filters"), 10); 00954 Camelot.DeclarePref(_T("Filters"), _T("MinLineWidth"), &MinLineWidth, 0, 10000); 00955 Camelot.DeclarePref(_T("Filters"), _T("ImportWithLayers"), &ImportWithLayers); 00956 Camelot.DeclarePref(_T("Filters"), _T("OpenWithLayers"), &OpenWithLayers); 00957 Camelot.DeclarePref(_T("Filters"), _T("ImportBitmapsOntoLayers"), &ImportBitmapsOntoLayers); 00958 Camelot.DeclarePref(_T("Filters"), _T("DontWarnBitmapNonMixTransp"), &bDontWarnBitmapNonMixTransp); 00959 Camelot.DeclarePref(_T("Filters"), _T("AddUnnamedColours"), &AddUnnamedColours); 00960 00961 #endif 00962 XSEPSExportOptions::Init(); 00963 BaseBitmapFilter::InitBaseClass(); 00964 // All ok 00965 return TRUE; 00966 } 00967 00968 00969 /******************************************************************************************** 00970 00971 > FilterID FilterManager::GetNewFilterID() 00972 00973 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00974 Created: 10/12/96 00975 Returns: A FilterID unique to this FilterManager for each call to the function 00976 Purpose: Support function providing an unique ID for each newly registered Filter 00977 00978 ********************************************************************************************/ 00979 ID Filter::GetNewFilterID() 00980 { 00981 ERROR3IF(!m_NextFilterID, "Creating duff FilterID"); 00982 00983 return m_NextFilterID++; 00984 } 00985 00986 00987 /******************************************************************************************** 00988 00989 > FilterID FilterManager::RegisterFilter( const Filter* const pFilter, 00990 const DESTRUCTION_METHOD DestructMethod) 00991 00992 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00993 Created: 15/12/94 00994 Inputs: pFilter: pointer to the filter to register 00995 DestructMethod : whether or not the given filter should be destructed when 00996 the collection of registered filters is destructed. 00997 00998 Returns: FilterID that uniquely identifies the given filter within the scope of this 00999 FilterManager and allows for fast retrieval of the filter. 01000 Purpose: Permits the filter to be used by the FilterManager. 01001 For an import filter to be present on the Import dialog the filter should 01002 associate itself with the requisite FileFormats via AssociateFilterWithFormat() 01003 01004 ********************************************************************************************/ 01005 ID Filter::RegisterFilter( Filter* const pFilter) 01006 { 01007 ERROR2IF(pFilter == NULL, 0, "NULL Args"); 01008 01009 ID newID = GetNewFilterID(); 01010 GetFilters().AddTail(pFilter); 01011 01012 return newID; 01013 } 01014 01015 01016 01017 /******************************************************************************************** 01018 01019 > void Filter::DeinitFilters() 01020 01021 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01022 Created: 22/02/94 01023 Purpose: Destroy all the Filter objects. 01024 SeeAlso: Filter 01025 01026 ********************************************************************************************/ 01027 01028 BOOL Filter::DeinitFilters() 01029 { 01030 ListItem* pListItem = FilterList.GetHead(); 01031 while (pListItem != NULL) 01032 { 01033 ((Filter*)pListItem)->Deinit(); 01034 01035 pListItem = FilterList.GetNext(pListItem); 01036 } 01037 01038 // Get rid of our filters 01039 FilterList.DeleteAll(); 01040 01041 // All ok 01042 return TRUE; 01043 } 01044 01045 01046 /******************************************************************************************** 01047 01048 > BOOL Filter::JoinFamily(CCRuntimeClass *pRuntimeClass) 01049 01050 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01051 Created: 26/07/94 01052 Inputs: pRuntimeClass - the type of filters in this family. 01053 Returns: TRUE if the filter can be added to the family; 01054 FALSE if not. 01055 Purpose: Allow a filter to choose whether or not it wants to become part of a 01056 filter 'family', e.g. a filter family such as "EPS files", or 01057 "Bitmap files". 01058 The default implementation checks to see if the filter is of the same 01059 kind of filter, using IsKindOf(), and if so, it consents to be in the 01060 filter family. Filters should only over-ride this if they need 01061 different behaviour for some bizarre reason. 01062 01063 ********************************************************************************************/ 01064 01065 BOOL Filter::JoinFamily(CCRuntimeClass *pRuntimeClass) 01066 { 01067 return IsKindOf(pRuntimeClass); 01068 } 01069 01070 /******************************************************************************************** 01071 01072 > Filter *Filter::GetFirst() 01073 01074 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01075 Created: 22/02/94 01076 Returns: Pointer to the first filter, or NULL if none. 01077 Purpose: Iterating through the list of filters known to Camelot. This function 01078 returns the first filter. 01079 SeeAlso: Filter::GetNext() 01080 Scope: Static 01081 01082 ********************************************************************************************/ 01083 01084 Filter *Filter::GetFirst() 01085 { 01086 return (Filter *) FilterList.GetHead(); 01087 } 01088 01089 /******************************************************************************************** 01090 01091 > Filter *Filter::GetNext(Filter *pFilter) 01092 01093 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01094 Created: 22/02/94 01095 Inputs: pFilter - pointer to the filter to be used to get the following filter. 01096 Returns: Pointer to the next filter, or NULL if none. 01097 Purpose: Iterating through the list of filters known to Camelot. This function 01098 returns the next filter. 01099 SeeAlso: Filter::GetFirst 01100 01101 ********************************************************************************************/ 01102 01103 Filter *Filter::GetNext(Filter *pFilter) 01104 { 01105 return (Filter *) FilterList.GetNext(pFilter); 01106 } 01107 01108 /******************************************************************************************** 01109 01110 > FilterFlags Filter::GetFlags() 01111 01112 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01113 Created: 22/02/94 01114 Returns: The FilterFlags structure 01115 Purpose: Get the flags for a specified filter. 01116 SeeAlso: FilterFlags 01117 01118 ********************************************************************************************/ 01119 01120 FilterFlags Filter::GetFlags() 01121 { 01122 return Flags; 01123 } 01124 01125 /******************************************************************************************** 01126 01127 > virtual BOOL Filter::IsDefaultDocRequired(const TCHAR* pcszPathName) 01128 01129 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01130 Created: 9/10/95 01131 Inputs: pcszPathName pointer to the pathname to check 01132 Returns: TRUE if the filter requires a default document, FALSE if not. 01133 Purpose: Works out if opening a file of this type requires a default document to be 01134 loaded. If the file format supplies the document then return FALSE otherwise 01135 return TRUE. An example would be opening a bitmap file. This has no document 01136 defined in the file format and so we need to laod the default document before 01137 importing the bitmap into this file. 01138 In this baseclass version return FALSE and hence assume that the filters that 01139 need to will override this function to return TRUE. 01140 SeeAlso: Filter; Filter::IsDefaultDocRequired; CCamDoc::OnOpenDocument; 01141 SeeAlso: FilterFamily::DoImport; Filter::DoImport; 01142 01143 ********************************************************************************************/ 01144 01145 BOOL Filter::IsDefaultDocRequired(const TCHAR* pcszPathName) 01146 { 01147 // No need to check the pathname, just return FALSE as most filters will not require the 01148 // default document. 01149 return FALSE; 01150 } 01151 01152 /******************************************************************************************** 01153 01154 > BOOL Filter::PreHowCompatible() 01155 01156 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01157 Created: 28/11/94 01158 Returns: True if it it worked ok. 01159 Purpose: Allows a filter or set of filters to take some action or set up variables 01160 before being called by HowCompatible. A group of filters which share common 01161 code may require some variable set up before being asked to check the type. 01162 Base class does nothing and so works for all filters which do not require it. 01163 SeeAlso: HowCompatible 01164 01165 ********************************************************************************************/ 01166 01167 BOOL Filter::PreHowCompatible() 01168 { 01169 return TRUE; 01170 } 01171 01172 /******************************************************************************************** 01173 01174 > INT32 Filter::HowCompatible(PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize, 01175 INT32 FileSize) 01176 01177 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01178 Created: 31/08/94 01179 Inputs: Filename - name of the file. 01180 HeaderStart - Address of the first few bytes of the file. 01181 HeaderSize - the number of bytes in the header pointed to by FileStart. 01182 FileSize - the size of the whole file, in bytes. 01183 Returns: 0 => Not compatible with this filter - the filter will NOT be asked to 01184 load such a file. 01185 10 => Filter thinks that it is 100% compatible with this file. 01186 Or any number in between depending on how much the filter likes the file. 01187 Purpose: Determine if this filter can load the specified file. 01188 The filter is provided with the first n bytes of the file, where n is 01189 HeaderSize. It should look at this data and/or the pathname to determine 01190 if it can load this file. 01191 NB. Base class function is pure virtual - override it! 01192 01193 ********************************************************************************************/ 01194 01195 /******************************************************************************************** 01196 01197 > ADDR Filter::LoadInitialSegment(CCLexFile* pFile, UINT32* pSize, INT32* pFileSize) 01198 01199 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01200 Created: 28/03/94 01201 Inputs: pFile - the file to load from. 01202 Size - the number of bytes to load from the file. 01203 Outputs: Size - the number of bytes actually loaded (not actually implemented yet; 01204 waiting for the CCFile class to be updated). 01205 Returns: Address the the loaded block 01206 Purpose: Loads in the first n bytes of a file, in order to investigate whether a 01207 filter (or number of filters in the case of the FilterFamily class), is 01208 compatible with the file - i.e. how well this file recognises the file 01209 header. 01210 The last byte in the block is set to 0, to prevent ASCII lexers from going 01211 trundling off the end. 01212 Errors: Unable to open file; Out of memory 01213 SeeAlso: Filter::HowCompatible; Filter::PreHowCompatible 01214 01215 ********************************************************************************************/ 01216 01217 ADDR Filter::LoadInitialSegment(CCLexFile* pFile, UINT32* pSize, size_t *pFileSize) 01218 { 01219 ERROR3IF(pFile == NULL, "Null CCLexFile* in Filter::LoadInitialSegment"); 01220 01221 BOOL ThrowState = pFile->SetThrowExceptions(TRUE); 01222 BOOL ErrorState = pFile->SetReportErrors(FALSE); 01223 01224 // Tell caller how big the file is in bytes 01225 *pFileSize = pFile->Size(); 01226 01227 // Now that we know the file size, check to see if it has a chance of being loaded. 01228 // 4 is a nice small size that would fail the tests below. 01229 if (*pFileSize < 4) 01230 { 01231 // Could set a new special 'I don't think this file has any useful info in'. 01232 TRACEUSER( "Neville", _T("LoadInitialSegment(): Very small file found\n")); 01233 ERROR1(NULL, _R(IDE_FILETOOSMALL)); 01234 } 01235 01236 // Check if the file size is less than the required initial segement size. 01237 // If so set the size to be the file size. 01238 // Casting UINT32 to INT32 should be ok as we know we are between 4 and the specified size. 01239 if ((UINT32) *pFileSize < *pSize) 01240 *pSize = (UINT32) *pFileSize; 01241 01242 ADDR FilterBuf = (ADDR) CCMalloc(*pSize); 01243 if (FilterBuf == NULL) 01244 return NULL; 01245 01246 // Save the current read pointer. 01247 FilePos nOldPos = pFile->tellIn(); 01248 01249 try 01250 { 01251 // A flag see if things are working 01252 BOOL IsResultOK = TRUE; 01253 01254 01255 // First we will check to see if it starts with the fabby binary EPS marker 01256 char Buf[4]; 01257 pFile->SetDontFail(TRUE); 01258 pFile->read(Buf, 4); 01259 pFile->SetDontFail(FALSE); 01260 01261 if( Progress::IsRalphAbort() ) 01262 return NULL; 01263 01264 if ((Buf[0]=='\xC5') && (Buf[1]=='\xD0') && (Buf[2]=='\xD3') && (Buf[3]=='\xC6')) 01265 { 01266 // Yes, this is a binary EPS file that has a TIFF attached, so find the EPS 01267 FilePos StartOfEPS = 0; 01268 01269 pFile->SetDontFail(TRUE); 01270 pFile->read(&StartOfEPS, 4); 01271 StartOfEPS = LEtoNative(StartOfEPS); 01272 pFile->SetDontFail(FALSE); 01273 if(Progress::IsRalphAbort()) 01274 return NULL; 01275 01276 TRACEUSER( "Rik", _T("EPS Starts at %ld\n"), StartOfEPS); 01277 01278 // see if the result makes sense 01279 if (StartOfEPS==0) 01280 { 01281 // Must be rubbish 01282 TRACEUSER( "Rik", _T("This file claims to start at 0 - Its rubbish\n")); 01283 IsResultOK = FALSE; 01284 } 01285 01286 // Seek to the start of the EPS ready for the importer to read it. 01287 pFile->seekIn(StartOfEPS, ios::beg); 01288 01289 // If the end of the file comes before the 1k we require then we must only read 01290 // the remaining file size otherwise the read below will error. 01291 if ((UINT32)(*pFileSize - StartOfEPS) < *pSize) 01292 { 01293 *pSize = (UINT32) (*pFileSize - StartOfEPS); 01294 TRACEUSER( "Neville", _T("Reduced initial segement size to %d\n"), *pSize); 01295 } 01296 } 01297 else 01298 { 01299 // This was not a binary EPS file, so go back to the start of the file 01300 pFile->seekIn(nOldPos, ios::beg); 01301 } 01302 01303 // BODGE: Size should be updated to the number of bytes actually read. 01304 pFile->SetDontFail(TRUE); 01305 if (IsResultOK) pFile->read(FilterBuf, *pSize); 01306 pFile->SetDontFail(FALSE); 01307 01308 if( Progress::IsRalphAbort() ) 01309 return NULL; 01310 01311 // Don't need this file anymore - restote its original read pointer. 01312 pFile->seekIn(nOldPos, ios::beg); 01313 01314 // Set back the old error informing and throwing states 01315 pFile->SetThrowExceptions(ThrowState); 01316 pFile->SetReportErrors(ErrorState); 01317 01318 // If it worked 01319 if (IsResultOK) 01320 { 01321 // Zero the last byte of the buffer to make it simple for ASCII analysis. 01322 FilterBuf[(*pSize) - 1] = 0; 01323 01324 // Return address of file data 01325 return FilterBuf; 01326 } 01327 01328 // If we get here, there was a problem, so return null 01329 if (FilterBuf != NULL) CCFree(FilterBuf); 01330 01331 // return 01332 ERROR1(NULL, _R(IDS_FILECORRUPT)); 01333 } 01334 catch( CFileException ) 01335 { 01336 // Restore the original read pointer. 01337 pFile->seekIn(nOldPos, ios::beg); 01338 01339 // Set back the old error informing and throwing states 01340 pFile->SetThrowExceptions(ThrowState); 01341 pFile->SetReportErrors(ErrorState); 01342 01343 // We had an error so the buffer is no good any more so remove it and 01344 // return NULL to the caller. 01345 if (FilterBuf != NULL) CCFree(FilterBuf); 01346 01347 // We had a problem so return null 01348 return NULL; 01349 } 01350 01351 // Should not get here 01352 return NULL; 01353 } 01354 01355 01356 ADDR Filter::LoadInitialSegment(PathName& Path, UINT32 *Size, size_t *FileSize) 01357 { 01358 CCDiskFile FilterFile; 01359 if (!FilterFile.open(Path, ios::in | ios::binary)) 01360 { 01361 TRACEUSER( "Tim", _T("LoadInitialSegment(): Could not open file\n")); 01362 ERROR1(NULL, _R(IDT_IMPORT_NOTFOUND)); 01363 } 01364 01365 return LoadInitialSegment(&FilterFile, Size, FileSize); 01366 } 01367 01368 01369 01370 01371 /******************************************************************************************** 01372 01373 > Layer *Filter::GetActiveLayer(Document *pDoc) 01374 01375 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01376 Created: 28/03/94 01377 Inputs: pDoc - the document to search. 01378 Returns: Pointer to the layer found, or NULL if none, 01379 Purpose: Find the active layer of the first spread of the specified document. 01380 SeeAlso: Filter::GetFirstSpread 01381 01382 ********************************************************************************************/ 01383 01384 Layer *Filter::GetActiveLayer(Document *pDoc) 01385 { 01386 PORTNOTE("spread", "Multi-spread warning!") 01387 Spread *pSpread = GetFirstSpread(pDoc); 01388 if (pSpread != NULL) 01389 return pSpread->FindActiveLayer(); 01390 01391 return NULL; 01392 } 01393 01394 01395 01396 /******************************************************************************************** 01397 01398 > BOOL Filter::MakeSureLayerExists(Document* pDoc) 01399 01400 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01401 Created: 4/4/95 01402 Inputs: pDoc - the document that the inserting is happening in 01403 Returns: TRUE if there is a layer 01404 Purpose: This functions checks that there is a layer to put nodes onto during an 01405 import, and will create a new layer if there are none. This means that 01406 filters can call this function just before they try and insert a new node 01407 into the tree and be sure that there will be a layer for it to go onto. 01408 The function will return TRUE if there is a layer in the document (even 01409 if this function had to create the layer). It will return FALSE only if 01410 there are no layers and it was unable to create any new ones. 01411 01412 ********************************************************************************************/ 01413 01414 BOOL Filter::MakeSureLayerExists(Document* pDoc) 01415 { 01416 // Find the spread that all the action is happening on 01417 PORTNOTE("spread", "Multi-spread warning!") 01418 Spread* pSpread = GetFirstSpread(pDoc); 01419 if (pSpread==NULL) 01420 return FALSE; 01421 01422 // Try and find a layer in this spread 01423 Layer* pLayer = pSpread->FindFirstLayer(); 01424 01425 // If there were no layers, then we should try and make one 01426 if (pLayer==NULL) 01427 { 01428 // Time to build a new layer... 01429 Layer *pNewLayer = new Layer(pSpread, LASTCHILD, String_256(_R(IDS_K_FILTERS_LAYERNAME))); 01430 01431 // If we failed, return FALSE to the caller 01432 if (pNewLayer==NULL) 01433 return FALSE; 01434 01435 // Make Layer1 (top layer) the active layer 01436 pNewLayer->SetActive(TRUE); 01437 01438 // Move the Insertion position onto the new layer 01439 pDoc->ResetInsertionPosition(); 01440 } 01441 01442 // all worked 01443 return TRUE; 01444 } 01445 01446 01447 01448 /******************************************************************************************** 01449 01450 > Spread *Filter::GetFirstSpread(Document *pDoc) 01451 01452 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01453 Created: 28/03/94 01454 Inputs: pDoc - the document to search. 01455 Returns: Pointer to the spread found, or NULL if no spread was found. 01456 Purpose: Find the first spread of the specified document. 01457 SeeAlso: Filter::GetActiveLayer 01458 01459 ********************************************************************************************/ 01460 01461 Spread *Filter::GetFirstSpread(Document *pDoc) 01462 { 01463 // Search for the first chapter node 01464 Node *pNode = pDoc->GetFirstNode()->FindNext()->FindFirstChild(); 01465 while ((pNode != NULL) && (!pNode->IsKindOf(CC_RUNTIME_CLASS(Chapter)))) 01466 pNode = pNode->FindNext(); 01467 01468 ENSURE(pNode->IsKindOf(CC_RUNTIME_CLASS(Chapter)), 01469 "Filter::GetFirstSpread(): Could not find Chapter"); 01470 Chapter *pChapter = (Chapter *) pNode; 01471 01472 // pSpread is a child of pChapter 01473 PORTNOTE("spread", "Multi-spread warning!") 01474 Spread *pSpread = (Spread *) pChapter->FindFirstChild(); 01475 ENSURE(pSpread->IsKindOf(CC_RUNTIME_CLASS(Spread)), 01476 "Filter::GetFirstSpread(): Could not find Spread"); 01477 01478 if (pSpread->IsKindOf(CC_RUNTIME_CLASS(Spread))) 01479 return pSpread; 01480 else 01481 return NULL; 01482 } 01483 01484 01485 /******************************************************************************************** 01486 01487 > BOOL Filter::ImportBinary(ADDR pData, INT32 Length) 01488 01489 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01490 Created: 23/08/94 01491 Inputs: Length - the number of bytes to read. 01492 Outputs: pData - the buffer to place the bytes in. 01493 Returns: The number of bytes read, or -1 for an error. 01494 (NB. Base class version always returns -1) 01495 Purpose: Read in binary data from the file and place it in the buffer supplied by 01496 the caller. This is over-ridden by filters to do whatever translation is 01497 necessary, e.g. EPS filters convert ASCII Hexadecimal data to binary. 01498 01499 NB. This base class version has no functionality - it always returns 01500 FALSE without setting the error ID and ENSUREs in debug builds. 01501 Don't use it! 01502 01503 Errors: End of file; Disk error 01504 01505 ********************************************************************************************/ 01506 01507 INT32 Filter::ImportBinary(ADDR pData, INT32 Length) 01508 { 01509 ENSURE(FALSE, "Base class ImportBinary() function called!"); 01510 return -1; 01511 } 01512 01513 01514 /******************************************************************************************** 01515 01516 > virtual UINT32 Filter::GetImportMsgID() 01517 01518 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01519 Created: 22/12/95 01520 Returns: The id of the message to put on the progress display whilst importing. 01521 Purpose: Used to get the message id to be used during export. 01522 Virtual, so that multi-stage importers can change the message. 01523 SeeAlso: DoImport; 01524 01525 ********************************************************************************************/ 01526 01527 UINT32 Filter::GetImportMsgID() 01528 { 01529 return ImportMsgID; 01530 } 01531 01532 /******************************************************************************************** 01533 01534 > virtual UINT32 Filter::GetExportMsgID() 01535 01536 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01537 Created: 18/09/95 01538 Returns: The id of the message to put on the progress display whilst exporting. 01539 Purpose: Used to get the message id to be used during export. 01540 Virtual, so that two stage exporters can change the message. 01541 SeeAlso: DoExport; 01542 01543 ********************************************************************************************/ 01544 01545 UINT32 Filter::GetExportMsgID() 01546 { 01547 return (m_nForcedStatusExportMessage) ? m_nForcedStatusExportMessage : ExportMsgID; 01548 } 01549 01550 01551 01552 /******************************************************************************************** 01553 > static void Filter::ForceStatusExportMessage(UINT32 nMessage) 01554 01555 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01556 Created: 19/9/96 01557 Inputs: nMessage ---- the message to use instead of the usual when 01558 exporting a file. 01559 Purpose: Overrides the status-line message shown when a file is exported. This is 01560 used by the clipboard code to change "Saving document..." to 01561 "Copying to clipboard..." 01562 SeeAlso: Filter::UnforceStatusExportMessage; ExternalClipboard::GetDataSource 01563 ********************************************************************************************/ 01564 01565 void Filter::ForceStatusExportMessage(UINT32 nMessage) 01566 { 01567 // Use this message please (if derived classes allow it). 01568 m_nForcedStatusExportMessage = nMessage; 01569 } 01570 01571 01572 01573 /******************************************************************************************** 01574 > static void Filter::UnforceStatusExportMessage() 01575 01576 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01577 Created: 19/9/96 01578 Purpose: Resets the message override on export back to "no override". 01579 SeeAlso: Filter::ForceStatusExportMessage; ExternalClipboard::GetDataSource 01580 ********************************************************************************************/ 01581 01582 void Filter::UnforceStatusExportMessage() 01583 { 01584 // Set this back to "no override". 01585 m_nForcedStatusExportMessage = 0; 01586 } 01587 01588 01589 01590 /******************************************************************************************** 01591 01592 > BOOL GetProgressString(CCLexFile* pTheFile, String_64 *pMessage, String_64* StrToAddToProgress=NULL) 01593 01594 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01595 Created: 9/7/95 01596 Inputs: pTheFile file being used for importing 01597 pMessage pointer to the string to append extra bits to 01598 StrToAddToProgress - A string to add to the progress string. This is used mainly by the 01599 html import filter when importing bitmap to display "file 1 of n". 01600 Outputs: - 01601 Returns: True if worked ok, False otherwise. 01602 Purpose: Works out what progress bar string to use during importing or exporting of 01603 the file specified. 01604 This consists of the passed in basic message plus, if it will fit, a truncated 01605 form, if necessary, of the filename. 01606 The file must be a diskfile so that it can access a filename, if not then 01607 nothing will be added. If the pTheFile is null then nothing will be added. 01608 SeeAlso: Filter::GetImportProgressString; Filter::GetExportProgressString; 01609 01610 ********************************************************************************************/ 01611 01612 BOOL GetProgressString(CCLexFile* pTheFile, String_64 *pMessage, String_64* StrToAddToProgress=NULL) 01613 { 01614 // Get a shortened name for the file 01615 String_256 Filename; 01616 INT32 MaxSize = pMessage->MaxLength() - pMessage->Length(); 01617 // Now take off the size of the " '" and "'" that will be added around it 01618 MaxSize -= 3; 01619 01620 // CCFile::GetName will return what will fit into the string povided. What we 01621 // really want is just the filename, only present on disk files. 01622 if (pTheFile != NULL && pTheFile->IS_KIND_OF(CCDiskFile)) 01623 { 01624 CCDiskFile *pTheDiskFile = (CCDiskFile *)pTheFile; 01625 // This will only work on CCDiskFiles 01626 PathName path = pTheDiskFile->GetPathName(); 01627 01628 // Use just the filename 01629 Filename = path.GetFileName(); 01630 01631 // If it is still too long, turn it into the form "...ffff.ext", i.e. have an 01632 // ellipsis followed by as much of the filename as we can fit into the string. 01633 // (We use the last segment of the filename, i.e. we throw away characters from 01634 // the beginning). 01635 INT32 FilenameLen = Filename.Length(); 01636 if (MaxSize < FilenameLen) 01637 { 01638 // Shuffle pathname down to fit into buffer 01639 Filename.Remove(0, FilenameLen - MaxSize); 01640 01641 // Put the ellipsis at the front 01642 TCHAR *Buf = (TCHAR *) Filename; 01643 Buf[0] = '.'; 01644 Buf[1] = '.'; 01645 Buf[2] = '.'; 01646 } 01647 01648 // Do an extra check to ensure that waht we are about to add in will fit 01649 if (Filename.Length() <= MaxSize) 01650 { 01651 // If we have a valid file name and it will fit into the progress string 01652 // then tag this onto the end of the progress string with single quotes. 01653 01654 PCTSTR res = camStrstr( (const TCHAR *)Filename, _T(".tmp") ); 01655 01656 if (res == NULL) 01657 { 01658 *pMessage += String_32(_R(IDS_K_FILTERS_FILESTARTQUOTE)); 01659 *pMessage += Filename; 01660 *pMessage += String_32(_R(IDS_K_FILTERS_FILEENDQUOTE)); 01661 } 01662 01663 // add (for instance) "file 1 of 5".... 01664 if (StrToAddToProgress && !StrToAddToProgress->IsEmpty()) 01665 *pMessage += *StrToAddToProgress; 01666 } 01667 } 01668 01669 // if (pExportFile->GetName(&Filename) && (Filename.Length() < MaxSize)) 01670 // { 01671 // // If we have a valid file name and it will fit into the progress string 01672 // // then tag this onto the end of the progress string with single quotes. 01673 // ProgressString += " '"; 01674 // ProgressString += Filename; 01675 // ProgressString += "'"; 01676 // } 01677 01678 return TRUE; 01679 } 01680 01681 01682 /******************************************************************************************** 01683 01684 > virtual BOOL Filter::AddStringToProgressString(String_64 *Str) 01685 01686 Author: Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com> 01687 Created: 21/04/97 01688 Inputs: Str - This is the string to add in the ProgressString 01689 Outputs: - 01690 Returns: TRUE 01691 Purpose: 01692 SeeAlso: 01693 01694 ********************************************************************************************/ 01695 01696 BOOL Filter::AddStringToProgressString(String_64 *Str) 01697 { 01698 m_StrToAddToProgress = *Str; 01699 01700 return TRUE; 01701 } 01702 01703 01704 /******************************************************************************************** 01705 01706 > virtual StringBase Filter::GetImportProgressString(CCLexFile* ImportFile, UINT32 ImportingMsgID) 01707 01708 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01709 Created: 9/7/95 01710 Inputs: ImportFile file being used for importing 01711 ImportingMsgID id of message to use as basis on progress string 01712 Outputs: - 01713 Returns: String to use on the progress bar during import. 01714 Purpose: Works out what progress bar string to use during importing of the file. 01715 This consists of a basic message plus, if it will fit, a truncated form of 01716 the filename being imported. 01717 SeeAlso: Filter::GetExportProgressString; 01718 01719 ********************************************************************************************/ 01720 01721 String_64 Filter::GetImportProgressString(CCLexFile* pImportFile, UINT32 ImportingMsgID) 01722 { 01723 String_64 ProgressString(ImportingMsgID); 01724 01725 // Ammend the string with the filename, if we can. 01726 GetProgressString(pImportFile, &ProgressString, &m_StrToAddToProgress); 01727 01728 return ProgressString; 01729 } 01730 01731 /******************************************************************************************** 01732 01733 > virtual StringBase Filter::GetExportProgressString(CCLexFile* ExportFile, UINT32 ExportingMsgID) 01734 01735 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01736 Created: 9/7/95 01737 Inputs: ExportFile file being used for importing 01738 ImportingMsgID id of message to use as basis on progress string 01739 Outputs: - 01740 Returns: String to use on the progress bar during import. 01741 Purpose: Works out what progress bar string to use during exporting of the file. 01742 This consists of a basic message plus, if it will fit, a truncated form of 01743 the filename being exported. 01744 SeeAlso: Filter::GetImportProgressString; 01745 01746 ********************************************************************************************/ 01747 01748 String_64 Filter::GetExportProgressString(CCLexFile* pExportFile, UINT32 ExportingMsgID) 01749 { 01750 #ifdef DO_EXPORT 01751 String_64 ProgressString(ExportingMsgID); 01752 01753 // Ammend the string with the filename, if we can. 01754 GetProgressString(pExportFile, &ProgressString); 01755 01756 return ProgressString; 01757 #else 01758 return String_64( _T("") ); 01759 #endif 01760 } 01761 01762 /******************************************************************************************** 01763 01764 > virtual BOOL Filter::ExportVisibleLayersOnly() 01765 01766 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01767 Created: 14/02/95 01768 Inputs: - 01769 Outputs: - 01770 Returns: True if this filter wants to exclude invisible layers and so export only 01771 visible items Or False if want to export everything. 01772 Purpose: Determines if the filter wants to export only visible layers. 01773 NB. This base class version does the default action of making the filter 01774 export everything including hidden layers. 01775 SeeAlso: Filter::ExportRender; 01776 01777 ********************************************************************************************/ 01778 01779 BOOL Filter::ExportVisibleLayersOnly() 01780 { 01781 // base class version includes all layers and so everything will get exported 01782 return FALSE; 01783 } 01784 01785 /******************************************************************************************** 01786 01787 > virtual BOOL Filter::ExportSelectionOnly() 01788 01789 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01790 Created: 18/09/95 01791 Returns: True if this filter wants check if an object is selected or not and so export 01792 only the selected items Or False if want to export everything. 01793 Purpose: Determines if the filter wants to export only selected items. 01794 In the filters baseclass version the default action will be to 01795 export all objects by default 01796 Only used by bitmap export and in particular masked gif rendering at present. 01797 SeeAlso: Filter::ExportRender; 01798 01799 ********************************************************************************************/ 01800 01801 BOOL Filter::ExportSelectionOnly(BOOL MaskedRender) 01802 { 01803 // base class version says export everything regardless of whether selected or not. 01804 return FALSE; 01805 } 01806 01807 01808 /******************************************************************************************** 01809 01810 > virtual BOOL Filter::OpenExportFile(CCDiskFile * pFile, PathName *pPath) 01811 01812 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01813 Created: 22/12/95 01814 Inputs: pDiskFile The constructed disk file to use 01815 pPath The pathname of the file to be opened 01816 Returns: True if the file has been opened correctly, False otherwise. 01817 Purpose: Opens up the file ready for exporting into. Assumes the file has already 01818 been constructed with the correct buffers etc.. 01819 SeeAlso: OpMenuExport::DoWithParam; Filters::DoExport; 01820 Errors: The relevent error is set if the file did not open properly 01821 01822 ********************************************************************************************/ 01823 01824 BOOL Filter::OpenExportFile(CCDiskFile * pDiskFile, PathName *pPath) 01825 { 01826 #ifdef DO_EXPORT 01827 ERROR2IF(pDiskFile == NULL, FALSE,"Filter::OpenExportFile null file supplied"); 01828 ERROR2IF(pPath == NULL, FALSE,"Filter::OpenExportFile null pathname supplied"); 01829 01830 // Open up the file. This will create a zero length file just to make sure that it 01831 // is possible, i.e. we have write access. This should have actually already been 01832 // checked by the file export dialog code and trapped before this. 01833 // Added 27/9/95 ios::trunc as exporting a bitmap or eps file to the same file twice 01834 // appended the data to the end of the file on Windows 95. 01835 BOOL ok = pDiskFile->open(*pPath, ios::in | ios::out | ios::binary | ios::trunc); 01836 01837 if (!ok) 01838 { 01839 // Failed to open the file so set the error that we want to report 01840 Error::SetError(_R(IDT_EXPORT_NOTFOUND), 0); 01841 } 01842 return ok; 01843 #else 01844 return FALSE; 01845 #endif 01846 } 01847 01848 /******************************************************************************************** 01849 01850 > virtual BOOL Filter::DeleteExportFile(CCDiskFile * pFile, PathName *pPath) 01851 01852 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01853 Created: 22/12/95 01854 Inputs: pDiskFile The constructed disk file to use 01855 Returns: True if the file has been closed and deleted correctly, False otherwise. 01856 Purpose: Used for when either an export has been aborted by the user half way through 01857 or when an error has occured. It closes up the export file, if open, and then 01858 deletes it. 01859 SeeAlso: OpMenuExport::DoWithParam; Filters::DoExport; 01860 SeeAlso: ClipboardMapping::ExportToTempFile; OpMenuSave::SaveSpecificFile; 01861 01862 ********************************************************************************************/ 01863 01864 BOOL Filter::DeleteExportFile(CCDiskFile * pDiskFile) 01865 { 01866 #ifdef DO_EXPORT 01867 ERROR2IF(pDiskFile == NULL, FALSE,"Filter::CloseExportFile null file supplied"); 01868 01869 // Remove the zero length file that we created as part of the process. 01870 01871 // First, ensure file is closed 01872 if (pDiskFile->isOpen()) 01873 pDiskFile->close(); 01874 01875 // Get its pathname 01876 PathName Path = pDiskFile->GetPathName(); 01877 01878 // And try and remove it, only if it exists 01879 if (Path.IsValid()) 01880 { 01881 BOOL Exists = TRUE; 01882 BOOL status = TRUE; 01883 Exists = SGLibOil::FileExists(&Path); 01884 if (Exists) 01885 status = SGLibOil::FileDelete(&Path); 01886 TRACEUSER( "Neville", _T("Filter::DeleteExportFile removed exists status =%d, file status =%d/n"),Exists,status); 01887 } 01888 #endif 01889 return TRUE; 01890 } 01891 01892 /******************************************************************************************** 01893 01894 > virtual BOOL Filter::ExportRender(RenderRegion *pRegion) 01895 01896 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01897 Created: 28/03/94 01898 Inputs: pRegion - the render region to export to. 01899 Returns: TRUE if the export process completed successfully, FALSE if an error occured. 01900 Purpose: Export a file to a given render region. It is the responsibility of the 01901 derived filter to create a render region of the correct type, and then pass 01902 it to this function. 01903 Errors: Render region is not connected to a spread. 01904 SeeAlso: EPSRenderRegion::ExportRender, FlashRenderRegion::ExportRender 01905 01906 ********************************************************************************************/ 01907 01908 BOOL Filter::ExportRender ( RenderRegion *pRegion, BOOL MaskedRender) 01909 { 01910 #ifdef DO_EXPORT 01911 // Disable bitmap caching but remember the old state so we can set it back 01912 ScopedFlagSetter fsBitmapCacheing(NodeRenderableBounded::bEnableCacheing, FALSE); 01913 01914 ERROR2IF(pRegion==NULL,FALSE,"Filter::ExportRender null render region supplied"); 01915 01916 // We need special handling for Camelot EPS 01917 // (NB. but not native files - do not change this to IS_KIND_OF!) 01918 BOOL IsCamelotEPS = IS_A(pRegion, CamelotEPSRenderRegion); 01919 01920 // Get the DC for this export operation 01921 // This can be NULL, in the case of bitmap export, or a CMetaFileDC in the case 01922 // of MetaFile export. In the later case we MUST NOT set up the ExportDC pointer 01923 // pDC otherwise the CATCH handlers will fail as there is no ExportFile. Also the 01924 // progress bar message will fail. 01925 // The CDC can be Null if we are talking about bitmap export 01926 CNativeDC* pCDC = pRegion->GetRenderDC(); 01927 ExportDC* pDC = NULL; 01928 NumNodes = 0; 01929 01930 // At present, it appears that only EPS derived filters have a file attached and so 01931 // are the only ones which use an ExportDC. All bitmap filters use NULL. 01932 if( pCDC != NULL && this->IS_KIND_OF(EPSFilter)) 01933 pDC = (ExportDC*)CCDC::ConvertFromNativeDC(pCDC); 01934 01935 // Find out how big the document and document components are... 01936 // (We only do this for EPS files) 01937 if( 01938 this->IS_KIND_OF(EPSFilter) && 01939 !IsCamelotEPS) 01940 { 01941 // First, we ask the document itself 01942 Document *pDocument = GetDocument(); 01943 NumNodes += pDocument->GetSizeOfExport(this); 01944 01945 // Next, the document components... 01946 DocComponent *pComponent = pDocument->EnumerateDocComponents(NULL); 01947 01948 while (pComponent != NULL) 01949 { 01950 // Ask this document component how much data it will export. 01951 NumNodes += pComponent->GetSizeOfExport(this); 01952 01953 // Look for next doc component 01954 pComponent = pDocument->EnumerateDocComponents(pComponent); 01955 } 01956 } 01957 01958 // Remember how big this initial header is, so we don't overflow when writing 01959 // out and screw up the progress indication (which could happen if, e.g. the 01960 // bitmap export code was incorrect). 01961 CurrentProgressLimit = NumNodes; 01962 01963 // Find the first node that we should export from this spread 01964 Node *pNode = pRegion->GetRenderSpread(); 01965 01966 ENSURE(pNode != NULL, "Render Region has no spread in Filter::ExportRender!"); 01967 ERRORIF(pNode == NULL, _R(IDT_EXPORT_INTERNAL_ERR), FALSE); 01968 01969 // Go and find the bounding rect for this spread and set the render regions 01970 // clipping rect to it 01971 if (pNode->IsSpread()) 01972 { 01973 // find out the old clip rect 01974 DocRect OldClipRect = pRegion->GetClipRect(); 01975 01976 // only do something if it is empty 01977 if (OldClipRect.IsEmpty()) 01978 { 01979 // Get a pointer to the spread and find out its bounding rect 01980 Spread* pSpread = (Spread*) pNode; 01981 DocRect SpreadRect = pSpread->GetBoundingRect(); 01982 pSpread->DocCoordToSpreadCoord(&SpreadRect); 01983 01984 // and set the render regions clipping rect to this 01985 pRegion->SetClipRect(SpreadRect); 01986 } 01987 } 01988 01989 // Work out if this filter wants to include all layers or just the visible ones 01990 // Default action will be to include all so that say an eps or native filters save 01991 // everything. 01992 BOOL bVisibleLayersOnly = ExportVisibleLayersOnly(); 01993 BOOL bSelectedOnly = ExportSelectionOnly(MaskedRender); 01994 01995 if (IsCamelotEPS) 01996 { 01997 try 01998 { 01999 // Special 3-stage rendering needed for Camelot EPS to be renderable. 02000 View *pView = DocView::GetSelected(); 02001 Matrix RenderMatrix = pRegion->GetMatrix(); 02002 RenderViewResult Result = pView->RenderSimpleView(pRegion, RenderMatrix, 02003 pRegion->GetRenderSpread(), 02004 FALSE); 02005 if (Result == RENDERVIEW_USERABORT) 02006 // Export is over - user has aborted it (but this is not an error) 02007 return TRUE; 02008 02009 if (Result == RENDERVIEW_FAILURE) 02010 // Export was not successful 02011 return FALSE; 02012 02013 // This should never happen, as Camelot EPS cannot do 'eveything' 02014 ERROR3IF(Result == RENDERVIEW_NOTNEEDED, 02015 "RenderSimpleView did not render anything into EPS!"); 02016 02017 // Finished render region - close down region (i.e. output trailer). 02018 ((EPSRenderRegion *) pRegion)->CloseDown(); 02019 } 02020 02021 catch(CFileException) 02022 { 02023 // Didn't work - report failure to caller. 02024 if (pDC) 02025 pDC->ExportFile->SetThrowExceptions(FALSE); 02026 return FALSE; 02027 } 02028 // All ok 02029 return TRUE; 02030 } 02031 else 02032 { 02033 FilterRenderCallback MyCallback(this, TRUE, bVisibleLayersOnly, bSelectedOnly); 02034 pRegion->RenderTree(pNode, FALSE, FALSE, &MyCallback); 02035 pRegion->ResetRender(); 02036 02037 // Now actually export the nodes themselves 02038 // Use a virtual function so that filters can overide this and say render in strips as 02039 // the bitmap filters are required to do 02040 ProgressOffset = 0; 02041 BOOL Result = ExportRenderNodes(pRegion, pDC, bVisibleLayersOnly, bSelectedOnly, FALSE/*TRUE*/); 02042 02043 // return the result to the caller 02044 return Result; 02045 } 02046 #else 02047 return FALSE; 02048 #endif 02049 } 02050 02051 02052 02053 02054 /******************************************************************************************** 02055 02056 > BOOL FilterRenderCallback::BeforeNode(RenderRegion* pRegion, Node* pNode) 02057 02058 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02059 Created: 30/11/2004 02060 Inputs: pNode - pointer to node about to be rendered by RenderTree 02061 pRender - pointer to RenderRegion running RenderTree loop 02062 Outputs: - 02063 Returns: TRUE if node can be rendered 02064 FALSE if not 02065 Purpose: Handle the callback from RenderTree that has been requested by Filter 02066 02067 ********************************************************************************************/ 02068 02069 BOOL FilterRenderCallback::BeforeNode(RenderRegion* pRegion, Node* pNode) 02070 { 02071 // Don't need to do this because BeforeSubtree should have doen it for every node 02072 // that gets passed to BeforeNode... 02073 // if (!pNode->NeedsToExport(pRegion, m_bVisibleLayersOnly, m_bSelectedOnly)) 02074 // return FALSE; 02075 02076 if (m_bCount) 02077 { 02078 if (pNode->IsNodeRenderableClass()) 02079 Filter::NumNodes += ((NodeRenderable*)pNode)->GetSizeOfExport(m_pFilter); 02080 02081 return FALSE; // Don't render anything! 02082 } 02083 02084 // -------------------------------------------------------------------------- 02085 // If rendering an RGBT bitmap, don't render anything in background layers 02086 if (pRegion->m_DoCompression) 02087 { 02088 Layer* pLayer = (Layer*)pNode->FindParent(CC_RUNTIME_CLASS(Layer)); 02089 if (pLayer && pLayer->IsBackground()) 02090 return FALSE; 02091 } 02092 02093 // Update the progress display 02094 if (pNode->IsNodeRenderableClass()) 02095 m_pFilter->UpdateFilterProgress(((NodeRenderable*)pNode)->GetSizeOfExport(m_pFilter)); 02096 else 02097 m_pFilter->UpdateFilterProgress(0); // For back compatibility with previous version of this code 02098 02099 // Render (export) the node that we have, using special export rendering if it exists. 02100 BOOL bExportRendered = pNode->ExportRender(pRegion); 02101 02102 return (!bExportRendered); // If not exported let RenderTree do it, return TRUE 02103 } 02104 02105 02106 /******************************************************************************************** 02107 02108 > BOOL FilterRenderCallback::BeforeSubtree(RenderRegion* pRegion, 02109 Node* pNode, 02110 Node** ppNextNode, 02111 BOOL bClip, 02112 SubtreeRenderState* pState) 02113 02114 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02115 Created: 30/11/2004 02116 Inputs: pNode - pointer to node about to be rendered by RenderTree 02117 pRender - pointer to RenderRegion running RenderTree loop 02118 Outputs: pNextNode - pointer to node where navigation should continue 02119 State - Navigation state for RenderTree state machine 02120 Returns: TRUE if we've returned a valid SubRenderState 02121 FALSE if not 02122 Purpose: Handle the callback from RenderTree that has been requested by Filter 02123 02124 ********************************************************************************************/ 02125 02126 BOOL FilterRenderCallback::BeforeSubtree(RenderRegion* pRegion, 02127 Node* pNode, 02128 Node** ppNextNode, 02129 BOOL bClip, 02130 SubtreeRenderState* pState) 02131 { 02132 if (pNode==NULL) 02133 return TRUE; 02134 02135 if (m_bCount) 02136 { 02137 // We're only counting so we will control tree navigation to ensure clever 02138 // nodes don't skip around by themselves 02139 if (pNode->NeedsToExport(pRegion, m_bVisibleLayersOnly, m_bSelectedOnly)) 02140 *pState = SUBTREE_ROOTANDCHILDREN; 02141 else 02142 *pState = SUBTREE_NORENDER; 02143 02144 return TRUE; 02145 } 02146 02147 // -------------------------------------------------------------------------- 02148 // We're not counting so let normal, smart navigation take place 02149 if (pNode->NeedsToExport(pRegion, m_bVisibleLayersOnly, m_bSelectedOnly)) 02150 { 02151 // This node does need to be exported 02152 // Tell the node at the root of the subtree that we're about to export it and it's children 02153 pNode->PreExportRender(pRegion); 02154 return FALSE; // Tell RenderTree we want normal navigation to take place 02155 } 02156 else 02157 { 02158 *pState = SUBTREE_NORENDER; // Tell RenderTree we want to forcibly skip this node 02159 return TRUE; 02160 } 02161 } 02162 02163 02164 02165 02166 /******************************************************************************************** 02167 02168 > virtual BOOL Filter::ExportRenderNodes ( RenderRegion *pRegion, 02169 ExportDC *pDC, 02170 BOOL VisibleLayersOnly = FALSE, 02171 BOOL CheckSelected = FALSE, 02172 BOOL ShowProgress = TRUE ) 02173 02174 Author: Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com> (from Neville's original code) 02175 Created: 12/4/00 02176 Inputs: pRegion - the render region to export to. 02177 pDc - device context to use, can be NULL. 02178 VisibleLayersOnly - use visible layers or not 02179 ShowProgress - TRUE then start up a progress bar or FALSE assume 02180 the caller has done it. 02181 Returns: TRUE if the export process completed successfully, FALSE if an error occured. 02182 Purpose: Sets up the file to do an export of the nodes in the tree, by initialising 02183 the file, and any slow-job code. It then calls the WriteNodes method to do 02184 the actual work, and EndExportRender to complete the task. 02185 SeeAlso: Filter::ExportRender, Filter::WriteNodes, Filter::EndExportRender 02186 02187 ********************************************************************************************/ 02188 02189 BOOL Filter::ExportRenderNodes ( RenderRegion *pRegion, 02190 ExportDC *pDC, 02191 BOOL VisibleLayersOnly, 02192 BOOL CheckSelected, 02193 BOOL ShowProgress ) 02194 { 02195 #ifdef DO_EXPORT 02196 ERROR2IF ( pRegion == NULL, FALSE, "Filter::ExportRender null render region supplied" ); 02197 02198 // Start a progress update going 02199 if ( ShowProgress ) 02200 { 02201 String_64 ExportMessage ( GetExportMsgID () ); 02202 if ( pDC && pDC->ExportFile ) 02203 { 02204 ExportMessage = GetExportProgressString ( pDC->ExportFile, GetExportMsgID () ); 02205 } 02206 BeginSlowJob ( NumNodes, FALSE, &ExportMessage ); 02207 } 02208 02209 // Work out how often we want to update the progress bar. 02210 UpdateEvery = ( NumNodes / 100 ) + 1; 02211 02212 LastExportProgressUpdate = 0; 02213 NumNodes = 0; 02214 02215 // Guard against disk/file errors, and get ready to render. 02216 //TRY 02217 { 02218 // Get the region ready to render. 02219 if ( !pRegion->StartRender() ) 02220 { 02221 // An error occured. 02222 if ( ShowProgress ) 02223 EndSlowJob (); 02224 return FALSE; 02225 } 02226 } 02227 #if 0 02228 CATCH ( CFileException, e ) 02229 { 02230 // Didn't work - report failure to caller. 02231 if ( pDC ) 02232 pDC->ExportFile->SetThrowExceptions ( FALSE ); 02233 if ( ShowProgress ) 02234 EndSlowJob (); 02235 return FALSE; 02236 } 02237 END_CATCH 02238 #endif 02239 // Write the nodes out to the file, and end the export 02240 if ( WriteNodes ( pRegion, pDC, VisibleLayersOnly, CheckSelected, ShowProgress ) && 02241 EndExportRender ( pRegion, ShowProgress ) ) 02242 { 02243 // It worked. 02244 return TRUE; 02245 } 02246 else 02247 { 02248 // Houston, we have a problem. 02249 return FALSE; 02250 } 02251 02252 #else 02253 return FALSE; 02254 #endif 02255 } 02256 02257 02258 /******************************************************************************************** 02259 02260 > virtual BOOL Filter::WriteNodes ( RenderRegion *pRegion, 02261 ExportDC *pDC, 02262 BOOL VisibleLayersOnly, 02263 BOOL CheckSelected, 02264 BOOL ShowProgress ) 02265 02266 Author: Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com> (from Neville's original code) 02267 Created: 12/4/00 02268 Inputs: pRegion - the render region to export to. 02269 pDc - device context to use, can be NULL. 02270 VisibleLayersOnly - use visible layers or not 02271 ShowProgress - TRUE then start up a progress bar or FALSE assume 02272 the caller has done it. 02273 Returns: TRUE if the export process completed successfully, FALSE if an error occured. 02274 Purpose: Actually export the nodes to the given render region showing a progress bar 02275 as we go. Assumes everything has been set up by ExportRender. 02276 Assumes that either a progress bar has been started and will be ended by the 02277 caller or that it should start and end the progress bar itself. 02278 SeeAlso: Filter::ExportRender, Filter::ExportRenderNodes 02279 02280 ********************************************************************************************/ 02281 02282 BOOL Filter::WriteNodes ( RenderRegion *pRegion, 02283 ExportDC *pDC, 02284 BOOL VisibleLayersOnly, 02285 BOOL SelectedOnly, 02286 BOOL ShowProgress ) 02287 { 02288 #ifdef DO_EXPORT 02289 02290 // Find the first node that we should export from this spread 02291 Node *pNode = pRegion->GetRenderSpread (); 02292 02293 // Cycle through all exportable nodes, and render (export) them. 02294 // Export the file, but catch any file errors. 02295 //TRY 02296 { 02297 // BOOL IsPageBackGroundAnd32BitAlpha = FALSE; 02298 // BOOL LookForPageBackgrounds = TRUE; 02299 02300 FilterRenderCallback MyCallback(this, FALSE, VisibleLayersOnly, SelectedOnly); // Not counting this time! 02301 pRegion->RenderTree(pNode, FALSE, FALSE, &MyCallback); 02302 pRegion->ResetRender(); 02303 } 02304 #if 0 02305 CATCH ( CFileException, e ) 02306 { 02307 // Didn't work - report failure to caller. 02308 if ( pDC ) 02309 pDC->ExportFile->SetThrowExceptions ( FALSE ); 02310 pRegion->StopRender (); 02311 if ( ShowProgress ) 02312 EndSlowJob (); 02313 return FALSE; 02314 } 02315 END_CATCH 02316 #endif 02317 // All OK 02318 return TRUE; 02319 #else 02320 return FALSE; 02321 #endif 02322 } 02323 02324 02325 /******************************************************************************************** 02326 02327 > virtual void Filter::UpdateFilterProgress(UINT32 increment) 02328 02329 Author: Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com> (from Neville's original code) 02330 Created: 12/4/00 02331 Inputs: pRegion - the render region to export to. 02332 ShowProgress - TRUE then start up a progress bar or FALSE assume 02333 the caller has done it. 02334 Returns: TRUE if the export process completed successfully, FALSE if an error occured. 02335 Purpose: Shuts down the export render process. 02336 SeeAlso: Filter::ExportRender, Filter::ExportRenderNodes 02337 02338 ********************************************************************************************/ 02339 02340 void Filter::UpdateFilterProgress(UINT32 increment) 02341 { 02342 // Limit the progress display to legal values 02343 if (increment>0) 02344 CurrentProgressLimit = NumNodes + increment; 02345 02346 // Update node count accordingly 02347 NumNodes = CurrentProgressLimit; 02348 02349 if (NumNodes > (LastExportProgressUpdate + UpdateEvery)) 02350 LastExportProgressUpdate = NumNodes; 02351 } 02352 02353 /******************************************************************************************** 02354 02355 > virtual BOOL Filter::EndExportRender ( RenderRegion *pRegion, 02356 BOOL ShowProgress ) 02357 02358 Author: Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com> (from Neville's original code) 02359 Created: 12/4/00 02360 Inputs: pRegion - the render region to export to. 02361 ShowProgress - TRUE then start up a progress bar or FALSE assume 02362 the caller has done it. 02363 Returns: TRUE if the export process completed successfully, FALSE if an error occured. 02364 Purpose: Shuts down the export render process. 02365 SeeAlso: Filter::ExportRender, Filter::ExportRenderNodes 02366 02367 ********************************************************************************************/ 02368 02369 BOOL Filter::EndExportRender ( RenderRegion *pRegion, 02370 BOOL ShowProgress ) 02371 { 02372 #ifdef DO_EXPORT 02373 02374 //TRY 02375 { 02376 // Finished rendering - deinit render region. 02377 pRegion->StopRender (); 02378 02379 // Shut down the render region. 02380 pRegion->CloseDown (); 02381 } 02382 #if 0 02383 CATCH ( CFileException, e ) 02384 { 02385 // Didn't work - report failure to caller. 02386 if ( ShowProgress ) 02387 EndSlowJob (); 02388 return FALSE; 02389 } 02390 END_CATCH 02391 #endif 02392 // Close down progress display, if present 02393 if ( ShowProgress ) 02394 EndSlowJob (); 02395 02396 // All OK 02397 return TRUE; 02398 #else 02399 return FALSE; 02400 #endif 02401 } 02402 02403 /******************************************************************************************** 02404 02405 > UINT32 Filter::GetNumNodes() 02406 02407 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02408 Created: 16/5/95 02409 Inputs: - 02410 Outputs: - 02411 Returns: The numbers of nodes which are currently set up to be used for a progress bar. 02412 Purpose: Allows access to the stored numbers of nodes which is currently set up to 02413 be used for a progress bar. 02414 02415 ********************************************************************************************/ 02416 02417 UINT32 Filter::GetNumNodes() 02418 { 02419 return NumNodes; 02420 } 02421 02422 /******************************************************************************************** 02423 02424 > UINT32 Filter::SetNumNodes(UINT32 NewNumNodes) 02425 02426 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02427 Created: 16/5/95 02428 Inputs: - 02429 Outputs: - 02430 Returns: The old number of nodes value 02431 Purpose: Allows setting of the stored numbers of nodes which is currently set up to 02432 be used for a progress bar. 02433 02434 ********************************************************************************************/ 02435 02436 UINT32 Filter::SetNumNodes(UINT32 NewNumNodes) 02437 { 02438 UINT32 OldNumNodes = NumNodes; 02439 02440 NumNodes = NewNumNodes; 02441 02442 return OldNumNodes; 02443 } 02444 02445 02446 /******************************************************************************************** 02447 02448 > BOOL Filter::UpdateExportedNodeCount(UINT32 NumNodesSaved) 02449 02450 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02451 Created: 27/01/95 02452 Inputs: NumNodes - number of nodes just saved. 02453 Returns: TRUE if the progress display was updated ok; 02454 FALSE if not (i.e. the user pressed Esc to cancel the operation). 02455 Purpose: Update the progress display according to the number passed in. The NumNodes 02456 parameter indicates how many nodes have just been saved. 02457 Most nodes won't call this when exporting as they are only '1' node. 02458 Nodes such as blenders or bitmaps may call this to update the progress 02459 more smoothly. 02460 E.g. a bitmap might say that it is 20 nodes if it has 20 scanlines. It 02461 could then call this function after each scanline is saved with the 02462 value 1. It should not call it with more than the number of nodes it 02463 claims to be, e.g. the example bitmap above should only ever call with 02464 NumNodes in the range 1 to 20. And the cumulative total of NumNodesSaved 02465 passed in by one node should never be more than the number of nodes it 02466 claims to be either. 02467 02468 SeeAlso: Node::GetSizeOfExport 02469 02470 ********************************************************************************************/ 02471 02472 BOOL Filter::UpdateExportedNodeCount(UINT32 NumNodesSaved) 02473 { 02474 #ifdef DO_EXPORT 02475 // Work out how many nodes have been saved in total. 02476 NumNodes += NumNodesSaved; 02477 02478 // Make sure we remain within the legal range of values 02479 if (NumNodes > CurrentProgressLimit) 02480 { 02481 #if _DEBUG 02482 // Only report an error once for each sub-section otherwise it's too annoying. 02483 static UINT32 LastError = 0; 02484 if (LastError != CurrentProgressLimit) 02485 { 02486 if (Error::IsUserName("Tim")) 02487 { 02488 ERROR3("Filter::UpdateExportedNodeCount() called with an out of range value!"); 02489 } 02490 LastError = CurrentProgressLimit; 02491 } 02492 #endif 02493 02494 // Ignore the error in retail builds - it's not serious (but limit the value) 02495 NumNodes = CurrentProgressLimit; 02496 } 02497 02498 // Check to see if it's worth updating yet. 02499 if (NumNodes > (LastExportProgressUpdate + UpdateEvery)) 02500 { 02501 LastExportProgressUpdate = NumNodes; 02502 02503 if (!ContinueSlowJob(NumNodes)) 02504 { 02505 return FALSE; 02506 } 02507 } 02508 02509 #endif 02510 // Everything is ok if we get here 02511 return TRUE; 02512 } 02513 02514 /******************************************************************************************** 02515 02516 > BitmapFilterSupport Filter::GetBitmapSupportLevel() 02517 02518 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02519 Created: 30/01/95 02520 Returns: NoBitmapSupport - This filter does not support bitmap images. 02521 SimpleBitmapSupport - This filter has simple support for bitmap images; 02522 they must be saved into the file whenever 02523 they are used. 02524 IndirectedBitmapSupport - This filter supports bitmap indirection; i.e. a 02525 bitmap pool of some type is saved and then this 02526 can be referenced in the file. 02527 Purpose: Determine how well this filter supports bitmaps when exporting. 02528 02529 ********************************************************************************************/ 02530 02531 BitmapFilterSupport Filter::GetBitmapSupportLevel() 02532 { 02533 // Defaults to no bitmap support 02534 return NoBitmapSupport; 02535 } 02536 02537 /******************************************************************************************** 02538 02539 > BOOL Filter::ImportBitmap(CCLexFile*, KernelBitmap**) 02540 02541 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02542 Created: 8/4/94 02543 Inputs: - 02544 Returns: TRUE if the bitmap was imported ok (or if it wasn't imported because the 02545 file format does not support it; 02546 FALSE if an error occured. 02547 Purpose: - 02548 Errors: Usual disk/file errors. 02549 SeeAlso: CamelotEPSFilter::ExportBitmap 02550 02551 ********************************************************************************************/ 02552 02553 BOOL Filter::ImportBitmap(CCLexFile*, KernelBitmap**) 02554 { 02555 // Base class - ignore bitmaps 02556 return TRUE; 02557 } 02558 02559 /******************************************************************************************** 02560 02561 > BOOL Filter::ExportBitmap(KernelBitmap& TheBitmap) 02562 02563 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02564 Created: 01/09/94 02565 Inputs: TheBitmap - the bitmap to export 02566 Returns: TRUE if the bitmap was exported ok (or if it wasn't exported because the 02567 file format does not support it; 02568 FALSE if an error occured. 02569 Purpose: Virtual function to export a bitmap to a file. This base class version 02570 always does nothing and returns TRUE, so formats which do not support 02571 bitmaps need do nothing. Formats that support bitmaps should over-ride 02572 this function to do the necessary work required to embed the bitmap into 02573 the file. 02574 Errors: Usual disk/file errors. 02575 SeeAlso: CamelotEPSFilter::ExportBitmap 02576 02577 ********************************************************************************************/ 02578 02579 BOOL Filter::ExportBitmap(KernelBitmap&) 02580 { 02581 // Base class - ignore bitmaps 02582 return TRUE; 02583 } 02584 02585 02586 /******************************************************************************************** 02587 02588 > BOOL Filter::SetLineColour(DocColour& Col) 02589 02590 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02591 Created: 13/04/94 02592 Inputs: Col - the new line colour to use. 02593 Returns: TRUE if the attribute was changed ok; 02594 FALSE otherwise. 02595 Purpose: Updates the current attribute for line colour to reflect the value passed 02596 in. 02597 Errors: Out of memory. 02598 SeeAlso: Filter; Filter::Init 02599 02600 ********************************************************************************************/ 02601 02602 BOOL Filter::SetLineColour(DocColour& Col) 02603 { 02604 // Sanity check 02605 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02606 02607 // If we haven't changed this attribute yet, then make a new attribute object for 02608 // our own personal use... 02609 if (!CurrentAttrs[ATTR_STROKECOLOUR].Temp) 02610 { 02611 // Make the correct attribute value and install it as the current one. 02612 CurrentAttrs[ATTR_STROKECOLOUR].pAttr = new StrokeColourAttribute(Col); 02613 if (CurrentAttrs[ATTR_STROKECOLOUR].pAttr == NULL) 02614 return FALSE; 02615 CurrentAttrs[ATTR_STROKECOLOUR].Temp = TRUE; 02616 } 02617 else 02618 { 02619 // We already have an attribute - just change it. 02620 StrokeColourAttribute *pAttr = 02621 (StrokeColourAttribute *) CurrentAttrs[ATTR_STROKECOLOUR].pAttr; 02622 pAttr->Colour = Col; 02623 } 02624 02625 // All worked ok. 02626 return TRUE; 02627 } 02628 02629 /******************************************************************************************** 02630 02631 > BOOL Filter::SetLineWidth(MILLIPOINT Width) 02632 02633 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02634 Created: 13/04/94 02635 Inputs: Width - the new line width to use. 02636 Returns: TRUE if the attribute was changed ok; 02637 FALSE otherwise. 02638 Purpose: Updates the current attribute for line width to reflect the value passed 02639 in. 02640 Errors: Out of memory. 02641 SeeAlso: Filter; Filter::Init 02642 02643 ********************************************************************************************/ 02644 02645 BOOL Filter::SetLineWidth(MILLIPOINT Width) 02646 { 02647 // Sanity check 02648 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02649 02650 // Avoid zero width lines - change them to the value specified in the user preference. 02651 if (Width == 0) 02652 Width = MinLineWidth; 02653 02654 // If we haven't changed this attribute yet, then make a new attribute object for 02655 // our own personal use... 02656 if (!CurrentAttrs[ATTR_LINEWIDTH].Temp) 02657 { 02658 // Make the correct attribute value and install it as the current one. 02659 CurrentAttrs[ATTR_LINEWIDTH].pAttr = new LineWidthAttribute(Width); 02660 if (CurrentAttrs[ATTR_LINEWIDTH].pAttr == NULL) 02661 return FALSE; 02662 CurrentAttrs[ATTR_LINEWIDTH].Temp = TRUE; 02663 } 02664 else 02665 { 02666 // We already have an attribute - just change it. 02667 LineWidthAttribute *pAttr = 02668 (LineWidthAttribute *) CurrentAttrs[ATTR_LINEWIDTH].pAttr; 02669 pAttr->LineWidth = Width; 02670 } 02671 02672 // All worked ok. 02673 return TRUE; 02674 } 02675 02676 /******************************************************************************************** 02677 02678 > BOOL Filter::SetLineCap(LineCapType LineCap) 02679 02680 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02681 Created: 13/04/94 02682 Inputs: LineCap - the new line cap style to use. 02683 Returns: TRUE if the attribute was changed ok; 02684 FALSE otherwise. 02685 Purpose: Updates the current attribute for line cap style to reflect the value passed 02686 in. 02687 Errors: Out of memory. 02688 SeeAlso: Filter; Filter::Init 02689 02690 ********************************************************************************************/ 02691 02692 BOOL Filter::SetLineCap(LineCapType LineCap) 02693 { 02694 // Sanity check 02695 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02696 02697 // If we haven't changed this attribute yet, then make a new attribute object for 02698 // our own personal use... 02699 if (!CurrentAttrs[ATTR_STARTCAP].Temp) 02700 { 02701 // Make the correct attribute value and install it as the current one. 02702 CurrentAttrs[ATTR_STARTCAP].pAttr = new StartCapAttribute; 02703 if (CurrentAttrs[ATTR_STARTCAP].pAttr == NULL) 02704 return FALSE; 02705 CurrentAttrs[ATTR_STARTCAP].Temp = TRUE; 02706 } 02707 02708 // We have an attribute - just change it. 02709 StartCapAttribute *pAttr = 02710 (StartCapAttribute *) CurrentAttrs[ATTR_STARTCAP].pAttr; 02711 pAttr->StartCap = LineCap; 02712 02713 // All worked ok. 02714 return TRUE; 02715 } 02716 02717 /******************************************************************************************** 02718 02719 > BOOL Filter::SetJoinType(JointType JoinType) 02720 02721 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02722 Created: 13/04/94 02723 Inputs: JoinType - the new line join style to use. 02724 Returns: TRUE if the attribute was changed ok; 02725 FALSE otherwise. 02726 Purpose: Updates the current attribute for line join style to reflect the value passed 02727 in. 02728 Errors: Out of memory. 02729 SeeAlso: Filter; Filter::Init 02730 02731 ********************************************************************************************/ 02732 02733 BOOL Filter::SetJoinType(JointType JoinType) 02734 { 02735 // Sanity check 02736 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02737 02738 // If we haven't changed this attribute yet, then make a new attribute object for 02739 // our own personal use... 02740 if (!CurrentAttrs[ATTR_JOINTYPE].Temp) 02741 { 02742 // Make the correct attribute value and install it as the current one. 02743 CurrentAttrs[ATTR_JOINTYPE].pAttr = new JoinTypeAttribute; 02744 if (CurrentAttrs[ATTR_JOINTYPE].pAttr == NULL) 02745 return FALSE; 02746 CurrentAttrs[ATTR_JOINTYPE].Temp = TRUE; 02747 } 02748 02749 // We have an attribute - just change it. 02750 JoinTypeAttribute *pAttr = 02751 (JoinTypeAttribute *) CurrentAttrs[ATTR_JOINTYPE].pAttr; 02752 pAttr->JoinType = JoinType; 02753 02754 // All worked ok. 02755 return TRUE; 02756 } 02757 02758 /******************************************************************************************** 02759 02760 > BOOL Filter::SetLineTransp(UINT32 TranspType, UINT32 Transp) 02761 02762 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02763 Created: 15/04/95 02764 Inputs: TranspType - the transparency type to use. 02765 Transp - the transparency (0 to 255) of the line. 02766 Returns: TRUE if the attribute was changed ok; 02767 FALSE otherwise. 02768 Purpose: Updates the current attribute for line transparency to reflect the value 02769 passed in. 02770 Errors: Out of memory. 02771 SeeAlso: Filter; Filter::Init 02772 02773 ********************************************************************************************/ 02774 02775 BOOL Filter::SetLineTransp(UINT32 TranspType, UINT32 Transp) 02776 { 02777 // Sanity check 02778 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02779 02780 // If we haven't changed this attribute yet, then make a new attribute object for 02781 // our own personal use... 02782 if (!CurrentAttrs[ATTR_STROKETRANSP].Temp) 02783 { 02784 // Make the correct attribute value and install it as the current one. 02785 CurrentAttrs[ATTR_STROKETRANSP].pAttr = new StrokeTranspAttribute; 02786 if (CurrentAttrs[ATTR_STROKETRANSP].pAttr == NULL) 02787 return FALSE; 02788 CurrentAttrs[ATTR_STROKETRANSP].Temp = TRUE; 02789 } 02790 02791 // We have an attribute - just change it. 02792 StrokeTranspAttribute *pAttr = 02793 (StrokeTranspAttribute *) CurrentAttrs[ATTR_STROKETRANSP].pAttr; 02794 02795 pAttr->TranspType = TranspType; 02796 pAttr->Transp = Transp; 02797 02798 // All worked ok. 02799 return TRUE; 02800 } 02801 02802 /******************************************************************************************** 02803 02804 > BOOL Filter::SetDashPattern(DashRec& Dash) 02805 02806 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02807 Created: 15/04/95 02808 Inputs: Dash - the Dash Pattern to use. 02809 Returns: TRUE if the attribute was changed ok; 02810 FALSE otherwise. 02811 Purpose: Updates the current attribute for dash pattern to reflect the value 02812 passed in. 02813 Errors: Out of memory. 02814 SeeAlso: Filter; Filter::Init 02815 02816 ********************************************************************************************/ 02817 02818 BOOL Filter::SetDashPattern(DashRec& Dash) 02819 { 02820 // Sanity check 02821 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02822 02823 // If we haven't changed this attribute yet, then make a new attribute object for 02824 // our own personal use... 02825 if (!CurrentAttrs[ATTR_DASHPATTERN].Temp) 02826 { 02827 // Make the correct attribute value and install it as the current one. 02828 CurrentAttrs[ATTR_DASHPATTERN].pAttr = new DashPatternAttribute; 02829 if (CurrentAttrs[ATTR_DASHPATTERN].pAttr == NULL) 02830 return FALSE; 02831 CurrentAttrs[ATTR_DASHPATTERN].Temp = TRUE; 02832 } 02833 02834 // We have an attribute - just change it. 02835 DashPatternAttribute *pAttr = 02836 (DashPatternAttribute *) CurrentAttrs[ATTR_DASHPATTERN].pAttr; 02837 02838 // Bodge 02839 // When we save Native files we at present save out a dash pattern ID and then 02840 // save out the full dash pattern definition! This is ok apart from wasting space. 02841 // The problem happens when we load the information back in, we load the id and apply 02842 // the relevent dash pattern and then load the definition and apply it, zapping the 02843 // id. 02844 // If we are a native filter then assume that the id has already been set up 02845 // Now done in CheckIfDefaultPattern below. 02846 // But have to disable both checks as if we set the id then we would have an id on 02847 // a scaled version of the pattern. This would also only fix files which have been 02848 // save once, as saving again will have completely lost all trace of the id! 02849 /* if (this->IS_KIND_OF(CamelotNativeEPSFilter)) 02850 { 02851 // Note the current id already put there by the native filter 02852 INT32 DashId = pAttr->DashPattern.GetDashID(); 02853 // Copy the new dash pattern over 02854 pAttr->DashPattern = Dash; 02855 // Copy the original ID across but only if it has been set 02856 // As it will default to zero then we copy it across if we have changed it! 02857 if (DashId != 0) 02858 pAttr->DashPattern.DashID = DashId; 02859 } 02860 else */ 02861 02862 pAttr->DashPattern = Dash; 02863 02864 // make sure the dash pattern is OK 02865 pAttr->DashPattern.CheckAndFix(); 02866 02867 // Reset the ID if it is one of our default patterns 02868 // Cannot do this check as when a line is first saved the definition is scaled 02869 // for some strange and bizarre reason, possible to do with the fact that a general 02870 // EPS saving routine is being used. 02871 //pAttr->DashPattern.CheckIfDefaultPattern(); 02872 02873 // All worked ok. 02874 return TRUE; 02875 } 02876 02877 /******************************************************************************************** 02878 02879 > BOOL Filter::SetStartArrow(ArrowRec& Arrow) 02880 02881 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02882 Created: 15/04/95 02883 Inputs: Arrow - the Arrow to use. 02884 Returns: TRUE if the attribute was changed ok; 02885 FALSE otherwise. 02886 Purpose: Updates the current attribute for Start Arrow to reflect the value 02887 passed in. 02888 Errors: Out of memory. 02889 SeeAlso: Filter; Filter::Init 02890 02891 ********************************************************************************************/ 02892 02893 BOOL Filter::SetStartArrow(ArrowRec& Arrow) 02894 { 02895 // Sanity check 02896 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02897 02898 // If we haven't changed this attribute yet, then make a new attribute object for 02899 // our own personal use... 02900 if (!CurrentAttrs[ATTR_STARTARROW].Temp) 02901 { 02902 // Make the correct attribute value and install it as the current one. 02903 CurrentAttrs[ATTR_STARTARROW].pAttr = new StartArrowAttribute; 02904 if (CurrentAttrs[ATTR_STARTARROW].pAttr == NULL) 02905 return FALSE; 02906 CurrentAttrs[ATTR_STARTARROW].Temp = TRUE; 02907 } 02908 02909 // We have an attribute - just change it. 02910 StartArrowAttribute *pAttr = 02911 (StartArrowAttribute *) CurrentAttrs[ATTR_STARTARROW].pAttr; 02912 02913 pAttr->StartArrow = Arrow; 02914 02915 // All worked ok. 02916 return TRUE; 02917 } 02918 02919 /******************************************************************************************** 02920 02921 > BOOL Filter::SetEndArrow(ArrowRec& Arrow) 02922 02923 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02924 Created: 15/04/95 02925 Inputs: Arrow - the Arrow to use. 02926 Returns: TRUE if the attribute was changed ok; 02927 FALSE otherwise. 02928 Purpose: Updates the current attribute for End Arrow to reflect the value 02929 passed in. 02930 Errors: Out of memory. 02931 SeeAlso: Filter; Filter::Init 02932 02933 ********************************************************************************************/ 02934 02935 BOOL Filter::SetEndArrow(ArrowRec& Arrow) 02936 { 02937 // Sanity check 02938 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02939 02940 // If we haven't changed this attribute yet, then make a new attribute object for 02941 // our own personal use... 02942 if (!CurrentAttrs[ATTR_ENDARROW].Temp) 02943 { 02944 // Make the correct attribute value and install it as the current one. 02945 CurrentAttrs[ATTR_ENDARROW].pAttr = new EndArrowAttribute; 02946 if (CurrentAttrs[ATTR_ENDARROW].pAttr == NULL) 02947 return FALSE; 02948 CurrentAttrs[ATTR_ENDARROW].Temp = TRUE; 02949 } 02950 02951 // We have an attribute - just change it. 02952 EndArrowAttribute *pAttr = 02953 (EndArrowAttribute *) CurrentAttrs[ATTR_ENDARROW].pAttr; 02954 02955 pAttr->EndArrow = Arrow; 02956 02957 // All worked ok. 02958 return TRUE; 02959 } 02960 02961 /******************************************************************************************** 02962 02963 > BOOL Filter::SetMitreLimit(MILLIPOINT MitreLimit) 02964 02965 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02966 Created: 15/04/95 02967 Inputs: Arrow - the Arrow to use. 02968 Returns: TRUE if the attribute was changed ok; 02969 FALSE otherwise. 02970 Purpose: Updates the current attribute for the Mitre Limit to reflect the value 02971 passed in. 02972 Errors: Out of memory. 02973 SeeAlso: Filter; Filter::Init 02974 02975 ********************************************************************************************/ 02976 02977 BOOL Filter::SetMitreLimit(MILLIPOINT MitreLimit) 02978 { 02979 // Sanity check 02980 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 02981 02982 // If we haven't changed this attribute yet, then make a new attribute object for 02983 // our own personal use... 02984 if (!CurrentAttrs[ATTR_MITRELIMIT].Temp) 02985 { 02986 // Make the correct attribute value and install it as the current one. 02987 CurrentAttrs[ATTR_MITRELIMIT].pAttr = new MitreLimitAttribute; 02988 if (CurrentAttrs[ATTR_MITRELIMIT].pAttr == NULL) 02989 return FALSE; 02990 CurrentAttrs[ATTR_MITRELIMIT].Temp = TRUE; 02991 } 02992 02993 // We have an attribute - just change it. 02994 MitreLimitAttribute *pAttr = 02995 (MitreLimitAttribute *) CurrentAttrs[ATTR_MITRELIMIT].pAttr; 02996 02997 pAttr->MitreLimit = MitreLimit; 02998 02999 // All worked ok. 03000 return TRUE; 03001 } 03002 03003 03004 03005 /******************************************************************************************** 03006 03007 > BOOL Filter::SetPathFilled(BOOL Filled) 03008 03009 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03010 Created: 04/01/95 03011 Inputs: Filled - whether or not paths should be filled. 03012 Returns: TRUE if ok; 03013 FALSE otherwise (e.g. out of memory) 03014 Purpose: Indicate whether paths should be filled or not. This is independent of the 03015 current fill attribute, so, for example, if this function is called to 03016 set the paths to be unfilled, and then called again to set them to be 03017 filled, then afterwards all paths filled will be filled with whatever 03018 fill attribute was last set. 03019 Errors: Out of memory => ERROR1 03020 SeeAlso: Filter::SetFillColour 03021 03022 ********************************************************************************************/ 03023 03024 BOOL Filter::SetPathFilled(BOOL Filled) 03025 { 03026 if(Filled == PathFilled) 03027 return TRUE; 03028 03029 if (Filled) 03030 { 03031 // See if we need to reinstate the fill attribute 03032 if (FillAttr.pAttr != NULL) 03033 { 03034 // Yes we do... 03035 if (CurrentAttrs[ATTR_FILLGEOMETRY].Temp) 03036 { 03037 // Get rid of the current one (if it is a temporary attribute) 03038 delete CurrentAttrs[ATTR_FILLGEOMETRY].pAttr; 03039 } 03040 03041 // Install the new one, and vape the pointer so we don't do this again. 03042 CurrentAttrs[ATTR_FILLGEOMETRY] = FillAttr; 03043 FillAttr.pAttr = NULL; 03044 } 03045 } 03046 else 03047 { 03048 // Lose the current saved FillAttr if we need to. 03049 if ((FillAttr.pAttr != NULL) && (FillAttr.Temp)) 03050 { 03051 delete FillAttr.pAttr; 03052 } 03053 03054 // Disabling the fill attribute - remember the current one. 03055 FillAttr = CurrentAttrs[ATTR_FILLGEOMETRY]; 03056 03057 // Install a new flat colour fill... 03058 CurrentAttrs[ATTR_FILLGEOMETRY].pAttr = new FlatFillAttribute; 03059 if (CurrentAttrs[ATTR_FILLGEOMETRY].pAttr == NULL) 03060 return FALSE; 03061 CurrentAttrs[ATTR_FILLGEOMETRY].Temp = TRUE; 03062 03063 // .. and make it a transparent fill 03064 DocColour TransCol(COLOUR_TRANS); 03065 FillGeometryAttribute *pAttr = (FillGeometryAttribute *) 03066 CurrentAttrs[ATTR_FILLGEOMETRY].pAttr; 03067 pAttr->SetStartColour(&TransCol); 03068 } 03069 03070 PathFilled = Filled; 03071 03072 // Must be ok if we got here 03073 return TRUE; 03074 } 03075 03076 03077 /******************************************************************************************** 03078 03079 > BOOL Filter::SetFillColour(DocColour& Col) 03080 03081 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03082 Created: 13/04/94 03083 Inputs: Col - the new fill colour to use. 03084 Returns: TRUE if the attribute was changed ok; 03085 FALSE otherwise. 03086 Purpose: Updates the current attribute for fill colour to reflect the value passed 03087 in. 03088 Errors: Out of memory. 03089 SeeAlso: Filter; Filter::Init 03090 03091 ********************************************************************************************/ 03092 03093 BOOL Filter::SetFillColour(DocColour& Col) 03094 { 03095 // Sanity check 03096 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03097 03098 // Find out which fill attribute to change 03099 AttributeEntry *pEntry; 03100 if (FillAttr.pAttr == NULL) 03101 // No 'saved' fill attribute, so just update the normal one. 03102 pEntry = &CurrentAttrs[ATTR_FILLGEOMETRY]; 03103 else 03104 // Update the saved fill attribute. 03105 pEntry = &FillAttr; 03106 03107 // If we haven't changed this attribute yet, then make a new attribute object for 03108 // our own personal use... 03109 if (!pEntry->Temp) 03110 { 03111 // Make the correct attribute value and install it as the current one. 03112 pEntry->pAttr = new FlatFillAttribute(Col); 03113 if (pEntry->pAttr == NULL) 03114 return FALSE; 03115 pEntry->Temp = TRUE; 03116 } 03117 else 03118 { 03119 // Ensure we have the correct attribute 03120 if (!IS_A(pEntry->pAttr, FlatFillAttribute)) 03121 { 03122 // Wrong type - delete it and get the right type of attribute value. 03123 delete pEntry->pAttr; 03124 pEntry->pAttr = new FlatFillAttribute; 03125 if (pEntry->pAttr == NULL) 03126 return FALSE; 03127 } 03128 } 03129 03130 // We've got an attribute - change it. 03131 FlatFillAttribute *pAttr = (FlatFillAttribute *) pEntry->pAttr; 03132 03133 pAttr->SetStartColour(&Col); 03134 03135 // All worked ok. 03136 return TRUE; 03137 } 03138 03139 /******************************************************************************************** 03140 03141 > BOOL Filter::SetLinearFill(DocColour StartColour, DocColour EndColour, 03142 DocCoord StartPoint, DocCoord EndPoint, 03143 DocCoord *EndPoint2 = NULL) 03144 03145 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03146 Created: 13/04/94 03147 Inputs: StartColour, EndColour, StartPoint, EndPoint - see GradFillAttribute. 03148 Returns: TRUE if the attribute was changed ok; 03149 FALSE otherwise. 03150 Purpose: Updates the current attribute for gradfill colour to reflect the value passed 03151 in. 03152 Errors: Out of memory. 03153 SeeAlso: Filter; Filter::Init; GradFillAttribute 03154 03155 ********************************************************************************************/ 03156 03157 BOOL Filter::SetLinearFill(DocColour &StartColour, DocColour &EndColour, 03158 DocCoord StartPoint, DocCoord EndPoint, 03159 DocCoord *EndPoint2) 03160 { 03161 // Sanity check 03162 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03163 03164 // Find out which fill attribute to change 03165 AttributeEntry *pEntry; 03166 if (FillAttr.pAttr == NULL) 03167 // No 'saved' fill attribute, so just update the normal one. 03168 pEntry = &CurrentAttrs[ATTR_FILLGEOMETRY]; 03169 else 03170 // Update the saved fill attribute. 03171 pEntry = &FillAttr; 03172 03173 // If we haven't changed this attribute yet, then make a new attribute object for 03174 // our own personal use... 03175 if (!pEntry->Temp) 03176 { 03177 // Make the correct attribute value and install it as the current one. 03178 pEntry->pAttr = new LinearFillAttribute; 03179 if (pEntry->pAttr == NULL) 03180 return FALSE; 03181 pEntry->Temp = TRUE; 03182 } 03183 else 03184 { 03185 // Ensure we have the correct attribute 03186 if (!IS_A(pEntry->pAttr, LinearFillAttribute)) 03187 { 03188 // Wrong type - delete it and get the right type of attribute value. 03189 delete pEntry->pAttr; 03190 pEntry->pAttr = new LinearFillAttribute; 03191 if (pEntry->pAttr == NULL) 03192 return FALSE; 03193 } 03194 } 03195 03196 // We've got an attribute - change it. 03197 LinearFillAttribute *pAttr = (LinearFillAttribute *) pEntry->pAttr; 03198 03199 // Copy field values. 03200 pAttr->SetStartColour(&StartColour); 03201 pAttr->SetEndColour(&EndColour); 03202 pAttr->SetStartPoint(&StartPoint); 03203 pAttr->SetEndPoint(&EndPoint); 03204 pAttr->SetEndPoint2(EndPoint2); 03205 03206 // All worked ok. 03207 return TRUE; 03208 } 03209 03210 /******************************************************************************************** 03211 03212 > BOOL Filter::SetRadialFill(DocColour StartColour, DocColour EndColour, 03213 DocCoord StartPoint, DocCoord EndPoint) 03214 03215 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03216 Created: 13/04/94 03217 Inputs: StartColour, EndColour - colours to fade between. 03218 StartPoint, EndPoint1 - the points defining the radial fill. 03219 Returns: TRUE if the attribute was changed ok; 03220 FALSE otherwise. 03221 Purpose: Updates the current attribute for gradfill colour to reflect the value passed 03222 in. 03223 Errors: Out of memory. 03224 SeeAlso: Filter; Filter::Init; GradFillAttribute 03225 03226 ********************************************************************************************/ 03227 03228 BOOL Filter::SetRadialFill(DocColour &StartColour, DocColour &EndColour, 03229 DocCoord StartPoint, DocCoord EndPoint) 03230 { 03231 // Call the more general function... 03232 BOOL Success = SetRadialFill(StartColour, EndColour, StartPoint, EndPoint, EndPoint); 03233 03234 // Set the new attribute to be a circular one, if it worked 03235 if (Success) 03236 { 03237 RadialFillAttribute *pAttr = 03238 (RadialFillAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr; 03239 pAttr->MakeCircular(); 03240 } 03241 03242 return Success; 03243 } 03244 03245 /******************************************************************************************** 03246 03247 > BOOL Filter::SetRadialFill(DocColour StartColour, DocColour EndColour, 03248 DocCoord StartPoint, 03249 DocCoord EndPoint1, DocCoord EndPoint2) 03250 03251 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03252 Created: 13/04/94 03253 Inputs: StartColour, EndColour - colours to fade between. 03254 StartPoint, EndPoint1, EndPoint2 - the points defining the elliptical 03255 radial fill. 03256 Returns: TRUE if the attribute was changed ok; 03257 FALSE otherwise. 03258 Purpose: Updates the current attribute for gradfill colour to reflect the value passed 03259 in. 03260 Errors: Out of memory. 03261 SeeAlso: Filter; Filter::Init; GradFillAttribute 03262 03263 ********************************************************************************************/ 03264 03265 BOOL Filter::SetRadialFill(DocColour &StartColour, DocColour &EndColour, 03266 DocCoord StartPoint, 03267 DocCoord EndPoint1, DocCoord EndPoint2) 03268 { 03269 // Sanity check 03270 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03271 03272 // Find out which fill attribute to change 03273 AttributeEntry *pEntry; 03274 if (FillAttr.pAttr == NULL) 03275 // No 'saved' fill attribute, so just update the normal one. 03276 pEntry = &CurrentAttrs[ATTR_FILLGEOMETRY]; 03277 else 03278 // Update the saved fill attribute. 03279 pEntry = &FillAttr; 03280 03281 // If we haven't changed this attribute yet, then make a new attribute object for 03282 // our own personal use... 03283 if (!pEntry->Temp) 03284 { 03285 // Make the correct attribute value and install it as the current one. 03286 pEntry->pAttr = new RadialFillAttribute; 03287 if (pEntry->pAttr == NULL) 03288 return FALSE; 03289 pEntry->Temp = TRUE; 03290 } 03291 else 03292 { 03293 // Ensure we have the correct attribute 03294 if (!IS_A(pEntry->pAttr, RadialFillAttribute)) 03295 { 03296 // Wrong type - delete it and get the right type of attribute value. 03297 delete pEntry->pAttr; 03298 pEntry->pAttr = new RadialFillAttribute; 03299 if (pEntry->pAttr == NULL) 03300 return FALSE; 03301 } 03302 } 03303 03304 // We've got an attribute - change it. 03305 RadialFillAttribute *pAttr = (RadialFillAttribute *) pEntry->pAttr; 03306 03307 // Copy field values. 03308 pAttr->SetStartColour(&StartColour); 03309 pAttr->SetEndColour(&EndColour); 03310 pAttr->SetStartPoint(&StartPoint); 03311 pAttr->SetEndPoint(&EndPoint1); 03312 pAttr->SetEndPoint2(&EndPoint2); 03313 03314 // Make sure it's elliptical 03315 pAttr->MakeElliptical(); 03316 03317 // All worked ok. 03318 return TRUE; 03319 } 03320 03321 /******************************************************************************************** 03322 03323 > BOOL Filter::SetSquareFill(DocColour StartColour, DocColour EndColour, 03324 DocCoord StartPoint, 03325 DocCoord EndPoint1, DocCoord EndPoint2) 03326 03327 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03328 Created: 27/08/94 03329 Inputs: StartColour, EndColour - colours to fade between. 03330 StartPoint, EndPoint1, EndPoint2 - the points defining the elliptical 03331 radial fill. 03332 Returns: TRUE if the attribute was changed ok; 03333 FALSE otherwise. 03334 Purpose: Updates the current attribute for gradfill colour to reflect the value passed 03335 in. 03336 03337 FN copied and modified by Ben. 03338 Errors: Out of memory. 03339 SeeAlso: Filter; Filter::Init; GradFillAttribute 03340 03341 ********************************************************************************************/ 03342 03343 BOOL Filter::SetSquareFill(DocColour &StartColour, DocColour &EndColour, 03344 DocCoord StartPoint, 03345 DocCoord EndPoint1, DocCoord EndPoint2) 03346 { 03347 // Sanity check 03348 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03349 03350 // Find out which fill attribute to change 03351 AttributeEntry *pEntry; 03352 if (FillAttr.pAttr == NULL) 03353 // No 'saved' fill attribute, so just update the normal one. 03354 pEntry = &CurrentAttrs[ATTR_FILLGEOMETRY]; 03355 else 03356 // Update the saved fill attribute. 03357 pEntry = &FillAttr; 03358 03359 // If we haven't changed this attribute yet, then make a new attribute object for 03360 // our own personal use... 03361 if (!pEntry->Temp) 03362 { 03363 // Make the correct attribute value and install it as the current one. 03364 pEntry->pAttr = new SquareFillAttribute; 03365 if (pEntry->pAttr == NULL) 03366 return FALSE; 03367 pEntry->Temp = TRUE; 03368 } 03369 else 03370 { 03371 // Ensure we have the correct attribute 03372 if (!IS_A(pEntry->pAttr, SquareFillAttribute)) 03373 { 03374 // Wrong type - delete it and get the right type of attribute value. 03375 delete pEntry->pAttr; 03376 pEntry->pAttr = new SquareFillAttribute; 03377 if (pEntry->pAttr == NULL) 03378 return FALSE; 03379 } 03380 } 03381 03382 // We've got an attribute - change it. 03383 SquareFillAttribute *pAttr = (SquareFillAttribute *) pEntry->pAttr; 03384 03385 // Copy field values. 03386 pAttr->SetStartColour(&StartColour); 03387 pAttr->SetEndColour(&EndColour); 03388 pAttr->SetStartPoint(&StartPoint); 03389 pAttr->SetEndPoint(&EndPoint1); 03390 pAttr->SetEndPoint2(&EndPoint2); 03391 03392 // All worked ok. 03393 return TRUE; 03394 } 03395 03396 /******************************************************************************************** 03397 03398 > BOOL Filter::SetConicalFill(DocColour StartColour, DocColour EndColour, 03399 DocCoord StartPoint, DocCoord EndPoint) 03400 03401 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03402 Created: 13/04/94 03403 Inputs: StartColour, EndColour, StartPoint, EndPoint - see GradFillAttribute. 03404 Returns: TRUE if the attribute was changed ok; 03405 FALSE otherwise. 03406 Purpose: Updates the current attribute for gradfill colour to reflect the value passed 03407 in. 03408 Errors: Out of memory. 03409 SeeAlso: Filter; Filter::Init; GradFillAttribute 03410 03411 ********************************************************************************************/ 03412 03413 BOOL Filter::SetConicalFill(DocColour &StartColour, DocColour &EndColour, 03414 DocCoord StartPoint, DocCoord EndPoint) 03415 { 03416 // Sanity check 03417 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03418 03419 // Find out which fill attribute to change 03420 AttributeEntry *pEntry; 03421 if (FillAttr.pAttr == NULL) 03422 // No 'saved' fill attribute, so just update the normal one. 03423 pEntry = &CurrentAttrs[ATTR_FILLGEOMETRY]; 03424 else 03425 // Update the saved fill attribute. 03426 pEntry = &FillAttr; 03427 03428 // If we haven't changed this attribute yet, then make a new attribute object for 03429 // our own personal use... 03430 if (!pEntry->Temp) 03431 { 03432 // Make the correct attribute value and install it as the current one. 03433 pEntry->pAttr = new ConicalFillAttribute; 03434 if (pEntry->pAttr == NULL) 03435 return FALSE; 03436 pEntry->Temp = TRUE; 03437 } 03438 else 03439 { 03440 // Ensure we have the correct attribute 03441 if (!IS_A(pEntry->pAttr, ConicalFillAttribute)) 03442 { 03443 // Wrong type - delete it and get the right type of attribute value. 03444 delete pEntry->pAttr; 03445 pEntry->pAttr = new ConicalFillAttribute; 03446 if (pEntry->pAttr == NULL) 03447 return FALSE; 03448 } 03449 } 03450 03451 // We've got an attribute - change it. 03452 ConicalFillAttribute *pAttr = (ConicalFillAttribute *) pEntry->pAttr; 03453 03454 // Copy field values. 03455 pAttr->SetStartColour(&StartColour); 03456 pAttr->SetEndColour(&EndColour); 03457 pAttr->SetStartPoint(&StartPoint); 03458 pAttr->SetEndPoint(&EndPoint); 03459 03460 // All worked ok. 03461 return TRUE; 03462 } 03463 03464 /******************************************************************************************** 03465 03466 > BOOL Filter::SetBitmapFill(KernelBitmap *pBitmap, 03467 DocCoord StartPoint, DocCoord EndPoint, DocCoord EndPoint2, 03468 DocColour *StartColour = 0, DocColour *EndColour = 0) 03469 03470 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03471 Created: 23/08/94 03472 Inputs: pBitmap - pointer to the bitmap object to fill with. 03473 StartPoint, EndPoint, EndPoint2 - see BitmapFillAttribute. 03474 Returns: TRUE if the attribute was changed ok; 03475 FALSE otherwise. 03476 Purpose: Updates the current attribute for fill colour to reflect the value passed 03477 in. 03478 Errors: Out of memory. 03479 SeeAlso: Filter; Filter::Init; BitmapFillAttribute 03480 03481 ********************************************************************************************/ 03482 03483 BOOL Filter::SetBitmapFill(KernelBitmap *pBitmap, 03484 DocCoord StartPoint, DocCoord EndPoint, DocCoord EndPoint2, 03485 DocColour *StartColour, DocColour *EndColour) 03486 { 03487 // Sanity check 03488 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03489 ERROR3IF((StartColour != 0 && EndColour == 0) || (StartColour == 0 && EndColour != 0), 03490 "SetBitmapFill, StartColour and EndColour have a different status"); 03491 03492 // Find out which fill attribute to change 03493 AttributeEntry *pEntry; 03494 if (FillAttr.pAttr == NULL) 03495 // No 'saved' fill attribute, so just update the normal one. 03496 pEntry = &CurrentAttrs[ATTR_FILLGEOMETRY]; 03497 else 03498 // Update the saved fill attribute. 03499 pEntry = &FillAttr; 03500 03501 // If we haven't changed this attribute yet, then make a new attribute object for 03502 // our own personal use... 03503 if (!pEntry->Temp) 03504 { 03505 // Make the correct attribute value and install it as the current one. 03506 pEntry->pAttr = new BitmapFillAttribute; 03507 if (pEntry->pAttr == NULL) 03508 return FALSE; 03509 pEntry->Temp = TRUE; 03510 } 03511 else 03512 { 03513 // Ensure we have the correct attribute 03514 if (!IS_A(pEntry->pAttr, BitmapFillAttribute)) 03515 { 03516 // Wrong type - delete it and get the right type of attribute value. 03517 delete pEntry->pAttr; 03518 pEntry->pAttr = new BitmapFillAttribute; 03519 if (pEntry->pAttr == NULL) 03520 return FALSE; 03521 } 03522 } 03523 03524 // We've got an attribute - change it. 03525 BitmapFillAttribute *pAttr = (BitmapFillAttribute *) pEntry->pAttr; 03526 03527 // Copy field values. 03528 pAttr->SetStartColour(StartColour); 03529 pAttr->SetEndColour(EndColour); 03530 03531 pAttr->SetStartPoint(&StartPoint); 03532 pAttr->SetEndPoint(&EndPoint); 03533 pAttr->SetEndPoint2(&EndPoint2); 03534 03535 GetDocument()->SetCurrent(); 03536 // pAttr->AttachBitmap(pBitmap); 03537 pAttr->GetBitmapRef()->Attach(pBitmap, GetDocument()); 03538 03539 if (pAttr->GetBitmap() != pBitmap) 03540 { 03541 // It didn't use the bitmap we gave it, so we can delete it 03542 delete pBitmap; 03543 } 03544 03545 // All worked ok. 03546 return TRUE; 03547 } 03548 03549 03550 /******************************************************************************************** 03551 03552 > BOOL Filter::SetFractalFill(DocColour &StartColour, DocColour &EndColour, 03553 DocCoord StartPoint, DocCoord EndPoint1, DocCoord EndPoint2, 03554 INT32 Seed, double Graininess, double Gravity, double Squash, 03555 UINT32 DPI, BOOL Tileable) 03556 03557 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03558 Created: 08/11/94 03559 Inputs: StartColour, EndColour - the colours of the fill 03560 StartPoint, EndPoint1, EndPoint2 - co-ordinates of the fill mesh 03561 Seed, Graininess, Gravity, Squash - strange fractal parameters 03562 DPI - the resolution of the fractal bitmap (dots per inch). 03563 Tileable - whether the fractal bitmap is tileable or not (ask Alex). 03564 Returns: TRUE if the attribute was changed ok; 03565 FALSE otherwise => ERROR1 03566 Purpose: Updates the current attribute for colour fill geometry to be a fractal fill 03567 using the values passed in. 03568 Errors: Out of memory => ERROR1 03569 SeeAlso: Filter; Filter::Init; FractalFillAttribute 03570 03571 ********************************************************************************************/ 03572 03573 BOOL Filter::SetFractalFill(DocColour &StartColour, DocColour &EndColour, 03574 DocCoord StartPoint, DocCoord EndPoint1, DocCoord EndPoint2, 03575 INT32 Seed, double Graininess, double Gravity, double Squash, 03576 UINT32 DPI, BOOL Tileable) 03577 { 03578 // Sanity check 03579 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03580 03581 // Find out which fill attribute to change 03582 AttributeEntry *pEntry; 03583 if (FillAttr.pAttr == NULL) 03584 // No 'saved' fill attribute, so just update the normal one. 03585 pEntry = &CurrentAttrs[ATTR_FILLGEOMETRY]; 03586 else 03587 // Update the saved fill attribute. 03588 pEntry = &FillAttr; 03589 03590 // If we haven't changed this attribute yet, then make a new attribute object for 03591 // our own personal use... 03592 if (!pEntry->Temp) 03593 { 03594 // Make the correct attribute value and install it as the current one. 03595 pEntry->pAttr = new FractalFillAttribute; 03596 if (pEntry->pAttr == NULL) 03597 return FALSE; 03598 pEntry->Temp = TRUE; 03599 } 03600 else 03601 { 03602 // Ensure we have the correct attribute 03603 if (!IS_A(pEntry->pAttr, FractalFillAttribute)) 03604 { 03605 // Wrong type - delete it and get the right type of attribute value. 03606 delete pEntry->pAttr; 03607 pEntry->pAttr = new FractalFillAttribute; 03608 if (pEntry->pAttr == NULL) 03609 return FALSE; 03610 } 03611 } 03612 03613 // We've got an attribute - change it. 03614 FractalFillAttribute *pAttr = (FractalFillAttribute *) pEntry->pAttr; 03615 03616 // Copy field values. 03617 pAttr->SetStartColour(&StartColour); 03618 pAttr->SetEndColour(&EndColour); 03619 pAttr->SetStartPoint(&StartPoint); 03620 pAttr->SetEndPoint(&EndPoint1); 03621 pAttr->SetEndPoint2(&EndPoint2); 03622 pAttr->SetSeed(Seed); 03623 pAttr->SetGraininess(Graininess); 03624 pAttr->SetGravity(Gravity); 03625 pAttr->SetSquash(Squash); 03626 pAttr->SetTileable(Tileable); 03627 03628 // Actually create the fractal bitmap 03629 pAttr->SetFractalDPI(DPI); 03630 pAttr->RecalcFractal(); 03631 03632 // All worked ok. 03633 return TRUE; 03634 } 03635 03636 03637 03639 // TRANSPARENT FILLS // 03641 03642 /******************************************************************************************** 03643 03644 > BOOL Filter::SetNoTranspFill() 03645 03646 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03647 Created: 10/10/94 03648 Returns: TRUE if the fill attribute is set ok; 03649 FALSE if not (e.g. out of memory) 03650 Purpose: Set the current transparency fill for this import operation to be none, 03651 i.e. there is no transparency. 03652 Errors: Out of memory 03653 SeeAlso: Filter; Filter::Init; Filter::SetFlatTranspFill; TranspFillAttribute 03654 Note: This also (via SetFlatTranspFill) set the new painting mode attribute as well 03655 03656 ********************************************************************************************/ 03657 03658 BOOL Filter::SetNoTranspFill() 03659 { 03660 // At present, we use a flat transparent fill with 0% transparency and T type 1 for 03661 // 'no transparency'. 03662 return SetFlatTranspFill(1, 0); 03663 } 03664 03665 /******************************************************************************************** 03666 03667 > BOOL Filter::SetFlatTranspFill(UINT32 TranspType, UINT32 Transp) 03668 03669 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03670 Created: 10/10/94 03671 Inputs: TranspType - the type of transparency (1-3) 03672 Transp - the 8 bit transparency value (0-255) 03673 Returns: TRUE if the fill attribute is set ok; 03674 FALSE if not (e.g. out of memory) 03675 Purpose: Set the current transparency fill for this import operation to be a flat 03676 transparency value. 03677 Errors: Out of memory 03678 SeeAlso: Filter; Filter::Init; TranspFillAttribute 03679 03680 ********************************************************************************************/ 03681 03682 BOOL Filter::SetFlatTranspFill(UINT32 TranspType, UINT32 Transp) 03683 { 03684 // Sanity check 03685 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03686 03687 // If we haven't changed this attribute yet, then make a new attribute object for 03688 // our own personal use... 03689 if (!CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp) 03690 { 03691 // Make the correct attribute value and install it as the current one. 03692 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new FlatTranspFillAttribute; 03693 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 03694 return FALSE; 03695 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp = TRUE; 03696 } 03697 else 03698 { 03699 // Ensure we have the correct attribute 03700 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr->GetRuntimeClass() != 03701 CC_RUNTIME_CLASS(FlatTranspFillAttribute)) 03702 { 03703 // Wrong type - delete it and get the right type of attribute value. 03704 delete CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03705 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new FlatTranspFillAttribute; 03706 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 03707 return FALSE; 03708 } 03709 } 03710 03711 // We've got an attribute - change it. 03712 FlatTranspFillAttribute *pAttr = 03713 (FlatTranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03714 03715 // Copy field values. 03716 pAttr->SetTranspType(TranspType); 03717 pAttr->SetStartTransp(&Transp); 03718 03719 // All worked ok. 03720 return TRUE; 03721 } 03722 03723 /******************************************************************************************** 03724 03725 > BOOL Filter::SetLinearTranspFill(UINT32 TranspType, UINT32 StartTransp, UINT32 EndTransp, 03726 DocCoord StartPoint, DocCoord EndPoint, 03727 DocCoord *EndPoint2 = NULL) 03728 03729 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03730 Created: 13/04/94 03731 Inputs: TranspType - the type of transparency (1-3) 03732 StartTransp - the 8 bit start transparency value (0-255) 03733 EndTransp - the 8 bit end transparency value (0-255) 03734 StartPoint, EndPoint - the start and end-points of the linear fill. 03735 Returns: TRUE if the attribute was changed ok; 03736 FALSE otherwise. 03737 Purpose: Updates the current attribute for transparency fill to be a linear 03738 transparent fill as specified by the values passed in. 03739 Errors: Out of memory. 03740 SeeAlso: Filter; Filter::Init; TranspFillAttribute 03741 03742 ********************************************************************************************/ 03743 03744 BOOL Filter::SetLinearTranspFill(UINT32 TranspType, UINT32 StartTransp, UINT32 EndTransp, 03745 DocCoord StartPoint, DocCoord EndPoint, 03746 DocCoord *EndPoint2) 03747 { 03748 // Sanity check 03749 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03750 03751 // If we haven't changed this attribute yet, then make a new attribute object for 03752 // our own personal use... 03753 if (!CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp) 03754 { 03755 // Make the correct attribute value and install it as the current one. 03756 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new LinearTranspFillAttribute; 03757 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 03758 return FALSE; 03759 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp = TRUE; 03760 } 03761 else 03762 { 03763 // Ensure we have the correct attribute 03764 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr->GetRuntimeClass() != 03765 CC_RUNTIME_CLASS(LinearTranspFillAttribute)) 03766 { 03767 // Wrong type - delete it and get the right type of attribute value. 03768 delete CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03769 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new LinearTranspFillAttribute; 03770 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 03771 return FALSE; 03772 } 03773 } 03774 03775 // We've got an attribute - change it. 03776 LinearTranspFillAttribute *pAttr = 03777 (LinearTranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03778 03779 // Copy field values. 03780 pAttr->SetTranspType(TranspType); // waz 3362 03781 pAttr->SetStartTransp(&StartTransp); 03782 pAttr->SetEndTransp(&EndTransp); 03783 pAttr->SetStartPoint(&StartPoint); 03784 pAttr->SetEndPoint(&EndPoint); 03785 pAttr->SetEndPoint2(EndPoint2); 03786 03787 // All worked ok. 03788 return TRUE; 03789 } 03790 03791 /******************************************************************************************** 03792 03793 > BOOL Filter::SetRadialTranspFill(UINT32 TranspType, UINT32 StartTransp, UINT32 EndTransp, 03794 DocCoord StartPoint, DocCoord EndPoint) 03795 03796 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03797 Created: 13/04/94 03798 Inputs: TranspType - the type of transparency (1-3) 03799 StartTransp - the 8 bit start transparency value (0-255) 03800 EndTransp - the 8 bit end transparency value (0-255) 03801 StartPoint - the centre of the radial fill. 03802 EndPoint - a point on the edge of the circle defining the radial fill. 03803 Returns: TRUE if the attribute was changed ok; 03804 FALSE otherwise. 03805 Purpose: Updates the current attribute for transparency fill to be a circular 03806 transparent fill as specified by the values passed in. 03807 Errors: Out of memory. 03808 SeeAlso: Filter; Filter::Init; GradFillAttribute 03809 03810 ********************************************************************************************/ 03811 03812 BOOL Filter::SetRadialTranspFill(UINT32 TranspType, UINT32 StartTransp, UINT32 EndTransp, 03813 DocCoord StartPoint, DocCoord EndPoint) 03814 { 03815 // Call the more general function... 03816 BOOL Success = SetRadialTranspFill(TranspType, StartTransp, EndTransp, 03817 StartPoint, EndPoint, EndPoint); 03818 03819 // Set the new attribute to be a circular one, if it worked 03820 if (Success) 03821 { 03822 RadialTranspFillAttribute *pAttr = 03823 (RadialTranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03824 pAttr->MakeCircular(); 03825 } 03826 03827 return Success; 03828 } 03829 03830 /******************************************************************************************** 03831 03832 > BOOL Filter::SetRadialTranspFill(UINT32 TranspType, UINT32 StartTransp, UINT32 EndTransp, 03833 DocCoord StartPoint, 03834 DocCoord EndPoint1, DocCoord EndPoint2) 03835 03836 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03837 Created: 13/04/94 03838 Inputs: TranspType - the type of transparency (1-3) 03839 StartTransp - the 8 bit start transparency value (0-255) 03840 EndTransp - the 8 bit end transparency value (0-255) 03841 StartPoint, EndPoint, EndPoint2 - the points defining the elliptical fill. 03842 Returns: TRUE if the attribute was changed ok; 03843 FALSE otherwise. 03844 Purpose: Updates the current attribute for transparency fill to be an elliptical 03845 transparent fill as specified by the values passed in. 03846 Errors: Out of memory. 03847 SeeAlso: Filter; Filter::Init; GradFillAttribute 03848 03849 ********************************************************************************************/ 03850 03851 BOOL Filter::SetRadialTranspFill(UINT32 TranspType, UINT32 StartTransp, UINT32 EndTransp, 03852 DocCoord StartPoint, 03853 DocCoord EndPoint1, DocCoord EndPoint2) 03854 { 03855 // Sanity check 03856 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03857 03858 // If we haven't changed this attribute yet, then make a new attribute object for 03859 // our own personal use... 03860 if (!CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp) 03861 { 03862 // Make the correct attribute value and install it as the current one. 03863 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new RadialTranspFillAttribute; 03864 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 03865 return FALSE; 03866 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp = TRUE; 03867 } 03868 else 03869 { 03870 // Ensure we have the correct attribute 03871 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr->GetRuntimeClass() != 03872 CC_RUNTIME_CLASS(RadialTranspFillAttribute)) 03873 { 03874 // Wrong type - delete it and get the right type of attribute value. 03875 delete CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03876 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new RadialTranspFillAttribute; 03877 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 03878 return FALSE; 03879 } 03880 } 03881 03882 // We've got an attribute - change it. 03883 RadialTranspFillAttribute *pAttr = 03884 (RadialTranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03885 03886 // Copy field values. 03887 pAttr->SetTranspType(TranspType); // waz 3469 03888 pAttr->SetStartTransp(&StartTransp); 03889 pAttr->SetEndTransp(&EndTransp); 03890 pAttr->SetStartPoint(&StartPoint); 03891 pAttr->SetEndPoint(&EndPoint1); 03892 pAttr->SetEndPoint2(&EndPoint2); 03893 03894 // Make sure it's elliptical 03895 pAttr->MakeElliptical(); 03896 03897 // All worked ok. 03898 return TRUE; 03899 } 03900 03901 /******************************************************************************************** 03902 03903 > BOOL Filter::SetConicalTranspFill(UINT32 TranspType, UINT32 StartTransp, UINT32 EndTransp, 03904 DocCoord StartPoint, DocCoord EndPoint) 03905 03906 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03907 Created: 13/04/94 03908 Inputs: TranspType - the type of transparency (1-3) 03909 StartTransp - the 8 bit start transparency value (0-255) 03910 EndTransp - the 8 bit end transparency value (0-255) 03911 StartPoint, EndPoint - the points defining the conical fill. 03912 Returns: TRUE if the attribute was changed ok; 03913 FALSE otherwise. 03914 Purpose: Updates the current attribute for gradfill colour to reflect the value passed 03915 in. 03916 Errors: Out of memory. 03917 SeeAlso: Filter; Filter::Init; GradFillAttribute 03918 03919 ********************************************************************************************/ 03920 03921 BOOL Filter::SetConicalTranspFill(UINT32 TranspType, UINT32 StartTransp, UINT32 EndTransp, 03922 DocCoord StartPoint, DocCoord EndPoint) 03923 { 03924 // Sanity check 03925 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03926 03927 // If we haven't changed this attribute yet, then make a new attribute object for 03928 // our own personal use... 03929 if (!CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp) 03930 { 03931 // Make the correct attribute value and install it as the current one. 03932 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new ConicalTranspFillAttribute; 03933 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 03934 return FALSE; 03935 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp = TRUE; 03936 } 03937 else 03938 { 03939 // Ensure we have the correct attribute 03940 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr->GetRuntimeClass() != 03941 CC_RUNTIME_CLASS(ConicalTranspFillAttribute)) 03942 { 03943 // Wrong type - delete it and get the right type of attribute value. 03944 delete CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03945 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new ConicalTranspFillAttribute; 03946 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 03947 return FALSE; 03948 } 03949 } 03950 03951 // We've got an attribute - change it. 03952 ConicalTranspFillAttribute *pAttr = 03953 (ConicalTranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 03954 03955 // Copy field values. 03956 pAttr->SetTranspType(TranspType); // waz 3538 03957 pAttr->SetStartTransp(&StartTransp); 03958 pAttr->SetEndTransp(&EndTransp); 03959 pAttr->SetStartPoint(&StartPoint); 03960 pAttr->SetEndPoint(&EndPoint); 03961 03962 // All worked ok. 03963 return TRUE; 03964 } 03965 03966 /******************************************************************************************** 03967 03968 > BOOL Filter::SetBitmapTranspFill(UINT32 TranspType, KernelBitmap *pBitmap, 03969 DocCoord StartPoint, 03970 DocCoord EndPoint, DocCoord EndPoint2, 03971 UINT32 StartTransp = 0, UINT32 EndTransp = 255) 03972 03973 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 03974 Created: 23/08/94 03975 Inputs: TranspType - the type of transparency (1-3) 03976 pBitmap - pointer to the bitmap object to fill with. 03977 StartPoint, EndPoint, EndPoint2 - see BitmapTranspFillAttribute. 03978 Returns: TRUE if the attribute was changed ok; 03979 FALSE otherwise. 03980 Purpose: Updates the current attribute for fill colour to reflect the value passed 03981 in. 03982 Errors: Out of memory. 03983 SeeAlso: Filter; Filter::Init; BitmapFillAttribute 03984 03985 ********************************************************************************************/ 03986 03987 BOOL Filter::SetBitmapTranspFill(UINT32 TranspType, KernelBitmap *pBitmap, 03988 DocCoord StartPoint, DocCoord EndPoint, DocCoord EndPoint2, 03989 UINT32 StartTransp, UINT32 EndTransp) 03990 { 03991 // Sanity check 03992 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 03993 03994 // If we haven't changed this attribute yet, then make a new attribute object for 03995 // our own personal use... 03996 if (!CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp) 03997 { 03998 // Make the correct attribute value and install it as the current one. 03999 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new BitmapTranspFillAttribute; 04000 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 04001 return FALSE; 04002 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp = TRUE; 04003 } 04004 else 04005 { 04006 // Ensure we have the correct attribute 04007 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr->GetRuntimeClass() != 04008 CC_RUNTIME_CLASS(BitmapTranspFillAttribute)) 04009 { 04010 // Wrong type - delete it and get the right type of attribute value. 04011 delete CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 04012 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new BitmapTranspFillAttribute; 04013 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 04014 return FALSE; 04015 } 04016 } 04017 04018 // We've got an attribute - change it. 04019 BitmapTranspFillAttribute *pAttr = 04020 (BitmapTranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 04021 04022 // Copy field values. 04023 pAttr->SetTranspType(TranspType); // waz 3606 04024 pAttr->SetStartTransp(&StartTransp); 04025 pAttr->SetEndTransp(&EndTransp); 04026 04027 pAttr->SetStartPoint(&StartPoint); 04028 pAttr->SetEndPoint(&EndPoint); 04029 pAttr->SetEndPoint2(&EndPoint2); 04030 04031 GetDocument()->SetCurrent(); 04032 // pAttr->AttachBitmap(pBitmap); 04033 pAttr->GetBitmapRef()->Attach(pBitmap, GetDocument()); 04034 04035 if (pAttr->GetBitmap() != pBitmap) 04036 { 04037 // It didn't use the bitmap we gave it, so we can delete it 04038 delete pBitmap; 04039 } 04040 04041 // All worked ok. 04042 return TRUE; 04043 } 04044 04045 /******************************************************************************************** 04046 04047 > BOOL Filter::SetFractalTranspFill(UINT32 TranspType, 04048 DocCoord StartPoint, DocCoord EndPoint1, DocCoord EndPoint2, 04049 INT32 Seed, double Graininess, double Gravity, double Squash, 04050 UINT32 DPI, BOOL Tileable, 04051 UINT32 StartTransp = 0, UINT32 EndTransp = 255) 04052 04053 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04054 Created: 08/11/94 04055 Inputs: TranspType - the type of transparency (1-3) 04056 StartPoint, EndPoint1, EndPoint2 - co-ordinates of the fill mesh 04057 Seed, Graininess, Gravity, Squash - strange fractal parameters 04058 DPI - the resolution of the fractal bitmap (dots per inch). 04059 Tileable - whether the fractal bitmap is tileable or not (ask Alex). 04060 Returns: TRUE if the attribute was changed ok; 04061 FALSE otherwise => ERROR1 04062 Purpose: Updates the current attribute for colour fill geometry to be a fractal fill 04063 using the values passed in. 04064 Errors: Out of memory => ERROR1 04065 SeeAlso: Filter; Filter::Init; FractalFillAttribute 04066 04067 ********************************************************************************************/ 04068 04069 BOOL Filter::SetFractalTranspFill(UINT32 TranspType, 04070 DocCoord StartPoint, DocCoord EndPoint1, DocCoord EndPoint2, 04071 INT32 Seed, double Graininess, double Gravity, double Squash, 04072 UINT32 DPI, BOOL Tileable, 04073 UINT32 StartTransp, UINT32 EndTransp) 04074 { 04075 // Sanity check 04076 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 04077 04078 // If we haven't changed this attribute yet, then make a new attribute object for 04079 // our own personal use... 04080 if (!CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp) 04081 { 04082 // Make the correct attribute value and install it as the current one. 04083 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new FractalTranspFillAttribute; 04084 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 04085 return FALSE; 04086 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].Temp = TRUE; 04087 } 04088 else 04089 { 04090 // Ensure we have the correct attribute 04091 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr->GetRuntimeClass() != 04092 CC_RUNTIME_CLASS(FractalTranspFillAttribute)) 04093 { 04094 // Wrong type - delete it and get the right type of attribute value. 04095 delete CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 04096 CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr = new FractalTranspFillAttribute; 04097 if (CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr == NULL) 04098 return FALSE; 04099 } 04100 } 04101 04102 // We've got an attribute - change it. 04103 FractalTranspFillAttribute *pAttr = 04104 (FractalTranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 04105 04106 // Copy field values. 04107 pAttr->SetTranspType(TranspType); // waz 3690 04108 pAttr->SetStartTransp(&StartTransp); 04109 pAttr->SetEndTransp(&EndTransp); 04110 04111 pAttr->SetStartPoint(&StartPoint); 04112 pAttr->SetEndPoint(&EndPoint1); 04113 pAttr->SetEndPoint2(&EndPoint2); 04114 04115 pAttr->SetSeed(Seed); 04116 pAttr->SetGraininess(Graininess); 04117 pAttr->SetGravity(Gravity); 04118 pAttr->SetSquash(Squash); 04119 pAttr->SetTileable(Tileable); 04120 04121 // Actually create the fractal bitmap 04122 pAttr->SetFractalDPI(DPI); 04123 pAttr->RecalcFractal(); 04124 04125 // All worked ok. 04126 return TRUE; 04127 } 04128 04129 04130 04131 BOOL Filter::SetFadeFillEffect() 04132 { 04133 // Sanity check 04134 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 04135 04136 // If we haven't changed this attribute yet, then make a new attribute object for 04137 // our own personal use... 04138 if (!CurrentAttrs[ATTR_FILLEFFECT].Temp) 04139 { 04140 // Make the correct attribute value and install it as the current one. 04141 CurrentAttrs[ATTR_FILLEFFECT].pAttr = new FillEffectFadeAttribute; 04142 if (CurrentAttrs[ATTR_FILLEFFECT].pAttr == NULL) 04143 return FALSE; 04144 CurrentAttrs[ATTR_FILLEFFECT].Temp = TRUE; 04145 } 04146 else 04147 { 04148 // Ensure we have the correct attribute 04149 if (!IS_A(CurrentAttrs[ATTR_FILLEFFECT].pAttr, FillEffectFadeAttribute)) 04150 { 04151 // Wrong type - delete it and get the right type of attribute value. 04152 delete CurrentAttrs[ATTR_FILLEFFECT].pAttr; 04153 CurrentAttrs[ATTR_FILLEFFECT].pAttr = new FillEffectFadeAttribute; 04154 if (CurrentAttrs[ATTR_FILLEFFECT].pAttr == NULL) 04155 return FALSE; 04156 } 04157 } 04158 04159 // All worked ok. 04160 return TRUE; 04161 } 04162 04163 BOOL Filter::SetRainbowFillEffect() 04164 { 04165 // Sanity check 04166 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 04167 04168 // If we haven't changed this attribute yet, then make a new attribute object for 04169 // our own personal use... 04170 if (!CurrentAttrs[ATTR_FILLEFFECT].Temp) 04171 { 04172 // Make the correct attribute value and install it as the current one. 04173 CurrentAttrs[ATTR_FILLEFFECT].pAttr = new FillEffectRainbowAttribute; 04174 if (CurrentAttrs[ATTR_FILLEFFECT].pAttr == NULL) 04175 return FALSE; 04176 CurrentAttrs[ATTR_FILLEFFECT].Temp = TRUE; 04177 } 04178 else 04179 { 04180 // Ensure we have the correct attribute 04181 if (!IS_A(CurrentAttrs[ATTR_FILLEFFECT].pAttr, FillEffectRainbowAttribute)) 04182 { 04183 // Wrong type - delete it and get the right type of attribute value. 04184 delete CurrentAttrs[ATTR_FILLEFFECT].pAttr; 04185 CurrentAttrs[ATTR_FILLEFFECT].pAttr = new FillEffectRainbowAttribute; 04186 if (CurrentAttrs[ATTR_FILLEFFECT].pAttr == NULL) 04187 return FALSE; 04188 } 04189 } 04190 04191 // All worked ok. 04192 return TRUE; 04193 } 04194 04195 BOOL Filter::SetAltRainbowFillEffect() 04196 { 04197 // Sanity check 04198 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 04199 04200 // If we haven't changed this attribute yet, then make a new attribute object for 04201 // our own personal use... 04202 if (!CurrentAttrs[ATTR_FILLEFFECT].Temp) 04203 { 04204 // Make the correct attribute value and install it as the current one. 04205 CurrentAttrs[ATTR_FILLEFFECT].pAttr = new FillEffectAltRainbowAttribute; 04206 if (CurrentAttrs[ATTR_FILLEFFECT].pAttr == NULL) 04207 return FALSE; 04208 CurrentAttrs[ATTR_FILLEFFECT].Temp = TRUE; 04209 } 04210 else 04211 { 04212 // Ensure we have the correct attribute 04213 if (!IS_A(CurrentAttrs[ATTR_FILLEFFECT].pAttr, FillEffectAltRainbowAttribute)) 04214 { 04215 // Wrong type - delete it and get the right type of attribute value. 04216 delete CurrentAttrs[ATTR_FILLEFFECT].pAttr; 04217 CurrentAttrs[ATTR_FILLEFFECT].pAttr = new FillEffectAltRainbowAttribute; 04218 if (CurrentAttrs[ATTR_FILLEFFECT].pAttr == NULL) 04219 return FALSE; 04220 } 04221 } 04222 04223 // All worked ok. 04224 return TRUE; 04225 } 04226 04227 04228 BOOL Filter::SetLinearFillMapping(INT32 Repeat) 04229 { 04230 // Sanity check 04231 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 04232 ERROR3IF((Repeat < 0) || (Repeat > 3),"Bad mapping repeat in SetLinearFillMapping()"); 04233 04234 // If we haven't changed this attribute yet, then make a new attribute object for 04235 // our own personal use... 04236 if (!CurrentAttrs[ATTR_FILLMAPPING].Temp) 04237 { 04238 // Make the correct attribute value and install it as the current one. 04239 CurrentAttrs[ATTR_FILLMAPPING].pAttr = new FillMappingLinearAttribute; 04240 if (CurrentAttrs[ATTR_FILLMAPPING].pAttr == NULL) 04241 return FALSE; 04242 CurrentAttrs[ATTR_FILLMAPPING].Temp = TRUE; 04243 } 04244 else 04245 { 04246 // Ensure we have the correct attribute 04247 if (!IS_A(CurrentAttrs[ATTR_FILLMAPPING].pAttr, FillMappingLinearAttribute)) 04248 { 04249 // Wrong type - delete it and get the right type of attribute value. 04250 delete CurrentAttrs[ATTR_FILLMAPPING].pAttr; 04251 CurrentAttrs[ATTR_FILLMAPPING].pAttr = new FillMappingLinearAttribute; 04252 if (CurrentAttrs[ATTR_FILLMAPPING].pAttr == NULL) 04253 return FALSE; 04254 } 04255 } 04256 04257 // Set the repeat state 04258 FillMappingLinearAttribute *pAttr = 04259 (FillMappingLinearAttribute *) CurrentAttrs[ATTR_FILLMAPPING].pAttr; 04260 pAttr->Repeat = Repeat; 04261 04262 // ******************************************************************* 04263 // Added by Will 12/2/95 04264 // Bitmap and Fractal tesselation does not appear to be being saved. 04265 // This code ensures that the repeat and tesselation values matach up. 04266 04267 FillGeometryAttribute* pCurrentFill = 04268 (FillGeometryAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr; 04269 04270 if (pCurrentFill != NULL) 04271 pCurrentFill->SetTesselation(Repeat); 04272 04273 // ******************************************************************* 04274 04275 // All worked ok. 04276 return TRUE; 04277 } 04278 04279 04280 BOOL Filter::SetLinearTranspFillMapping(INT32 Repeat) 04281 { 04282 // Sanity check 04283 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 04284 ERROR3IF((Repeat < 0) || (Repeat > 3),"Bad mapping repeat in SetLinearTranspFillMapping()"); 04285 04286 // If we haven't changed this attribute yet, then make a new attribute object for 04287 // our own personal use... 04288 if (!CurrentAttrs[ATTR_TRANSPFILLMAPPING].Temp) 04289 { 04290 // Make the correct attribute value and install it as the current one. 04291 CurrentAttrs[ATTR_TRANSPFILLMAPPING].pAttr = new TranspFillMappingLinearAttribute; 04292 if (CurrentAttrs[ATTR_TRANSPFILLMAPPING].pAttr == NULL) 04293 return FALSE; 04294 CurrentAttrs[ATTR_TRANSPFILLMAPPING].Temp = TRUE; 04295 } 04296 else 04297 { 04298 // Ensure we have the correct attribute 04299 if (!IS_A(CurrentAttrs[ATTR_TRANSPFILLMAPPING].pAttr, TranspFillMappingLinearAttribute)) 04300 { 04301 // Wrong type - delete it and get the right type of attribute value. 04302 delete CurrentAttrs[ATTR_TRANSPFILLMAPPING].pAttr; 04303 CurrentAttrs[ATTR_TRANSPFILLMAPPING].pAttr = new TranspFillMappingLinearAttribute; 04304 if (CurrentAttrs[ATTR_TRANSPFILLMAPPING].pAttr == NULL) 04305 return FALSE; 04306 } 04307 } 04308 04309 // Set the repeat state 04310 TranspFillMappingLinearAttribute *pAttr = 04311 (TranspFillMappingLinearAttribute *) CurrentAttrs[ATTR_TRANSPFILLMAPPING].pAttr; 04312 pAttr->Repeat = Repeat; 04313 04314 // ******************************************************************* 04315 // Added by Will 12/2/95 04316 // Bitmap and Fractal tesselation does not appear to be being saved. 04317 // This code ensures that the repeat and tesselation values matach up. 04318 04319 TranspFillAttribute* pCurrentFill = 04320 (TranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr; 04321 04322 if (pCurrentFill != NULL) 04323 pCurrentFill->SetTesselation(Repeat); 04324 04325 // ******************************************************************* 04326 04327 // All worked ok. 04328 return TRUE; 04329 } 04330 04331 04332 /******************************************************************************************** 04333 04334 > BOOL Filter::SetWindingRule(WindingType WindingRule) 04335 04336 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04337 Created: 13/04/94 04338 Inputs: WindingRule - the new winding rule to use. 04339 Returns: TRUE if the attribute was changed ok; 04340 FALSE otherwise. 04341 Purpose: Updates the current attribute for winding rule to reflect the value passed 04342 in. 04343 Errors: Out of memory. 04344 SeeAlso: Filter; Filter::Init; WindingType 04345 04346 ********************************************************************************************/ 04347 04348 BOOL Filter::SetWindingRule(WindingType WindingRule) 04349 { 04350 // Sanity check 04351 ENSURE(CurrentAttrs != NULL, "No current attributes in filter!"); 04352 04353 // If we haven't changed this attribute yet, then make a new attribute object for 04354 // our own personal use... 04355 if (!CurrentAttrs[ATTR_WINDINGRULE].Temp) 04356 { 04357 // Make the correct attribute value and install it as the current one. 04358 CurrentAttrs[ATTR_WINDINGRULE].pAttr = new WindingRuleAttribute(WindingRule); 04359 if (CurrentAttrs[ATTR_WINDINGRULE].pAttr == NULL) 04360 return FALSE; 04361 CurrentAttrs[ATTR_WINDINGRULE].Temp = TRUE; 04362 } 04363 else 04364 { 04365 // We already have an attribute - just change it. 04366 WindingRuleAttribute *pAttr = 04367 (WindingRuleAttribute *) CurrentAttrs[ATTR_WINDINGRULE].pAttr; 04368 pAttr->WindingRule = WindingRule; 04369 } 04370 04371 // All worked ok. 04372 return TRUE; 04373 } 04374 04375 /******************************************************************************************** 04376 04377 > virtual BOOL Filter::GetDragAndDropTranslation(ImportPosition *pPos, DocRect BoundsRect, 04378 Coord* Offset) 04379 04380 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04381 Created: 04/10/94 04382 Inputs: pSpread - the spread to check against. 04383 BoundsRect - the bounding rectangle to check (in spread coordinates). 04384 Outputs: Offset - 04385 Returns: TRUE if the bounding rectangle is smaller than the spread => Offset now 04386 contains the translation necessary to position the objects correctly. 04387 FALSE if bounding rectangle is bigger than the spread, or pPos was NULL. 04388 In either case, a FALSE return results in Offset containing (0,0). 04389 Purpose: Given an drag'n'drop point (in pPos), calculate the translation necessary 04390 to position the imported objects at this position on the spread. It ensures 04391 that bounding rectangles smaller than the spread are wholly contained within 04392 the spread. i.e. if you drag a file right to the edge of a spread, the 04393 translation will move it closer to the centre of the spread so that it is 04394 wholly contained within the spread. 04395 04396 Used by the import filters for drag'n'drop to ensure that after the 04397 imported objects are translated to the drop point, they are all still 04398 on the spread. 04399 Made virtual 20/5/97. 04400 SeeAlso: Filter::DoImport 04401 04402 ********************************************************************************************/ 04403 04404 BOOL Filter::GetDragAndDropTranslation(ImportPosition *pPos, DocRect BoundsRect, 04405 Coord* Offset) 04406 { 04407 #if !defined(EXCLUDE_FROM_RALPH) 04408 // First check to se if we actually have a drag and drop point. 04409 if (pPos == NULL) 04410 { 04411 // No - set offset to 0 and return FALSE to indicate we can't cope with this. 04412 Offset->x = 0; 04413 Offset->y = 0; 04414 return FALSE; 04415 } 04416 04417 // Get the spread's bounding rectangle and convert it to spread coords. 04418 DocRect SpreadRect = pPos->pSpread->GetPasteboardRect(); 04419 pPos->pSpread->DocCoordToSpreadCoord(&SpreadRect); 04420 04421 #if defined( DODGY_BITMAP_POS_CODE ) 04422 // Now check that the bounding rectangle is small enough to fit on the spread... 04423 if ((BoundsRect.Width() > SpreadRect.Width()) || 04424 (BoundsRect.Height() > SpreadRect.Height())) 04425 { 04426 // No - set offset to 0 and return FALSE to indicate we can't cope with this. 04427 Offset->x = 0; 04428 Offset->y = 0; 04429 return FALSE; 04430 } 04431 #endif 04432 04433 // Bounding box should be centred on drop point 04434 DocCoord Centre; 04435 Centre.x = (BoundsRect.lo.x + BoundsRect.hi.x) / 2; 04436 Centre.y = (BoundsRect.lo.y + BoundsRect.hi.y) / 2; 04437 04438 Offset->x = pPos->Position.x - Centre.x; 04439 Offset->y = pPos->Position.y - Centre.y; 04440 04441 // Transform the bounding rect to see if it's off the spread. 04442 BoundsRect.Translate(Offset->x, Offset->y); 04443 04444 // If it's off the spread - limit it to the edge of the spread: 04445 04446 // (a) Horizontal adjustment 04447 if (BoundsRect.lo.x < SpreadRect.lo.x) 04448 Offset->x += (SpreadRect.lo.x - BoundsRect.lo.x); 04449 else if (BoundsRect.hi.x > SpreadRect.hi.x) 04450 Offset->x -= (BoundsRect.hi.x - SpreadRect.hi.x); 04451 04452 // (b) Vertical adjustment (most useful to clip hi co-ords) 04453 if (BoundsRect.hi.y > SpreadRect.hi.y) 04454 Offset->y -= (BoundsRect.hi.y - SpreadRect.hi.y); 04455 else if (BoundsRect.lo.y < SpreadRect.lo.y) 04456 Offset->y += (SpreadRect.lo.y - BoundsRect.lo.y); 04457 04458 // Whatever happened, we can fit it on the spread. 04459 return TRUE; 04460 #else 04461 Offset->x = 0; 04462 Offset->y = 0; 04463 return FALSE; 04464 #endif 04465 } 04466 04467 /******************************************************************************************** 04468 04469 > virtual BOOL Filter::WillAcceptExistingFile(PathName pthToReplace) 04470 04471 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 04472 Created: 9/5/97 04473 Returns: TRUE if this filter is willing to accept this existing file 04474 FALSE otherwise 04475 Purpose: Checks to see if this filter will accept an existing file to export 04476 to. 04477 04478 This base version will simply ask the user if she wants to overwrite 04479 the file. 04480 04481 But ImagemapFilter::WillAcceptExistingFile will override this 04482 so the user can insert an imagemap into an existing HTML file. 04483 04484 ********************************************************************************************/ 04485 04486 BOOL Filter::WillAcceptExistingFile(PathName pthToReplace) 04487 { 04488 PORTNOTETRACE("filter","Filter::WillAcceptExistingFile - do nothing"); 04489 #ifndef EXCLUDE_FROM_XARALX 04490 //We're going to put up a message box to ask the user if she wants to 04491 //replace the existing file. 04492 04493 //So first get the truncated path name 04494 String_256 strToReplace = pthToReplace.GetTruncatedPath(50); 04495 04496 //Now create a string to put our error message in 04497 String_256 strError; 04498 04499 //And make the error message up using the file name 04500 strError.MakeMsg(_R(IDM_EXPORT_OVERWRITE), &strToReplace); 04501 04502 //Now, set that error message as the next one to display 04503 Error::SetError( 0, strError, 0 ); 04504 04505 //And set up the message help context 04506 SetNextMsgHelpContext(_R(IDM_EXPORT_OVERWRITE)); 04507 04508 //Now set up the buttons 04509 ErrorInfo Info; 04510 Info.Button[0] = _R(IDB_OVERWRITE); 04511 Info.Button[1] = _R(IDS_CANCEL); 04512 04513 //Make "cancel" the default 04514 Info.OK = Info.Cancel = 2; 04515 04516 //And put the error box up 04517 switch (AskQuestion( &Info )) 04518 { 04519 case _R(IDS_CANCEL): 04520 return FALSE; 04521 04522 case _R(IDB_OVERWRITE): 04523 default: 04524 return TRUE; 04525 } 04526 #endif 04527 return false; 04528 } 04529 04530 /******************************************************************************************** 04531 04532 > virtual void Filter::SetSaveAttributes ( BOOL DoSave ) 04533 04534 Author: Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com> 04535 Created: 14/3/00 04536 Inputs: DoSave - Should the attributes be saved along with the file data? 04537 Returns: - 04538 Purpose: Informs the filter whether or not it should record the attribute settings 04539 along with the file data. This allows templates to have default colours other 04540 than the standard Camelot values, whilst not encumbering save files with this 04541 extra information. 04542 ********************************************************************************************/ 04543 04544 void Filter::SetSaveAttributes ( BOOL DoSave ) 04545 { 04546 SaveAttributes = DoSave; 04547 } 04548 04549 /******************************************************************************************** 04550 04551 > CompatibleFilter::CompatibleFilter(Filter *NewFilter, INT32 NewCompatibility) 04552 04553 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04554 Created: 28/03/94 04555 Inputs: NewFilter - the filter to add to the list. 04556 NewCompatibility - the compatibility rating for this filter. 04557 Purpose: Initialises a list item for a CompatibleFilterList. 04558 SeeAlso: CompatibleFilter 04559 04560 ********************************************************************************************/ 04561 04562 CompatibleFilter::CompatibleFilter(Filter *NewFilter, INT32 NewCompatibility) 04563 { 04564 pFilter = NewFilter; 04565 Compatibility = NewCompatibility; 04566 } 04567 04568 04569 04570 CC_IMPLEMENT_MEMDUMP(CompatibleFilter, ListItem) 04571 CC_IMPLEMENT_MEMDUMP(CompatibleFilterList, List) 04572 04573 04574 04575 /******************************************************************************************** 04576 04577 > BOOL CompatibleFilterList::AddFilter(Filter *pFilter, INT32 Compatibility) 04578 04579 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04580 Created: 28/03/94 04581 Inputs: pFilter - the filter to add to the list. 04582 Compatibility - the compatibility rating of the filter. 04583 Returns: TRUE if the filter was added to the list ok; FALSE if not. 04584 Purpose: Add a new item to the compatible filter list, which points to the given 04585 filter, and stores the given compatibility rating in the list entry. 04586 The list is kept in sorted order, i.e. the list item is added to the list 04587 according to its compatibility rating; the higher the rating, the closer 04588 it is to the head of the list. 04589 Errors: Out of memory. 04590 SeeAlso: ComaptibleFilterList; CompatibleFilter 04591 04592 ********************************************************************************************/ 04593 04594 BOOL CompatibleFilterList::AddFilter(Filter *pFilter, INT32 Compatibility) 04595 { 04596 // Make a new list item for this filter. 04597 CompatibleFilter *pNewItem = new CompatibleFilter(pFilter, Compatibility); 04598 if (pNewItem == NULL) 04599 return FALSE; 04600 04601 // Search for the correct place in the list 04602 CompatibleFilter *pItem = (CompatibleFilter *) GetHead(); 04603 04604 while ((pItem != NULL) && (pItem->Compatibility > Compatibility)) 04605 pItem = (CompatibleFilter *) GetNext(pItem); 04606 04607 // If come to the end of the list, add it to the end, otherwise add before the 04608 // current item 04609 if (pItem == NULL) 04610 AddTail(pNewItem); 04611 else 04612 InsertBefore(pItem, pNewItem); 04613 04614 // All ok 04615 return TRUE; 04616 } 04617 04618 /******************************************************************************************** 04619 04620 > FilterFamily::FilterFamily() 04621 04622 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04623 Created: 28/03/94 04624 Purpose: Initialise the FilterFamily object. This can import but not export. 04625 SeeAlso: FilterFamily; Filter 04626 04627 ********************************************************************************************/ 04628 04629 FilterFamily::FilterFamily() 04630 { 04631 // We can import, but not export. 04632 Flags.CanImport = TRUE; 04633 Flags.CanExport = FALSE; 04634 Flags.CanExportMultipleImages = FALSE; 04635 04636 pCachedBestFilter = NULL; 04637 } 04638 04639 /******************************************************************************************** 04640 04641 > FilterFamily::~FilterFamily() 04642 04643 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04644 Created: 28/03/94 04645 Purpose: Destructor for FilterFamily object. Does nothing at present. 04646 SeeAlso: FilterFamily 04647 04648 ********************************************************************************************/ 04649 04650 FilterFamily::~FilterFamily() 04651 { 04652 } 04653 04654 04655 04656 /******************************************************************************************** 04657 04658 > INT32 FilterFamily::HowCompatible(PathName& Filename, 04659 ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize); 04660 04661 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04662 Created: 28/03/94 04663 Inputs: As base class version. 04664 Returns: Always returns 0 => don't understand file. 04665 Purpose: Returns 0, to indicate that this filter does not recognise the file. 04666 This is because this is not a 'proper' import filter - it's just pretending 04667 to be a number of the other filters joined into one. 04668 SeeAlso: FilterFamily; Filter::HowCompatible 04669 04670 ********************************************************************************************/ 04671 04672 INT32 FilterFamily::HowCompatible(PathName& Filename, 04673 ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize) 04674 04675 { 04676 return 0; 04677 } 04678 04679 04680 /******************************************************************************************** 04681 04682 > Filter* FilterFamily::GetBestFilter(CCLexFile* pFile, BOOL ShowWarnings = FALSE) 04683 04684 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04685 Created: 9/10/95 04686 Inputs: pFile the file to be checked 04687 ShowWarnings TRUE shows a message box if the best filter is found is 04688 not perfect for this file. (added 1/2/01 ChrisG) 04689 Returns: pointer to the best filter found or NULL if none found. 04690 Purpose: Works out the best filter to use for the specified file by asking all the 04691 filters in turn whether it recognises the file. 04692 Errors: Out of memory, File not recognised. 04693 SeeAlso: FilterFamily::DoImport; FilterFamily::IsDefaultDocRequired; 04694 SeeAlso: Filter::IsDefaultDocRequired; 04695 04696 ********************************************************************************************/ 04697 04698 // Graeme (28/6/00) - Because AI9 files have a load of junk at their start, the original 04699 // 1kb file header just isn't big enough. I've extended it to 8kb (which should fit nicely 04700 // into the cache), to cover for this. 04701 #define FILTER_HDRSIZE (8192) 04702 04703 Filter* FilterFamily::GetBestFilter(CCLexFile* pFile, BOOL ShowWarnings /*= FALSE*/) 04704 { 04705 ERROR2IF(pFile == NULL, NULL, "FilterFamily::GetBestFilter NULL CCFile* supplied"); 04706 04707 // Load the first 1k of the file. 04708 UINT32 SegmentSize = FILTER_HDRSIZE; 04709 size_t FileSize; 04710 ADDR FilterBuf = LoadInitialSegment(pFile, &SegmentSize, &FileSize); 04711 04712 // Error occured when accessing file 04713 if (FilterBuf == NULL) 04714 return NULL; 04715 04716 #if FALSE 04717 { 04718 DWORD* pDWord = (DWORD*) FilterBuf; 04719 BYTE* pByte = (BYTE*) FilterBuf; 04720 04721 TRACE( _T("Initial segment\n")); 04722 04723 for (UINT32 i = 0; i < 16; i++) 04724 { 04725 char c0 = isprint(pByte[0])?pByte[0]:'.'; 04726 char c1 = isprint(pByte[1])?pByte[1]:'.'; 04727 char c2 = isprint(pByte[2])?pByte[2]:'.'; 04728 char c3 = isprint(pByte[3])?pByte[3]:'.'; 04729 04730 TRACE( _T("%04x : %08x "), (i*4), pDWord[0]); 04731 TRACE( _T("%02x %02x %02x %02x "), pByte[0], pByte[1], pByte[2], pByte[3]); 04732 TRACE( _T("%c%c%c%c\n"), c0, c1, c2, c3); 04733 pDWord += 1; 04734 pByte += 4; 04735 } 04736 } 04737 #endif 04738 04739 // Try to create a file-path from the file. Some files don't have a notion of a 04740 // path, for these ones we will use a blank string. 04741 PathName Path = pFile->GetPathName(); 04742 04743 // Create a list of all the filters that understand this file to one degree or 04744 // another, sorted on how much they like the file. 04745 CompatibleFilterList Filters; 04746 04747 Filter* pFilter = Filter::GetFirst(); 04748 while (pFilter != NULL) 04749 { 04750 // Inform any filters that we are about to do a HowCompatible call. 04751 // This would allow a set of filters which have common functionality hidden in a 04752 // filter that cannot import and cannot export handle this call and hence set 04753 // itself up. This would allow it to maybe cache a result which should only be 04754 // checked by the first filter in the group. 04755 if (pFilter->JoinFamily(pFilterType) && (!pFilter->GetFlags().CanImport)) 04756 /*BOOL ok =*/ pFilter->PreHowCompatible(); 04757 04758 if (pFilter->GetFlags().CanImport && pFilter->JoinFamily(pFilterType)) 04759 { 04760 // This is an import filter which belongs to our family - ask it if it 04761 // understands this file. 04762 INT32 Compatibility = pFilter->HowCompatible(Path, FilterBuf, SegmentSize, 04763 (UINT32) FileSize); 04764 04765 // RELTRACE( _T("Filter %s - Compatibility %d\n"), (LPCTSTR)pFilter->FilterName, (INT32)Compatibility); 04766 if (Compatibility > 0) 04767 { 04768 // Add this filter to the list 04769 if (Filters.AddFilter(pFilter, Compatibility) == FALSE) 04770 { 04771 // Error has occured - clean up our objects and return error 04772 CCFree(FilterBuf); 04773 Filters.DeleteAll(); 04774 return NULL; 04775 } 04776 } 04777 } 04778 04779 // Get the next filter. 04780 pFilter = Filter::GetNext(pFilter); 04781 } 04782 04783 04784 // added by Ben to avoid the MacPaint filter grabbing everything 04785 CompatibleFilter* pCFilter = (CompatibleFilter *)Filters.GetHead(); 04786 04787 // run through all the filters to see if their extensions match 04788 CompatibleFilter* pBestFilter = NULL; 04789 CompatibleFilter* pSecondBestFilter = NULL; 04790 04791 /* BOOL fPathValid = Path.IsValid(); 04792 TRACEUSER( "JustinF", _T("File path is %s\n"), 04793 (LPCTSTR) (fPathValid ? Path.GetPath() : "INVALID")); 04794 */ 04795 04796 INT32 bestCompatibility = 0; 04797 while(pCFilter != NULL) 04798 { 04799 PORTNOTE("filter","Removed OILFilter usage") 04800 #ifndef EXCLUDE_FROM_XARALX 04801 // (ChrisG 22/01/01) File extension matching is now done for all of the filters, 04802 // regardless of their current comaptibility score. If one is found that doesn't 04803 // have the correct extension, then we subtract one from that filter's score. 04804 // 04805 // This allows dodgy EPS files to have a better chance of getting the right 04806 // filter without having to give any indication of what format they're in other than 04807 // the file extension. 04808 // 04809 // NOTE: This check is only done if the path is valid. 04810 if (fPathValid && !pCFilter->pFilter->pOILFilter->DoesExtensionOfFileMatch(pFile)) 04811 { 04812 pCFilter->Compatibility --; 04813 } 04814 #endif 04815 // If this filter has a higher compatibility than the current best, make this the new 04816 // "best filter" and relegate the other to second best. 04817 if (pCFilter->Compatibility >= bestCompatibility) 04818 { 04819 pSecondBestFilter = pBestFilter; 04820 pBestFilter = pCFilter; 04821 bestCompatibility = pCFilter->Compatibility; 04822 } 04823 // if this isn't the best, but IS better than the previous best, then update SecondBest. 04824 else if (pSecondBestFilter != NULL) 04825 { 04826 if (pCFilter->Compatibility >= pSecondBestFilter->Compatibility) 04827 { 04828 pSecondBestFilter = pCFilter; 04829 } 04830 } 04831 04832 pCFilter = (CompatibleFilter*) Filters.GetNext(pCFilter); 04833 } 04834 04835 // BODGE: 04836 // For now, just choose the filter at the head of the list. 04837 // We should check for the compatibility being less than 10 and provide a scrolly list 04838 // for the user to choose from if more than one filter is interested. 04839 // 04840 // Improved 16/10/2000 by ChrisG - added a scan for the best possible compatibility, so 04841 // that the filter's position in the list is not quite as important as it was. Although a 04842 // dialog with a list box filled with the results and compatibilities would be better. 04843 // 04844 // Note: SecondBestFilter is a bit of an irrelevance now, but may be useful for debugging 04845 // purposes 04846 04847 if (pBestFilter == NULL) 04848 { 04849 // If we have a second best filter then choose it 04850 if (pSecondBestFilter != NULL) 04851 pBestFilter = pSecondBestFilter; 04852 else 04853 { 04854 pBestFilter = (CompatibleFilter*) Filters.GetHead(); 04855 TRACE( _T("Couldn't find best filter in FilterFamily::GetBestFilter\n")); 04856 } 04857 } 04858 04859 if (pBestFilter == NULL) 04860 { 04861 #ifdef STANDALONE 04862 // if this is the standalone version, see if it's an EPS file we just tried 04863 if(camStrncmp((char*) FilterBuf, "%!PS-Adobe", 10) == 0) 04864 { 04865 Error::SetError(_R(IDT_NOTTHISEPS)); 04866 CCFree(FilterBuf); 04867 Filters.DeleteAll(); 04868 return NULL; 04869 } 04870 #endif 04871 // None of the filters liked this file - tell the user 04872 CCFree(FilterBuf); 04873 Filters.DeleteAll(); 04874 Error::SetError(_R(IDT_FILE_NOTRECOGNISED)); 04875 return NULL; 04876 } 04877 04878 // (ChrisG 1/2/01) if this filter is not perfectly compatible, tell the user, 04879 // if we're showing warnings 04880 if (pBestFilter->Compatibility < 9) 04881 { 04882 if (ShowWarnings) 04883 InformWarning (_R(IDT_IMPORTFILTER_NOTPERFECT)); 04884 } 04885 04886 // Free up the objects that we used 04887 Filter* pBest = pBestFilter->pFilter; 04888 CCFree(FilterBuf); 04889 Filters.DeleteAll(); 04890 return pBest; 04891 } 04892 04893 04894 04895 /******************************************************************************************** 04896 04897 > BOOL FilterFamily::IsDefaultDocRequired(const TCHAR* pcszPathName) 04898 04899 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04900 Created: 9/10/95 04901 Inputs: pcszPathName pointer to the pathname to check 04902 Returns: TRUE if the filter requires a default document, FALSE if not. 04903 Purpose: Works out if opening a file of this type requires a default document to be 04904 loaded. If the file format supplies the document then return FALSE otherwise 04905 return TRUE. An example would be opening a bitmap file. This has no document 04906 defined in the file format and so we need to laod the default document before 04907 importing the bitmap into this file. 04908 SeeAlso: Filter; Filter::IsDefaultDocRequired; CCamDoc::OnOpenDocument; 04909 SeeAlso: FilterFamily::DoImport; Filter::DoImport; FilterFamily::GetBestFilter 04910 04911 ********************************************************************************************/ 04912 04913 BOOL FilterFamily::IsDefaultDocRequired(const TCHAR* pcszPathName) 04914 { 04915 // If the pathname passed in is NULL then there is nothing we can do so say no 04916 // default document is required. 04917 if (pcszPathName == NULL) return FALSE; 04918 04919 // Ensure the cached best filter is set to null 04920 pCachedBestFilter = NULL; 04921 04922 // Work out the best filter to use on this file. 04923 Filter* pBestFilter = NULL; 04924 04925 // First off, we have to try and open the file 04926 CCDiskFile file(1024, FALSE, TRUE); 04927 04928 // Build a string out of the path name 04929 String_256 FileName(pcszPathName); 04930 04931 // get it into the proper PathName class 04932 PathName Path(FileName); 04933 04934 // If we cannot open the file then return false 04935 if (!file.open(Path, ios::in | ios::binary)) return FALSE; 04936 04937 // Find the best file for this to use 04938 pBestFilter = GetBestFilter(&file); 04939 04940 // On this pass, no errors are allowed, at present. 04941 Error::ClearError(); 04942 04943 // Close the file again 04944 if (file.isOpen()) file.close(); 04945 04946 // If the filter is NULL then not found, must have set an error. 04947 if (pBestFilter == NULL) return FALSE; 04948 04949 // Result: do we require the default document? 04950 BOOL Result; 04951 04952 // Ask the best filter to see if we need to load a default document for it to use. 04953 // At this point the pathname is irrelevent. 04954 Result = pBestFilter->IsDefaultDocRequired(pcszPathName); 04955 04956 // Make a note of the filter that we decided on as the best filter. 04957 pCachedBestFilter = pBestFilter; 04958 04959 return Result; 04960 } 04961 04962 04963 /******************************************************************************************** 04964 04965 > BOOL FilterFamily::DoImport(SelOperation *pOp, CCLexFile* pFile, 04966 Document *pDestDoc, BOOL AutoChosen, ImportPosition *Pos, 04967 KernelBitmap** ppImportedBitmap, DocCoord* pPosTranslate, 04968 String_56& URL) 04969 04970 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04971 Created: 21/03/94 04972 Inputs: pOp - the live operation associated with this file import process. 04973 pFile - The file to import from 04974 pDestDoc - the document to import the file into. 04975 Pos - 04976 ppImportedBitmap - this is used mainly in the bitfltr.cpp for the HTML 04977 import filter. HTMLFilter::DoImport() needs a pointer to a kernel bitmap 04978 to set the background bitmap up into Camelot. 04979 pPosTranslate - This is used too by the HTMLFilter in order to do a formatting. 04980 URL - the URL of the original imported file 04981 Returns: TRUE if the document was loaded ok, FALSE if not. 04982 Purpose: Loads in the initial 1k of the file, and passes this around all the filters 04983 to see which ones understand it. It then chooses the filter that claims 04984 the highest 'compatibility', and calls its DoImport() function to load it. 04985 Errors: Out of memory, File not recognised. 04986 SeeAlso: Filter; Filter::DoImport; FilterFamily::GetBestFilter; 04987 SeeAlso: FilterFamily::IsDefaultDocRequired; Filter::IsDefaultDocRequired; 04988 04989 ********************************************************************************************/ 04990 04991 BOOL FilterFamily::DoImport(SelOperation *pOp, CCLexFile* pFile, 04992 Document *pDestDoc, BOOL AutoChosen, ImportPosition *Pos, 04993 KernelBitmap** ppImportedBitmap, DocCoord* pPosTranslate, String_256* URL) 04994 { 04995 // Work out the best filter to use on this file. 04996 // (ChrisG 1/2/01) We do want to be warned if this filter isn't perfect 04997 Filter *pBestFilter = GetBestFilter(pFile, TRUE); 04998 04999 // If the filter is NULL then not found, must have set an error. 05000 if (pBestFilter == NULL) 05001 { 05002 // Ensure the cached best filter is set to null 05003 pCachedBestFilter = NULL; 05004 return FALSE; 05005 } 05006 05007 // Result: did we import the file ok? 05008 BOOL Result = FALSE; 05009 05010 // Use this filter to import the file, and tell the filter that it was chosen 05011 // automatically. 05012 Result = pBestFilter->DoImport(pOp, pFile, pDestDoc, TRUE, Pos, NULL, NULL, URL); 05013 05014 // Make sure the art file error is more specific 05015 if (!Result && pBestFilter->FilterID == FILTERID_NATIVE_EPS) 05016 { 05017 // Check that it is not our special do nothing message 05018 // or that the error has been reported before and cleared 05019 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED) && 05020 Error::GetErrorNumber() != _R(IDT_IMPORT_USERABORT)) 05021 { 05022 Error::ClearError(); 05023 Error::SetError(_R(IDS_ERRORINARTFILE)); 05024 } 05025 } 05026 05027 // Ensure the cached best filter is set back to null again 05028 pCachedBestFilter = NULL; 05029 05030 // Return the result of importing the file. 05031 return Result; 05032 } 05033 05034 05035 05036 /******************************************************************************************** 05037 05038 > BOOL FilterFamily::ImportBitmap(CCLexFile* pFile, KernelBitmap** ppBitmap) 05039 05040 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 05041 Created: 8/04/94 05042 Inputs: pFile - The file to import from 05043 Outputs: *ppBitmap is updated to point at the imported bitmap. 05044 Returns: TRUE if the bitmap was loaded ok, FALSE if not. 05045 Purpose: Loads in the initial 1k of the file, and passes this around all the filters 05046 to see which ones understand it. It then chooses the filter that claims 05047 the highest 'compatibility', and calls its ImportBitmap() function to load it. 05048 Errors: Out of memory, File not recognised. 05049 SeeAlso: Filter; Filter::ImportBitmap 05050 05051 ********************************************************************************************/ 05052 05053 BOOL FilterFamily::ImportBitmap(CCLexFile* pFile, KernelBitmap** ppBitmap) 05054 { 05055 // If it is not a disk file, then bail right out now. 05056 // if (!pFile->IS_KIND_OF(CCDiskFile)) return FALSE; 05057 05058 // Find out the pathname of the file in question 05059 PathName Path = pFile->GetPathName(); 05060 05061 // Load the first 1k of the file. 05062 UINT32 SegmentSize = FILTER_HDRSIZE; 05063 size_t FileSize; 05064 ADDR FilterBuf = LoadInitialSegment(pFile, &SegmentSize, &FileSize); 05065 if (FilterBuf == NULL) 05066 // Error occured when accessing file 05067 return FALSE; 05068 05069 // Create a list of all the filters that understand this file to one degree or 05070 // another, sorted on how much they like the file. 05071 CompatibleFilterList Filters; 05072 05073 Filter* pFilter = Filter::GetFirst(); 05074 while (pFilter != NULL) 05075 { 05076 // Inform any filters that we are about to do a HowCompatible call. 05077 // This would allow a set of filters which have common functionality hidden in a 05078 // filter that cannot import and cannot export handle this call and hence set 05079 // itself up. This would allow it to maybe cache a result which should only be 05080 // checked by the first filter in the group. 05081 if (pFilter->JoinFamily(pFilterType) && (!pFilter->GetFlags().CanImport)) 05082 /*BOOL ok =*/ pFilter->PreHowCompatible(); 05083 05084 if (pFilter->GetFlags().CanImport && pFilter->JoinFamily(pFilterType)) 05085 { 05086 // This is an import filter which belongs to our family - ask it if it 05087 // understands this file. 05088 INT32 Compatibility = pFilter->HowCompatible(Path, FilterBuf, SegmentSize, 05089 (UINT32) FileSize); 05090 05091 if (Compatibility > 0) 05092 { 05093 // Add this filter to the list 05094 if (Filters.AddFilter(pFilter, Compatibility) == FALSE) 05095 { 05096 // Error has occured - clean up our objects and return error 05097 CCFree(FilterBuf); 05098 Filters.DeleteAll(); 05099 return FALSE; 05100 } 05101 } 05102 } 05103 05104 // Get the next filter. 05105 pFilter = Filter::GetNext(pFilter); 05106 } 05107 05108 // BODGE: 05109 // For now, just choose the filter at the head of the list. 05110 // We should check for the compatibility being less than 10 and provide a scrolly list 05111 // for the user to choose from if more than one filter is interested. 05112 CompatibleFilter* pBestFilter = (CompatibleFilter*) Filters.GetHead(); 05113 05114 // Result: did we import the file ok? 05115 BOOL Result; 05116 05117 if (pBestFilter == NULL) 05118 { 05119 // None of the filters liked this file - tell the user 05120 Result = FALSE; 05121 Error::SetError(_R(IDT_FILE_NOTRECOGNISED)); 05122 } 05123 else 05124 { 05125 // Use this filter to import the file, and tell the filter that it was chosen 05126 // automatically. 05127 Result = pBestFilter->pFilter->ImportBitmap(pFile, ppBitmap); 05128 } 05129 05130 // Clean up 05131 CCFree(FilterBuf); 05132 Filters.DeleteAll(); 05133 05134 // Return the result of importing the file. 05135 return Result; 05136 } 05137 05138 /******************************************************************************************** 05139 05140 > BOOL FilterFamily::DoExport(Operation*, CCLexFile*, PathName *, Document*, BOOL) 05141 05142 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05143 Created: 28/03/94 05144 Inputs: As base class version. 05145 Returns: Always returns FALSE. 05146 Purpose: Dummy function - this filter does not allow export. 05147 Errors: ENSURE failure when called. 05148 05149 ********************************************************************************************/ 05150 05151 BOOL FilterFamily::DoExport(Operation*, CCLexFile*, PathName*, Document*, BOOL) 05152 { 05153 // This filter doesn't export. 05154 ENSURE(FALSE, "FilterFamily::DoExport() called - this should not happen!"); 05155 return FALSE; 05156 } 05157 05158 05159 /******************************************************************************************** 05160 05161 > BOOL FilterFamily::JoinFamily(CCRuntimeClass *) 05162 05163 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05164 Created: 26/07/94 05165 Purpose: Over-rides this function, because we don't ever want a filter family to 05166 join another filter family, as this would be nonsensical. 05167 SeeAlso: FilterFamily 05168 05169 ********************************************************************************************/ 05170 05171 BOOL FilterFamily::JoinFamily(CCRuntimeClass *) 05172 { 05173 return FALSE; 05174 } 05175 05176 05177 /******************************************************************************************** 05178 05179 > GenericFilter::GenericFilter() 05180 05181 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05182 Created: 28/07/94 05183 Purpose: Sets up the generic filter object to interface to all the installed 05184 filters. 05185 05186 ********************************************************************************************/ 05187 05188 GenericFilter::GenericFilter() 05189 { 05190 // This is the generic filter, so we want *all* filters in it. 05191 pFilterType = CC_RUNTIME_CLASS(Filter); 05192 } 05193 05194 /******************************************************************************************** 05195 05196 > BOOL GenericFilter::Init() 05197 05198 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05199 Created: 28/03/94 05200 Returns: TRUE if initalised ok; FALSE if error occurred. 05201 Purpose: Set up a generic filter object. This creates the associated OILFilter 05202 object, and sets up the filter ID number and strings. 05203 Errors: Out of memory. 05204 SeeAlso: FilterFamily; OILFilter 05205 05206 ********************************************************************************************/ 05207 05208 BOOL GenericFilter::Init() 05209 { 05210 // Get the OILFilter object 05211 pOILFilter = new OILFilterFamily(this, _R(IDT_FILTERNAME_GENERIC)); 05212 if (pOILFilter == NULL) 05213 return FALSE; 05214 05215 // Load the description strings 05216 FilterName.Load(_R(IDT_GENERIC_FILTERNAME)); 05217 FilterInfo.Load(_R(IDT_GENERIC_FILTERINFO)); 05218 FilterID = FILTERID_GENERIC; 05219 05220 // All ok 05221 return TRUE; 05222 } 05223 05224 /******************************************************************************************** 05225 05226 > VectorFilterFamily::VectorFilterFamily() 05227 05228 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05229 Created: 28/07/94 05230 Purpose: Sets up the vector filter object to interface to all the installed 05231 filters that decode vector file formats. 05232 05233 ********************************************************************************************/ 05234 05235 VectorFilterFamily::VectorFilterFamily() 05236 { 05237 // This is the vector files filter, so we want *all* vector filters in it. 05238 pFilterType = CC_RUNTIME_CLASS(VectorFilter); 05239 } 05240 05241 /******************************************************************************************** 05242 05243 > BOOL VectorFilterFamily::Init() 05244 05245 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05246 Created: 28/03/94 05247 Returns: TRUE if initalised ok; FALSE if error occurred. 05248 Purpose: Set up a vector file filter object. This creates the associated OILFilter 05249 object, and sets up the filter ID number and strings. 05250 Errors: Out of memory. 05251 SeeAlso: FilterFamily; OILFilter 05252 05253 ********************************************************************************************/ 05254 05255 BOOL VectorFilterFamily::Init() 05256 { 05257 // Get the OILFilter object 05258 pOILFilter = new OILFilterFamily(this, _R(IDT_FILTERNAME_VECTOR)); 05259 if (pOILFilter == NULL) 05260 return FALSE; 05261 05262 // Load the description strings 05263 FilterName.Load(_R(IDT_VECTOR_FILTERNAME)); 05264 FilterInfo.Load(_R(IDT_VECTOR_FILTERINFO)); 05265 FilterID = FILTERID_VECTOR; 05266 05267 // All ok 05268 return TRUE; 05269 } 05270 05271 /******************************************************************************************** 05272 05273 > BitmapFilterFamily::BitmapFilterFamily() 05274 05275 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05276 Created: 28/07/94 05277 Purpose: Sets up the bitmap filter object to interface to all the installed 05278 filters that decode bitmap file formats. 05279 05280 ********************************************************************************************/ 05281 05282 BitmapFilterFamily::BitmapFilterFamily() 05283 { 05284 // This is the bitmap files filter, so we want *all* bitmap filters in it. 05285 pFilterType = CC_RUNTIME_CLASS(BitmapFilter); 05286 } 05287 05288 /******************************************************************************************** 05289 05290 > BOOL BitmapFilterFamily::Init() 05291 05292 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05293 Created: 28/03/94 05294 Returns: TRUE if initalised ok; FALSE if error occurred. 05295 Purpose: Set up a bitmap filter object. This creates the associated OILFilter 05296 object, and sets up the filter ID number and strings. 05297 Errors: Out of memory. 05298 SeeAlso: FilterFamily; OILFilter 05299 05300 ********************************************************************************************/ 05301 05302 BOOL BitmapFilterFamily::Init() 05303 { 05304 // Get the OILFilter object 05305 pOILFilter = new OILFilterFamily(this, _R(IDT_FILTERNAME_BITMAP)); 05306 if (pOILFilter == NULL) 05307 return FALSE; 05308 05309 // Load the description strings 05310 FilterName.Load(_R(IDT_BITMAP_FILTERNAME)); 05311 FilterInfo.Load(_R(IDT_BITMAP_FILTERINFO)); 05312 FilterID = FILTERID_BITMAP; 05313 05314 // All ok 05315 return TRUE; 05316 } 05317 05318 05319 05320 #if BUILD_TEXT_FILTERS 05321 /******************************************************************************************** 05322 > TextFilterFamily::TextFilterFamily() 05323 05324 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 05325 Created: 24/11/95 05326 Purpose: Sets up the text filter object to interface to all the installed 05327 filters that decode text file formats. 05328 ********************************************************************************************/ 05329 TextFilterFamily::TextFilterFamily() 05330 { 05331 pFilterType = CC_RUNTIME_CLASS(TextFilter); 05332 } 05333 05334 05335 /******************************************************************************************** 05336 > BOOL TextFilterFamily::Init() 05337 05338 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 05339 Created: 24/11/95 05340 Returns: TRUE if initalised ok; FALSE if error occurred. 05341 Purpose: Set up a text filter object. This creates the associated OILFilter 05342 object, and sets up the filter ID number and strings. 05343 Errors: Out of memory. 05344 SeeAlso: FilterFamily; OILFilter 05345 ********************************************************************************************/ 05346 BOOL TextFilterFamily::Init() 05347 { 05348 // Get the OILFilter object 05349 pOILFilter = new OILFilterFamily(this, _R(IDT_FILTERNAME_TEXT)); 05350 if (pOILFilter == NULL) 05351 return FALSE; 05352 05353 // Load the description strings 05354 FilterName.Load(_R(IDT_TEXT_FILTERNAME)); 05355 FilterInfo.Load(_R(IDT_TEXT_FILTERINFO)); 05356 FilterID = FILTERID_TEXT; 05357 05358 // All ok 05359 return TRUE; 05360 } 05361 #endif // #if BUILD_TEXT_FILTERS 05362 05363 05364 /******************************************************************************************** 05365 05366 > GenericEPSFilter::GenericFilter() 05367 05368 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05369 Created: 28/07/94 05370 Purpose: Sets up the generic EPS filter object to interface to all the installed 05371 EPS filters. 05372 05373 ********************************************************************************************/ 05374 05375 GenericEPSFilter::GenericEPSFilter() 05376 { 05377 // This is the generic EPS filter, so we want all EPS filters in it. 05378 pFilterType = CC_RUNTIME_CLASS(EPSFilter); 05379 } 05380 05381 /******************************************************************************************** 05382 05383 > BOOL GenericEPSFilter::Init() 05384 05385 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05386 Created: 28/03/94 05387 Returns: TRUE if initalised ok; FALSE if error occurred. 05388 Purpose: Set up a generic EPS filter object. This creates the associated OILFilter 05389 object, and sets up the filter ID number and strings. 05390 Errors: Out of memory. 05391 SeeAlso: FilterFamily; OILFilter; EPSFilter 05392 05393 ********************************************************************************************/ 05394 05395 BOOL GenericEPSFilter::Init() 05396 { 05397 // Get the OILFilter object 05398 pOILFilter = new OILFilterFamily(this, _R(IDT_FILTERNAME_EPS)); 05399 if (pOILFilter == NULL) 05400 return FALSE; 05401 05402 // Load the description strings 05403 FilterName.Load(_R(IDT_EPS_FILTERNAME)); 05404 FilterInfo.Load(_R(IDT_EPS_FILTERINFO)); 05405 FilterID = FILTERID_EPS; 05406 05407 // All ok 05408 return TRUE; 05409 } 05410 05411 05412 #ifndef NOCDRCMX 05413 05414 /******************************************************************************************** 05415 > PaletteFilterFamily::PaletteFilterFamily() 05416 05417 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 05418 Created: 30/4/96 05419 Purpose: Sets up the filter object to interface to all the installed filters that 05420 decode palette file formats. 05421 ********************************************************************************************/ 05422 PaletteFilterFamily::PaletteFilterFamily() 05423 { 05424 PORTNOTETRACE("filter","PaletteFilterFamily::PaletteFilterFamily - do nothing"); 05425 #ifndef EXCLUDE_FROM_XARALX 05426 pFilterType = CC_RUNTIME_CLASS(PaletteFilter); 05427 #endif 05428 05429 } 05430 05431 05432 /******************************************************************************************** 05433 > BOOL PaletteFilterFamily::Init() 05434 05435 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 05436 Created: 30/4/96 05437 Returns: TRUE if initalised ok; FALSE if error occurred. 05438 Purpose: Set up a filter object. This creates the associated OILFilter object, and 05439 sets up the filter ID number and strings. 05440 Errors: Out of memory. 05441 SeeAlso: FilterFamily; OILFilter 05442 ********************************************************************************************/ 05443 BOOL PaletteFilterFamily::Init() 05444 { 05445 PORTNOTE("filter","Removed OILFilter usage") 05446 #ifndef EXCLUDE_FROM_XARALX 05447 // Get the OILFilter object 05448 pOILFilter = new OILFilterFamily(this, _R(IDT_FILTERNAME_PALETTE)); 05449 if (pOILFilter == NULL) 05450 return FALSE; 05451 #endif 05452 // Load the description strings 05453 FilterName.Load(_R(IDT_FILTERNAME_PALETTE)); 05454 FilterInfo.Load(_R(IDT_FILTERINFO_PALETTE)); 05455 FilterID = FILTERID_PALETTE; 05456 05457 // All ok 05458 return TRUE; 05459 } 05460 05461 #endif 05462 05463 /******************************************************************************************** 05464 05465 > SnapShotItem::SnapShotItem() 05466 05467 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05468 Created: 16/10/95 05469 Inputs: - 05470 Returns: - 05471 Purpose: Construct a SnapShotItem to record a list of current attributes 05472 05473 *********************************************************************************************/ 05474 05475 SnapShotItem::SnapShotItem() 05476 { 05477 SnapShotAttrs = NULL; 05478 SnapShotAttrsStack = NULL; 05479 } 05480 05481 05482 /******************************************************************************************** 05483 05484 > SnapShotItem::~SnapShotItem() 05485 05486 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05487 Created: 16/10/95 05488 Inputs: - 05489 Returns: - 05490 Purpose: Destroy a SnapShotItem - removes all allocated arrays 05491 05492 *********************************************************************************************/ 05493 05494 SnapShotItem::~SnapShotItem() 05495 { 05496 if (SnapShotAttrs!=NULL) 05497 { 05498 INT32 i, NumAttrs = AttributeManager::GetNumAttributes(); 05499 for (i=0; i<NumAttrs; i++) 05500 { 05501 if (SnapShotAttrs[i] != NULL) 05502 { 05503 delete SnapShotAttrs[i]; 05504 SnapShotAttrs[i]=NULL; 05505 } 05506 } 05507 CCFree(SnapShotAttrs); 05508 SnapShotAttrs=NULL; 05509 } 05510 05511 if (SnapShotAttrsStack!=NULL) 05512 { 05513 CCFree(SnapShotAttrsStack); 05514 SnapShotAttrsStack=NULL; 05515 } 05516 } 05517 05518 05519 /******************************************************************************************** 05520 05521 > BOOL SnapShotItem::Initialise(AttributeEntry* CurrAttrs) 05522 05523 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05524 Created: 16/10/95 05525 Inputs: CurrAttrs = a pointer to a list of attributeentry items. There 05526 as usual should be AttributeManager::NumAttributes() of them 05527 Returns: TRUE if able to initialise this snapshot item 05528 FALSE if not 05529 Purpose: This function grabs a snap shot of the described attributes list 05530 05531 *********************************************************************************************/ 05532 05533 BOOL SnapShotItem::Initialise(AttributeEntry* CurrAttrs) 05534 { 05535 INT32 i, NumAttrs = AttributeManager::GetNumAttributes(); 05536 05537 SnapShotAttrs = (NodeAttribute**)CCMalloc(NumAttrs*sizeof(NodeAttribute*)); 05538 if (SnapShotAttrs==NULL) 05539 return FALSE; 05540 05541 SnapShotAttrsStack = (AttributeEntry*)CCMalloc(NumAttrs*sizeof(AttributeEntry)); 05542 if (SnapShotAttrsStack==NULL) 05543 { 05544 CCFree(SnapShotAttrs); 05545 SnapShotAttrs=NULL; 05546 return FALSE; 05547 } 05548 05549 // store the temp values 05550 for (i=0; i<NumAttrs; i++) 05551 { 05552 // of course the following MakeNode may fail, but it just sets 05553 // the SnapShotAttrs ptr to NULL which we MUST check (and do) later on 05554 SnapShotAttrs[i] = (CurrAttrs[i].pAttr)->MakeNode(); 05555 05556 SnapShotAttrsStack[i].pAttr = NULL; 05557 SnapShotAttrsStack[i].Temp = FALSE; 05558 SnapShotAttrsStack[i].Ignore = TRUE; 05559 } 05560 05561 return TRUE; 05562 } 05563 05564 05565 //******************************************************************************************** 05566 //******************************************************************************************** 05567 05568 05569 05570 /******************************************************************************************** 05571 05572 > SnapShotList::SnapShotList() 05573 05574 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05575 Created: 16/10/95 05576 Inputs: - 05577 Purpose: Constructs a snap shot list 05578 05579 *********************************************************************************************/ 05580 05581 SnapShotList::SnapShotList() 05582 { 05583 } 05584 05585 05586 /******************************************************************************************** 05587 05588 > SnapShotList::~SnapShotList() 05589 05590 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05591 Created: 16/10/95 05592 Inputs: - 05593 Returns: - 05594 Purpose: Destroys a snapshot list. At this stage the snap shot list should be 05595 empty (if Create and Destroy have been matched correctly). 05596 05597 *********************************************************************************************/ 05598 05599 SnapShotList::~SnapShotList() 05600 { 05601 BOOL notempty=FALSE; 05602 SnapShotItem* pItem=NULL; 05603 while ( (pItem=(SnapShotItem*)SnapShot.RemoveTail()) !=NULL ) 05604 { 05605 notempty=TRUE; 05606 delete pItem; 05607 } 05608 if (notempty) 05609 { 05610 ERROR3("Destroyed a none empty snapshot list!\n"); 05611 } 05612 } 05613 05614 05615 /******************************************************************************************** 05616 05617 > SnapShotItem* SnapShotList::GetCurrentSnapShot() 05618 05619 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05620 Created: 16/10/95 05621 Inputs: - 05622 Returns: A pointer to the current snap shot. 05623 Purpose: This function is an abstracted way of finding the current snap shot 05624 created by the last CreateSnapShot() to be called (as snap shots can 05625 be stacked) 05626 05627 *********************************************************************************************/ 05628 05629 SnapShotItem* SnapShotList::GetCurrentSnapShot() 05630 { 05631 return (SnapShotItem*)SnapShot.GetTail(); 05632 } 05633 05634 05635 /******************************************************************************************** 05636 05637 > BOOL SnapShotList::CreateSnapShot(AttributeEntry* CurrAttrs) 05638 05639 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05640 Created: 16/10/95 05641 Inputs: CurrAttrs = a pointer to a list of attributeentry items. There as usual 05642 should be AttributeManager::NumAttributes() of them 05643 Returns: TRUE if a snap shot has been created 05644 FALSE if not 05645 Purpose: Take a snap shot of the attribute list described by CurrAttrs 05646 05647 *********************************************************************************************/ 05648 05649 BOOL SnapShotList::CreateSnapShot(AttributeEntry* CurrAttrs) 05650 { 05651 SnapShotItem* pItem = new SnapShotItem; 05652 if (pItem==NULL) 05653 return FALSE; 05654 05655 if (!pItem->Initialise(CurrAttrs)) 05656 { 05657 delete pItem; 05658 return FALSE; 05659 } 05660 05661 SnapShot.AddTail(pItem); 05662 return TRUE; 05663 } 05664 05665 05666 /******************************************************************************************** 05667 05668 > void SnapShotList::DestroySnapShot() 05669 05670 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05671 Created: 16/10/95 05672 Inputs: - 05673 Returns: - 05674 Purpose: Destroy the last snap shot taken by CreateSnapShot() 05675 05676 *********************************************************************************************/ 05677 05678 void SnapShotList::DestroySnapShot() 05679 { 05680 SnapShotItem* pItem = (SnapShotItem*)SnapShot.RemoveTail(); 05681 if (pItem==NULL) 05682 { 05683 ERROR3("underflow in SnapShotList::DestroySnapShot()"); 05684 return; 05685 } 05686 05687 delete pItem; 05688 } 05689 05690 05691 /******************************************************************************************** 05692 05693 > BOOL SnapShotList::ApplyChangedAttrs(Node* pNode, AttributeEntry* CurrAttrs) 05694 05695 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05696 Created: 16/10/95 05697 Inputs: - 05698 Returns: TRUE if the changed attributes have been applied to pNode 05699 FALSE if nothing has been applied 05700 Purpose: This function uses the snapshot facility to work out which of the 05701 current attributes have changed. Obviously it expects a snap shot to have 05702 been taken some time earlier. Only those attributes that have changes will be 05703 applied to the node described on entry. Note, any changed attributes which 05704 now match defaults will not be applied as the function calls 05705 ApplyBasedOnDefaults() with the changes list. 05706 05707 *********************************************************************************************/ 05708 05709 BOOL SnapShotList::ApplyChangedAttrs(Node* pNode, AttributeEntry* CurrAttrs) 05710 { 05711 // check that we have a snap shot attr mask 05712 SnapShotItem* pCurrItem = GetCurrentSnapShot(); 05713 if (pCurrItem==NULL) 05714 { 05715 ERROR3("No snap shot taken of the current attributes in SnapShotList::ApplyChangedAttrs()"); 05716 return FALSE; 05717 } 05718 05719 // Now get a set of default attributes so we can use them to reset the 05720 // current values 05721 INT32 i, NumAttrs = AttributeManager::GetNumAttributes(); 05722 AttributeEntry *pDefAtts = AttributeManager::GetDefaultAttributes(); 05723 if (pDefAtts==NULL) 05724 return FALSE; 05725 05726 // Alter the list of default attrs we've just created to include the differences 05727 // between our snap shot set and the current attributes described. 05728 for (i=0; i<NumAttrs; i++) 05729 { 05730 pDefAtts[i].Ignore = TRUE; 05731 NodeAttribute* pNodeAtt = pCurrItem->SnapShotAttrs[i]; 05732 if (pNodeAtt) 05733 { 05734 AttributeValue* pSavedAttr = pNodeAtt->GetAttributeValue(); 05735 05736 if ((pSavedAttr!=NULL) && (CurrAttrs[i].pAttr->IsDifferent(pSavedAttr))) 05737 { 05738 pDefAtts[i].pAttr = CurrAttrs[i].pAttr; 05739 pDefAtts[i].Temp = FALSE; 05740 pDefAtts[i].Ignore = FALSE; 05741 } 05742 } 05743 } 05744 05745 // Now apply the attribute list we have built 05746 BOOL Success = AttributeManager::ApplyBasedOnDefaults(pNode, pDefAtts); 05747 05748 // finally free up the array we have created and return 05749 CCFree(pDefAtts); 05750 return Success; 05751 } 05752 05753 05754 05755 05756 /******************************************************************************************** 05757 05758 > void SnapShotList::PushAttrsBasedOnSnapShot(AttributeEntry* CurrAttrs) 05759 05760 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05761 Created: 16/10/95 05762 Inputs: - 05763 Returns: - 05764 Purpose: This function uses the snap shot facility. It checks the snap shot list 05765 against the current attribute list to find attributes which differ. Those 05766 that do are obviously new attributes. ie attributes which have been parsed 05767 by the filter after the snap shot was taken. This function takes the current 05768 attrubute list and removes all those attributes which have changed in this 05769 way. It resets them to their default none temp attribute types. 05770 05771 *********************************************************************************************/ 05772 05773 void SnapShotList::PushAttrsBasedOnSnapShot(AttributeEntry* CurrAttrs) 05774 { 05775 // check that we have a snap shot attr mask 05776 SnapShotItem* pCurrItem = GetCurrentSnapShot(); 05777 if (pCurrItem==NULL) 05778 { 05779 ERROR3("No snap shot taken of the current attributes in SnapShotList::PushAttrsBasedOnSnapShot()"); 05780 return; 05781 } 05782 05783 // Now get a set of default attributes so we can use them to reset the 05784 // current values 05785 INT32 i, NumAttrs = AttributeManager::GetNumAttributes(); 05786 AttributeEntry *pDefAtts = AttributeManager::GetDefaultAttributes(); 05787 if (pDefAtts==NULL) 05788 return; 05789 05790 for (i=0; i<NumAttrs; i++) 05791 { 05792 pCurrItem->SnapShotAttrsStack[i].pAttr = NULL; 05793 pCurrItem->SnapShotAttrsStack[i].Temp = FALSE; 05794 pCurrItem->SnapShotAttrsStack[i].Ignore = TRUE; 05795 05796 NodeAttribute* pNodeAtt = pCurrItem->SnapShotAttrs[i]; 05797 05798 if (pNodeAtt) 05799 { 05800 AttributeValue* pSavedAttr = pNodeAtt->GetAttributeValue(); 05801 05802 if ((pSavedAttr!=NULL) && (CurrAttrs[i].pAttr->IsDifferent(pSavedAttr))) 05803 { 05804 // we don't want to apply this attr! 05805 pCurrItem->SnapShotAttrsStack[i].pAttr = CurrAttrs[i].pAttr; 05806 pCurrItem->SnapShotAttrsStack[i].Temp = CurrAttrs[i].Temp; 05807 pCurrItem->SnapShotAttrsStack[i].Ignore = CurrAttrs[i].Ignore; 05808 05809 CurrAttrs[i].pAttr = pDefAtts[i].pAttr; 05810 CurrAttrs[i].Temp = pDefAtts[i].Temp; 05811 CurrAttrs[i].Ignore = pDefAtts[i].Ignore; 05812 } 05813 } 05814 } 05815 05816 CCFree(pDefAtts); 05817 } 05818 05819 05820 05821 /******************************************************************************************** 05822 05823 > void SnapShotList::PopAttrsBasedOnSnapShot(AttributeEntry* CurrAttrs) 05824 05825 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05826 Created: 16/10/95 05827 Inputs: - 05828 Returns: - 05829 Purpose: This function uses the snap shot facility. It checks the snap shot list 05830 against the current attribute list to find attributes which differ. Those 05831 that do are obviously new attributes. ie attributes which have been parsed 05832 by the filter after the snap shot was taken. This function takes the current 05833 attrubute list and removes all those attributes which have changed in this 05834 way. It resets them to their default none temp attribute types. 05835 05836 *********************************************************************************************/ 05837 05838 void SnapShotList::PopAttrsBasedOnSnapShot(AttributeEntry* CurrAttrs) 05839 { 05840 // check that we have a snap shot attr mask 05841 SnapShotItem* pCurrItem = GetCurrentSnapShot(); 05842 if (pCurrItem==NULL) 05843 { 05844 ERROR3("No snap shot taken of the current attributes in SnapShotList::PopAttrsBasedOnSnapShot()"); 05845 return; 05846 } 05847 05848 INT32 i, NumAttrs = AttributeManager::GetNumAttributes(); 05849 AttributeEntry *pDefAtts = AttributeManager::GetDefaultAttributes(); 05850 if (pDefAtts==NULL) 05851 return; 05852 05853 for (i=0; i<NumAttrs; i++) 05854 { 05855 if (pCurrItem->SnapShotAttrsStack[i].pAttr != NULL) 05856 { 05857 if ( !(CurrAttrs[i].pAttr->IsDifferent(pDefAtts[i].pAttr)) ) 05858 { 05859 CurrAttrs[i].pAttr = pCurrItem->SnapShotAttrsStack[i].pAttr; 05860 CurrAttrs[i].Temp = pCurrItem->SnapShotAttrsStack[i].Temp; 05861 CurrAttrs[i].Ignore = pCurrItem->SnapShotAttrsStack[i].Ignore; 05862 } 05863 } 05864 } 05865 05866 CCFree(pDefAtts); 05867 } 05868 05869 05870 05871 /******************************************************************************************** 05872 05873 > BOOL Filter::SetTextFont(String_64 *EncodedFont, INT32 Millipoint) 05874 05875 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05876 Created: 17/05/95 05877 Returns: TRUE if the font has been set correctly 05878 FALSE if an error occured specifying the font 05879 Purpose: Set the font specified in the encoded font name. The font which actually 05880 gets set in the attribute stack is one found by GetCompatibleFont(), a super 05881 new fontmanager call. 05882 05883 ********************************************************************************************/ 05884 05885 BOOL Filter::SetTextFont(String_64 *EncodedName, INT32 MillFSize) 05886 { 05887 String_64 CompFont; 05888 INT32 Style; 05889 BOOL Bold,Italic; 05890 05891 // Find a nice compatible font we can use 05892 FONTMANAGER->GetCompatibleFont(*EncodedName, CompFont, Style); 05893 // get the style bits 05894 Bold=((Style & 1) != 0); 05895 Italic=((Style & 2) != 0); 05896 05897 return SetTextFontStyle(&CompFont, MillFSize, Bold, Italic); 05898 } 05899 05900 /* 05901 // This has all moved into the fontmanager, tada! 05902 05903 if (EncodedName->Sub(String_32("_"),0,0) == 0) 05904 EncodedName->Remove(0,1); 05905 05906 String_64 TryFont((*EncodedName)); 05907 TryFont.SwapChar('-',' '); 05908 05909 // Try to find the specified font name 05910 INT32 found = FONTMANAGER->DoesFontExist(&TryFont,TRUE,TRUE); 05911 if (found>0) 05912 return SetTextFontStyle(&TryFont, MillFSize, FALSE, FALSE); 05913 05914 // Ok, if we can't find the whole thing, try decoding 05915 String_64 DecodedName; 05916 INT32 Style = FONTMANAGER->DecodeFontName(*EncodedName, DecodedName); 05917 05918 // find out what styles this font has 05919 BOOL Bold,Italic; 05920 Bold=((Style & 1) != 0); 05921 Italic=((Style & 2) != 0); 05922 05923 // if both bold and italic found 05924 if (Bold && Italic) 05925 { 05926 String_64 HoldName(TryFont); 05927 // try to find bold first 05928 INT32 pos = HoldName.Sub(String_32("Italic"),0,0); 05929 HoldName.Remove(pos,6); 05930 found = FONTMANAGER->DoesFontExist(&HoldName,TRUE,TRUE); 05931 if (found>0) 05932 return SetTextFontStyle(&HoldName, MillFSize, FALSE, TRUE); 05933 05934 // Then try Italic 05935 HoldName=TryFont; 05936 pos = HoldName.Sub(String_32("Bold"),0,0); 05937 HoldName.Remove(pos,4); 05938 found = FONTMANAGER->DoesFontExist(&HoldName,TRUE,TRUE); 05939 if (found>0) 05940 return SetTextFontStyle(&HoldName, MillFSize, TRUE, FALSE); 05941 } 05942 05943 // Does the decoded name exist?, so we can make the rest up in styles? 05944 found = FONTMANAGER->DoesFontExist(&DecodedName,TRUE,TRUE); 05945 if (found>0) 05946 return SetTextFontStyle(&DecodedName, MillFSize, Bold, Italic); 05947 05948 // otherwise, we have a font with an extension, eg Trinity.Bold 05949 // (1) Trinity.Bold - does not exist 05950 // (2) Trinity - does not exist 05951 // now we set the font to (1), which will be replaced by Times-Roman. 05952 // Now we should also set the font styles too to give us TimesRoman bold 05953 return SetTextFontStyle(&TryFont, MillFSize, Bold, Italic); 05954 } 05955 */ 05956 05957 /******************************************************************************************** 05958 05959 > BOOL Filter::SetTextFontStyle(String_64 *FName, INT32 MillFSize, BOOL Bold, BOOL Italic) 05960 05961 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05962 Created: 17/05/95 05963 Returns: TRUE if the font and styles have been set 05964 FALSE if an error occured (out of memory) 05965 Purpose: This function creates attributes for the typeface, the pointsize, bold and 05966 italic all at once. 05967 05968 ********************************************************************************************/ 05969 05970 BOOL Filter::SetTextFontStyle(String_64 *FName, INT32 MillFSize, BOOL Bold, BOOL Italic) 05971 { 05972 if ((FONTMANAGER->CacheNamedFont(FName) == ILLEGALFHANDLE)) 05973 return FALSE; 05974 05975 if (!SetTextTypeFace(FName)) 05976 return FALSE; 05977 05978 if (!SetTextSize(MillFSize)) 05979 return FALSE; 05980 05981 // Build any style definitions we need 05982 if (!SetTextBold(Bold)) 05983 return FALSE; 05984 05985 if (!SetTextItalic(Italic)) 05986 return FALSE; 05987 05988 return TRUE; 05989 } 05990 05991 05992 /******************************************************************************************** 05993 05994 > BOOL Filter::SetTextSize(INT32 Size) 05995 05996 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 05997 Created: 13/04/94 05998 Inputs: Size - the new FontSize to use. 05999 Returns: TRUE if the attribute was changed ok; 06000 FALSE otherwise. 06001 Purpose: Updates the current attribute for TextSize to reflect the value passed 06002 in. 06003 Errors: Out of memory. 06004 SeeAlso: Filter; Filter::Init 06005 06006 ********************************************************************************************/ 06007 06008 BOOL Filter::SetTextSize(INT32 Size) 06009 { 06010 // Sanity check 06011 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06012 06013 // If we haven't changed this attribute yet, then make a new attribute object for 06014 // our own personal use... 06015 if (!CurrentAttrs[ATTR_TXTFONTSIZE].Temp) 06016 { 06017 // Make the correct attribute value and install it as the current one. 06018 CurrentAttrs[ATTR_TXTFONTSIZE].pAttr = new TxtFontSizeAttribute(Size); 06019 if (CurrentAttrs[ATTR_TXTFONTSIZE].pAttr == NULL) 06020 return FALSE; 06021 CurrentAttrs[ATTR_TXTFONTSIZE].Temp = TRUE; 06022 } 06023 else 06024 { 06025 // We already have an attribute - just change it. 06026 TxtFontSizeAttribute *pAttr = 06027 (TxtFontSizeAttribute *) CurrentAttrs[ATTR_TXTFONTSIZE].pAttr; 06028 pAttr->FontSize = Size; 06029 } 06030 06031 // All worked ok. 06032 return TRUE; 06033 } 06034 06035 06036 /******************************************************************************************** 06037 06038 > BOOL Filter::SetTextTypeFace(String_64 * Name, FontClass Class=FC_UNDEFINED) 06039 06040 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 06041 Created: 13/04/94 06042 Inputs: Name - the font name to use when creating a new typeface attribute 06043 Class - the class of font this name is supposed to be eg FC_TRUETYPE. 06044 the class defaults to FC_UDEFINED which means the first font 06045 cached which matches the font name will be used whatever 06046 type of font it is. 06047 Returns: TRUE if the attribute was changed ok; 06048 FALSE otherwise. 06049 Purpose: Updates the current attribute for TextSize to reflect the value passed 06050 in. 06051 Errors: Out of memory. 06052 SeeAlso: Filter; Filter::Init 06053 06054 ********************************************************************************************/ 06055 06056 BOOL Filter::SetTextTypeFace(String_64 * Name, FontClass Class) 06057 { 06058 // Sanity check 06059 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06060 06061 WORD hTypeface = FONTMANAGER->GetFontHandle(Name, Class); 06062 06063 // If we haven't changed this attribute yet, then make a new attribute object for 06064 // our own personal use... 06065 if (!CurrentAttrs[ATTR_TXTFONTTYPEFACE].Temp) 06066 { 06067 // Make the correct attribute value and install it as the current one. 06068 CurrentAttrs[ATTR_TXTFONTTYPEFACE].pAttr = new TxtFontTypefaceAttribute(hTypeface); 06069 if (CurrentAttrs[ATTR_TXTFONTTYPEFACE].pAttr == NULL) 06070 return FALSE; 06071 CurrentAttrs[ATTR_TXTFONTTYPEFACE].Temp = TRUE; 06072 } 06073 else 06074 { 06075 // We already have an attribute - just change it. 06076 TxtFontTypefaceAttribute *pAttr = (TxtFontTypefaceAttribute*) CurrentAttrs[ATTR_TXTFONTTYPEFACE].pAttr; 06077 pAttr->HTypeface = hTypeface; 06078 pAttr->IsBold = FALSE; 06079 pAttr->IsItalic = FALSE; 06080 } 06081 06082 // All worked ok. 06083 return TRUE; 06084 } 06085 06086 06087 /******************************************************************************************** 06088 06089 > BOOL Filter::SetTextBold(BOOL Bold) 06090 06091 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 06092 Created: 13/04/94 06093 Inputs: Bold - the new Bold state to use. 06094 Returns: TRUE if the attribute was changed ok; 06095 FALSE otherwise. 06096 Purpose: Updates the current attribute for Bold to reflect the value passed 06097 in. 06098 Errors: Out of memory. 06099 SeeAlso: Filter; Filter::Init 06100 06101 ********************************************************************************************/ 06102 06103 BOOL Filter::SetTextBold(BOOL Bold) 06104 { 06105 // Sanity check 06106 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06107 06108 // If we haven't changed this attribute yet, then make a new attribute object for 06109 // our own personal use... 06110 if (!CurrentAttrs[ATTR_TXTBOLD].Temp) 06111 { 06112 // Make the correct attribute value and install it as the current one. 06113 CurrentAttrs[ATTR_TXTBOLD].pAttr = new TxtBoldAttribute(Bold); 06114 if (CurrentAttrs[ATTR_TXTBOLD].pAttr == NULL) 06115 return FALSE; 06116 CurrentAttrs[ATTR_TXTBOLD].Temp = TRUE; 06117 } 06118 else 06119 { 06120 // We already have an attribute - just change it. 06121 TxtBoldAttribute *pAttr = (TxtBoldAttribute*) CurrentAttrs[ATTR_TXTBOLD].pAttr; 06122 pAttr->BoldOn = Bold; 06123 } 06124 06125 // All worked ok. 06126 return TRUE; 06127 } 06128 06129 06130 /******************************************************************************************** 06131 06132 > BOOL Filter::SetTextItalic(BOOL Italic) 06133 06134 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 06135 Created: 13/04/94 06136 Inputs: Italic- the new Italic state to use. 06137 Returns: TRUE if the attribute was changed ok; 06138 FALSE otherwise. 06139 Purpose: Updates the current attribute for Italic to reflect the value passed 06140 in. 06141 Errors: Out of memory. 06142 SeeAlso: Filter; Filter::Init 06143 06144 ********************************************************************************************/ 06145 06146 BOOL Filter::SetTextItalic(BOOL Italic) 06147 { 06148 // Sanity check 06149 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06150 06151 // If we haven't changed this attribute yet, then make a new attribute object for 06152 // our own personal use... 06153 if (!CurrentAttrs[ATTR_TXTITALIC].Temp) 06154 { 06155 // Make the correct attribute value and install it as the current one. 06156 CurrentAttrs[ATTR_TXTITALIC].pAttr = new TxtItalicAttribute(Italic); 06157 if (CurrentAttrs[ATTR_TXTITALIC].pAttr == NULL) 06158 return FALSE; 06159 CurrentAttrs[ATTR_TXTITALIC].Temp = TRUE; 06160 } 06161 else 06162 { 06163 // We already have an attribute - just change it. 06164 TxtItalicAttribute *pAttr = (TxtItalicAttribute*) CurrentAttrs[ATTR_TXTITALIC].pAttr; 06165 pAttr->ItalicOn = Italic; 06166 } 06167 06168 // All worked ok. 06169 return TRUE; 06170 } 06171 06172 06173 /******************************************************************************************** 06174 06175 > BOOL Filter::SetTextUnderline(BOOL Underline) 06176 06177 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 06178 Created: 13/04/94 06179 Inputs: Underline - the new Underline state to use. 06180 Returns: TRUE if the attribute was changed ok; 06181 FALSE otherwise. 06182 Purpose: Updates the current attribute for Underline to reflect the value passed 06183 in. 06184 Errors: Out of memory. 06185 SeeAlso: Filter; Filter::Init 06186 06187 ********************************************************************************************/ 06188 06189 BOOL Filter::SetTextUnderline(BOOL Underline) 06190 { 06191 // Sanity check 06192 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06193 06194 // If we haven't changed this attribute yet, then make a new attribute object for 06195 // our own personal use... 06196 if (!CurrentAttrs[ATTR_TXTUNDERLINE].Temp) 06197 { 06198 // Make the correct attribute value and install it as the current one. 06199 CurrentAttrs[ATTR_TXTUNDERLINE].pAttr = new TxtUnderlineAttribute(Underline); 06200 if (CurrentAttrs[ATTR_TXTUNDERLINE].pAttr == NULL) 06201 return FALSE; 06202 CurrentAttrs[ATTR_TXTUNDERLINE].Temp = TRUE; 06203 } 06204 else 06205 { 06206 // We already have an attribute - just change it. 06207 TxtUnderlineAttribute *pAttr = (TxtUnderlineAttribute*) CurrentAttrs[ATTR_TXTUNDERLINE].pAttr; 06208 pAttr->Underlined = Underline; 06209 } 06210 06211 // All worked ok. 06212 return TRUE; 06213 } 06214 06215 06216 /******************************************************************************************** 06217 06218 > BOOL Filter::SetTextAspectRatio(FIXED16 AspectRatio) 06219 06220 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 06221 Created: 13/04/94 06222 Inputs: AspectRatio - the new Aspect Ratio to use. 06223 Returns: TRUE if the attribute was changed ok; 06224 FALSE otherwise. 06225 Purpose: Updates the current attribute for AspectRatio to reflect the value passed 06226 in. 06227 Errors: Out of memory. 06228 SeeAlso: Filter; Filter::Init 06229 06230 ********************************************************************************************/ 06231 06232 BOOL Filter::SetTextAspectRatio(FIXED16 AspectRatio) 06233 { 06234 // Sanity check 06235 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06236 06237 // If we haven't changed this attribute yet, then make a new attribute object for 06238 // our own personal use... 06239 if (!CurrentAttrs[ATTR_TXTASPECTRATIO].Temp) 06240 { 06241 // Make the correct attribute value and install it as the current one. 06242 CurrentAttrs[ATTR_TXTASPECTRATIO].pAttr = new TxtAspectRatioAttribute(AspectRatio); 06243 if (CurrentAttrs[ATTR_TXTASPECTRATIO].pAttr == NULL) 06244 return FALSE; 06245 CurrentAttrs[ATTR_TXTASPECTRATIO].Temp = TRUE; 06246 } 06247 else 06248 { 06249 // We already have an attribute - just change it. 06250 TxtAspectRatioAttribute *pAttr = (TxtAspectRatioAttribute*) CurrentAttrs[ATTR_TXTASPECTRATIO].pAttr; 06251 pAttr->AspectRatio = AspectRatio; 06252 } 06253 06254 // All worked ok. 06255 return TRUE; 06256 } 06257 06258 06259 /******************************************************************************************** 06260 06261 > BOOL Filter::SetTextTracking(INT32 Tracking) 06262 06263 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 06264 Created: 13/04/94 06265 Inputs: Size - the new FontSize to use. 06266 Returns: TRUE if the attribute was changed ok; 06267 FALSE otherwise. 06268 Purpose: Updates the current attribute for TextSize to reflect the value passed 06269 in. 06270 Errors: Out of memory. 06271 SeeAlso: Filter; Filter::Init 06272 06273 ********************************************************************************************/ 06274 06275 BOOL Filter::SetTextTracking(INT32 Tracking) 06276 { 06277 // Sanity check 06278 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06279 06280 // If we haven't changed this attribute yet, then make a new attribute object for 06281 // our own personal use... 06282 if (!CurrentAttrs[ATTR_TXTTRACKING].Temp) 06283 { 06284 // Make the correct attribute value and install it as the current one. 06285 CurrentAttrs[ATTR_TXTTRACKING].pAttr = new TxtTrackingAttribute(Tracking); 06286 if (CurrentAttrs[ATTR_TXTTRACKING].pAttr == NULL) 06287 return FALSE; 06288 CurrentAttrs[ATTR_TXTTRACKING].Temp = TRUE; 06289 } 06290 else 06291 { 06292 // We already have an attribute - just change it. 06293 TxtTrackingAttribute *pAttr = (TxtTrackingAttribute*) CurrentAttrs[ATTR_TXTTRACKING].pAttr; 06294 pAttr->Tracking = Tracking; 06295 } 06296 06297 // All worked ok. 06298 return TRUE; 06299 } 06300 06301 06302 /******************************************************************************************** 06303 06304 > BOOL Filter::SetTextJustification(Justification Justify) 06305 06306 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 06307 Created: 13/04/94 06308 Inputs: Size - the new FontSize to use. 06309 Returns: TRUE if the attribute was changed ok; 06310 FALSE otherwise. 06311 Purpose: Updates the current attribute for TextSize to reflect the value passed 06312 in. 06313 Errors: Out of memory. 06314 SeeAlso: Filter; Filter::Init 06315 06316 ********************************************************************************************/ 06317 06318 BOOL Filter::SetTextJustification(Justification Justify) 06319 { 06320 // Sanity check 06321 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06322 06323 // If we haven't changed this attribute yet, then make a new attribute object for 06324 // our own personal use... 06325 if (!CurrentAttrs[ATTR_TXTJUSTIFICATION].Temp) 06326 { 06327 // Make the correct attribute value and install it as the current one. 06328 CurrentAttrs[ATTR_TXTJUSTIFICATION].pAttr = new TxtJustificationAttribute(Justify); 06329 if (CurrentAttrs[ATTR_TXTJUSTIFICATION].pAttr == NULL) 06330 return FALSE; 06331 CurrentAttrs[ATTR_TXTJUSTIFICATION].Temp = TRUE; 06332 } 06333 else 06334 { 06335 // We already have an attribute - just change it. 06336 TxtJustificationAttribute *pAttr = (TxtJustificationAttribute*) CurrentAttrs[ATTR_TXTJUSTIFICATION].pAttr; 06337 pAttr->justification = Justify; 06338 } 06339 06340 // All worked ok. 06341 return TRUE; 06342 } 06343 06344 06345 /******************************************************************************************** 06346 06347 > BOOL Filter::SetTextLineSpacing( INT32 Type, 06348 INT32 EMLSpace, 06349 MILLIPOINT MLSpace, 06350 double DLSpace) 06351 06352 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 06353 Created: 24/04/94 06354 Inputs: Type = the type of linespacing to create (0,1 or 2) 06355 0 EMLSpace = linespacing in em's (units related to the current pointsize) 06356 1 MLSpace = absolute millipoint line spacing 06357 2 DLSpace = propoptional linespacing 06358 Returns: TRUE if the attribute was changed ok; 06359 FALSE otherwise. 06360 Purpose: Updates the current attribute for line spacing to reflect the value passed 06361 in. One of three values will be used depending on the type (as above) 06362 Errors: Out of memory. 06363 SeeAlso: Filter; Filter::Init 06364 06365 ********************************************************************************************/ 06366 06367 BOOL Filter::SetTextLineSpacing(INT32 Type, 06368 INT32 EMLSpace, 06369 MILLIPOINT MLSpace, 06370 double DLSpace) 06371 { 06372 // Sanity check 06373 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06374 06375 INT32 LLSpace=0; 06376 double RLSpace=0; 06377 06378 switch (Type) 06379 { 06380 case 0: 06381 { 06382 // Use the default size. 06383 INT32 FSize = 19200; 06384 // Need to convert the linespacing to a sensible millipoint value 06385 if (CurrentAttrs[ATTR_TXTFONTSIZE].Temp) 06386 { 06387 // We already have an attribute - just change it. 06388 TxtFontSizeAttribute *pAttr = (TxtFontSizeAttribute*) CurrentAttrs[ATTR_TXTFONTSIZE].pAttr; 06389 FSize = pAttr->FontSize; 06390 } 06391 // Convert line space to millipoints. 06392 double LS = (double)EMLSpace; 06393 LLSpace = (INT32)((LS*FSize/1000)+0.5); 06394 break; 06395 } 06396 06397 case 1: 06398 LLSpace = MLSpace; 06399 break; 06400 06401 case 2: 06402 RLSpace = DLSpace; 06403 break; 06404 } 06405 06406 // If we haven't changed this attribute yet, then make a new attribute object for 06407 // our own personal use... 06408 if (!CurrentAttrs[ATTR_TXTLINESPACE].Temp) 06409 { 06410 // Make the correct attribute value and install it as the current one. 06411 CurrentAttrs[ATTR_TXTLINESPACE].pAttr = new TxtLineSpaceAttribute(); 06412 if (CurrentAttrs[ATTR_TXTLINESPACE].pAttr == NULL) 06413 return FALSE; 06414 CurrentAttrs[ATTR_TXTLINESPACE].Temp = TRUE; 06415 } 06416 06417 // Get a pointer to the attribute and set its new values 06418 TxtLineSpaceAttribute *pAttr = (TxtLineSpaceAttribute*) CurrentAttrs[ATTR_TXTLINESPACE].pAttr; 06419 06420 switch (Type) 06421 { 06422 case 0: 06423 case 1: 06424 pAttr->IsRatio = FALSE; 06425 pAttr->Value = LLSpace; 06426 pAttr->Ratio = FIXED16(0); 06427 break; 06428 06429 case 2: 06430 pAttr->IsRatio = TRUE; 06431 pAttr->Value = 0; 06432 pAttr->Ratio = RLSpace; 06433 break; 06434 } 06435 06436 // All worked ok. 06437 return TRUE; 06438 } 06439 06440 06441 /******************************************************************************************** 06442 06443 > BOOL Filter::SetTextBaseLine(MILLIPOINT BaseShift) 06444 06445 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 06446 Created: 24/04/94 06447 Inputs: BaseShift - the new baseline shift to use. 06448 Returns: TRUE if the attribute was changed ok; 06449 FALSE otherwise. 06450 Purpose: Updates the current attribute for BaseLine shift to reflect the value passed 06451 in. 06452 Errors: Out of memory. 06453 SeeAlso: Filter; Filter::Init 06454 06455 ********************************************************************************************/ 06456 06457 BOOL Filter::SetTextBaseLine(MILLIPOINT BaseShift) 06458 { 06459 // Sanity check 06460 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06461 06462 // If we haven't changed this attribute yet, then make a new attribute object for 06463 // our own personal use... 06464 if (!CurrentAttrs[ATTR_TXTBASELINE].Temp) 06465 { 06466 // Make the correct attribute value and install it as the current one. 06467 CurrentAttrs[ATTR_TXTBASELINE].pAttr = new TxtBaseLineAttribute(BaseShift); 06468 if (CurrentAttrs[ATTR_TXTBASELINE].pAttr == NULL) 06469 return FALSE; 06470 CurrentAttrs[ATTR_TXTBASELINE].Temp = TRUE; 06471 } 06472 else 06473 { 06474 // We already have an attribute - just change it. 06475 TxtBaseLineAttribute *pAttr = (TxtBaseLineAttribute*) CurrentAttrs[ATTR_TXTBASELINE].pAttr; 06476 pAttr->Value = BaseShift; 06477 } 06478 06479 // All worked ok. 06480 return TRUE; 06481 } 06482 06483 06484 /******************************************************************************************** 06485 06486 > BOOL Filter::SetTextScript(INT32 rise, INT32 pointsize) 06487 06488 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 06489 Created: 24/04/94 06490 Inputs: rise = signed rise in millipoints away from the baseline 06491 pointsize = size of font to use in millipoints 06492 Returns TRUE if the attribute was changed ok 06493 FALSE otherwise. 06494 Purpose: Updates the current attribute for subscript or superscript 06495 Errors: Out of memory. 06496 SeeAlso: Filter; Filter::Init 06497 06498 ********************************************************************************************/ 06499 06500 BOOL Filter::SetTextScript(INT32 rise, INT32 pointsize) 06501 { 06502 // Sanity check 06503 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06504 06505 // ignore any crazy values 06506 if (pointsize<=0) 06507 return TRUE; 06508 06509 // Use the default size. 06510 INT32 fsize = 19200; 06511 if (CurrentAttrs[ATTR_TXTFONTSIZE].Temp) 06512 { 06513 TxtFontSizeAttribute *pAttr = (TxtFontSizeAttribute*) CurrentAttrs[ATTR_TXTFONTSIZE].pAttr; 06514 fsize = pAttr->FontSize; 06515 } 06516 06517 double tr = (double)rise/(double)fsize; 06518 double tp = (double)pointsize/(double)fsize; 06519 FIXED16 offset(tr); 06520 FIXED16 size(tp); 06521 06522 // If we haven't changed this attribute yet, then make a new attribute object for 06523 // our own personal use... 06524 if (!CurrentAttrs[ATTR_TXTSCRIPT].Temp) 06525 { 06526 // Make the correct attribute value and install it as the current one. 06527 CurrentAttrs[ATTR_TXTSCRIPT].pAttr = new TxtScriptAttribute(offset,size); 06528 if (CurrentAttrs[ATTR_TXTSCRIPT].pAttr == NULL) 06529 return FALSE; 06530 CurrentAttrs[ATTR_TXTSCRIPT].Temp = TRUE; 06531 } 06532 else 06533 { 06534 // We already have an attribute - just change it. 06535 CurrentAttrs[ATTR_TXTSCRIPT].Ignore = FALSE; 06536 TxtScriptAttribute *pAttr = (TxtScriptAttribute*) CurrentAttrs[ATTR_TXTSCRIPT].pAttr; 06537 pAttr->Offset = offset; 06538 pAttr->Size = size; 06539 } 06540 06541 // All worked ok. 06542 return TRUE; 06543 } 06544 06545 06546 /******************************************************************************************** 06547 06548 > BOOL Filter::RemoveTextScript() 06549 06550 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 06551 Created: 26/04/94 06552 Inputs: - 06553 Returns TRUE if the attribute was removed 06554 FALSE otherwise. 06555 Purpose: Removes any script attribute which is currently active 06556 Errors: Out of memory. 06557 SeeAlso: 06558 06559 ********************************************************************************************/ 06560 06561 BOOL Filter::RemoveTextScript() 06562 { 06563 // Sanity check 06564 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06565 06566 // if a script attribute exists, delete it. 06567 if (CurrentAttrs[ATTR_TXTSCRIPT].Temp) 06568 CurrentAttrs[ATTR_TXTSCRIPT].Ignore = TRUE; 06569 return TRUE; 06570 } 06571 06572 06573 /******************************************************************************************** 06574 06575 > BOOL Filter::SetTextBoldFont(BOOL Bold) 06576 06577 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 06578 Created: 13/06/95 06579 Returns: TRUE if the font and style has been set 06580 FALSE if an error occured (out current typeface) 06581 Purpose: This function simply sets the bold style flag in the current 06582 font typeface attribute (to be applied to the next created character). 06583 06584 ********************************************************************************************/ 06585 06586 BOOL Filter::SetTextBoldFont(BOOL Bold) 06587 { 06588 // Sanity check 06589 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06590 06591 // If there is no current typeface then we cannot set its style 06592 if (!CurrentAttrs[ATTR_TXTFONTTYPEFACE].Temp) 06593 return FALSE; 06594 06595 // There is an attribute - just change it. 06596 TxtFontTypefaceAttribute *pAttr = (TxtFontTypefaceAttribute*) CurrentAttrs[ATTR_TXTFONTTYPEFACE].pAttr; 06597 pAttr->IsBold = Bold; 06598 06599 return TRUE; 06600 } 06601 06602 06603 /******************************************************************************************** 06604 06605 > BOOL Filter::SetTextItalicFont(BOOL Italic) 06606 06607 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 06608 Created: 13/06/95 06609 Returns: TRUE if the font and style has been set 06610 FALSE if an error occured (no current typeface) 06611 Purpose: This function simply sets the italic style flag in the current 06612 font typeface attribute (to be applied to the next created character). 06613 06614 ********************************************************************************************/ 06615 06616 BOOL Filter::SetTextItalicFont(BOOL Italic) 06617 { 06618 // Sanity check 06619 ERROR2IF(CurrentAttrs == NULL, FALSE, "No current attributes in filter!"); 06620 06621 // If there is no current typeface then we cannot set its style 06622 if (!CurrentAttrs[ATTR_TXTFONTTYPEFACE].Temp) 06623 return FALSE; 06624 06625 // There is an attribute - just change it. 06626 TxtFontTypefaceAttribute *pAttr = (TxtFontTypefaceAttribute*) CurrentAttrs[ATTR_TXTFONTTYPEFACE].pAttr; 06627 pAttr->IsItalic = Italic; 06628 06629 return TRUE; 06630 } 06631 06632 06633 06634 /******************************************************************************************** 06635 > Filter* FilterManager::FindFilterFromID(const UINT32 FilterID) const 06636 06637 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (moved into this class by Graham 7/7/97) 06638 Created: 10/12/96 06639 Purpose: Provides the Filter given its ID 06640 06641 (This function is also in Filter Manager. Unfortunately, having it there 06642 means that every time you use it you have to get a pointer to the 06643 application, then use that to get a pointer to the filter manager, then 06644 use that pointer to call this function. So I've copied it here for 06645 convenience) 06646 ********************************************************************************************/ 06647 06648 Filter* Filter::FindFilterFromID(const UINT32 FilterID) 06649 { 06650 Filter *pFilter; 06651 for( pFilter = Filter::GetFirst(); 06652 pFilter != 0; 06653 pFilter = Filter::GetNext(pFilter)) 06654 if (pFilter->FilterID == FilterID) 06655 { 06656 ERROR3IF(FilterID == FILTERID_NONE, 06657 "Filter::FindFilterFromID: filter has _R(ID_NONE)?"); 06658 break; 06659 } 06660 06661 return pFilter; 06662 } 06663 06664 06665 06666 /********************************************************************************************* 06667 > AttrRecordItem::AttrRecordItem() 06668 06669 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 06670 Created: 1/12/95 06671 Purpose: Constructor - initalises member variables 06672 **********************************************************************************************/ 06673 AttrRecordItem::AttrRecordItem() 06674 { 06675 RecordedAttrs = NULL; 06676 } 06677 06678 06679 /********************************************************************************************* 06680 > AttrRecordItem::~AttrRecordItem() 06681 06682 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 06683 Created: 1/12/95 06684 Purpose: Destructor - deletes any claimed memory 06685 **********************************************************************************************/ 06686 AttrRecordItem::~AttrRecordItem() 06687 { 06688 // Free the AttributeEntry array 06689 if (RecordedAttrs != NULL) 06690 CCFree(RecordedAttrs); 06691 } 06692 06693 06694 /********************************************************************************************* 06695 > BOOL AttrRecordItem::Initialise(AttributeEntry* pCurrAttrs) 06696 06697 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 06698 Created: 1/12/95 06699 Inputs: pCurrAttrs - an AttributeEntry array 06700 Outputs: - 06701 Returns: TRUE/FALSE for success/failure 06702 Purpose: Copies the current AttributeValues in the AttributeEntry array so the current 06703 state can be restored at a later date 06704 **********************************************************************************************/ 06705 BOOL AttrRecordItem::Initialise(AttributeEntry* pCurrAttrs) 06706 { 06707 const INT32 NumAttrs = AttributeManager::GetNumAttributes(); 06708 06709 // Claim memory for copy of AttributeEntry array 06710 RecordedAttrs = (AttributeEntry*)CCMalloc(NumAttrs*sizeof(AttributeEntry)); 06711 if (RecordedAttrs==NULL) 06712 return FALSE; 06713 06714 // store the temp values 06715 for (INT32 i=0; i<NumAttrs; i++) 06716 { 06717 // Get the runtime class info on this object and create another object of that type 06718 CCRuntimeClass *pCCRuntimeClass = pCurrAttrs[i].pAttr->GetRuntimeClass(); 06719 AttributeValue *pNewAttr = (AttributeValue *) pCCRuntimeClass->CreateObject(); 06720 if (pNewAttr == NULL) 06721 return FALSE; 06722 06723 // Object created ok - get the object to copy its contents across. 06724 pNewAttr->SimpleCopy(pCurrAttrs[i].pAttr); 06725 RecordedAttrs[i].pAttr = pNewAttr; 06726 } 06727 06728 return TRUE; 06729 } 06730 06731 06732 /********************************************************************************************* 06733 > BOOL AttrRecordItem::Restore(AttributeEntry* pCurrAttrs) 06734 06735 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 06736 Created: 1/12/95 06737 Inputs: pCurrAttrs - an AttributeEntry array 06738 Outputs: - 06739 Returns: TRUE/FALSE for success/failure 06740 Purpose: Copies the stored attribute state back into the current attribute array 06741 **********************************************************************************************/ 06742 BOOL AttrRecordItem::Restore(AttributeEntry* pCurrAttrs) 06743 { 06744 const INT32 NumAttrs = AttributeManager::GetNumAttributes(); 06745 06746 for (INT32 i=0; i<NumAttrs; i++) 06747 { 06748 if (RecordedAttrs[i].pAttr != NULL) 06749 { 06750 pCurrAttrs[i].pAttr->SimpleCopy(RecordedAttrs[i].pAttr); 06751 delete RecordedAttrs[i].pAttr; 06752 RecordedAttrs[i].pAttr = NULL; 06753 } 06754 } 06755 06756 return TRUE; 06757 } 06758 06759 06760 /********************************************************************************************* 06761 > AttrRecordList::AttrRecordList() 06762 06763 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 06764 Created: 1/12/95 06765 Purpose: Constructor - initalises member variables 06766 **********************************************************************************************/ 06767 AttrRecordList::AttrRecordList() 06768 { 06769 } 06770 06771 06772 /********************************************************************************************* 06773 > AttrRecordItem::~AttrRecordItem() 06774 06775 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 06776 Created: 1/12/95 06777 Purpose: Destructor - deletes any claimed memory 06778 **********************************************************************************************/ 06779 AttrRecordList::~AttrRecordList() 06780 { 06781 } 06782 06783 06784 /********************************************************************************************* 06785 > BOOL AttrRecordList::SaveContext(AttributeEntry* pCurrAttrs) 06786 06787 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 06788 Created: 1/12/95 06789 Inputs: pCurrAttrs - an AttributeEntry array 06790 Outputs: - 06791 Returns: TRUE/FALSE for success/failure 06792 Purpose: Stores the current state of the attribute entry array 06793 **********************************************************************************************/ 06794 BOOL AttrRecordList::SaveContext(AttributeEntry* pCurrAttrs) 06795 { 06796 // Create a new record 06797 AttrRecordItem* pItem = new AttrRecordItem; 06798 if (pItem==NULL) 06799 return FALSE; 06800 06801 // Copy the attributes into it 06802 if (!pItem->Initialise(pCurrAttrs)) 06803 { 06804 delete pItem; 06805 return FALSE; 06806 } 06807 else 06808 { 06809 AttrRecord.AddTail(pItem); 06810 return TRUE; 06811 } 06812 } 06813 06814 06815 /********************************************************************************************* 06816 > BOOL AttrRecordList::RestoreContext(AttributeEntry* pCurrAttrs) 06817 06818 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 06819 Created: 1/12/95 06820 Inputs: pCurrAttrs - an AttributeEntry array 06821 Outputs: - 06822 Returns: TRUE/FALSE for success/failure 06823 Purpose: Returns the current attribute array back to the stored state 06824 **********************************************************************************************/ 06825 BOOL AttrRecordList::RestoreContext(AttributeEntry* pCurrAttrs) 06826 { 06827 AttrRecordItem* pItem = (AttrRecordItem*)AttrRecord.RemoveTail(); 06828 ERROR2IF(pItem == NULL, FALSE, "Record list empty"); 06829 pItem->Restore(pCurrAttrs); 06830 delete pItem; 06831 06832 return TRUE; 06833 }