00001 // $Id: bitfilt.cpp 1762 2006-09-27 09:39:14Z 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 // Base class for bitmap filters (currently meaningful for export only) 00100 00101 00102 #include "camtypes.h" 00103 #include "bitfilt.h" 00104 00105 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "resource.h" // _R(IDS_OUT_OF_MEMORY) 00107 //#include "camvw.h" // sadly 00108 #include "layer.h" 00109 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00110 #include "page.h" 00111 //#include "tim.h" 00112 #include "grndbmp.h" 00113 #include "osrndrgn.h" 00114 #include "nodebmp.h" 00115 #include "bitmpinf.h" 00116 #include "progress.h" 00117 //#include "nev.h" // _R(IDN_USER_CANCELLED) 00118 //#include "bmpres.h" // general bitmap filter based resources 00119 #include "prvwflt.h" 00120 #ifndef WEBSTER 00121 //#include "extfilts.h" // Accusoft filters 00122 #endif //WEBSTER 00123 //#include "selop.h" 00124 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00125 #include "bmpexdoc.h" 00126 #include "impexpop.h" 00127 #include "zoomops.h" 00128 //#include "will3.h" // for _R(IDS_GENOPTPALMSGID) 00129 #include "nodetxtl.h" 00130 #include "qualattr.h" 00131 #include "ccbuffil.h" 00132 //#include "palman.h" 00133 #include "bmpprefs.h" 00134 #include "exjpeg.h" 00135 //#include "giffiltr.h" 00136 #include "grndbmp.h" 00137 00138 #include "bmapprev.h" 00139 00140 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00141 00142 #include "filtimag.h" //The imagemap filter class 00143 #include "filtrmgr.h" //The Filter Manager - used to find the imagemap filter 00144 //#include "resimmap.h" //Imagemap resources 00145 //#include "clipint.h" //To put text on the clipboard 00146 00147 #include "htmlfltr.h" //For HTMLFilter::ImportingHTML 00148 00149 #include "sprdmsg.h" // SpreadMsg 00150 #include "layermsg.h" // UPDATE_ACTIVE_LAYER 00151 00152 #include "fileutil.h" 00153 //#include "prevwres.h" // _R(IDS_DEFAULTFRAMENAME) 00154 //#include "will2.h" // _R(IDS_K_EPSFILTER_IMPORTED) 00155 //#include "phil.h" 00156 //#include "simon.h" 00157 00158 //#include "opbevel.h" // for bevel tools 00159 //#include "registry.h" 00160 //#include "sliceres.h" 00161 00162 #include "gpalopt.h" 00163 #include "colplate.h" 00164 #include "fillattr2.h" 00165 #include "nodetext.h" 00166 00167 CC_IMPLEMENT_MEMDUMP(BitmapImportOptions, CC_CLASS_MEMDUMP) 00168 CC_IMPLEMENT_DYNAMIC(BaseBitmapFilter, BitmapFilter) 00169 00170 // Declare smart memory handling in Debug builds 00171 #define new CAM_DEBUG_NEW 00172 00173 GRenderBitmap* BaseBitmapFilter::ExportRegion = NULL; // The region used for export 00174 CCLexFile* BaseBitmapFilter::OutputFile = NULL; // The file used for output 00175 BOOL BaseBitmapFilter::WrittenHeader = FALSE;// Have we done the first strip yet 00176 00177 UINT32 BaseBitmapFilter::SizeOfExport = 100; // defined progress bar size. 00178 UINT32 BaseBitmapFilter::OurNumNodes = 0; // our copy of the number of nodes being exported 00179 00180 LPLOGPALETTE BaseBitmapFilter::pOptimisedPalette = NULL; 00181 00182 BOOL BaseBitmapFilter::WeAreGeneratingOptPalette = FALSE; 00183 00184 const INT32 BaseBitmapFilter::MinPelsPerMeter = 1000; // Minimum Pels per meter allowed 00185 00186 const INT32 BaseBitmapFilter::MinExportSize = 10; // Minimum selection width/height allowed 00187 00188 KernelBitmap* BaseBitmapFilter::pExportBitmap = NULL; // Store for the bitmap pointr in DoExportBitmap 00189 00190 DPI BaseBitmapFilter::m_DefaultExportDPI = 96.0; // Used as the default DPI when exporting 00191 00192 LPLOGPALETTE BaseBitmapFilter::m_pBrowserPalette = NULL; 00193 00194 BOOL BaseBitmapFilter::s_fZoomOnImport = 9999; 00195 BOOL BaseBitmapFilter::s_fWarnedZoomOnImport = 9999; 00196 00197 // This constant gives you the ( square of the ) maximum distance that a colour has to be from a browser colour 00198 // to be snapped to that colour. 00199 const INT32 WEB_SNAP_OPTIMISED_DISTANCE_SQUARED = 25; 00200 00201 void PixelAlignedFiddle(DocRect*); 00202 00203 // Added by Craig Hamilton 29/8/00. 00204 INT32 BaseBitmapFilter::m_NumberOfPaletteEntries = 0; 00205 // End added. 00206 00207 /******************************************************************************************** 00208 00209 > BaseBitmapFilter::BaseBitmapFilter() 00210 00211 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00212 Created: 28/6/94 00213 Purpose: Constructor for an BaseBitmapFilter object. The object should be initialised 00214 before use. Base class version 00215 SeeAlso: BaseBitmapFilter::Init 00216 00217 ********************************************************************************************/ 00218 00219 BaseBitmapFilter::BaseBitmapFilter() 00220 { 00221 OutputFile = NULL; 00222 ExportRegion = NULL; 00223 pNewBitmap = NULL; 00224 InputFile = NULL; 00225 BackgroundRedrawState = FALSE; 00226 BackgroundRedrawStateSet = FALSE; 00227 ViewQualitySet = FALSE; 00228 IsPreviewBitmap = FALSE; 00229 pExportBitmap = NULL; 00230 pSpread = NULL; 00231 m_pImportOptions = NULL; 00232 m_pExportOptions = NULL; 00233 pOptimisedPalette = NULL; 00234 00235 WrittenHeader = FALSE;// Have we done the first strip yet 00236 RenderInStrips = TRUE; // Should we render in strips or not 00237 RenderBottomToTop = TRUE; // control over which way we render 00238 BadExportRender = FALSE;// whether the export rendering has gone ok or not 00239 00240 SizeOfExport = 100; // defined progress bar size. 00241 OurNumNodes = 0; // our copy of the number of nodes being exported 00242 00243 PaletteType = PAL_OPTIMISED; 00244 00245 //Should these lines be in or out - Martin 14/04/97 00246 PreviewDither = XARADITHER_ERROR_DIFFUSION; 00247 PreviewPalette = PAL_OPTIMISED; 00248 00249 WeAreGeneratingOptPalette = FALSE; 00250 ClipRect.MakeEmpty(); 00251 00252 m_pOptimisedPalette2 = NULL; 00253 m_pExportOptions = NULL; 00254 } 00255 00256 00257 00258 /******************************************************************************************** 00259 00260 > BaseBitmapFilter::~BaseBitmapFilter() 00261 00262 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00263 Created: 28/6/94 00264 Purpose: Destructor for an BaseBitmapFilter object. 00265 00266 ********************************************************************************************/ 00267 00268 BaseBitmapFilter::~BaseBitmapFilter() 00269 { 00270 // Clear up some dynamically allocated memory 00271 if (m_pOptimisedPalette2) 00272 { 00273 CCFree(m_pOptimisedPalette2); 00274 m_pOptimisedPalette2 = 0; 00275 } 00276 00277 if (m_pBrowserPalette) 00278 { 00279 CCFree(m_pBrowserPalette); 00280 m_pBrowserPalette = 0; 00281 } 00282 00283 delete m_pImportOptions; 00284 m_pImportOptions = 0; 00285 00286 // delete m_pExportOptions; 00287 m_pExportOptions = 0; 00288 } 00289 00290 00291 00292 /******************************************************************************************** 00293 00294 > BOOL BaseBitmapFilter::InitBaseClass() 00295 00296 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00297 Created: 23/5/97 00298 Returns: TRUE if the filter was initialized ok 00299 FALSE otherwise 00300 Purpose: Initialises any static member variables for the base bitmap filter 00301 class 00302 00303 ********************************************************************************************/ 00304 BOOL BaseBitmapFilter::InitBaseClass() 00305 { 00306 if( 9999 == s_fZoomOnImport && 00307 Camelot.DeclareSection( _T("Filters"), 10 ) ) 00308 { 00309 s_fZoomOnImport = TRUE; 00310 s_fWarnedZoomOnImport = FALSE; 00311 00312 Camelot.DeclarePref( NULL, _T("ZoomToFitOnImport"), &s_fZoomOnImport, FALSE, TRUE ); 00313 Camelot.DeclarePref( NULL, _T("WarnedZoomToFitOnImport"), &s_fWarnedZoomOnImport, FALSE, TRUE ); 00314 } 00315 00316 return BitmapExportOptions::Declare(); 00317 } 00318 00319 00320 /******************************************************************************************** 00321 00322 > void BaseBitmapFilter::SetPreviewBitmap(BOOL IsPreviewBmp) 00323 00324 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00325 Created: 2/2/95 00326 Inputs: isPreviewBmp - TRUE if this bitmap we are saving is actually a Preview bitmap 00327 FALSE if not. 00328 Purpose: Allows you to set the state of this flag. Always set it back to FALSE after 00329 the export as the filter hangs around, ready for the next export. 00330 00331 ********************************************************************************************/ 00332 00333 void BaseBitmapFilter::SetPreviewBitmap(BOOL IsPreviewBmp) 00334 { 00335 IsPreviewBitmap = IsPreviewBmp; 00336 } 00337 00338 00339 /******************************************************************************************** 00340 00341 > virtual BOOL BaseBitmapFilter::ExportVisibleLayersOnly() 00342 00343 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00344 Created: 14/02/95 00345 Inputs: - 00346 Outputs: - 00347 Returns: True if this filter wants to exclude invisible layers and so export only 00348 visible items Or False if want to export everything. 00349 Purpose: Determines if the filter wants to export only visible layers. 00350 In the base bitmap filters class version the default action will be to 00351 export only those layers which are visible. 00352 SeeAlso: Filter::ExportRender; 00353 00354 ********************************************************************************************/ 00355 00356 BOOL BaseBitmapFilter::ExportVisibleLayersOnly() 00357 { 00358 // only include all layer that are visible in this bitmap export 00359 return TRUE; 00360 } 00361 00362 00363 /******************************************************************************************** 00364 00365 > BOOL BaseBitmapFilter::IsSecondPassRequired() 00366 00367 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00368 Created: 18/09/95 00369 Returns: True if this filter wants a second export rendering pass and so have a chance 00370 to setup semething like a mask. False if no second pass required. 00371 Purpose: Determines if the a second rendering pass is required or not. 00372 SeeAlso: DoExport; 00373 00374 ********************************************************************************************/ 00375 00376 BOOL BaseBitmapFilter::IsSecondPassRequired() 00377 { 00378 return FALSE; 00379 } 00380 00381 /******************************************************************************************** 00382 00383 > virtual BOOL BaseBitmapFilter::IsDefaultDocRequired(const TCHAR* pcszPathName) 00384 00385 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00386 Created: 9/10/95 00387 Inputs: pcszPathName pointer to the pathname to check 00388 Returns: TRUE if the filter requires a default document, FALSE if not. 00389 Purpose: Works out if opening a file of this type requires a default document to be 00390 loaded. If the file format supplies the document then return FALSE otherwise 00391 return TRUE. An example would be opening a bitmap file. This has no document 00392 defined in the file format and so we need to laod the default document before 00393 importing the bitmap into this file. 00394 In this baseclass version return FALSE and hence assume that the filters that 00395 need to will override this function to return TRUE. 00396 SeeAlso: Filter; Filter::IsDefaultDocRequired; CCamDoc::OnOpenDocument; 00397 SeeAlso: FilterFamily::DoImport; Filter::DoImport; 00398 00399 ********************************************************************************************/ 00400 00401 BOOL BaseBitmapFilter::IsDefaultDocRequired(const TCHAR* pcszPathName) 00402 { 00403 // No need to check the pathname, just return TRUE as all currently known bitmap filters 00404 // will require the default document. 00405 return TRUE; 00406 } 00407 00408 00409 /******************************************************************************************** 00410 00411 > virtual void BaseCamelotFilter::IncProgressBarCount(UINT32 n) 00412 00413 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (Markn) 00414 Created: 5/6/96 00415 Inputs: n = amount to inc the progress bar count by 00416 Returns: - 00417 Purpose: Func to incrementing the progress bar count. 00418 If there is a progress bar available, it is updated by this call. 00419 Scope: Protected. 00420 00421 ********************************************************************************************/ 00422 BOOL BaseBitmapFilter::IncProgressBarCount(UINT32 n) 00423 { 00424 return TRUE; 00425 } 00426 00427 00428 /******************************************************************************************** 00429 00430 > virtual void BaseBitmapFilter::SetTotalProgressBarCount(UINT32 n) 00431 00432 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (Markn) 00433 Created: 5/6/96 00434 Inputs: n = amount to set the total progress bar count to 00435 Purpose: Func to set total the progress bar count. 00436 If there is a progress bar available, it is updated by this call. 00437 Scope: Protected. 00438 00439 ********************************************************************************************/ 00440 void BaseBitmapFilter::SetTotalProgressBarCount(UINT32 n) 00441 { 00442 ERROR3IF(n == 0,"Should only be set to a value greater that 0"); 00443 00444 m_TotalProgressBarCount = n; 00445 } 00446 00447 /******************************************************************************************** 00448 00449 > virtual BitmapSource* BaseBitmapFilter::CreateBitmapSource(FilePos Size) const 00450 00451 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00452 Created: 21/08/96 00453 Inputs: Size: The required size of the BitmapSource 00454 Returns: A pointer to a new BitmapSource 00455 Purpose: The PrepareToImport() function calls this member to create a BitmapSource 00456 for lossy file formats. 00457 The BaseBitmapFilter implementation returns NULL. 00458 Derived classes with lossy formats should override this function to provide 00459 a subclassed BitmapSource. 00460 SeeAlso: IsFormatLossy() 00461 Scope: protected 00462 00463 ********************************************************************************************/ 00464 BitmapSource* BaseBitmapFilter::CreateBitmapSource(OFFSET Size) const 00465 { 00466 return NULL; 00467 } 00468 00469 00470 /******************************************************************************************** 00471 00472 > BOOL BaseBitmapFilter::PrepareBitmapSource() 00473 00474 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00475 Created: 21/08/96 00476 Returns: TRUE if successful 00477 FALSE otherwise 00478 Purpose: The PrepareToImport() function calls this member to create a BitmapSource 00479 for lossy file formats, and a CCLexFile to work with it. 00480 SeeAlso: IsFormatLossy() 00481 Scope: protected 00482 00483 ********************************************************************************************/ 00484 BOOL BaseBitmapFilter::PrepareBitmapSource() 00485 { 00486 #ifdef DO_EXPORT 00487 OFFSET offset = GetDataStartOffset(); 00488 OFFSET size = InputFile->Size() - offset; 00489 00490 // Create the actual BitmapSource object 00491 m_pBitmapSource = CreateBitmapSource(size); 00492 if (m_pBitmapSource == NULL || !m_pBitmapSource->IsOK()) 00493 { 00494 Error::SetError(_R(IDS_OUT_OF_MEMORY)); 00495 return FALSE; 00496 } 00497 00498 // Check for errors but let CCFile report them 00499 InputFile->SetThrowExceptions(FALSE); 00500 InputFile->SetReportErrors(TRUE); 00501 00502 // Ignore those superfluous bits at the start of the file 00503 InputFile->seekIn(offset); 00504 if (!InputFile->good()) 00505 { 00506 return FALSE; 00507 } 00508 00509 // Now create a file to fill our BitmapSource & provide the filter with something 00510 // to work with 00511 CCBufferFile* pBufferFile = new CCBufferFile(InputFile); 00512 if (pBufferFile == NULL || !pBufferFile->IsInited()) 00513 { 00514 Error::SetError(_R(IDS_OUT_OF_MEMORY)); 00515 return FALSE; 00516 } 00517 00518 // We have a file, so attach out BitmapSource to it 00519 m_pBitmapSource->AttachToBufferFile(pBufferFile); 00520 00521 // Now ditch our current InputFile in favour of the BitmapSource's one 00522 // We don't need InputFile again 00523 InputFile = (CCLexFile*)pBufferFile; 00524 #endif 00525 00526 return TRUE; 00527 } 00528 00529 00530 /******************************************************************************************** 00531 00532 > virtual BOOL BaseBitmapFilter::PrepareToImport() 00533 00534 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00535 Created: 28/6/94 00536 Returns: TRUE if succeeded, FALSE if not. 00537 Purpose: Prepare to import bitmap data using this filter. This sets up the filter 00538 to a sensible state for reading. 00539 Errors: Out of memory. 00540 SeeAlso: BaseBitmapFilter::DoImport; BaseBitmapFilter::CleanUpAfterImport 00541 Scope: Private 00542 00543 ********************************************************************************************/ 00544 00545 BOOL BaseBitmapFilter::PrepareToImport() 00546 { 00547 ERROR2IF(InputFile == NULL, FALSE, "InputFile is NULL"); 00548 00549 // Assume we won't want a BitmapSource 00550 m_pBitmapSource = NULL; 00551 00552 #ifdef DO_EXPORT 00553 // Do we need to keep the data to prevent it from deteriorating? 00554 if (IsFormatLossy()) 00555 { 00556 // SetTotalProgressBarCount(InputFile->Size()); ...one day 00557 if (!PrepareBitmapSource()) 00558 { 00559 return FALSE; 00560 } 00561 } 00562 #endif 00563 return TRUE; 00564 } 00565 00566 /******************************************************************************************** 00567 00568 > void BaseBitmapFilter::CleanUpAfterImport() 00569 00570 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00571 Created: 28/6/94 00572 Purpose: Cleans up the memory allocated by BaseBitmapFilter::PrepareToImport() - used 00573 when the import process ends, either normally or abnormally. 00574 SeeAlso: BaseBitmapFilter::PrepareToImport; BaseBitmapFilter::DoImport 00575 Scope: Private 00576 00577 ********************************************************************************************/ 00578 00579 void BaseBitmapFilter::CleanUpAfterImport() 00580 { 00581 TheDocument = NULL; 00582 00583 //WEBSTER-Martin-02/01/97 00584 #ifndef WEBSTER 00585 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00586 // Reset the filter type used by the Accusoft filters so that it can cache the 00587 // filter type correctly and so only call the Accusoft DLL on the first filter 00588 // rather than on all filters. 00589 00590 AccusoftFilters::ResetFilterType(); 00591 00592 #endif 00593 #endif //WEBSTER 00594 } 00595 00596 /******************************************************************************************** 00597 00598 > BitmapImportOptions* BaseBitmapFilter::GetImportOptions() 00599 00600 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00601 Created: 22/11/94 00602 Inputs: None 00603 Outputs: None 00604 Returns: A pointer to BitmapImportOptions with the options in it set. 00605 NULL if an error occured. 00606 Purpose: To allow a filter to offer the user a choice over what gets imported. 00607 Derived BaseBitmapFilter classes should also derive a new BitmapImportOptions 00608 class and return a new copy on the heap with the user options in it. 00609 BaseBitmapFilter will delete the BitmapImportOptions class when no longer needed. 00610 At present used by PhotoCD filter to get image to import. 00611 SeeAlso: BaseBitmapFilter::PrepareToImport; BaseBitmapFilter::DoImport 00612 Scope: Protected 00613 00614 ********************************************************************************************/ 00615 00616 BitmapImportOptions* BaseBitmapFilter::GetImportOptions() 00617 { 00618 BitmapImportOptions* pOptions = new BitmapImportOptions; 00619 return pOptions; 00620 } 00621 00622 00623 /******************************************************************************************** 00624 00625 > virtual BOOL BaseBitmapFilter::IsFormatLossy() const 00626 00627 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00628 Created: 20/08/96 00629 00630 Returns: TRUE if the file format for the derived filter is lossy 00631 FALSE otherwise 00632 00633 Purpose: Provides information to the BaseBitmapFilter so that it knows whether 00634 or not to provide a BitmapSource to prevent progressive degradation of 00635 the bitmap when exported via the new file format. 00636 Notes: Derived classes should override this function for their particular 00637 implementation. 00638 00639 ********************************************************************************************/ 00640 BOOL BaseBitmapFilter::IsFormatLossy() const 00641 { 00642 return FALSE; 00643 } 00644 00645 00646 /******************************************************************************************** 00647 00648 > virtual OFFSET BaseBitmapFilter::GetDataStartOffset() const 00649 00650 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00651 Created: 20/08/96 00652 00653 Returns: The offset from the HeaderStart parameter given in HowCompatible(), 00654 from which data essential to the correct functionality of this filter 00655 starts. 00656 00657 Purpose: Provides information to the BaseBitmapFilter, so that it knows where 00658 to start any required BitmapSource. It will only be useful to derived 00659 classes that deal with a lossy file format. 00660 Notes: The default implementation returns zero, assuming there is no useless 00661 garbage before any actual header. Derived classes should override this 00662 for any special case. 00663 00664 See Also: IsFormatLossy() 00665 00666 ********************************************************************************************/ 00667 OFFSET BaseBitmapFilter::GetDataStartOffset() const 00668 { 00669 return 0; 00670 } 00671 00672 00673 /******************************************************************************************** 00674 00675 > BOOL BaseBitmapFilter::DoImport(SelOperation *Op, CCLexFile* pFile, 00676 Document *DestDoc, BOOL AutoChosen, ImportPosition *Pos, 00677 KernelBitmap** ppImportedBitmap, 00678 DocCoord* pPosTranslate, String_256* URL) 00679 00680 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00681 Created: 28/6/94 00682 Inputs: Op - pointer to the operation that this input process is associated with. 00683 pFile - The file that we should load the bitmap from 00684 DestDoc - The Document object which should hold the data read in from 00685 the bitmap. 00686 ImportPosition - 00687 ppImportedBitmap - Used to set the bitmap background 00688 pPosTranslate - specify the position of the bitmap on the screen 00689 Returns: TRUE if the input operation worked ok, FALSE if not. 00690 Purpose: Read bitmap data from a file. This is the same for all bitmap filters; 00691 the ImportBitmap() function should be over-ridden for actual bitmap 00692 import filters. 00693 Errors: Fails (returns FALSE) if the document structure is incorrect, or if there 00694 is a problem with the bitmap. 00695 00696 ********************************************************************************************/ 00697 00698 BOOL BaseBitmapFilter::DoImport(SelOperation *Op, CCLexFile* pFile, 00699 Document *DestDoc, BOOL AutoChosen, ImportPosition *Pos, 00700 KernelBitmap** ppImportedBitmap, 00701 DocCoord* pPosTranslate, String_256* URL) 00702 { 00703 ERROR2IF(Op == NULL, FALSE, "BaseBitmapFilter::DoImport NULL operation supplied"); 00704 ERROR2IF(pFile == NULL, FALSE, "BaseBitmapFilter::DoImport NULL diskfile supplied"); 00705 ERROR2IF(DestDoc == NULL, FALSE, "BaseBitmapFilter::DoImport NULL doc supplied"); 00706 00707 // Make a note of the disk file we are given 00708 InputFile = pFile; 00709 00710 // Set up the class variable which is used by the bitmap system to determine which document 00711 // to load the bitmap into. Added 24/9/96 as opening a PhotoCD causes the selection to change! 00712 // Removing the photocd import dialog box causes the selection to be put into an existing doc 00713 // rather than a new one. 00714 TheDocument = DestDoc; 00715 00716 if (ProcessImportOptions() == FALSE) 00717 return FALSE; 00718 00719 Spread *pSpread = NULL; 00720 DocCoord Origin; 00721 00722 //So first find the current view 00723 DocView* pDocView=DocView::GetCurrent(); 00724 00725 if (Pos == NULL) 00726 { 00727 // For now, position Draw objects on 1st page of spread 1 00728 00729 //Graham 30/6/97: We now position imported bitmaps in the top left of the view 00730 00731 ERROR2IF(pDocView==NULL, FALSE, "BaseBitmapFilter::DoImport - no current view"); 00732 00733 //And get the centre coordinate 00734 Origin=pDocView->GetTopLeftCoord(); 00735 00736 // Find the first spread in that document. 00737 pSpread = TheDocument->FindFirstSpread (); 00738 } 00739 else 00740 { 00741 pSpread = Pos->pSpread; 00742 Origin = Pos->Position; 00743 } 00744 00745 // If we use the PhotoCD import then current/selected doc/spread MAY be wrong. So force it again. 00746 // Must ensure the selected spread is in the destination document as otherwise we will insert the 00747 // object AFTER the insertion node and hence in an illegal position. 00748 Document::SetSelectedViewAndSpread(DestDoc, DocView::GetCurrent(), pSpread); 00749 00750 // Let's get ready 00751 if (!PrepareToImport()) 00752 return FALSE; 00753 00754 UINT32 nBitmapToRead = 0; 00755 Layer* pNewLayer = NULL; 00756 Layer* pNewActiveLayer = NULL; 00757 do // for every bitmap in the file 00758 { 00759 KernelBitmap* pKernelBmp = NULL; 00760 ++nBitmapToRead; 00761 00762 // Import that bitmap, if first bitmap then nBitmapToRead will be set to 1 00763 BOOL Success = ImportBitmap(pFile, &pKernelBmp, nBitmapToRead); 00764 if (!Success) 00765 { 00766 if (m_pImportOptions != NULL) 00767 { 00768 delete m_pImportOptions; 00769 m_pImportOptions = NULL; 00770 } 00771 00772 // Did not work - report this to the caller. 00773 return FALSE; 00774 } 00775 00776 // If the caller wants to handle the imported bitmap, then set the return pointer up, 00777 // otherwise, we handle the bitmap by inserting a NodeBitmap into the document 00778 if (ppImportedBitmap != NULL && pPosTranslate == NULL) 00779 *ppImportedBitmap = pKernelBmp; 00780 else 00781 { 00782 // Get a new NodeBitmap object to import into. 00783 NodeBitmap *pNodeBitmap = new NodeBitmap; 00784 if ((pNodeBitmap == NULL) || (!pNodeBitmap->SetUpPath(12,12))) 00785 { 00786 if (m_pImportOptions != NULL) 00787 { 00788 delete m_pImportOptions; 00789 m_pImportOptions = NULL; 00790 } 00791 if (pNodeBitmap != NULL) 00792 delete pNodeBitmap; 00793 00794 return FALSE; 00795 } 00796 00797 pNodeBitmap->GetBitmapRef()->Attach(pKernelBmp, DestDoc); //GetDocument()); 00798 00799 if (pNodeBitmap->GetBitmap() != pKernelBmp) 00800 { 00801 // It didn't use the bitmap we gave it, so we can delete it 00802 delete pKernelBmp; 00803 } 00804 00805 //And if the caller wants a pointer to the kernel bitmap, give them one... 00806 if (ppImportedBitmap) 00807 { 00808 *ppImportedBitmap=pNodeBitmap->GetBitmap(); 00809 } 00810 00811 // Import worked - try to add the bitmap object into the tree. 00812 // First, set the rectangle to the right size for the bitmap... 00813 BitmapInfo Info; 00814 pNodeBitmap->GetBitmap()->ActualBitmap->GetInfo(&Info); 00815 00816 const INT32 HPixelSize = ( pDocView->GetPixelWidth() + 0.5 ).MakeLong(); // Size of output pixel in millipoints 00817 const INT32 VPixelSize = ( pDocView->GetPixelHeight() + 0.5 ).MakeLong();// Size of output pixel in millipoints 00818 00819 DocRect BoundsRect; 00820 BoundsRect.lo = Origin; 00821 // Make sure that this is snapped to a pixel grid 00822 BoundsRect.lo.x = GridLock(BoundsRect.lo.x, HPixelSize); 00823 BoundsRect.lo.y = GridLock(BoundsRect.lo.y, VPixelSize); 00824 // And now add in the rest of the bounds 00825 BoundsRect.hi.x = BoundsRect.lo.x + Info.RecommendedWidth; 00826 BoundsRect.hi.y = BoundsRect.lo.y + Info.RecommendedHeight; 00827 BoundsRect.hi.x = GridLock(BoundsRect.hi.x, HPixelSize); 00828 BoundsRect.hi.y = GridLock(BoundsRect.hi.y, VPixelSize); 00829 00830 // And set this in our bitmap node 00831 pNodeBitmap->CreateShape(BoundsRect); 00832 00833 // Make sure that there is a layer to put the bitmap onto 00834 if (!MakeSureLayerExists(DestDoc)) 00835 { 00836 // There is no layer and one could not be made, so we will have to fail 00837 delete pNodeBitmap; 00838 if (m_pImportOptions != NULL) 00839 { 00840 delete m_pImportOptions; 00841 m_pImportOptions = NULL; 00842 } 00843 return FALSE; 00844 } 00845 00846 // Set the default attrs 00847 // This MUST be done before the NodeBitmap is Inserted into the tree 00848 if (!pNodeBitmap->ApplyDefaultBitmapAttrs(Op)) 00849 { 00850 if (m_pImportOptions != NULL) 00851 { 00852 delete m_pImportOptions; 00853 m_pImportOptions = NULL; 00854 } 00855 return FALSE; 00856 } 00857 00858 // Insert the node, but don't invalidate its region 00859 // If we are the only bitmap then just add it as the first child of the active layer 00860 // Could use Filter::ImportWithLayers to determine if we use layers or not 00861 BOOL Fail = FALSE; 00862 BOOL SingleBitmap = !AreBitmapsToRead() && nBitmapToRead <= 1; 00863 00864 //Graham 30/5/97 00865 //If we're importing an animated bitmap as part of an 00866 //HTML document 00867 PORTNOTE("filters","Removed HTMLFilter usage") 00868 if( !SingleBitmap 00869 #ifndef EXCLUDE_FROM_XARALX 00870 && HTMLFilter::ImportingHTML 00871 #endif 00872 ) 00873 { 00874 //Then turn the "all layers visible" flag on in the document 00875 DestDoc->SetMultilayer(TRUE); 00876 DestDoc->SetAllVisible(TRUE); 00877 } 00878 00879 if (SingleBitmap || !Filter::ImportBitmapsOntoLayers) 00880 { 00881 // This inserts the node as the last child of the active layer 00882 if (!Op->DoInsertNewNode(pNodeBitmap, pSpread, FALSE)) 00883 { 00884 Fail = TRUE; 00885 // It didn't work - delete the sub-tree we just created, and report error. 00886 pNodeBitmap->CascadeDelete(); 00887 // Of course, Cascade delete does not actually delete the node itself, so now do that 00888 delete pNodeBitmap; 00889 pNodeBitmap = NULL; 00890 } 00891 } 00892 else 00893 { 00894 // We are not the only bitmap in the loading process so for each bitmap try and create 00895 // a new layer and put the new bitmap there. 00896 // The first layer should be added after the active layer. 00897 // We could do this but this means that when multiple animations are being loaded you 00898 // end up with the first frames close together rather than the two animations being 00899 // separate. 00900 if (!InsertBitmapOnNewLayer(Op, pSpread, pNodeBitmap, &pNewLayer)) 00901 { 00902 Fail = TRUE; 00903 // It didn't work - delete the sub-tree we just created, and report error. 00904 pNodeBitmap->CascadeDelete(); 00905 // Of course, Cascade delete does not actually delete the node itself, so now do that 00906 delete pNodeBitmap; 00907 pNodeBitmap = NULL; 00908 } 00909 // Remember the layer we used for the first bitmap so that we can make it active 00910 if (nBitmapToRead == 1) 00911 pNewActiveLayer = pNewLayer; 00912 00913 // Let the filter set things up from the bitmap on the layer 00914 // GIF filter can use disposal method to set overlay and solid flags 00915 KernelBitmap * pBitmap = pNodeBitmap->GetBitmap(); 00916 SetFlagsFromBitmap(pNewLayer, pBitmap, nBitmapToRead); 00917 } 00918 // If we noted a failure then handle it now 00919 if (Fail) 00920 { 00921 if (m_pImportOptions != NULL) 00922 { 00923 delete m_pImportOptions; 00924 m_pImportOptions = NULL; 00925 } 00926 return FALSE; 00927 } 00928 00929 // and move it to the correct location if we need to... 00930 DocCoord Offset(0,0); 00931 if (GetDragAndDropTranslation(Pos, BoundsRect, &Offset)) 00932 { 00933 // See if the bitmap contained an offset and if it did add it in 00934 // Baseclass defaults to 0,0 offset 00935 AddOffsetFromBitmap(&Offset); 00936 00937 Offset.x = GridLock(Offset.x, HPixelSize); 00938 Offset.y = GridLock(Offset.y, VPixelSize); 00939 00940 // Build the matrix and transform the bitmap to the correct place 00941 Trans2DMatrix Xlate(Offset.x, Offset.y); 00942 pNodeBitmap->Transform(Xlate); 00943 } 00944 else 00945 { 00946 // No drag and drop - bitmap is currently positioned so its bottom left hand 00947 // corner is at the top left of the page - translate it down by its height so 00948 // that the top left corner of the bitmap is aligned to the top left corner 00949 // of the page. 00950 00951 // Do we have an additional translation to apply? 00952 if (pPosTranslate != NULL) 00953 { 00954 Offset.x = pPosTranslate->x; 00955 Offset.y = pPosTranslate->y; 00956 } 00957 00958 // See if the bitmap contained an offset as well and if it did add it in 00959 // Baseclass defaults to 0,0 offset 00960 AddOffsetFromBitmap(&Offset); 00961 00962 Offset.x = GridLock(Offset.x, HPixelSize); 00963 Offset.y = GridLock(Offset.y, VPixelSize); 00964 00965 Trans2DMatrix Xlate(Offset.x, -(Info.RecommendedHeight) + Offset.y); 00966 pNodeBitmap->Transform(Xlate); 00967 } 00968 00969 // Invalidate the region 00970 Success = Op->DoInvalidateNodeRegion(pNodeBitmap, TRUE, FALSE); 00971 if (!Success) 00972 { 00973 if (m_pImportOptions != NULL) 00974 { 00975 delete m_pImportOptions; 00976 m_pImportOptions = NULL; 00977 } 00978 return FALSE; // hmmm.... 00979 } 00980 00981 DocRect docrectBounds = pNodeBitmap->GetBoundingRect(); 00982 DocRect docrectView = pDocView->GetDocViewRect( pSpread ); 00983 pSpread->DocCoordToSpreadCoord( &docrectView ); 00984 if( ( docrectBounds.lo.x < docrectView.lo.x || 00985 docrectBounds.lo.y < docrectView.lo.y || 00986 docrectBounds.hi.x > docrectView.hi.x || 00987 docrectBounds.hi.y > docrectView.hi.y ) && 00988 s_fZoomOnImport ) 00989 { 00990 // Calculate bounding rect of view plus new photo and then make sure that edges in 00991 // in both axes grow by same amount. We make use of the fact that zoom code only allows 00992 // zooming in both axes by the same amount, so we don't need to make sure that growth in 00993 // both axes is by the same percentage. 00994 docrectBounds = docrectBounds.Union( docrectView ); 00995 if( docrectView.lo.x - docrectBounds.lo.x > docrectBounds.hi.x - docrectView.hi.x ) 00996 docrectBounds.hi.x = docrectView.hi.x + docrectView.lo.x - docrectBounds.lo.x; 00997 else 00998 docrectBounds.lo.x = docrectView.lo.x - docrectBounds.hi.x + docrectView.hi.x; 00999 if( docrectView.lo.y - docrectBounds.lo.y > docrectBounds.hi.y - docrectView.hi.y ) 01000 docrectBounds.hi.y = docrectView.hi.y + docrectView.lo.y - docrectBounds.lo.y; 01001 else 01002 docrectBounds.lo.y = docrectView.lo.y - docrectBounds.hi.y + docrectView.hi.y; 01003 01004 OpZoomFitRectDescriptor* pOpDesc = (OpZoomFitRectDescriptor*)OpDescriptor::FindOpDescriptor( OPTOKEN_ZOOMRECT ); 01005 if( NULL != pOpDesc ) 01006 { 01007 pOpDesc->SetZoomRect( docrectBounds ); 01008 pOpDesc->Invoke(); 01009 } 01010 01011 if( !s_fWarnedZoomOnImport ) 01012 { 01013 ErrorInfo Info; 01014 memset( &Info, 0, sizeof(Info) ); 01015 Info.ErrorMsg = _R(IDS_ZOOM_ON_IMAGE_IMPORT); 01016 Info.Button[0] = _R(IDS_OK); 01017 Info.Button[1] = _R(IDS_DONT_SHOW_AGAIN); 01018 Info.OK = 1; 01019 if( _R(IDS_DONT_SHOW_AGAIN) == UINT32(InformMessage( &Info )) ) 01020 s_fWarnedZoomOnImport = TRUE; 01021 } 01022 } 01023 } 01024 } 01025 while (AreBitmapsToRead()); 01026 01027 // If we have loaded bitmaps onto layers and hence requested a new active layer then set 01028 // it now. 01029 // Graham 1/8/97: If we are importing an animated GIF as part of an HTML page, we don't 01030 // change the active layer, because this may result in subsequent bitmaps in the HTML 01031 // page being imported on the wrong layer. 01032 PORTNOTE("filters","Removed HTMLFilter usage") 01033 if( pNewActiveLayer 01034 #ifndef EXCLUDE_FROM_XARALX 01035 && !HTMLFilter::ImportingHTML 01036 #endif 01037 ) 01038 { 01039 // If the old active layer is blank and has nothing on it, then delete it 01040 Layer * pActiveLayer = pSpread->FindActiveLayer(); 01041 if (pActiveLayer) 01042 { 01043 // Scans the layer for children that render something on the screen. 01044 // It ignores attributes, hidden nodes, etc - nodes that don't render anything themselves. 01045 Node* pNode = pActiveLayer->FindFirstChild(); 01046 BOOL ChildFound = FALSE; 01047 while (pNode != NULL && !ChildFound) 01048 { 01049 ChildFound = pNode->IsBounded(); 01050 pNode = pNode->FindNext(); 01051 } 01052 // Hide the old active layer 01053 if (!ChildFound) 01054 Op->DoHideNode(pActiveLayer, TRUE); 01055 } 01056 01057 // Check that all visible layers are actually frame layers as we have 01058 // created some new frame layers for each of the bitmaps. 01059 PORTNOTE("dialog","Removed FrameSGallery usage") 01060 #ifndef EXCLUDE_FROM_XARALX 01061 FrameSGallery::MakeActiveLayer(pNewActiveLayer); 01062 #endif 01063 BROADCAST_TO_ALL( LayerMsg( pNewActiveLayer, LayerMsg::UPDATE_ACTIVE_LAYER ) ); 01064 01065 // Try and fix up the animation properties according to the bitmaps that have been loaded in 01066 SetAnimationPropertiesFromLoaded(pSpread); 01067 } 01068 01069 // Ensure Sel Bounds are correct after translation 01070 GetApplication()->UpdateSelection(); 01071 01072 if (m_pImportOptions != NULL) 01073 { 01074 delete m_pImportOptions; 01075 m_pImportOptions = NULL; 01076 } 01077 // All ok 01078 01079 return TRUE; 01080 } 01081 01082 /******************************************************************************************** 01083 01084 > BOOL BaseBitmapFilter::InsertBitmapOnNewLayer(SelOperation *pOp, Spread * pSpread, NodeBitmap *pNodeBitmap, 01085 Layer ** ppNewLayer) 01086 01087 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01088 Created: 6/5/97 01089 Inputs: pOp the operation to use to insert new items 01090 pSpread the spread we are using 01091 pNodeBitmap the new node bitmap which is to be inserted 01092 Outputs: ppNewlayer the new layer that was inserted (ready to be used next time around) 01093 Returns: TRUE if everything was insert ok, FALSE otherwise. 01094 Purpose: When loading in multiple bitmaps then each bitmap should be inserted onto 01095 a new layer. The first bitmap is inserted as the last child on the active 01096 layer. Each subsequent bitmap is loaded onto a new layer after this. 01097 The routine returns the new layer so that this can be used next time as the 01098 insertion point. 01099 SeeAlso: BaseBitmapFilter::DoImport 01100 01101 ********************************************************************************************/ 01102 01103 BOOL BaseBitmapFilter::InsertBitmapOnNewLayer(SelOperation *pOp, Spread * pSpread, NodeBitmap *pNodeBitmap, 01104 Layer ** ppNewLayer) 01105 { 01106 ERROR2IF(pOp == NULL || pSpread == NULL || pNodeBitmap == NULL || ppNewLayer == NULL,FALSE,"InsertBitmapOnNewLayer bad parameters!"); 01107 01108 Layer * pCurrentLayer = NULL; 01109 if (*ppNewLayer) 01110 { 01111 // We have been supplied with the last inserted new layer so use this. 01112 pCurrentLayer = *ppNewLayer; 01113 } 01114 else 01115 { 01116 // We are the first time through and so try and create 01117 // a layer after the active layer and put the bitmap there. 01118 // We could do this but we get problems when loading multiple animations. So 01119 // do what we do elsewhere and load after the last layer. 01120 Layer * pInsertionLayer = pSpread->FindLastLayer(); 01121 01122 // No Active layer so get out now! 01123 if (pInsertionLayer == NULL) 01124 return FALSE; 01125 01126 // Use the active layer as the insertion point 01127 pCurrentLayer = pInsertionLayer; 01128 } 01129 01130 // Create the new layer 01131 Layer* pNewLayer = new Layer; 01132 if (pNewLayer == NULL) 01133 return FALSE; 01134 01135 // Ensure that the layer name has a frame flavour about it 01136 // We also need to add an imported at the start so that if the original Frame 1 01137 // layer is deleted as it has nothing on it, then the layer is not called Frame 2 01138 // but Imported Frame 1 01139 String_256 LayerName(_R(IDS_K_EPSFILTER_IMPORTED)); 01140 String_256 Suffix(_R(IDS_DEFAULTFRAMENAME)); // Frame 01141 LayerName += Suffix; 01142 PORTNOTE("dialog","Removed FrameSGallery usage") 01143 #ifndef EXCLUDE_FROM_XARALX 01144 String_256 NewLayerName = FrameSGallery::CreateUniqueLayerID(pSpread, &LayerName); 01145 #else 01146 String_256 NewLayerName = ""; 01147 #endif 01148 pNewLayer->SetLayerID(NewLayerName); 01149 01150 pNewLayer->SetVisible(TRUE); // Ensure visible 01151 pNewLayer->SetLocked(FALSE); // Ensure unlocked so insertion works 01152 pNewLayer->SetPrintable(FALSE); 01153 pNewLayer->SetBackground(FALSE); // Ensure it is foreground 01154 pNewLayer->SetOutline(FALSE); 01155 pNewLayer->SetGuide(FALSE); 01156 pNewLayer->SetPageBackground(FALSE); 01157 #ifdef WEBSTER 01158 // In Webster mode, always make the new layer a frame layer 01159 pNewLayer->SetFrame(TRUE); // Mark it as a frame layer 01160 #else 01161 // In Camelot mode, only make the new layer a frame layer if there are 01162 // already frame layers in the document 01163 Layer * pFrame = pSpread->FindFirstFrameLayer(); 01164 if (pFrame != NULL) 01165 pNewLayer->SetFrame(TRUE); // Mark it as a frame layer 01166 else 01167 pNewLayer->SetFrame(FALSE); // Mark it as a layer 01168 #endif 01169 // Insert the new layer as the next node after the last page. 01170 if (!pOp->DoInsertNewNode(pNewLayer, pCurrentLayer, NEXT, FALSE,FALSE,FALSE,FALSE)) 01171 { 01172 delete pNewLayer; 01173 pNewLayer = NULL; 01174 // Return the new layer to the caller 01175 *ppNewLayer = pNewLayer; 01176 return FALSE; 01177 } 01178 01179 // And now insert the bitmap node into the new layer 01180 if (!pOp->DoInsertNewNode(pNodeBitmap, pNewLayer, FIRSTCHILD,FALSE,FALSE,FALSE,FALSE)) 01181 { 01182 // It didn't work - hide the layer sub-tree we just created 01183 pOp->DoHideNode(pNewLayer, TRUE); 01184 // Return the new layer to the caller as null 01185 *ppNewLayer = NULL; 01186 // Assume the caller deletes the node bitmap 01187 return FALSE; 01188 } 01189 01190 pNewLayer->SetVisible(FALSE); // Ensure it is invisible 01191 pNewLayer->SetLocked(TRUE); // Ensure locked 01192 01193 // Set the fact that this layer is presently fully defined by this bitmap 01194 KernelBitmap * pBitmap = pNodeBitmap->GetBitmap(); 01195 pNewLayer->SetReferencedBitmap(pBitmap); 01196 01197 pNewLayer->EnsureUniqueLayerID(); 01198 BROADCAST_TO_ALL( SpreadMsg( pSpread, SpreadMsg::LAYERCHANGES ) ); 01199 01200 // Return the new layer to the caller 01201 *ppNewLayer = pNewLayer; 01202 01203 return TRUE; 01204 } 01205 01206 /******************************************************************************************** 01207 01208 > virtual BOOL BaseBitmapFilter::SetFlagsFromBitmap(Layer * pLayer, KernelBitmap * pBitmap, 01209 UINT32 nBitmapToRead) 01210 01211 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01212 Created: 20/5/97 01213 Inputs: pLayer the layer that the bitmap is being put on 01214 pBitmap the bitmap being placed on the layer 01215 nBitmapToRead the number of the bitmap in the sequence 01216 Returns: TRUE if was ok, FALSE otherwise. 01217 Purpose: When loading in multiple bitmaps and placing them on new layers, we should 01218 give the filter an opportunity to set the layer flags from the bitmap. In the 01219 case of a GIF filter this would allow it to set the solid and overlay flags. 01220 This baseclass version does nothing. 01221 01222 ********************************************************************************************/ 01223 01224 BOOL BaseBitmapFilter::SetFlagsFromBitmap(Layer * pLayer, KernelBitmap * pBitmap, 01225 UINT32 nBitmapToRead) 01226 { 01227 // Do nothing 01228 return TRUE; 01229 } 01230 01231 /******************************************************************************************** 01232 01233 > BOOL BaseBitmapFilter::AddOffsetFromBitmap(DocCoord * pOffset) 01234 01235 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01236 Created: 15/5/97 01237 Inputs: pOffset the present offset in the bitmap 01238 Returns: TRUE if was ok, FALSE otherwise. 01239 Purpose: When loading in a bitmap, the bitmap definition may contain an offset. We need 01240 to add this to the offset that we are given so that the bitmap is loaded at 01241 the correct position. 01242 This baseclass version does nothing. 01243 01244 ********************************************************************************************/ 01245 01246 BOOL BaseBitmapFilter::AddOffsetFromBitmap(DocCoord * pOffset) 01247 { 01248 // Do nothing 01249 return TRUE; 01250 } 01251 01252 /******************************************************************************************** 01253 01254 > virtual BOOL BaseBitmapFilter::SetAnimationPropertiesFromLoaded(Spread * pSpread) 01255 01256 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01257 Created: 8/7/97 01258 Inputs: pSpread the spread that the bitmaps have been put on 01259 Returns: TRUE if was ok, FALSE otherwise. 01260 Purpose: When loading in multiple bitmaps and placing them on new layers, we should 01261 give the filter an opportunity after all the bitmaps have been loaded, to go 01262 and look at the bitmaps and set the animation properties accordingly. 01263 In the case of a GIF filter this would allow it to set the dithering to none 01264 and the palette to something closer to what has been loaded. 01265 This baseclass version does nothing. 01266 01267 ********************************************************************************************/ 01268 01269 BOOL BaseBitmapFilter::SetAnimationPropertiesFromLoaded(Spread * pSpread) 01270 { 01271 // Do nothing 01272 return TRUE; 01273 } 01274 01275 /******************************************************************************************** 01276 01277 > BOOL BaseBitmapFilter::ImportBitmap(CCLexFile* pDiskFile, KernelBitmap** ppBitmap) 01278 01279 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01280 Created: 8/4/94 01281 Inputs: - 01282 Returns: TRUE if the bitmap was imported ok (or if it wasn't imported because the 01283 file format does not support it; 01284 FALSE if an error occured. 01285 Purpose: - 01286 Errors: Usual disk/file errors. 01287 SeeAlso: CamelotEPSFilter::ExportBitmap 01288 01289 ********************************************************************************************/ 01290 01291 BOOL BaseBitmapFilter::ImportBitmap(CCLexFile* pDiskFile, KernelBitmap** ppBitmap) 01292 { 01293 // Make a note of the disk file we are given 01294 InputFile = pDiskFile; 01295 01296 if (ProcessImportOptions() == FALSE) 01297 return FALSE; 01298 01299 // Let's get ready 01300 if (!PrepareToImport()) 01301 return FALSE; 01302 01303 if (!ImportBitmap(pDiskFile, ppBitmap, 1)) 01304 { 01305 if (m_pImportOptions != NULL) 01306 { 01307 delete m_pImportOptions; 01308 m_pImportOptions = NULL; 01309 } 01310 return FALSE; 01311 } 01312 if (m_pImportOptions != NULL) 01313 { 01314 delete m_pImportOptions; 01315 m_pImportOptions = NULL; 01316 } 01317 return TRUE; 01318 } 01319 01320 01321 /******************************************************************************************** 01322 01323 > BOOL BaseBitmapFilter::ImportBitmap(CCLexFile* pDiskFile, KernelBitmap** ppBitmap, const UINT32 nBitmapToRead) 01324 01325 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01326 Created: 12/06/96 01327 Inputs: pDiskFile - the CCLexFile from which the bitmap should be imported 01328 nBitmapToRead - the position of the bitmap in the CCLexFile 01329 Outputs: ppBitmap - a pointer to the KernelBitmap into which the bitmap will be 01330 imported 01331 Returns: TRUE if the bitmap was imported ok (or if it wasn't imported because the 01332 file format does not support it; 01333 FALSE if an error occured. 01334 Purpose: Imports the nBitmapToRead'th bitmap from the given file. 01335 This may be used to import a file either via the menu or from the EPS filters. 01336 Errors: 01337 SeeAlso: CamelotEPSFilter::ExportBitmap, DoImport(), SGLibOil:: 01338 01339 ********************************************************************************************/ 01340 01341 BOOL BaseBitmapFilter::ImportBitmap(CCLexFile* pDiskFile, KernelBitmap** ppBitmap, const UINT32 nBitmapToRead) 01342 { 01343 ERROR2IF(pDiskFile == NULL, FALSE, "pDiskFile - invalid"); 01344 ERROR2IF(ppBitmap == NULL, FALSE, "ppBitmap is NULL"); 01345 ERROR2IF(nBitmapToRead < 1, FALSE, "nBitmapToRead < 1"); 01346 01347 *ppBitmap = NULL; 01348 SetBitmapNumber(nBitmapToRead); 01349 01350 KernelBitmap* KernelBmp; 01351 BOOL IsNew = TRUE; 01352 01353 BOOL ReuseExisting = ShouldReuseExistingBitmaps(); 01354 01355 if (IsPreviewBitmap) //for preview bitmaps always false 01356 ReuseExisting = FALSE; 01357 01358 BOOL Success = KernelBitmap::ImportBitmap(this, NULL, 0, &KernelBmp, ReuseExisting ? &IsNew : NULL); 01359 01360 if (Success && IsNew) 01361 { 01362 // Give the bitmap a name from the file path 01363 CreateBitmapName(pDiskFile, KernelBmp, nBitmapToRead); 01364 01365 // If we have a BitmapSource then use it 01366 if (m_pBitmapSource != NULL) 01367 { 01368 KernelBmp->SetOriginalSource(m_pBitmapSource, this); 01369 delete InputFile; 01370 InputFile = NULL; 01371 } 01372 } 01373 else 01374 { 01375 // Throw away the source as we already have it or don't need it 01376 if (m_pBitmapSource != NULL) 01377 { 01378 delete m_pBitmapSource; 01379 delete InputFile; 01380 InputFile = NULL; 01381 } 01382 } 01383 01384 // Free up dynamic objects used for import and close the file 01385 CleanUpAfterImport(); 01386 01387 if (!Success) 01388 { 01389 // Did not work - report this to the caller. 01390 return FALSE; 01391 } 01392 01393 *ppBitmap = KernelBmp; 01394 01395 return TRUE; 01396 } 01397 01398 01399 /******************************************************************************************** 01400 01401 > BOOL BaseBitmapFilter::ProcessImportOptions() 01402 01403 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01404 Created: 12/06/96 01405 Inputs: - 01406 Outputs: - 01407 Returns: TRUE if it is OK to continue processing 01408 FALSE if an error occured or the user cancelled the import, in which case 01409 Error::SetError is called signalling the fact. 01410 Purpose: Validates the options returned by GetImportOptions 01411 Sets m_pImportOptions if OK 01412 Shouldn't really be overridden 01413 SeeAlso: BaseBitmapFilter::DoImport() 01414 01415 ********************************************************************************************/ 01416 BOOL BaseBitmapFilter::ProcessImportOptions() 01417 { 01418 // Get any user options, if required 01419 ERROR3IF(m_pImportOptions != NULL, "m_pImportOptions not deleted"); 01420 BitmapImportOptions* options = GetImportOptions(); 01421 if (options == NULL) 01422 { 01423 ERROR3("options is NULL"); 01424 return FALSE; 01425 } 01426 ERROR3IF(!options->IS_KIND_OF(BitmapImportOptions), "options is not"); 01427 if (!options->m_bValid) 01428 { 01429 delete options; 01430 m_pImportOptions = NULL; 01431 return TRUE; 01432 } 01433 if (options->m_bCancelled) 01434 { 01435 delete options; 01436 m_pImportOptions = NULL; 01437 Error::SetError(_R(IDN_USER_CANCELLED),0); // Expects error set on cancel 01438 return FALSE; // if cancelled 01439 } 01440 m_pImportOptions = options; 01441 return TRUE; 01442 } 01443 01444 01445 /******************************************************************************************** 01446 01447 > BOOL BaseBitmapFilter::CreateBitmapName(const CCLexFile* pDiskFile, const KernelBitmap* pBitmap, 01448 const UINT32 nBitmapNumber) 01449 01450 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01451 Created: 18/06/96 01452 Inputs: pDiskFile : file from which the bitmap was extracted 01453 pBitmap : the bitmap itself 01454 nBitmapNumber : the number of the bitmap in the file 01455 Outputs: - 01456 Returns: TRUE if name set OK, FALSE if failed. 01457 Purpose: Sets the name of the given bitmap to that of the form "filename - number.ext" 01458 or "filename.ext" depending on whether we have assumed there to be more than 01459 one image in the imported file. 01460 Used by ImportBitmap to supply this name and avoid bizarre file names when 01461 re-exporting. 01462 Errors: ERROR2 for invalid arguments 01463 ERROR3 if pDiskFile is not a kind of CCDiskFile 01464 Notes: Suppose we should really set the names after when we know that there actually 01465 are multiple bitmaps 01466 01467 ********************************************************************************************/ 01468 01469 BOOL BaseBitmapFilter::CreateBitmapName(const CCLexFile* pDiskFile, const KernelBitmap* pBitmap, 01470 const UINT32 nBitmapNumber) 01471 { 01472 ERROR2IF(pDiskFile == NULL, FALSE, "pDiskFile - invalid"); 01473 ERROR2IF(pBitmap == NULL, FALSE, "pBitmap - invalid"); 01474 01475 PathName Path = pDiskFile->GetPathName(); 01476 if (!Path.IsValid()) 01477 { 01478 TRACE( _T("Invalid file path in BaseBitmapFilter::CreateBitmapName\n") ); 01479 return FALSE; 01480 } 01481 01482 String_256 Str; 01483 if ((nBitmapNumber > 1) || AreBitmapsToRead()) 01484 { 01485 // give it a number ? 01486 String_256 shortName = Path.GetFileName(FALSE); // without extension 01487 String_16 index; 01488 Convert::LongToString(INT32(nBitmapNumber), &index); 01489 Str.MakeMsg(_R(IDS_BITMAP_NAME), (TCHAR*)shortName, (TCHAR*)index); 01490 Path.SetFileName(Str); 01491 } 01492 Str = Path.GetFileName(TRUE); // with extension 01493 pBitmap->ActualBitmap->SetName(Str); 01494 return TRUE; 01495 } 01496 01497 01498 /******************************************************************************************** 01499 01500 > BOOL BaseBitmapFilter::ReadFromFile( OILBitmap* pOilBitmap ) 01501 01502 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01503 Created: 18/8/95 01504 Inputs: pOilBitmap pointer to the oil bitmap data to be filled in 01505 Outputs: Will have filled in BMInfo pointer to the bitmap header to fill in 01506 BMBytes pointer to the bitmap data to fill in 01507 Purpose: Actually does the process of reading a bitmap from a file. 01508 Inherited classes override this to read in different file formats. 01509 01510 Returns: TRUE if worked, FALSE if failed. 01511 01512 ********************************************************************************************/ 01513 01514 BOOL BaseBitmapFilter::ReadFromFile( OILBitmap* pOilBitmap ) 01515 { 01516 ERROR3("Base class bitmap filter ReadFromFile called"); 01517 return FALSE; 01518 } 01519 01520 /******************************************************************************************** 01521 01522 > virtual BOOL BaseBitmapFilter::ReadFromFile( OILBitmap* pOilBitmap, 01523 BaseCamelotFilter *pFilter, 01524 CCLexFile* pFile, BOOL IsCompressed) 01525 01526 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01527 Created: 20/6/96 01528 Inputs: pOilBitmap pointer to the oil bitmap data to be filled in 01529 pFilter - the BaseCamelotFilter which provides functions like progress update 01530 pFile - the CCFile class to use to read the data from 01531 IsCompressed - Flag to say the bitmap is compressed or not. 01532 Outputs: Will have filled in BMInfo pointer to the bitmap header to fill in 01533 BMBytes pointer to the bitmap data to fill in 01534 Purpose: Actually does the process of reading a bitmap from a file. 01535 Inherited classes override this to read in different file formats. 01536 It is used by the web/native filters to pull out a bitmap definition from 01537 inside a bitmap definition record. 01538 IsCompressed is only used for BMP/BMPZIP type bitmaps at present. 01539 Assumes: 01540 pFile has already been opened up for reading 01541 pFilter has been set up for reading the data e.g. progress bar 01542 Returns: TRUE if worked, FALSE if failed. 01543 01544 ********************************************************************************************/ 01545 01546 BOOL BaseBitmapFilter::ReadFromFile(OILBitmap* pOilBitmap, BaseCamelotFilter* pFilter, 01547 CCLexFile* pFile, BOOL IsCompressed) 01548 { 01549 ERROR3("Base class bitmap filter ReadFromFile called"); 01550 return FALSE; 01551 } 01552 01553 /******************************************************************************************** 01554 > UINT32 BaseBitmapFilter::GetBitmapNumber() const 01555 01556 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01557 Created: 11/06/96 01558 Inputs: - 01559 Returns: The next bitmap to read 01560 0 if the bitmap number is invalid 01561 Purpose: On entry to the filter this member function returns the number of the desired 01562 bitmap in the file. Once the import is complete, either SetBitmapNumber is 01563 called with an argument of the next bitmap that can be read or SetLastBitmap 01564 is called indicating there are no more to read. 01565 Scope: protected 01566 SeeAlso: SetBitmapNumber(), SetLastBitmap(), ...ReadFromFile() 01567 01568 ********************************************************************************************/ 01569 UINT32 BaseBitmapFilter::GetBitmapNumber() const 01570 { 01571 return m_nBitmapToRead < 1 ? 0 : (UINT32) m_nBitmapToRead; 01572 } 01573 01574 01575 01576 /******************************************************************************************** 01577 > BOOL BaseBitmapFilter::SetBitmapNumber(UINT32 nBitmapToRead) 01578 01579 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01580 Created: 11/06/96 01581 Inputs: - 01582 Returns: TRUE if set OK 01583 FALSE otherwise 01584 Purpose: Once a filter has read a bitmap it should call this member function with 01585 the number of the next bitmap that can be read. If there are none, 01586 SetLastBitmap() should be called instead. 01587 Scope: protected 01588 SeeAlso: SetLastBitmap(), GetBitmapNumber() 01589 01590 ********************************************************************************************/ 01591 BOOL BaseBitmapFilter::SetBitmapNumber(const UINT32 nBitmapToRead) 01592 { 01593 ERROR2IF(nBitmapToRead < 1, FALSE, "nBitmapToRead invalid"); 01594 m_nBitmapToRead = nBitmapToRead; 01595 return TRUE; 01596 } 01597 01598 01599 /******************************************************************************************** 01600 > BOOL BaseBitmapFilter::SetLastBitmap() 01601 01602 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01603 Created: 11/06/96 01604 Inputs: - 01605 Returns: TRUE if set OK 01606 FALSE otherwise 01607 Purpose: When the bitmap filter has no more bitmaps to read from its file it should 01608 call this member function. 01609 Scope: protected 01610 SeeAlso: SetBitmapNumber(), GetBitmapNumber() 01611 01612 ********************************************************************************************/ 01613 BOOL BaseBitmapFilter::SetLastBitmap() 01614 { 01615 m_nBitmapToRead = -1; 01616 return TRUE; 01617 } 01618 01619 01620 /******************************************************************************************** 01621 > BOOL BaseBitmapFilter::AreBitmapsToRead() const 01622 01623 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01624 Created: 11/06/96 01625 Inputs: - 01626 Returns: TRUE if there are bitmaps in the set OK 01627 FALSE otherwise 01628 Purpose: The BaseBitmapFilter uses this to determine whether or not it should try 01629 to read another bitmap from the file. 01630 Scope: protected 01631 SeeAlso: GetBitmapNumber(), SetBitmapNumber(), SetLastBitmap() 01632 01633 ********************************************************************************************/ 01634 BOOL BaseBitmapFilter::AreBitmapsToRead() const 01635 { 01636 return (m_nBitmapToRead != -1); 01637 } 01638 01639 01640 /******************************************************************************************** 01641 01642 > BOOL BaseBitmapFilter::SetPixelWidth(const BMP_SIZE& Width) 01643 01644 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01645 Created: 29/10/96 01646 Inputs: Width : The width of the bitmap to be exported in pixels 01647 Returns: TRUE if the operation was successful 01648 FALSE otherwise 01649 Purpose: Support function to obtain bitmap info 01650 See Also: GetExportHeight() 01651 01652 ********************************************************************************************/ 01653 BOOL BaseBitmapFilter::SetPixelWidth(const BMP_SIZE& Width) 01654 { 01655 m_PixelWidth = Width; 01656 return TRUE; 01657 } 01658 01659 01660 /******************************************************************************************** 01661 01662 > BMP_SIZE BaseBitmapFilter::GetPixelWidth() const 01663 01664 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01665 Created: 29/10/96 01666 Returns: The width of the bitmap to export in pixels 01667 Purpose: Support function to obtain bitmap info 01668 01669 ********************************************************************************************/ 01670 BMP_SIZE BaseBitmapFilter::GetPixelWidth() const 01671 { 01672 return m_PixelWidth; 01673 } 01674 01675 01676 /******************************************************************************************** 01677 01678 > BMP_SIZE BaseBitmapFilter::GetPixelHeight() const 01679 01680 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01681 Created: 29/10/96 01682 Returns: The height of the bitmap to export in pixels 01683 Purpose: Support function to obtain bitmap info 01684 01685 ********************************************************************************************/ 01686 BMP_SIZE BaseBitmapFilter::GetPixelHeight() const 01687 { 01688 return m_PixelHeight; 01689 } 01690 01691 01692 /******************************************************************************************** 01693 01694 > virtual BOOL BaseBitmapFilter::SetPixelHeight(const BMP_SIZE& Height) 01695 01696 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01697 Created: 29/10/96 01698 Inputs: Height : The pixel height of the bitmap to be exported 01699 Returns: TRUE if the operation was successful 01700 FALSE otherwise 01701 Purpose: Support function to obtain bitmap info 01702 See Also: GetExportHeight() 01703 01704 ********************************************************************************************/ 01705 BOOL BaseBitmapFilter::SetPixelHeight(const BMP_SIZE& Height) 01706 { 01707 m_PixelHeight = Height; 01708 return TRUE; 01709 } 01710 01711 01712 /******************************************************************************************** 01713 01714 > BOOL BaseBitmapFilter::GetExportOptions(* pOptions) 01715 01716 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01717 Created: 12/11/96 01718 Inputs: pOptions : A pointer to some BitmapExportOptions 01719 Outputs: pOptions : the same with some extra information in it 01720 Returns: TRUE if OK 01721 FALSE if user pressed Cancel. 01722 01723 Purpose: Allows the user to be prompted to get export information which should be set 01724 in the given BitmapExportOptions. 01725 01726 Notes: Due to the existence of three public entry points into bitmap filters, 01727 two of which are virtual, the BaseBitmapFilter::WriteBitmapToFile may not 01728 be called and so may not create a BitmapExportOptions object, which would 01729 not be disasterous in itself, unless a derived class calls BaseBitmapFilter 01730 functions which use BitmapExportOptions. It is therefore at the filter 01731 author's discretion whether or not to create one of these objects. 01732 01733 Scope: protected 01734 01735 ********************************************************************************************/ 01736 BOOL BaseBitmapFilter::GetExportOptions(BitmapExportOptions* pOptions) 01737 { 01738 #if !defined(EXCLUDE_FROM_RALPH) 01739 ERROR2IF(pOptions == NULL, FALSE, "NULL Args"); 01740 01741 WrittenHeader = FALSE; 01742 01743 // When saving a bitmap directly then only use the dialog box for certain filter types 01744 // as it will be just requesting compression type and hence otherwise it is superfluous. 01745 // Otherwise, always use it. 01746 BOOL Ok = TRUE; 01747 if (pOptions->GetSelectionType() != ABITMAP) 01748 { 01749 // This is ok as we are using a modal dialog box 01750 PORTNOTE("export", "Remove BmpPrefsDlg usage") 01751 #if !defined(EXCLUDE_FROM_XARALX) 01752 Ok = BmpPrefsDlg::InvokeDialog(pOptions); 01753 #endif 01754 } 01755 01756 if (Ok) 01757 { 01758 // Only save the depth as the default if not saving a bitmap itself 01759 // from say the bitmap gallery. (keep this rubbish for now...) 01760 if (pOptions->GetSelectionType() != ABITMAP && pOptions->GetSelectionType() != SOMEBITMAPS) 01761 { 01762 pOptions->SetAsDefaults(); 01763 } 01764 PaletteType = PAL_OPTIMISED; 01765 } 01766 01767 // Return with the ok/cancel state used on the dialog box 01768 return Ok; 01769 #else 01770 return FALSE; 01771 #endif 01772 } 01773 01774 01775 // SMFIX sjk 5/12/00 there used to be some junk in the call to GetExportOptions that assumed the 01776 // filter type being used which could be changed by the GetExportOptions call itself 01777 // therefore all this sort of stuff should be called on the correct known filter using this 01778 // call afterwards 01779 void BaseBitmapFilter::PostGetExportOptions(BitmapExportOptions* pOptions) 01780 { 01781 pOptions->SetAsDefaults(); 01782 } 01783 01784 01785 01786 01787 /******************************************************************************************** 01788 01789 > virtual BOOL BaseBitmapFilter::SetUpClippingRectangleForExport(Spread *pSpread, SelectionType Selection) 01790 01791 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01792 Created: 29/4/97 01793 Inputs: pSpread the spread to export 01794 Selection the selection type to use during export 01795 Returns: TRUE if the operation was successful 01796 FALSE otherwise 01797 Purpose: Sets up the class variable ClipRect to be the clipping rectangle to be used 01798 during export. 01799 See Also: PrepareToExport() 01800 01801 ********************************************************************************************/ 01802 01803 BOOL BaseBitmapFilter::SetUpClippingRectangleForExport(Spread *pSpread, SelectionType Selection) 01804 { 01805 ERROR2IF(pSpread == NULL,FALSE,"SetUpClippingRectangleForExport Bad spread"); 01806 01807 // We need to decide what clipping rectangle to set up which we will then render the 01808 // bitmap through. The choice might be to export:- 01809 // - the selection bounds (if there is a selection), 01810 // - or the current spread 01811 // - or the current drawing 01812 // First, check if there is a selection present. ClipRect should be empty if not. 01813 01814 // Karim 17/07/2000 01815 // We need to take controller nodes into account when we're finding this bbox, 01816 // which means temporarily setting PromoteToParent on the selection. 01817 SelRange* pSel = GetApplication()->FindSelection(); 01818 if (pSel != NULL) 01819 { 01820 ClipRect = pSel->GetBoundingRect(TRUE); 01821 } 01822 01823 // However, if this is a Preview Bitmap then use the spreads bounds as the clip rect 01824 // This should in fact be the bounding rectangle of all visible layers in the current 01825 // drawing. 01826 if (IsPreviewBitmap || (Selection==DRAWING)) 01827 { 01828 // Work out the size of the rectangle encompassing the drawing (visible layers only) 01829 ClipRect = GetSizeOfDrawing(pSpread); 01830 } 01831 01832 if (!IsPreviewBitmap && (Selection==SELECTION)) 01833 { 01834 // Quick check to make sure the selection is something sensible ... 01835 SelRange* pSel = GetApplication()->FindSelection(); 01836 if (pSel && 01837 pSel->Count()==1) 01838 { 01839 // Only one thing selected ... Is it the Text Caret per chance ? 01840 Node* pSelNode = pSel->FindFirst(); 01841 if (pSelNode && pSelNode->IsAVisibleTextNode()) 01842 { 01843 VisibleTextNode* pTextNode = (VisibleTextNode*)pSelNode; 01844 if (pTextNode->IsACaret()) 01845 { 01846 // Aha! It's the Caret that's selected. 01847 01848 // We'll use the bounds of the parent text line instead then ... 01849 Node* pTextLine = pTextNode->FindParent(); 01850 ERROR3IF(!IS_A(pTextLine, TextLine), "Caret doesn't have a parent text line in DoCreateBitmap"); 01851 01852 // Get the bounds of the text line 01853 ClipRect = ((TextLine*)pTextLine)->GetBoundingRect(); 01854 Selection = DRAWING; 01855 } 01856 } 01857 } 01858 } 01859 01860 // If this is the Preview bitmap, then we have to check for too big and too small cases 01861 if (IsPreviewBitmap) 01862 { 01863 // Find out how big the preview is at the moment 01864 MILLIPOINT Width = ClipRect.Width(); 01865 MILLIPOINT Height = ClipRect.Height(); 01866 01867 // Note from Martin: This is probably a bodge connected with the scaling bodge which 01868 // has been corrected below, but I'm leaving this one in cos it leaves a nice 1 pixel 01869 // boarder round the thumbnail. 01870 // Inflate the rect a little as we can get odd clipping effects at the edges otherwise 01871 ClipRect.Inflate(Width/128, Height/128); 01872 01873 // Define what too big and too small are 01874 // bigger the 2 feet or smaller than 1/2 inch 01875 MILLIPOINT MaxWidth = 72000 * 12 * 2; 01876 MILLIPOINT MinWidth = 72000 / 2; 01877 01878 // See if the rectangle is too big or too small and fix it if it is 01879 MILLIPOINT WidthChange = 0; 01880 MILLIPOINT HeightChange = 0; 01881 // too big? 01882 WidthChange = Width>MaxWidth ? (MaxWidth - Width)/2 : 0; // a -ve number 01883 HeightChange = Height>MaxWidth ? (MaxWidth - Height)/2 : 0; // a -ve number 01884 // too little? 01885 WidthChange = Width<MinWidth ? (MinWidth - Width)/2 : 0; // a +ve number 01886 HeightChange = Height<MinWidth ? (MinWidth - Height)/2 : 0; // a +ve number 01887 // Shrink or expand the clip rect 01888 if ( WidthChange || HeightChange ) 01889 ClipRect.Inflate( WidthChange, HeightChange ); 01890 } 01891 01892 return TRUE; 01893 } 01894 01895 01896 /******************************************************************************************** 01897 01898 > BOOL BaseBitmapFilter::PrepareToExport(Spread *pSpread, UINT32 Depth, double DPI, 01899 SelectionType Selection, 01900 UINT32 Dither = XARADITHER_ORDERED_GREY) 01901 01902 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 01903 Created: 28/6/94 01904 Inputs: Pointer to the spread, colour depth in bpp, resolution in dpi and a selection 01905 flag which indicates whether there is a selection present (=1), no selection 01906 (=0) and if there is a selection whether we want to export the spread instead 01907 (=2). 01908 Returns: TRUE if succeeded, FALSE if not (e.g. no memory) 01909 Purpose: Prepare to export bitmap data using this filter. This sets up the filter 01910 to a sensible state for reading. Assumes file is opened by caller. This 01911 should NOT be overridden by inherited classes. 01912 Errors: Out of memory. 01913 SeeAlso: BaseBitmapFilter::DoImport; BaseBitmapFilter::CleanUpAfterImport 01914 Scope: Private 01915 01916 ********************************************************************************************/ 01917 01918 #define PIXELWIDTH 750 // @ 96DPI @ 100% 01919 #define PIXELHEIGHT 750 // @ 96DPI @ 100% 01920 01921 BOOL BaseBitmapFilter::PrepareToExport(Spread *pSpread, UINT32 Depth, double DPI, 01922 SelectionType Selection, UINT32 Dither) 01923 { 01924 #ifdef DO_EXPORT 01925 ERROR2IF(pSpread==NULL,FALSE,"BaseBitmapFilter::PrepareToExport null spread pointer"); 01926 01927 // Check whether the selection contains objects that can't be represented 01928 // in a bitmap 01929 if (WarnIfIncompatible()==FALSE) 01930 { 01931 ERRORIF(TRUE, _R(IDN_USER_CANCELLED), FALSE); 01932 } 01933 01934 // We need to decide what clipping rectangle to set up which we will then render the 01935 // bitmap through. The choice might be to export:- 01936 // - the selection bounds (if there is a selection), 01937 // - or the current spread 01938 // - or the current drawing 01939 // Ask the virtual function to set it up for us 01940 01941 if (ClipRect.IsEmpty()) 01942 SetUpClippingRectangleForExport(pSpread, Selection); 01943 01944 // We can either have no selection present whereby the user may have chosen to export 01945 // the spread or the drawing OR we have a selection present whereby the user may have 01946 // chosen to export the spread or drawing instead. In the later case we must output the 01947 // spread instead of the selection but double check there is a selection. 01948 if (ClipRect.IsEmpty() || ClipRect.Width() < MinExportSize || ClipRect.Height() < MinExportSize || 01949 ((Selection==SPREAD) && (!IsPreviewBitmap))) 01950 { 01951 // Use our function to work out the size of the spread 01952 ClipRect = GetSizeOfSpread(pSpread); 01953 01954 if (ClipRect.IsEmpty()) 01955 { 01956 ENSURE(FALSE, "Current spread has no pages"); 01957 ERRORIF(TRUE, _R(IDT_DOC_BADSTRUCTURE), FALSE); 01958 } 01959 } 01960 01961 // Don't use rendering matrix when exporting BMPs as it uses coordinates as is 01962 Matrix Identity; 01963 01964 // Don't use view scale; set to 1 01965 FIXED16 Scale(1); 01966 01967 // If this is the Preview bitmap, the scale may need changin 01968 if (IsPreviewBitmap) 01969 { 01970 // Find out the maximum dimension of the clip rect 01971 MILLIPOINT Width = ClipRect.Width(); 01972 MILLIPOINT Height = ClipRect.Height(); 01973 MILLIPOINT MaxSize = (Width>Height) ? Width : Height; 01974 01975 // this can't happen considering the code above - but you never know. 01976 ERROR3IF( MaxSize==0, "BaseBitmapFilter::PrepareToExport both dimensions of preview are zero"); 01977 // stop div zeros. We set it quite high here otherwise we get huge values in the DPI field 01978 if (MaxSize==0) 01979 MaxSize = 1000; 01980 01981 // Set the scale factor to get this down into the required size 01982 //WEBSTER-Martin-02/01/97 01983 MILLIPOINT WantSize = PreviewFilter::PreviewBitmapSize; 01984 01985 // Removed changes to 'Scale' variable so the scale factor is 01986 // now always 1. Jonathan Payne, 8/9/2000. 01987 01988 // The Scale Factor is not actually used, so we have to change the size of things 01989 // by effecting the DPI. Scale the DPI, but make sure it does not get too small. 01990 DPI = ((double)WantSize) / ((double)MaxSize) * DPI; 01991 if (DPI < 4.0) 01992 DPI = 4.0; 01993 01994 //WEBSTER-Martin-30/01/97 01995 // It doesn't matter what rounding we do here, but there is a problem because the bitmap 01996 // is not exactly the same size as the cliprect need something like ??? Any region outside 01997 // the cliprect is rendered as black hence the black lines that appear at the top and bottom 01998 // of some previews. It is especially noticable when the original is smaller than the preview. 01999 // Here we are using the dpi to do some scaling we're not really concerned with the exact value 02000 INT32 b_dpi = (INT32) DPI; 02001 DPI = (double)b_dpi; //round down 02002 } 02003 else 02004 { 02005 // Ensure Bitmap is at least 1 pixel square! 02006 if (ClipRect.Width()<PIXELWIDTH) ClipRect.hi.x = ClipRect.lo.x + PIXELWIDTH; 02007 if (ClipRect.Height()<PIXELHEIGHT) ClipRect.hi.y = ClipRect.lo.y + PIXELHEIGHT; 02008 } 02009 02010 // Remember the size of the bitmap 02011 WinRect Rect = OSRenderRegion::BitmapDocRectToWin( Identity, ClipRect, DPI ); 02012 SetPixelWidth(Rect.GetWidth()); 02013 SetPixelHeight(Rect.GetHeight()); 02014 02015 // Create the region 02016 // TRACEUSER( "Gerry", _T("PrepareToExport creating GRenderBitmap %d bpp (cmyk = %d)\n"), Depth, GetBitmapExportOptions()->IsCMYK()); 02017 ExportRegion = new GRenderBitmap(ClipRect, Identity, Scale, Depth, DPI, FALSE, Dither, NULL, TRUE); 02018 if (ExportRegion == NULL) 02019 // Error already set by new, so just return 02020 return FALSE; 02021 02022 ExportRegion->SetFilter(this); 02023 02024 // exporting a bitmap, so we will want any bitmaps used in there to be of the best quality - sjk 02025 ExportRegion->SetUsingSmoothedBitmaps(TRUE); 02026 02027 // MarkH 23/7/99 - New Flag to say that we require to render using the biCompression Field 02028 if(GetBitmapExportOptions()->GetDepth() == 32) 02029 { 02030 ExportRegion->m_DoCompression = TRUE; 02031 } 02032 02033 // we need a View to Attach to, so that: 02034 // default Quality setting 02035 // CalcPixelWidth etc get called 02036 02037 DocView *View = DocView::GetCurrent(); 02038 if (View) 02039 { 02040 // Must force background rendering off as otherwise we might get a partly 02041 // rendered drawing or object if it is complex. 02042 ForceBackgroundRedrawOff(View); 02043 02044 if (GetBitmapExportOptions()->GetDepth() == 1) 02045 { 02046 // If we are outputting at 1bpp, then we'll force antialiasing off, 02047 // so that Gavin's palette optimisation can detect objects which 02048 // are 'one solid colour' 02049 ForceAntialiasingOff(View); 02050 } 02051 02052 // If we are in preview bitmap mode then force anti-aliasing to be full 02053 // rather than the default setting for the view 02054 if (IsPreviewBitmap) 02055 { 02056 ForceAntialiasingFull(View); 02057 } 02058 02059 // Attach to the right device. (note no DC) 02060 ExportRegion->AttachDevice(View, NULL, pSpread); 02061 } 02062 else 02063 { 02064 ERROR2(FALSE,"BaseBitmapFilter::WriteToFile no current view"); 02065 } 02066 #endif 02067 // All ok 02068 return TRUE; 02069 } 02070 02071 /******************************************************************************************** 02072 02073 > BOOL BaseBitmapFilter::WarnIfIncompatible() 02074 02075 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02076 Created: 14/05/2004 02077 Inputs: - 02078 Returns: TRUE is can continue 02079 FALSE if export should be aborted 02080 Purpose: Checks for things that can't be represented using the current options 02081 E.g. non-mix transparencies in Alpha channel bitmap 02082 Errors: - 02083 Scope: Protected 02084 02085 ********************************************************************************************/ 02086 02087 BOOL BaseBitmapFilter::WarnIfIncompatible() 02088 { 02089 // Check whether the user has asked us to be silent about this 02090 if (bDontWarnBitmapNonMixTransp) 02091 return TRUE; 02092 02093 // Check whether the export options will make transparencies difficult 02094 // Is export type 32BPP including alpha? 02095 // If not everything's OK 02096 if (m_pExportOptions->GetDepth()!=32) 02097 { 02098 return TRUE; 02099 } 02100 02101 // Check whether the export selection contains non-mix transparency 02102 BOOL bFound = FALSE; 02103 Node* pNode = NULL; 02104 switch (m_pExportOptions->GetSelectionType()) 02105 { 02106 case SELECTION: 02107 { 02108 Range* pscanrange; 02109 pscanrange = Camelot.FindSelection(); 02110 pNode = pscanrange->FindFirst(TRUE); 02111 while (pNode!=NULL && !bFound) 02112 { 02113 if (pNode->IsAnAttribute()) 02114 { 02115 if (((NodeAttribute*)pNode)->IsATranspFill()) 02116 { 02117 UINT32 transptype = ((AttrFillGeometry*)pNode)->GetTranspType(); 02118 if (transptype!=TT_Mix && transptype!=TT_NoTranspType) 02119 bFound = TRUE; 02120 } 02121 } 02122 pNode = pscanrange->FindNext(pNode, TRUE); 02123 } 02124 } 02125 break; 02126 case DRAWING: 02127 case PAGE: 02128 case SPREAD: 02129 { 02130 Node* pRootNode = pSpread; 02131 pNode = pRootNode->FindFirstDepthFirst(); 02132 while (pNode!=NULL && !bFound) 02133 { 02134 if (pNode->IsAnAttribute()) 02135 { 02136 if (((NodeAttribute*)pNode)->IsATranspFill()) 02137 { 02138 UINT32 transptype = ((AttrFillGeometry*)pNode)->GetTranspType(); 02139 if (transptype!=TT_Mix && transptype!=TT_NoTranspType) 02140 bFound = TRUE; 02141 } 02142 } 02143 02144 pNode = pNode->FindNextDepthFirst(pRootNode); 02145 } 02146 } 02147 break; 02148 default: 02149 ERROR2RAW("Unknown selection type in WarnIfIncompatible"); 02150 return FALSE; 02151 } 02152 02153 if (!bFound) 02154 return TRUE; 02155 02156 // We need to show the warning dialog... 02157 INT32 ret = InformWarning(_R(IDS_WARN_INCOMPATIBLETRANSPARENCY), _R(IDS_CONTINUE), _R(IDS_ALWAYSCONTINUE), _R(IDS_CANCEL)); 02158 if (ret==3) 02159 return FALSE; 02160 02161 if (ret==2) 02162 bDontWarnBitmapNonMixTransp = TRUE; 02163 02164 return TRUE; 02165 } 02166 02167 02168 02169 02170 /******************************************************************************************** 02171 02172 > void BaseBitmapFilter::ForceBackgroundRedrawOff(DocView* pView) 02173 02174 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02175 Created: 1/7/96 02176 Inputs: pView, pointer to the View to change 02177 Returns: - 02178 Purpose: Forces background redraw off in the specified view, so we render all the 02179 objects in one pass. 02180 Use RestoreBackgroundRedrawState to restore the state. 02181 Errors: - 02182 SeeAlso: BaseBitmapFilter::RestoreBackgroundRedrawState 02183 Scope: Protected 02184 02185 ********************************************************************************************/ 02186 02187 void BaseBitmapFilter::ForceBackgroundRedrawOff(DocView* pView) 02188 { 02189 ERROR3IF(pView == NULL, "NULL pointer passed into BaseBitmapFilter::ForceBackgroundRedrawOff"); 02190 if (pView == NULL) 02191 return; 02192 02193 // We wan't to make sure we only remember the old state once ... 02194 if (!BackgroundRedrawStateSet) 02195 { 02196 BackgroundRedrawState = pView->GetForeBackMode(); 02197 BackgroundRedrawStateSet = TRUE; // So we don't do this more than once 02198 } 02199 02200 pView->SetForeBackMode(FALSE); 02201 } 02202 02203 /******************************************************************************************** 02204 02205 > void BaseBitmapFilter::RestoreBackgroundRedrawState(DocView* pView) 02206 02207 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02208 Created: 1/7/96 02209 Inputs: pView, pointer to the View to change 02210 Returns: - 02211 Purpose: Restores the background redraw state in the specified view, to the state 02212 before we called BaseBitmapFilter::ForceBackgroundRedrawOff. 02213 Errors: - 02214 SeeAlso: BaseBitmapFilter::ForceBackgroundRedrawOff 02215 Scope: Protected 02216 02217 ********************************************************************************************/ 02218 02219 void BaseBitmapFilter::RestoreBackgroundRedrawState(DocView* pView) 02220 { 02221 ERROR3IF(pView == NULL, "NULL pointer passed into BaseBitmapFilter::RestoreBackgroundRedrawState"); 02222 if (pView == NULL) 02223 return; 02224 02225 // Only restore if we saved the state earlier ... 02226 if (BackgroundRedrawStateSet) 02227 { 02228 pView->SetForeBackMode(BackgroundRedrawState); 02229 BackgroundRedrawStateSet = FALSE; 02230 } 02231 } 02232 02233 /******************************************************************************************** 02234 02235 > void BaseBitmapFilter::ForceAntialiasingOff(DocView* pView) 02236 02237 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02238 Created: 1/7/96 02239 Inputs: pView, pointer to the View to change 02240 Returns: - 02241 Purpose: Forces Antialiasing off in the specified view. 02242 Use RestoreViewQuality to restore the quality. 02243 Errors: - 02244 SeeAlso: BaseBitmapFilter::RestoreViewQuality 02245 Scope: Protected 02246 02247 ********************************************************************************************/ 02248 02249 void BaseBitmapFilter::ForceAntialiasingOff(DocView* pView) 02250 { 02251 ERROR3IF(pView == NULL, "NULL pointer passed into BaseBitmapFilter::ForceAntialiasingOff"); 02252 if (pView == NULL) 02253 return; 02254 02255 // We don't need to do anything if the view quality is already not Antialiased 02256 if (!ViewQualitySet && pView->RenderQuality.GetAntialiasQuality() >= Quality::FullAntialias) 02257 { 02258 ViewQuality = pView->RenderQuality; 02259 ViewQualitySet = TRUE; // So we don't do this more than once 02260 02261 pView->RenderQuality.SetQuality(QUALITY_DEFAULT); 02262 } 02263 } 02264 02265 /******************************************************************************************** 02266 02267 > void BaseBitmapFilter::ForceAntialiasingFull(DocView* pView) 02268 02269 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02270 Created: 11/9/96 02271 Inputs: pView, pointer to the View to change 02272 Returns: - 02273 Purpose: Forces Antialiasing to be full in the specified view. 02274 Use RestoreViewQuality to restore the quality. 02275 Used when generating preview bitmaps, which should always be in full anti- 02276 aliasing mode. 02277 Errors: - 02278 SeeAlso: BaseBitmapFilter::RestoreViewQuality 02279 Scope: Protected 02280 02281 ********************************************************************************************/ 02282 02283 void BaseBitmapFilter::ForceAntialiasingFull(DocView* pView) 02284 { 02285 ERROR3IF(pView == NULL, "NULL pointer passed into BaseBitmapFilter::ForceAntialiasingFull"); 02286 if (pView == NULL) 02287 return; 02288 02289 // We don't need to do anything if the view quality is already not Antialiased 02290 if (!ViewQualitySet && pView->RenderQuality.GetAntialiasQuality() < Quality::FullAntialias) 02291 { 02292 ViewQuality = pView->RenderQuality; 02293 ViewQualitySet = TRUE; // So we don't do this more than once 02294 02295 pView->RenderQuality.SetQuality(QUALITY_MAX); 02296 } 02297 } 02298 02299 /******************************************************************************************** 02300 02301 > void BaseBitmapFilter::RestoreViewQuality(DocView* pView) 02302 02303 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02304 Created: 1/7/96 02305 Inputs: pView, pointer to the View to change 02306 Returns: - 02307 Purpose: Restores the view quality to the state before we called ForceAntialiasingOff 02308 Errors: - 02309 SeeAlso: BaseBitmapFilter::ForceAntialiasingOff 02310 Scope: Protected 02311 02312 ********************************************************************************************/ 02313 02314 void BaseBitmapFilter::RestoreViewQuality(DocView* pView) 02315 { 02316 ERROR3IF(pView == NULL, "NULL pointer passed into BaseBitmapFilter::RestoreViewQuality"); 02317 if (pView == NULL) 02318 return; 02319 02320 if (ViewQualitySet) 02321 { 02322 // Restore the previous view quality 02323 pView->RenderQuality = ViewQuality; 02324 ViewQualitySet = FALSE; 02325 } 02326 } 02327 02328 /******************************************************************************************** 02329 02330 > void BaseBitmapFilter::CleanUpAfterExport() 02331 02332 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 02333 Created: 28/6/94 02334 Purpose: Cleans up the memory allocated by BaseBitmapFilter::PrepareToImport() - used 02335 when the import process ends, either normally or abnormally. Override if 02336 extra things are required. 02337 SeeAlso: BaseBitmapFilter::PrepareToImport; BaseBitmapFilter::DoImport 02338 Scope: Private 02339 02340 ********************************************************************************************/ 02341 02342 void BaseBitmapFilter::CleanUpAfterExport() 02343 { 02344 #ifdef DO_EXPORT 02345 // Get rid of our dynamic objects 02346 if (OutputFile) 02347 { 02348 OutputFile = NULL; 02349 } 02350 02351 DocView *View = DocView::GetCurrent(); 02352 if (View) 02353 { 02354 if( ViewQualitySet ) 02355 { 02356 // Only need to do this if the view quality has been set but not restored. 02357 RestoreViewQuality(View); 02358 } 02359 } 02360 02361 if (ExportRegion) 02362 { 02363 // If we have create the export region then delete it 02364 delete ExportRegion; 02365 ExportRegion = NULL; 02366 02367 // Must try and set our background rendering state back to the default 02368 DocView *View = DocView::GetCurrent(); 02369 if (View) 02370 { 02371 // Force background back to its entry state 02372 RestoreBackgroundRedrawState(View); 02373 } 02374 } 02375 02376 if (pOptimisedPalette) 02377 { 02378 CCFree( pOptimisedPalette ); 02379 pOptimisedPalette = NULL; 02380 } 02381 02382 #endif 02383 } 02384 02385 /******************************************************************************************** 02386 02387 > virtual BOOL BaseBitmapFilter::GetRenderBottomToTop() 02388 02389 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02390 Created: 17/5/95 02391 Inputs: - 02392 Outputs: - 02393 Returns: TRUE if going to use the default of rendering bottom to top, FALSE otherwise 02394 Purpose: Find out which way we need to render 02395 02396 ********************************************************************************************/ 02397 02398 BOOL BaseBitmapFilter::GetRenderBottomToTop() 02399 { 02400 return TRUE; 02401 } 02402 02403 02404 /******************************************************************************************** 02405 02406 > virtual BOOL BaseBitmapFilter::DoExport(Operation* pOp, CCLexFile* pFile, PathName* pPath, 02407 Document* pDoc) 02408 02409 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 02410 Created: 22/8/94 02411 Inputs: pOp - the operation that started the export off 02412 pDiskFile - the file to put the exported data into 02413 pPath - the pathname of the file to be exported to 02414 pDoc - the document to export 02415 Returns: TRUE if worked, FALSE if failed. 02416 Purpose: Exports the current selection as a bitmap, via the virtual fns of the 02417 inherited class. Do not override unless really necessary. 02418 SeeAlso: GetExportOptions; PrepareToExport; ExportRenderNodes; CleanUpAfterExport; 02419 02420 ********************************************************************************************/ 02421 02422 BOOL BaseBitmapFilter::DoExport(Operation *pOp, CCLexFile* pFile, 02423 PathName* pPath, Document* pDoc, 02424 BOOL ShowOptions) 02425 { 02426 // The success / failure flag. 02427 BOOL ok = TRUE; 02428 02429 // smfix put back more or less this should be only used by the preview filters 02430 02431 #ifdef DO_EXPORT 02432 02433 // Dreamweaver integration. 02434 // BOOL bDesignNotesSelectedValue = FALSE; 02435 02436 ERROR2IF(pOp == NULL, FALSE,"BaseBitmapFilter::DoExport no export operation"); 02437 ERROR2IF(pFile == NULL, FALSE,"BaseBitmapFilter::DoExport no file to export to"); 02438 ERROR2IF(pPath == NULL, FALSE,"BaseBitmapFilter::DoExport no export pathname"); 02439 ERROR2IF(pDoc == NULL, FALSE,"BaseBitmapFilter::DoExport no document to export"); 02440 02441 // Set the bitmap pointer to null just in case, usually only used by DoExportBitmap 02442 pExportBitmap = NULL; 02443 02444 // Get pointer to the spread to export. 02445 PORTNOTE("spread", "Multi-spread warning!") 02446 pSpread = GetFirstSpread(pDoc); 02447 ERROR2IF(pSpread == NULL, FALSE,"BaseCamelotFilter::DoExport no spread to export"); 02448 02449 // We must now check if there is a selection present so that we can set up whether the 02450 // user gets the choice of exporting the selection, drawing or spread if there is a 02451 // selection present OR just a choice between the spread or drawing if no selection is 02452 // present. 02453 // If have a caret selected in a text story then the selection will be almost zero so 02454 // trap this case as well. 02455 ClipRect = GetApplication ()->FindSelection ()->GetBoundingRect(TRUE); 02456 SelectionType Selection = DRAWING; 02457 02458 // Determine the selection type. 02459 if ( !IsPreviewBitmap && !ClipRect.IsEmpty() && ClipRect.Width() >= MinExportSize && ClipRect.Height() >= MinExportSize ) 02460 { 02461 Selection = SELECTION; // Something is selected, so use this. 02462 } 02463 else // The selection is either too small to export, or the clipping rectangle is empty. 02464 { 02465 // Work out the size of the rectangle encompassing the drawing (visible layers only). 02466 ClipRect = GetSizeOfDrawing(pSpread); 02467 02468 // Check that that cliprect is ok, if not then set the spread as the export type. 02469 if ( ClipRect.IsEmpty() || ClipRect.Width() < MinExportSize || ClipRect.Height() < MinExportSize ) 02470 Selection = SPREAD; 02471 } 02472 02473 // If there is no selection then warn the user that exporting the current spread may 02474 // take a lot of disc space, but only if this is not a Preview Bitmap. 02475 if ((!IsPreviewBitmap) && (Selection == SPREAD)) 02476 { 02477 // Warn the user that there is no selection = large export 02478 ErrorInfo Info; 02479 Info.ErrorMsg = _R(IDT_BMPEXP_NOSELECTION); 02480 Info.Button[0] = _R(IDB_EXPQUERY_EXPORT); 02481 Info.Button[1] = _R(IDB_EXPQUERY_DONTEXPORT); 02482 if ((ResourceID)(AskQuestion(&Info)) == _R(IDB_EXPQUERY_DONTEXPORT)) 02483 { 02484 Error::SetError(_R(IDN_USER_CANCELLED),0); // Expects error set on cancel 02485 ok = FALSE; 02486 } 02487 } 02488 02489 // Mark H 18/12/00 02490 // From here on, I`ve tidied up the code so that this function is responsible for it`s 02491 // own Bitmap Export Options pointer and not reliant on the member variable. This fixes 02492 //a 1.5MB!!! memory leak on exiting of the program! 02493 02494 // Create a new Bitmap Export Options pointer for the current filter 02495 BitmapExportOptions* pExportOptions = CreateExportOptions(); 02496 02497 // Try to create the export options. 02498 if (ok && pExportOptions) 02499 { 02500 pExportOptions->RetrieveDefaults(); 02501 pExportOptions->SetSelectionType(Selection); 02502 pExportOptions->SetBackgroundTransparency(FALSE); 02503 } 02504 else 02505 ok = FALSE; 02506 02507 //Graham W 3/7/97: Tell the preview dialog what the path to save out to is 02508 BmapPrevDlg::m_pthExport=*pPath; 02509 02510 if(ok) 02511 ok = GetExportOptions(pExportOptions); 02512 02513 // This pointer is used to call the ExportBitmap function. If the filetype has changed, 02514 // then it will be set-up to be invoked from the new type. 02515 BaseBitmapFilter *pFilter = this; 02516 02517 // Write out the bitmap. 02518 if (ok) 02519 { 02520 if (!pFilter->DoExportWithOptions(pOp, pFile, pPath, pDoc, pExportOptions)) 02521 { 02522 // Export failed, therefore no valid export options. 02523 Error::SetError(_R(IDN_USER_CANCELLED),0); 02524 } 02525 } 02526 02527 // Clear up the existing bitmap options. 02528 if(pExportOptions) 02529 { 02530 delete pExportOptions; 02531 pExportOptions = NULL; 02532 } 02533 02534 #endif 02535 02536 return ok; 02537 } 02538 02539 02540 /******************************************************************************************** 02541 02542 > virtual BOOL BaseBitmapFilter::DoExportDoc(Operation* pOp, CCLexFile* pFile, PathName* pPath, 02543 Document* pDoc, UINT32 Depth, double DPI, 02544 const SelectionType& Selection , BOOL UseExistingPalette) 02545 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 02546 Created: 12/6/96 02547 Purpose: Actually does the work of DoExport() above 02548 Code split out for use by DoExportBitmaps() function 02549 This DOES NOT call CleanUpAfterExport() if it fails 02550 If the call returns FALSE then the caller must call CleanUpAfterExport() 02551 Returns: TRUE if worked, FALSE if failed. 02552 Scope: protected 02553 SeeAlso: GetExportOptions; PrepareToExport; ExportRenderNodes; CleanUpAfterExport; 02554 Additional information( ap ) - Added 'UseExistingPalette'. If this is TRUE, then the 02555 existing palette in BmapPrevDlg is used instead of a newly generated one. This variable 02556 is given the default value of FALSE. 02557 02558 ********************************************************************************************/ 02559 02560 BOOL BaseBitmapFilter::DoExportDoc(Operation* pOp, CCLexFile* pFile, PathName* pPath, 02561 Document* pDoc, UINT32 RenderDepth, double DPI, 02562 const SelectionType& Selection , BOOL UseExistingPalette) 02563 { 02564 #ifdef DO_EXPORT 02565 if (!WritePreFrame()) return(FALSE); 02566 02567 /* 02568 // Only try to do the exact palette if we are using an 8 bit optimised palette 02569 if( ( PaletteType == 1 ) && ( GetBitmapExportOptions()->GetDepth() == 8 ) ) 02570 GRenderOptPalette::UseOldPalette = FALSE; 02571 else 02572 GRenderOptPalette::UseOldPalette = TRUE; 02573 */ 02574 02575 // Set up device context and render region for this export. 02576 // This will show a progress hourglass for the objects being rendered 02577 // This will now also write the data out to file via our ExportRenderNodes function 02578 if (!PrepareToExport(pSpread, RenderDepth, DPI, Selection)) 02579 { 02580 return FALSE; 02581 } 02582 02583 // SMFIX 02584 // this is where we will build up the palette from the export options IF the one 02585 // that is already in the export options is NOT valid 02586 // the fn bellow export render needs the palette to be valid 02587 // m_pExportOptions->CreateValidPalette(); 02588 02589 // this call sets this palette in the lower reaches of the code from the palette held in the export options 02590 // AlterPaletteContents(m_pExportOptions->GetLogicalPalette()); 02591 02592 // Export the data to the file ensuring we render in strips, if required. 02593 RenderInStrips = TRUE; 02594 if (!ExportRender(ExportRegion)) 02595 { 02596 // SMFIX - Make sure we reset the StripStart as it could stuff up further operations. 02597 m__StripStart = 0; 02598 return FALSE; 02599 } 02600 02601 02602 //SMFIX was calling AlterPaletteContents( lpPalette ); on a palette that it built here 02603 02604 02605 02606 // Ask the filter if it requires a second pass export render. This might be used for 02607 // say preparing a mask for transparency or something. Used by the GIF filter for this 02608 // purpose. 02609 /* 02610 if (IsSecondPassRequired()) 02611 { 02612 WritePreSecondPass(); 02613 02614 // Set up device context and render region for this export. 02615 // This will show a progress hourglass for the objects being rendered 02616 // This will now also write the data out to file via our ExportRenderNodes function 02617 if (!PrepareToExport(pSpread, RenderDepth, DPI, Selection)) 02618 { 02619 return FALSE; 02620 } 02621 02622 // Export the data to the file esnuring we render in strips, if required. 02623 RenderInStrips = TRUE; 02624 if (!ExportRender(ExportRegion)) 02625 { 02626 return FALSE; 02627 } 02628 } 02629 */ 02630 02631 if (!WritePostFrame()) 02632 { 02633 // SMFIX - Make sure we reset the StripStart as it could stuff up further operations. 02634 m__StripStart = 0; 02635 return FALSE; 02636 } 02637 02638 // SMFIX - Make sure we reset the StripStart as it could stuff up further operations. 02639 m__StripStart = 0; 02640 #endif 02641 return TRUE; 02642 } 02643 02644 02645 02646 02647 /******************************************************************************************** 02648 02649 > BOOL BaseBitmapFilter::DoExportBitmap(Operation* pOp, CCLexFile* pFile, PathName* pPath, 02650 KernelBitmap* pBitmap) 02651 02652 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02653 Created: 25/4/95 02654 Inputs: 02655 Purpose: Exports the specified bitmap straight out to file with none of the rendering 02656 that DoExport does. Uses the virtual fns of the inherited class. 02657 Do not override unless really necessary. 02658 Returns: TRUE if worked, FALSE if failed. 02659 02660 ********************************************************************************************/ 02661 02662 BOOL BaseBitmapFilter::DoExportBitmap(Operation* pOp, CCLexFile* pFile, PathName* pPath, 02663 KernelBitmap* pBitmap) 02664 { 02665 #ifdef DO_EXPORT 02666 ERROR2IF(pBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmap null bitmap pointer specified"); 02667 02668 // Note this pointer for later use 02669 pExportBitmap = pBitmap; 02670 02671 // Note this ptr for use in JPEG export. 02672 JPEGExportOptions::SetKernelBitmap(pBitmap); 02673 02674 // Get a pointer to the actual bitmap so that we can get some details from it. 02675 OILBitmap *pOilBitmap = pBitmap->ActualBitmap; 02676 ERROR2IF(pOilBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmap null oil bitmap pointer"); 02677 02678 // Create a record of information about the export 02679 m_pExportOptions = CreateExportOptions(); 02680 02681 if (m_pExportOptions == NULL) 02682 { 02683 return FALSE; 02684 } 02685 02686 // Get the default settings 02687 GetBitmapExportOptions()->RetrieveDefaults(); 02688 02689 // Specify to the user what the export options for depth etc are going to be 02690 GetBitmapExportOptions()->SetSelectionType(ABITMAP); 02691 02692 // Get the details from the specified bitmap 02693 BitmapInfo BmInfo; 02694 pOilBitmap->GetInfo(&BmInfo); 02695 GetBitmapExportOptions()->SetDepth(BmInfo.PixelDepth); // get the bitmaps bpp 02696 02697 // Should really save the dpi when we load the file itself rather than doing 02698 // all this conversion with possible rounding errors. 02699 // Use the original size that has been calculated in the info header 02700 UINT32 PixWidth = BmInfo.PixelWidth; 02701 // UINT32 PixHeight = BmInfo.PixelHeight; 02702 MILLIPOINT RecWidth = BmInfo.RecommendedWidth; 02703 // MILLIPOINT RecHeight = BmInfo.RecommendedHeight; 02704 02705 if (PixWidth > 0) 02706 { 02707 GetBitmapExportOptions()->SetDPI((PixWidth * 72000.0)/(double)RecWidth); 02708 } 02709 02710 // WEBSTER - markn 5/2/97 02711 // If the bitmap has a transparent colour index, store it in the options object 02712 // -1 means no transparent colour 02713 INT32 TransIndex = -1; 02714 if (!pBitmap->GetTransparencyIndex(&TransIndex)) TransIndex = -1; 02715 GetBitmapExportOptions()->SetTransparencyIndex(TransIndex); 02716 02717 BOOL ok = TRUE; 02718 02719 /* It used to call the export options dlg here - but why bother just export as is 02720 BOOL ok = GetExportOptions(GetBitmapExportOptions()); 02721 if (!ok) 02722 { 02723 delete m_pExportOptions; 02724 m_pExportOptions = 0; 02725 02726 Error::SetError(_R(IDN_USER_CANCELLED),0); // Expects error set on cancel 02727 return FALSE; // if cancelled 02728 } 02729 02730 if (GetBitmapExportOptions()->HasTempFile()) 02731 { 02732 // the export options preview dialog has produced a temp file, so just rename that 02733 02734 // get the temp file name 02735 PathName TempPath = GetBitmapExportOptions()->GetPathName(); 02736 02737 String_256 FinalName = pPath->GetPath(); 02738 String_256 TempName = TempPath.GetPath(); 02739 02740 if (pFile->isOpen()) 02741 pFile->close(); 02742 02743 // delete the empty file, if one was created 02744 FileUtil::DeleteFile(pPath); 02745 02746 // try to rename the file 02747 if (_trename(TempName, FinalName) != 0) 02748 ok = FALSE; 02749 else 02750 ok = TRUE; 02751 } 02752 else */ 02753 { 02754 // Used to open the file up before starting DoExport. But this meant a cancel on the export 02755 // options dialog had filled the file, if it was already present. So now up up here if 02756 // not open already. In the PreviewBitmap case the file will already be open. 02757 if (!pFile->isOpen()) 02758 { 02759 if (pFile->IsKindOf(CC_RUNTIME_CLASS(CCDiskFile))) 02760 { 02761 ok = OpenExportFile((CCDiskFile*) pFile, pPath); 02762 if (!ok) return FALSE; 02763 } 02764 else 02765 { 02766 TRACEUSER( "JustinF", _T("Tried to open non-CCDiskFile in BaseBitmapFilter::DoExportBitmap\n") ); 02767 return FALSE; 02768 } 02769 } 02770 02771 // Make a note of the Disk file we are to use 02772 OutputFile = pFile; 02773 02774 // We do not use an export region so specify null. 02775 ExportRegion = NULL; 02776 02777 // Actually write to the file, showing progress hourglass as we go 02778 ok = WriteBitmapToFile(pBitmap, GetBitmapExportOptions()->GetDPI()); 02779 02780 if (ok) 02781 WriteFileEnd(); 02782 } 02783 02784 // All done - deallocate dynamic objects, stop the progress display/hourglass 02785 // and return success. (Also closes file). 02786 CleanUpAfterExport(); 02787 02788 // we created these here so we should delete them 02789 delete m_pExportOptions; 02790 m_pExportOptions = NULL; 02791 02792 return ok; 02793 #else 02794 return FALSE; 02795 #endif 02796 } 02797 02798 02799 02800 /******************************************************************************************** 02801 02802 > virtual BOOL BaseBitmapFilter::DoExportBitmaps(Operation* pOp, CCLexFile* pFile, 02803 PathName* pPath, BitmapExportParam* pParam) 02804 02805 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 02806 Created: 11/6/96 02807 Inputs: 02808 Purpose: Exports the bitmaps specified by the BitmapExportParam object to a multi- 02809 image capable filter. 02810 It works creating a special document containing a single NodeBitmap 02811 It then sets this document to use each bitmap in turn and calls DoExport 02812 to actually export it. 02813 Returns: TRUE if worked, FALSE if failed. 02814 02815 ********************************************************************************************/ 02816 02817 BOOL BaseBitmapFilter::DoExportBitmaps(Operation *pOp, CCLexFile* pFile, PathName* pPath, 02818 BitmapExportParam* pParam) 02819 { 02820 #ifdef DO_EXPORT 02821 ERROR2IF(pOp == NULL || pFile == NULL || pPath == NULL, FALSE,"NULL Parameters"); 02822 ERROR2IF(pParam == NULL,FALSE,"BaseBitmapFilter::DoExportBitmaps null BitmapExportParam specified"); 02823 02824 // Create an object so we can ask the user for some options 02825 if (m_pExportOptions) 02826 delete m_pExportOptions; 02827 02828 m_pExportOptions = CreateExportOptions(); 02829 02830 if (m_pExportOptions == NULL) 02831 return FALSE; 02832 02833 // Get the first bitmap pointer 02834 KernelBitmap* pBitmap = pParam->GetBitmap(0); 02835 ERROR2IF(pBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmaps has no bitmaps to export"); 02836 02837 pExportBitmap = pBitmap; 02838 02839 // Get a pointer to the actual bitmap so that we can get some details from it. 02840 OILBitmap *pOilBitmap = pBitmap->ActualBitmap; 02841 ERROR2IF(pOilBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmaps null oil bitmap pointer"); 02842 02843 // Specify to the user what the export options for depth etc are going to be 02844 GetBitmapExportOptions()->SetSelectionType(SOMEBITMAPS); 02845 02846 GetBitmapExportOptions()->SetBitmapExportParam(pParam); 02847 02848 // Get the defaults from the first bitmap 02849 BitmapInfo BmInfo; 02850 pOilBitmap->GetInfo(&BmInfo); 02851 GetBitmapExportOptions()->SetDepth(BmInfo.PixelDepth); // get the bitmaps bpp 02852 02853 // Calculate the millipoint size from the pixel size assuming 96 dpi 02854 double DPI = 96.0; 02855 MILLIPOINT RecWidth = (MILLIPOINT) ((((double)BmInfo.PixelWidth * 72000.0) / DPI) + 0.5); 02856 MILLIPOINT RecHeight = (MILLIPOINT) ((((double)BmInfo.PixelHeight * 72000.0) / DPI) + 0.5); 02857 // Create a Coord for GetExportOptions 02858 GetBitmapExportOptions()->SetOutputSize(RecWidth, RecHeight); 02859 02860 BOOL ok = GetExportOptions(GetBitmapExportOptions()); 02861 if (!ok) 02862 { 02863 delete m_pExportOptions; 02864 m_pExportOptions = NULL; 02865 02866 Error::SetError(_R(IDN_USER_CANCELLED),0); // Expects error set on cancel 02867 return FALSE; // if cancelled 02868 } 02869 02870 // Used to open the file up before starting DoExport. But this meant a cancel on the export 02871 // options dialog had filled the file, if it was already present. So now up up here if 02872 // not open already. In the PreviewBitmap case the file will already be open. 02873 if (!pFile->isOpen()) 02874 { 02875 if (pFile->IsKindOf(CC_RUNTIME_CLASS(CCDiskFile))) 02876 { 02877 ok = OpenExportFile((CCDiskFile*) pFile, pPath); 02878 if (!ok) return FALSE; 02879 } 02880 else 02881 { 02882 TRACEUSER( "JustinF", _T("Tried to open non-CCDiskFile in BaseBitmapFilter::DoExportBitmaps\n") ); 02883 return FALSE; 02884 } 02885 } 02886 02887 // Make a note of the Disk file we are to use 02888 OutputFile = pFile; 02889 02890 // Make sure the Region pointer is NULL for the time being 02891 ExportRegion = NULL; 02892 02893 // TODO: Rampant change to Selection 02894 GetBitmapExportOptions()->SetSelectionType(DRAWING); 02895 02896 // Output the file header 02897 if (!WriteFileHeader()) 02898 { 02899 CleanUpAfterExport(); 02900 return(FALSE); 02901 } 02902 02903 // Remember the current document as we are just about to use a new document and 02904 // then delete it. Of course, systems like the bitmap system may just decide to 02905 // change current document just to screw things up. Put back before the end as the 02906 // EndOp will broadcast a message causing controls to update which require current 02907 // document to get the units list correctly. 02908 Document *pOldCurrent = Document::GetCurrent(); 02909 02910 // Create a document for the export 02911 BitmapExportDocument* pDoc = new BitmapExportDocument; 02912 02913 if (pDoc != NULL) 02914 { 02915 if (!pDoc->Init(pBitmap, DocRect(0, 0, GetBitmapExportOptions()->GetOutputSize().x, GetBitmapExportOptions()->GetOutputSize().y))) 02916 { 02917 TRACEUSER( "Gerry", _T("BitmapExportDocument::Init() failed\n") ); 02918 delete pDoc; 02919 pDoc = NULL; 02920 CleanUpAfterExport(); 02921 if (pOldCurrent != NULL) 02922 pOldCurrent->SetCurrent(); 02923 return(FALSE); 02924 } 02925 02926 // Get pointer to the spread to export. 02927 PORTNOTE("spread", "Multi-spread warning!") 02928 pSpread = GetFirstSpread(pDoc); 02929 02930 UINT32 BitmapCount = pParam->GetBitmapCount(); 02931 02932 for (UINT32 Index = 0; ok && (Index < BitmapCount); Index++) 02933 { 02934 // Get the bitmap pointer 02935 pBitmap = pParam->GetBitmap(Index); 02936 02937 // We have to render the bitmap so... 02938 // Update the BitmapExportDocument 02939 pDoc->SetBitmap(pBitmap); 02940 02941 // Export the document 02942 // If it fails then break out of the image loop 02943 ok = DoExportDoc( pOp, pFile, pPath, pDoc, GetRenderDepth(), 02944 GetBitmapExportOptions()->GetDPI(), 02945 GetBitmapExportOptions()->GetSelectionType()); 02946 02947 if (ExportRegion != NULL) 02948 { 02949 delete ExportRegion; 02950 ExportRegion = NULL; 02951 } 02952 if (pOptimisedPalette != NULL) 02953 { 02954 CCFree( pOptimisedPalette ); 02955 pOptimisedPalette = NULL; 02956 } 02957 02958 } 02959 02960 delete pDoc; 02961 pDoc = NULL; 02962 } 02963 02964 // Write any end of file stuff 02965 if (ok) 02966 ok = WriteFileEnd(); 02967 02968 // All done - deallocate dynamic objects, stop the progress display/hourglass 02969 // and return success. (Also closes file). 02970 CleanUpAfterExport(); 02971 02972 // Ensure that we return CurrentDoc to its original value 02973 // Leave QuickShape tool with item selected before exporting animated gif from bitmap 02974 // gallery. Convert/Unit system blows up as using current doc! 02975 if (pOldCurrent != NULL) 02976 pOldCurrent->SetCurrent(); 02977 02978 return ok; 02979 #endif 02980 return FALSE; 02981 } 02982 02983 02984 02985 02986 /******************************************************************************************** 02987 02988 > BOOL BaseBitmapFilter::SetUpExportOptions(BitmapExportOptions **ppExportOptions, 02989 BOOL OnlyDefaults = FALSE) 02990 02991 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 02992 Created: 12/5/97 02993 Inputs: 02994 Outputs: ppExportOptions - pointer, where a pointer to the export options object 02995 will be returned 02996 Purpose: Displays the export options dialog for this bitmap filter. This allows export 02997 options to be obtained by somebody else then the filter 02998 Returns: TRUE if worked, FALSE if failed. 02999 03000 NB. SMFIX sjk this function will if you pass it a NULL ptr new the correct options for the filter for 03001 the calling function. This is great. However in this case the caller function has responsibility 03002 to delete this export object when they are finished with it. They receive the export object through 03003 the static member variable BmapPrevDlg::m_pExportOptions which is a ptr to the base class BitmapExportOptions, 03004 rather than just filling in the users structure, since if the graphic type has changed the users class will have 03005 been deleted and the export object could be a different class derived from BitmapExportOptions. 03006 03007 ********************************************************************************************/ 03008 03009 BOOL BaseBitmapFilter::SetUpExportOptions(BitmapExportOptions **ppExportOptions, BOOL OnlyDefaults) 03010 { 03011 ERROR2IF(ppExportOptions == NULL, FALSE,"BaseBitmapFilter::Can't Set up export options"); 03012 03013 Document *pDoc = Document::GetCurrent(); 03014 03015 // Get pointer to the spread to export. 03016 PORTNOTE("spread", "Multi-spread warning!") 03017 pSpread = GetFirstSpread(pDoc); 03018 ERROR2IF(pSpread == NULL, FALSE,"BaseCamelotFilter::DoExport no spread to export"); 03019 03020 // We must now check if there is a selection present so that we can set up whether the 03021 // user gets the choice of exporting the selection, drawing or spread if there is a 03022 // selection present OR just a choice between the spread or drawing if no selection is 03023 // present. 03024 // If have a caret selected in a text story then the selection will be almost zero so trap 03025 // this case as well. 03026 DocRect ClipRect = GetApplication()->FindSelection()->GetBoundingRect(TRUE); 03027 SelectionType Selection = DRAWING; 03028 if ( 03029 ClipRect.IsEmpty() || 03030 ClipRect.Width() < MinExportSize || ClipRect.Height() < MinExportSize 03031 ) 03032 Selection = DRAWING; // no selection present, so choose drawing by default 03033 else 03034 Selection = SELECTION; // selection present, so choose this by default 03035 03036 if (Selection == DRAWING) 03037 { 03038 // Work out the size of the rectangle encompassing the drawing (visible layers only) 03039 ClipRect = GetSizeOfDrawing(pSpread); 03040 03041 // Check that that cliprect is ok, if not then set the spread as the export type 03042 if ( 03043 ClipRect.IsEmpty() || 03044 ClipRect.Width() < MinExportSize || ClipRect.Height() < MinExportSize 03045 ) 03046 Selection = SPREAD; 03047 } 03048 03049 03050 // If there is no selection then warn the user that exporting the current spread may 03051 // take a lot of disc space, but only if this is not a Preview Bitmap. 03052 if ((!IsPreviewBitmap) && (Selection == SPREAD)) 03053 { 03054 // Warn the user that there is no selection = large export 03055 ErrorInfo Info; 03056 Info.ErrorMsg = _R(IDT_BMPEXP_NOSELECTION); 03057 Info.Button[0] = _R(IDB_EXPQUERY_EXPORT); 03058 Info.Button[1] = _R(IDB_EXPQUERY_DONTEXPORT); 03059 if ((ResourceID)AskQuestion(&Info) == _R(IDB_EXPQUERY_DONTEXPORT)) 03060 { 03061 Error::SetError(_R(IDN_USER_CANCELLED),0); // Expects error set on cancel 03062 return FALSE; // if cancelled 03063 } 03064 } 03065 03066 // Create a record of information about the export 03067 *ppExportOptions = CreateExportOptions(); 03068 if (*ppExportOptions == NULL) 03069 { 03070 return FALSE; 03071 } 03072 03073 (*ppExportOptions)->RetrieveDefaults(); 03074 03075 (*ppExportOptions)->SetSelectionType(Selection); 03076 03077 // check whether only the defaults are needed 03078 if (OnlyDefaults) 03079 return TRUE; 03080 03081 // get the user options for depth etc here 03082 BOOL ok = GetExportOptions( *ppExportOptions ); 03083 03084 // remember this ptr and make it externally available 03085 // dont do this any more the above call brings up the export dlg and sets the BmapPrevDlg::m_pExportOptions 03086 // even when the user has messed around with them 03087 //BmapPrevDlg::m_pExportOptions = *ppExportOptions; 03088 // so rather the *ppExportOptions should reflect the state that the dlg left them in 03089 if (BmapPrevDlg::m_pExportOptions) 03090 *ppExportOptions = BmapPrevDlg::m_pExportOptions; 03091 03092 if (!ok) 03093 { 03094 if (*ppExportOptions != NULL) 03095 { 03096 delete *ppExportOptions; 03097 *ppExportOptions = NULL; 03098 } 03099 Error::SetError(_R(IDN_USER_CANCELLED),0); // Expects error set on cancel 03100 BmapPrevDlg::m_pExportOptions = NULL; // we have no export options 03101 03102 return FALSE; // if cancelled 03103 } 03104 03105 return TRUE; 03106 } 03107 03108 03109 03110 03111 /******************************************************************************************** 03112 03113 > virtual BOOL BaseBitmapFilter::DoExportWithOptions(Operation* pOp, CCLexFile* pFile, 03114 PathName* pPath, Document* pDoc, BitmapExportOptions *pOptions) 03115 03116 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 03117 Created: 12/5/97 03118 Inputs: pOp - the operation that started the export off 03119 pFile - the file to put the exported data into 03120 pPath - the pathname of the file to be exported to 03121 pDoc - the document to export 03122 pOptions - the bitmap export options to use when exporting. The options are 03123 deleted after the export, so if you want to keep them make a copy first. 03124 Purpose: Exports the document by using the export options passed as parameter, rather 03125 then invoking an options dialog box to obtain them. 03126 Returns: TRUE if worked, FALSE if failed. 03127 03128 ********************************************************************************************/ 03129 03130 BOOL BaseBitmapFilter::DoExportWithOptions(Operation* pOp, CCLexFile* pFile, PathName* pPath, 03131 Document* pDoc, BitmapExportOptions *pOptions, DocRect *pRect) 03132 { 03133 ERROR2IF(pOp == NULL, FALSE,"BaseBitmapFilter::DoExport no export operation"); 03134 ERROR2IF(pFile == NULL, FALSE,"BaseBitmapFilter::DoExport no file to export to"); 03135 ERROR2IF(pPath == NULL, FALSE,"BaseBitmapFilter::DoExport no export pathname"); 03136 ERROR2IF(pDoc == NULL, FALSE,"BaseBitmapFilter::DoExport no document to export"); 03137 03138 // Have any valid export options been passed in? 03139 if (pOptions == NULL) 03140 { 03141 // Create a record of information about the export. 03142 SetUpExportOptions(&m_pExportOptions, TRUE); 03143 if (m_pExportOptions == NULL) 03144 return FALSE; 03145 } 03146 else 03147 { 03148 // Copy the existing export options. 03149 //m_pExportOptions = pOptions->MakeCopy (); 03150 m_pExportOptions = pOptions; // rather point at the options passed in 03151 } 03152 03153 // set up the pSpread 03154 PORTNOTE("spread", "Multi-spread warning!") 03155 pSpread = GetFirstSpread(pDoc); 03156 03157 // deal with no selection 03158 SelRange* pSelection = GetApplication()->FindSelection(); 03159 // deal with exporting no selection as the drawing 03160 if (pRect == NULL && pSelection->Count() == 0 && (m_pExportOptions->GetSelectionType() == SELECTION)) 03161 m_pExportOptions->SetSelectionType(DRAWING); 03162 03163 if (pRect != NULL) // Force the cliping rect for the image to be the one passed in 03164 // and not just defined by the selection! sjk 03165 { 03166 ClipRect = *pRect; 03167 } 03168 else 03169 { 03170 // reassign the clipping rectangle to the selection's bounding rect 03171 SetUpClippingRectangleForExport(pSpread, m_pExportOptions->GetSelectionType()); 03172 03173 // Set the page limits to drawing if thats whats requested 03174 if (pSpread && m_pExportOptions->IsClipToPage() ) 03175 { 03176 Page *pPage = pSpread->FindFirstPageInSpread(); 03177 if (pPage) 03178 ClipRect = pPage->GetPageRect(); 03179 } 03180 03181 // to use SJK's new fiddle the rect to maintain the antialiasing 03182 // as seen on screen call the function bellow 03183 // If you want it to work like it did in CX2 comment the line out 03184 if( m_pExportOptions->GetAntiAliasing() == MAINTAIN_SCREEN_AA ) 03185 PixelAlignedFiddle(&ClipRect); 03186 } 03187 03188 BOOL ok = TRUE; 03189 03190 // Always export the whole thing into one composite file 03191 ok = DoExportHelper(pOp, pFile, pPath, pDoc); 03192 03193 if (!IsPreviewBitmap && m_pExportOptions->CanExportSeparateLayers()) 03194 { 03195 // We need to export each layer as a separate file 03196 Layer* pLayer = pSpread->FindFirstLayer(); 03197 while (ok && pLayer!=NULL) 03198 { 03199 if (pLayer->IsVisible() 03200 && !pLayer->IsGuide() 03201 && pLayer->HasLayerGotRenderableChildren() 03202 ) 03203 { 03204 SetSoleLayer(pLayer); 03205 03206 PathName pathLayer = pLayer->MakeExportLayerName(*pPath); 03207 CCLexFile* pLayerFile = new CCDiskFile(pathLayer, ios::in | ios::out | ios::binary | ios::trunc); 03208 03209 if (ok) ok = DoExportHelper(pOp, pLayerFile, &pathLayer, pDoc); 03210 03211 delete pLayerFile; 03212 03213 SetSoleLayer(NULL); 03214 } 03215 03216 pLayer = pLayer->FindNextLayer(); 03217 } 03218 } 03219 03220 // Delete the newly created export options ONLY if we did create them 03221 if (pOptions == NULL) 03222 { 03223 delete m_pExportOptions; 03224 m_pExportOptions = NULL; 03225 } 03226 03227 // Restore the file. 03228 OutputFile = pFile; 03229 03230 return ok; 03231 } 03232 03233 03234 03235 /******************************************************************************************** 03236 03237 > virtual BOOL BaseBitmapFilter::DoExportWithOptions(Operation* pOp, 03238 CCLexFile* pFile, 03239 PathName* pPath, 03240 Document* pDoc) 03241 03242 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> (from Stefan) 03243 Created: 24/03/2004 03244 Inputs: pOp - the operation that started the export off 03245 pFile - the file to put the exported data into 03246 pPath - the pathname of the file to be exported to 03247 pDoc - the document to export 03248 Purpose: Exports the document by using the export options passed as parameter, rather 03249 then invoking an options dialog box to obtain them. 03250 Returns: TRUE if worked, FALSE if failed. 03251 03252 ********************************************************************************************/ 03253 03254 BOOL BaseBitmapFilter::DoExportHelper(Operation* pOp, 03255 CCLexFile* pFile, 03256 PathName* pPath, 03257 Document* pDoc) 03258 { 03259 // Used to open the file up before starting DoExport. But this meant a cancel on the export 03260 // options dialog had filled the file, if it was already present. So now up up here if 03261 // not open already. In the PreviewBitmap case the file will already be open. 03262 if ( !pFile->isOpen() && 03263 pFile->IsKindOf ( CC_RUNTIME_CLASS ( CCDiskFile ) ) && 03264 !OpenExportFile ( static_cast<CCDiskFile*> ( pFile ), pPath) ) 03265 { 03266 return FALSE; 03267 } 03268 03269 WrittenHeader = 0; 03270 SetDepthToRender(32); 03271 03272 // set the palette type which might get changed during the preview 03273 if (m_pExportOptions->IS_KIND_OF(BMPExportOptions)) 03274 { 03275 PaletteType = ((BMPExportOptions *)m_pExportOptions)->GetPalette() ? 1 : 0; // 1 for an optimised palette 03276 BMPFilter::SetDefaultExportDPI(m_pExportOptions->GetDPI()); 03277 BMPFilter::SetDefaultExportDepth(m_pExportOptions->GetDepth()); 03278 PORTNOTE("filter", "Removed use fo GIFFilter") 03279 #ifndef EXCLUDE_FROM_XARALX 03280 // Need to set the dither for the accusoft filter here, otherwise the dither 03281 // changes by the user will not have any effect 03282 AccusoftFilters::SetDitherToUse(m_pExportOptions->GetDither()); 03283 #endif 03284 } 03285 else if (m_pExportOptions->IS_KIND_OF(MaskedFilterExportOptions)) 03286 { 03287 PaletteType = ((MaskedFilterExportOptions *)m_pExportOptions)->GetPalette() ? 1 : 0;// 1 for an optimised palette 03288 } 03289 03290 // set the render depth, which might change during the preview 03291 switch (m_pExportOptions->GetFilterType()) 03292 { 03293 PORTNOTE("filter", "Removed use fo GIFFilter") 03294 #ifndef EXCLUDE_FROM_XARALX 03295 case TI_GIF: 03296 if (m_pExportOptions->GetDepth() > 8) 03297 m_pExportOptions->SetDepth(8); 03298 SetDepthToRender(m_pExportOptions->GetDepth()); 03299 break; 03300 #endif 03301 03302 case JPEG: 03303 SetDepthToRender(24); 03304 break; 03305 03306 default: 03307 SetDepthToRender(m_pExportOptions->GetDepth()); 03308 break; 03309 } 03310 03311 //Mark Howitt, 24/10/97. Reset the FilterType variable as Importing uses this for something else! 03312 PORTNOTE("filter", "Removed use of AccusoftFilters") 03313 #if !defined(EXCLUDE_FROM_XARALX) && !defined(WEBSTER) 03314 // Andy Hills, 21-12-00 03315 // Warning: bodge alert! 03316 // At this stage, AccusoftFilters::FilterType may contain a useful value. 03317 // E.g. 9 for TIFF_LZW. This means that AccusoftFilters can make a special 03318 // case for exporting TIFFs, and export using CTIFFWriter instead of 03319 // calling Snowbound. 03320 // For whatever reason, the following line of code replaced this value with 03321 // m_pExportOptions->m_FilterID, which since the rewrite of the export dlg 03322 // contains the value 0. 03323 // This bodge ensures that we don't overwrite AccusoftFilters::FilterType 03324 // with 0. 03325 if (m_pExportOptions->GetFilterType() != 0) 03326 AccusoftFilters::SetFilterType(m_pExportOptions->GetFilterType()); 03327 #endif 03328 03329 // Make a note of the Disk file we are to use 03330 OutputFile = pFile; 03331 03332 // Actually export the document 03333 BOOL ok = WriteFileHeader(); 03334 03335 // Do we want to use the existing palette, or generate a new one? The 03336 // value of BmapPrevDlg::m_bUseExistingPalette determines whether or 03337 // not one is needed to be generated, so no need to use any switch 03338 // logic. 03339 if ( ok ) 03340 { 03341 ok = DoExportDoc( pOp, pFile, pPath, pDoc, GetRenderDepth (), 03342 m_pExportOptions->GetDPI (), 03343 m_pExportOptions->GetSelectionType (), 03344 BmapPrevDlg::m_bUseExistingPalette ); 03345 } 03346 03347 ok &= WriteFileEnd(); 03348 03349 // pOptimised memory freed here. 03350 CleanUpAfterExport(); 03351 03352 return ok; 03353 } 03354 03355 03356 03357 03358 /******************************************************************************************** 03359 03360 > BOOL BaseBitmapFilter::SetUpExportBitmapOptions(BitmapExportOptions **ppExportOptions, 03361 KernelBitmap *pBitmap, BOOL OnlyDefaults = FALSE) 03362 03363 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 03364 Created: 12/5/97 03365 Inputs: 03366 Outputs: ppExportOptions - pointer, where a pointer to the export options object 03367 will be returned 03368 Purpose: Displays the export options dialog for this bitmap filter. This allows export 03369 options to be obtained by somebody else then the filter 03370 Returns: TRUE if worked, FALSE if failed. 03371 03372 ********************************************************************************************/ 03373 03374 BOOL BaseBitmapFilter::SetUpExportBitmapOptions(BitmapExportOptions **ppExportOptions, 03375 KernelBitmap *pBitmap, BOOL OnlyDefaults) 03376 { 03377 #ifdef DO_EXPORT 03378 ERROR2IF(pBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmap null bitmap pointer specified"); 03379 03380 // Note this pointer for later use 03381 pExportBitmap = pBitmap; 03382 03383 // Note this ptr for use in JPEG export. 03384 JPEGExportOptions::SetKernelBitmap(pBitmap); 03385 03386 // Get a pointer to the actual bitmap so that we can get some details from it. 03387 OILBitmap *pOilBitmap = pBitmap->ActualBitmap; 03388 ERROR2IF(pOilBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmap null oil bitmap pointer"); 03389 03390 // Create a record of information about the export 03391 *ppExportOptions = CreateExportOptions(); 03392 if (*ppExportOptions == NULL) 03393 { 03394 return FALSE; 03395 } 03396 03397 // Get the default settings 03398 (*ppExportOptions)->RetrieveDefaults(); 03399 03400 // Specify to the user what the export options for depth etc are going to be 03401 (*ppExportOptions)->SetSelectionType(ABITMAP); 03402 03403 // Get the details from the specified bitmap 03404 BitmapInfo BmInfo; 03405 pOilBitmap->GetInfo(&BmInfo); 03406 (*ppExportOptions)->SetDepth(BmInfo.PixelDepth); // get the bitmaps bpp 03407 03408 // Should really save the dpi when we load the file itself rather than doing 03409 // all this conversion with possible rounding errors. 03410 // Use the original size that has been calculated in the info header 03411 UINT32 PixWidth = BmInfo.PixelWidth; 03412 // UINT32 PixHeight = BmInfo.PixelHeight; 03413 MILLIPOINT RecWidth = BmInfo.RecommendedWidth; 03414 // MILLIPOINT RecHeight = BmInfo.RecommendedHeight; 03415 03416 if (PixWidth > 0) 03417 { 03418 (*ppExportOptions)->SetDPI((PixWidth * 72000.0)/(double)RecWidth); 03419 } 03420 03421 // WEBSTER - markn 5/2/97 03422 // If the bitmap has a transparent colour index, store it in the options object 03423 // -1 means no transparent colour 03424 INT32 TransIndex = -1; 03425 if (!pBitmap->GetTransparencyIndex(&TransIndex)) 03426 TransIndex = -1; 03427 (*ppExportOptions)->SetTransparencyIndex(TransIndex); 03428 03429 // check whether only the defaults are needed 03430 if (OnlyDefaults) 03431 return TRUE; 03432 03433 BOOL ok = GetExportOptions(*ppExportOptions); 03434 if (!ok) 03435 { 03436 if (*ppExportOptions != NULL) 03437 { 03438 delete *ppExportOptions; 03439 *ppExportOptions = NULL; 03440 } 03441 Error::SetError(_R(IDN_USER_CANCELLED),0); // Expects error set on cancel 03442 return FALSE; // if cancelled 03443 } 03444 03445 return ok; 03446 #else 03447 return FALSE; 03448 #endif 03449 } 03450 03451 /******************************************************************************************** 03452 03453 > BOOL BaseBitmapFilter::DoExportBitmapWithOptions(Operation* pOp, CCLexFile* pFile, PathName* pPath, 03454 KernelBitmap* pBitmap, BitmapExportOptions *pOptions) 03455 03456 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 03457 Created: 25/7/97 03458 Inputs: 03459 Purpose: Exports the specified bitmap straight out to file with none of the rendering 03460 that DoExport does. Uses the virtual fns of the inherited class. 03461 Do not override unless really necessary. Similar to DoExportBitmap in the base 03462 class, but uses the passed options, rather then invoking a dialog to get ones. 03463 Returns: TRUE if worked, FALSE if failed. 03464 03465 ********************************************************************************************/ 03466 03467 BOOL BaseBitmapFilter::DoExportBitmapWithOptions(Operation* pOp, CCLexFile* pFile, PathName* pPath, 03468 KernelBitmap* pBitmap, BitmapExportOptions *pOptions) 03469 { 03470 #ifdef DO_EXPORT 03471 ERROR2IF(pBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmap null bitmap pointer specified"); 03472 03473 if (pOptions == NULL) 03474 { 03475 // Create a record of information about the export 03476 SetUpExportBitmapOptions(&pOptions, pBitmap, TRUE); 03477 if (pOptions == NULL) 03478 return FALSE; 03479 } 03480 03481 // remember the old export options 03482 BitmapExportOptions *pOldOptions = GetBitmapExportOptions(); 03483 if (pOldOptions != NULL) 03484 pOldOptions->RetrieveDefaults(); 03485 03486 // set the new ones 03487 SetExportOptions(pOptions); 03488 pOptions->SetAsDefaults(); 03489 03490 // Make a note of the Disk file we are to use 03491 OutputFile = pFile; 03492 03493 // Note this pointer for later use 03494 pExportBitmap = pBitmap; 03495 03496 // Note this ptr for use in JPEG export. 03497 JPEGExportOptions::SetKernelBitmap(pBitmap); 03498 03499 // Get a pointer to the actual bitmap so that we can get some details from it. 03500 OILBitmap *pOilBitmap = pBitmap->ActualBitmap; 03501 ERROR2IF(pOilBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmap null oil bitmap pointer"); 03502 03503 // Get the details from the specified bitmap 03504 BitmapInfo BmInfo; 03505 pOilBitmap->GetInfo(&BmInfo); 03506 GetBitmapExportOptions()->SetDepth(BmInfo.PixelDepth); // get the bitmaps bpp 03507 03508 // Should really save the dpi when we load the file itself rather than doing 03509 // all this conversion with possible rounding errors. 03510 // Use the original size that has been calculated in the info header 03511 UINT32 PixWidth = BmInfo.PixelWidth; 03512 // UINT32 PixHeight = BmInfo.PixelHeight; 03513 MILLIPOINT RecWidth = BmInfo.RecommendedWidth; 03514 // MILLIPOINT RecHeight = BmInfo.RecommendedHeight; 03515 03516 if (PixWidth > 0) 03517 { 03518 //DPI = Mul32Div32( PixWidth, 72000, RecWidth ); 03519 GetBitmapExportOptions()->SetDPI((PixWidth * 72000.0)/(double)RecWidth); 03520 } 03521 03522 BOOL ok = TRUE; 03523 03524 // Used to open the file up before starting DoExport. But this meant a cancel on the export 03525 // options dialog had filled the file, if it was already present. So now up up here if 03526 // not open already. In the PreviewBitmap case the file will already be open. 03527 if (!pFile->isOpen()) 03528 { 03529 if (pFile->IsKindOf(CC_RUNTIME_CLASS(CCDiskFile))) 03530 { 03531 ok = OpenExportFile((CCDiskFile*) pFile, pPath); 03532 if (!ok) return FALSE; 03533 } 03534 else 03535 { 03536 TRACEUSER( "JustinF", _T("Tried to open non-CCDiskFile in BaseBitmapFilter::DoExportBitmap\n") ); 03537 return FALSE; 03538 } 03539 } 03540 03541 // Make a note of the Disk file we are to use 03542 OutputFile = pFile; 03543 03544 // We do not use an export region so specify null. 03545 ExportRegion = NULL; 03546 03547 // Actually write to the file, showing progress hourglass as we go 03548 ok = WriteBitmapToFile(pBitmap, GetBitmapExportOptions()->GetDPI()); 03549 03550 if (ok) 03551 WriteFileEnd(); 03552 03553 // All done - deallocate dynamic objects, stop the progress display/hourglass 03554 // and return success. (Also closes file). 03555 CleanUpAfterExport(); 03556 03557 // restore the old export options 03558 if (pOldOptions != NULL) 03559 { 03560 SetExportOptions(pOldOptions); 03561 pOldOptions->SetAsDefaults(); 03562 } 03563 03564 // restore the file 03565 OutputFile = pFile; 03566 03567 return ok; 03568 #else 03569 return FALSE; 03570 #endif 03571 } 03572 03573 03574 03575 /******************************************************************************************** 03576 03577 > virtual BOOL BaseBitmapFilter::SaveExportBitmapsToFile(CCLexFile* pFile, PathName* pPath, BitmapExportParam* pParam, 03578 BOOL DontShowFileName = FALSE) 03579 03580 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03581 Created: 1/5/97 03582 Inputs: pDiskFile - the file to put the exported data into 03583 pPath - the pathname of the file to be exported to 03584 pParam - the data to use when exporting the bitmaps 03585 DontShowFileName - if set to true then don't show the filename in the progress string 03586 Purpose: Exports the bitmaps specified by the BitmapExportParam object to a multi- 03587 image capable filter. Each of the bitmaps will be saved to file using the 03588 settings specified. 03589 This is the baseclass version and so is usually overriden 03590 Returns: TRUE if worked, FALSE if failed. 03591 03592 ********************************************************************************************/ 03593 03594 BOOL BaseBitmapFilter::SaveExportBitmapsToFile(CCLexFile* pFile, PathName* pPath, BitmapExportParam* pParam, 03595 BOOL DontShowFileName) 03596 { 03597 #ifdef DO_EXPORT 03598 ERROR2IF(pFile == NULL || pPath == NULL, FALSE,"NULL Parameters"); 03599 ERROR2IF(pParam == NULL,FALSE,"TI_GIFFilter::DoExportBitmaps null BitmapExportParam specified"); 03600 03601 ERROR3("BaseBitmapFilter::SaveExportBitmapsToFile calling baseclass version!"); 03602 03603 return TRUE; 03604 #endif 03605 return FALSE; 03606 } 03607 03608 03609 /******************************************************************************************** 03610 03611 > virtual BOOL BaseBitmapFilter::ExportRenderNodes(RenderRegion *pRegion, ExportDC *pDC, 03612 BOOL VisibleLayersOnly = FALSE, 03613 BOOL CheckSelected = FALSE, 03614 BOOL ShowProgress = TRUE) 03615 03616 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03617 Created: 12/5/95 03618 Inputs: pRegion - the render region to export to. 03619 pDc - device context to use 03620 VisibleLayersOnly - use visible layers or not 03621 ShowProgress - TRUE then start up a progress bar or FALSE assume the caller 03622 has done it. 03623 Returns: TRUE if the export process completed successfully, FALSE if an error occured. 03624 Purpose: Actually export the nodes to the given render region showing a progress bar 03625 as we go. Assumes everything has been set up by ExportRender. 03626 Overrides the baseclass version so that we can render in strips. 03627 Ignores the setting of ShowProgress as we must be in charge of the progress 03628 bar in this version. 03629 SeeAlso: ExportRender 03630 03631 ********************************************************************************************/ 03632 03633 BOOL BaseBitmapFilter::ExportRenderNodes(RenderRegion *pRegion, ExportDC *pDC, 03634 BOOL VisibleLayersOnly, BOOL CheckSelected, 03635 BOOL ShowProgress) 03636 { 03637 #ifdef DO_EXPORT 03638 ERROR2IF(pRegion==NULL,FALSE,"BaseBitmapFilter::ExportRender null render region supplied"); 03639 03640 // Set up the Accusoft variables used for its redenring loop and call back form of the 03641 // do next strip. This is just in case we are going to change from using the Bitmap 03642 // filter to using the Accusoft filters as we are saving in a format which the Bitmap 03643 // filters do not understand. 03644 //WEBSTER-Martin-03/01/97 03645 PORTNOTE("ExportAccusoft", "Removed use fo Accusoft filters") 03646 #ifndef EXCLUDE_FROM_XARALX 03647 AccusoftFilters::SetRenderVariables(this, pRegion, pDC, VisibleLayersOnly, CheckSelected); 03648 #endif 03649 03650 // Set the bad rendering flag to its default value 03651 BadExportRender = FALSE; 03652 03653 BOOL ok = TRUE; 03654 DocRect rClipRect = pRegion->GetRegionRect(); 03655 03656 BitmapExportOptions * pExportOptions = GetBitmapExportOptions(); 03657 BOOL DidASwap = FALSE; 03658 03659 // Check our class variable to see if we should render in strips or not 03660 // We do this so that things like the GIF filters 1bpp masked rendering can turn the 03661 // rendering in strips off. Should be on by default. 03662 if (RenderInStrips) 03663 { 03664 OurNumNodes = GetNumNodes(); 03665 //UINT32 OurUpdateEvery = UpdateEvery; 03666 03667 // We have a useful function in the GRenderBitmap class which tells us the number 03668 // of strips we are going to render with. 03669 GRenderBitmap *pGRenderBitmap = (GRenderBitmap*)pRegion; 03670 INT32 NumberOfStrips = pGRenderBitmap->GetNumBands(); 03671 if (NumberOfStrips <= 0) 03672 NumberOfStrips = 1; 03673 TRACEUSER( "Gerry", _T("Number of bands is %d\n"), NumberOfStrips); 03674 TRACEUSER( "Gerry", _T("Number of nodes is %d\n"), OurNumNodes); 03675 03676 // We need the progress bar to just move up once rather than for every strip 03677 // plus include the number of lines in the export bitmap so that we can show 03678 // a progress bar for this part of the export. 03679 // First, get the size of the bitmap we are going to export 03680 INT32 HeightInPixels = pGRenderBitmap->GetFullRegionHeight(); 03681 TRACEUSER( "Gerry", _T("Full region height in pixels is %d\n"), HeightInPixels ); 03682 03683 SizeOfExport = OurNumNodes * NumberOfStrips; 03684 SetNumNodes(SizeOfExport); 03685 03686 BitmapExportOptions* pOptions = GetBitmapExportOptions(); 03687 03688 // Start a progress update going 03689 // Extend it by the pixel height of the export 03690 String_64 ExportMessage(GetExportMsgID()); 03691 ExportMessage = GetExportProgressString(OutputFile, GetExportMsgID()); 03692 BeginSlowJob(200, FALSE, &ExportMessage); 03693 TRACEUSER( "Gerry", _T("Size of progress bar = %d\n"), SizeOfExport + HeightInPixels ); 03694 03695 // Reset this back to zero so that when we update the progress bar in WriteToFile 03696 // we can work out the current point reached on the progress bar 03697 SizeOfExport = 0; 03698 ProgressOffset = 0; 03699 m__StripStart = 0; 03700 03701 // Find out which way we want to render by asking the filters 03702 BOOL BottomToTop = GetRenderBottomToTop(); 03703 pGRenderBitmap->SetRenderBottomToTop(BottomToTop); 03704 03705 // SMFIX this is where we will generate a new optimal palette if we need to 03706 BOOL CreatingPalette = !pExportOptions->IsPaletteValid() && pExportOptions->GetDepth() <= 8; 03707 if (CreatingPalette) 03708 { 03709 if (!pExportOptions->CreatePaletteOptimiser()) 03710 { 03711 // we didn't create an optimiser as we already have a good one 03712 // use it to create the palette NOW! without the stats gathering part as are stats are still valid 03713 pExportOptions->CreateValidPalette(); 03714 // let the optimiser fill in the palette in the export options 03715 AlterPaletteContents(pExportOptions->GetLogicalPalette()); 03716 CreatingPalette = FALSE; 03717 } 03718 } 03719 else if(pExportOptions->GetDepth() <= 8) 03720 { 03721 // this call sets this palette in the lower reaches of the code from the palette held in the export options 03722 AlterPaletteContents(pExportOptions->GetLogicalPalette()); 03723 } 03724 03725 if (pExportOptions->IsCMYK()) 03726 { 03727 // If we are doing a CMYK export then we need to do a really cunning 4-pass render 03728 03729 TRACEUSER( "Gerry", _T("BaseBitmapFilter::ExportRenderNodes starting CMYK export\n") ); 03730 03731 // We need to save away the current ColourPlate and restore it afterwards 03732 // This may be problematic as the render region has already been created at this point 03733 // and also, the view will redraw when the ColourPlate is changed 03734 03735 View* pView = pRegion->GetRenderView(); 03736 ColourPlate* pCurPlate = pView->GetColourPlate(); 03737 if (pCurPlate) 03738 { 03739 pCurPlate = new ColourPlate(*pCurPlate); // Make a copy of it 03740 } 03741 else 03742 { 03743 pCurPlate = new ColourPlate; // Make a default 03744 pCurPlate->SetMonochrome(NULL, FALSE); // Set to non-mono 03745 } 03746 03747 // Get the first strip ready for action 03748 ok = pRegion->SetFirstBand(); 03749 if (!ok) 03750 { 03751 BadExportRender = TRUE; // flag that something has gone wrong 03752 EndWriteToFile(); 03753 EndSlowJob(); 03754 return FALSE; 03755 } 03756 03757 UINT32 nBandsCompleted = 0; 03758 03759 // Now render all the other strips, if there are any, until we have completed 03760 // the entire region. 03761 do 03762 { 03763 // Make sure this gets set back to the correct value before doing any rendering 03764 pGRenderBitmap->SetDoBitmapConversion(TRUE); 03765 03766 // Set up a destination bitmap of the strip size at 32 bpp 03767 // We must somehow get the size of the bitmap here before 03768 // it has actually been allocated in StartRender 03769 WinRect BitmapRect = ((GRenderRegion*)pGRenderBitmap)->CalculateWinRect(pGRenderBitmap->GetClipRect()); 03770 03771 TRACEUSER( "Gerry", _T("CMYK bitmap is (%d, %d)\n"), BitmapRect.GetWidth(), BitmapRect.GetHeight() ); 03772 LPBYTE pCMYKBits = NULL; 03773 LPBITMAPINFO pCMYKInfo = AllocDIB(BitmapRect.GetWidth(), BitmapRect.GetHeight(), 32, &pCMYKBits); 03774 memset(pCMYKBits, 0, BitmapRect.GetWidth() * BitmapRect.GetHeight() * sizeof(DWORD)); 03775 03776 // Loop around the four plates 03777 for (UINT32 PlateType = COLOURPLATE_CYAN; PlateType <= COLOURPLATE_KEY; PlateType += 1) 03778 { 03779 // Set the relevant ColourPlate on the View 03780 ColourPlate* pPlate = new ColourPlate((ColourPlateType)PlateType, TRUE, FALSE); 03781 pView->SetColourPlate(pPlate, FALSE); 03782 delete pPlate; 03783 03784 // This will cause a new ColourContext to be got from the view 03785 pRegion->ResetColourContext(); 03786 03787 // Call the base class version to do the actual node exporting 03788 // We have started the progress bar so tell it not to 03789 ok = Filter::ExportRenderNodes(pRegion, pDC, VisibleLayersOnly, CheckSelected, FALSE); 03790 // If a problem happened then get out quick. 03791 // Assume function has stopped the rendering. 03792 if (!ok) 03793 { 03794 if (pView) 03795 { 03796 pView->SetColourPlate(pCurPlate); 03797 delete pCurPlate; 03798 } 03799 BadExportRender = TRUE; // flag that something has gone wrong 03800 EndWriteToFile(); 03801 EndSlowJob(); 03802 return FALSE; 03803 } 03804 03805 LPBITMAPINFO pRenderInfo = NULL; 03806 LPBYTE pRenderData = NULL; 03807 pGRenderBitmap->GetBitmapData(&pRenderInfo, &pRenderData, FALSE); 03808 TRACEUSER( "Gerry", _T("Strip bitmap for plate %d is (%d, %d)\n"), PlateType, pRenderInfo->bmiHeader.biWidth, pRenderInfo->bmiHeader.biHeight); 03809 BYTE* pSrcBits = pRenderData; 03810 UINT32 NumPixels = pRenderInfo->bmiHeader.biWidth * pRenderInfo->bmiHeader.biHeight; 03811 BYTE* pDestBits = ((BYTE*)pCMYKBits) + PlateType - COLOURPLATE_CYAN; // Pointer arithmetic 03812 for (UINT32 Pixel = 0; Pixel < NumPixels; Pixel++) 03813 { 03814 *pDestBits = (255 - pSrcBits[0]) * (255 - pSrcBits[3]) / 255; 03815 pDestBits += 4; 03816 pSrcBits += 4; 03817 } 03818 } 03819 03820 // Update our size of export variable 03821 SizeOfExport += OurNumNodes; 03822 // Update the filters stored progress offset value 03823 ProgressOffset += OurNumNodes; 03824 TRACEUSER( "Gerry", _T("BaseBitmapFilter::RenderNextStrip ProgressOffset = %d\n"), ProgressOffset); 03825 03826 // Now we need to get WriteFrame to output the composited bitmap 03827 // The easiest way to do this will be to replace the bitmap in the render region 03828 // with the composited one and just call WriteFrame as normal 03829 DWORD* pSrcBits = (DWORD*)pGRenderBitmap->Get32BitRGBQuadData(); 03830 UINT32 NumPixels = pGRenderBitmap->GetSizeOfRGBQuadData(); 03831 memcpy(pSrcBits, pCMYKBits, NumPixels * sizeof(DWORD)); 03832 03833 // We need to stop GetBitmapData from doing another conversion when reading the CMYK data 03834 pGRenderBitmap->SetDoBitmapConversion(FALSE); 03835 03836 // Free the temp bitmap 03837 FreeDIB(pCMYKInfo, pCMYKBits); 03838 03839 // Save that data out to file, this should update SizeOfExport with the 03840 // current strip size 03841 // Note: it will also render all the remaining strips 03842 ok = WriteFrame(); 03843 // If a problem happened then get out quick. 03844 if (!ok) 03845 { 03846 if (pView) 03847 { 03848 pView->SetColourPlate(pCurPlate); 03849 delete pCurPlate; 03850 } 03851 BadExportRender = TRUE; // flag that something has gone wrong 03852 EndWriteToFile(); 03853 EndSlowJob(); 03854 return FALSE; 03855 } 03856 03857 // Advance the progress bar 03858 UINT32 nProgress = UINT32((double(nBandsCompleted) / double(NumberOfStrips)) * 200.0); 03859 TRACEUSER( "Gerry", _T("nProgress = %d\n"), nProgress); 03860 03861 if ( !ContinueSlowJob (nProgress) ) 03862 { 03863 // Error; close down and exit nicely. 03864 // Must set an error otherwise we will get the dreaded reporting error 03865 // when none set message. 03866 // If no error message ID set in this filter then use default 03867 03868 // Andy, 13-12-00 03869 // N.B. At the moment, things go pear-shaped if we press ESC during export. 03870 // e.g. subsequent presses of 'preview' do not generate a preview. 03871 // However it wasn't exactly well behaved before, e.g. sometimes gave 03872 // internal error 'Failed to create an intermediate bitmap pointer!', or 03873 // access violated if the user clicked 'background transparency' after a 03874 // cancelled export. 03875 if (pView) 03876 { 03877 pView->SetColourPlate(pCurPlate); 03878 delete pCurPlate; 03879 } 03880 if ( StopExportMsgID == 0 ) 03881 Error::SetError ( _R(IDW_CANCELEXPORT) ); 03882 else 03883 Error::SetError ( StopExportMsgID ); 03884 pRegion->StopRender (); 03885 if ( ShowProgress ) 03886 EndSlowJob (); 03887 return FALSE; 03888 } 03889 03890 nBandsCompleted ++; 03891 03892 // Check if there are any more bands 03893 } while (pRegion->GetNextBand()); 03894 03895 if (pView) 03896 { 03897 pView->SetColourPlate(pCurPlate); 03898 delete pCurPlate; 03899 } 03900 } 03901 else 03902 { 03903 for (INT32 loop = 0; loop < 2; loop++) // never do this more than twice once for the palette and once to write it out to file 03904 { 03905 TRACEUSER( "Gerry", _T("BaseBitmapFilter::ExportRenderNodes loop = %d\n"), loop); 03906 03907 if (!CreatingPalette && pExportOptions->GetDepth() <= 8) 03908 { 03909 DidASwap = pExportOptions->SwapEditedColoursInLogicalPalette(); 03910 AlterPaletteContents(pExportOptions->GetLogicalPalette()); 03911 } 03912 03913 // Get the first strip ready for action 03914 ok = pRegion->SetFirstBand(); 03915 if (!ok) 03916 { 03917 BadExportRender = TRUE; // flag that something has gone wrong 03918 EndWriteToFile(); 03919 EndSlowJob(); 03920 return FALSE; 03921 } 03922 03923 UINT32 nBandsCompleted = 0; 03924 03925 // Now render all the other strips, if there are any, until we have completed 03926 // the entire region. 03927 do 03928 { 03929 // Call the base class version to do the actual node exporting 03930 // We have started the progress bar so tell it not to 03931 ok = Filter::ExportRenderNodes(pRegion, pDC, VisibleLayersOnly, CheckSelected, FALSE); 03932 // If a problem happened then get out quick. 03933 // Assume function has stopped the rendering. 03934 if (!ok) 03935 { 03936 BadExportRender = TRUE; // flag that something has gone wrong 03937 EndWriteToFile(); 03938 EndSlowJob(); 03939 return FALSE; 03940 } 03941 03942 if (!CreatingPalette) 03943 { 03944 // Update our size of export variable 03945 SizeOfExport += OurNumNodes; 03946 // Update the filters stored progress offset value 03947 ProgressOffset += OurNumNodes; 03948 TRACEUSER( "Gerry", _T("BaseBitmapFilter::RenderNextStrip ProgressOffset = %d\n"),ProgressOffset); 03949 } 03950 03951 // Save that data out to file, this should update SizeOfExport with the 03952 // current strip size 03953 if (CreatingPalette) 03954 { 03955 // calc the stats for an optimised palette 03956 pExportOptions->GatherPaletteStats( ((GRenderRegion * )pRegion)->Get32BitRGBQuadData(), 03957 ((GRenderRegion * )pRegion)->GetSizeOfRGBQuadData()); 03958 } 03959 else 03960 ok = WriteFrame(); 03961 // If a problem happened then get out quick. 03962 if (!ok) 03963 { 03964 BadExportRender = TRUE; // flag that something has gone wrong 03965 EndWriteToFile(); 03966 EndSlowJob(); 03967 return FALSE; 03968 } 03969 03970 // Advance the progress bar 03971 UINT32 nProgress; 03972 // if this image doesn't need a palette, scale the progress value to 03973 // the full length of the bar 03974 if (!CreatingPalette && loop==0) 03975 nProgress = UINT32((double(nBandsCompleted) / double(NumberOfStrips)) * 200.0); 03976 // otherwise, scale the progress value to half the length of the bar 03977 // (as this rendering loop will occur twice) 03978 else 03979 nProgress = UINT32((double(nBandsCompleted) / double(NumberOfStrips)) * 100.0 + double(loop)*100.0); 03980 TRACEUSER( "Gerry", _T("nProgress = %d\n"), nProgress); 03981 03982 if ( !ContinueSlowJob (nProgress) ) 03983 { 03984 // Error; close down and exit nicely. 03985 // Must set an error otherwise we will get the dreaded reporting error 03986 // when none set message. 03987 // If no error message ID set in this filter then use default 03988 03989 // Andy, 13-12-00 03990 // N.B. At the moment, things go pear-shaped if we press ESC during export. 03991 // e.g. subsequent presses of 'preview' do not generate a preview. 03992 // However it wasn't exactly well behaved before, e.g. sometimes gave 03993 // internal error 'Failed to create an intermediate bitmap pointer!', or 03994 // access violated if the user clicked 'background transparency' after a 03995 // cancelled export. 03996 if ( StopExportMsgID == 0 ) 03997 Error::SetError ( _R(IDW_CANCELEXPORT) ); 03998 else 03999 Error::SetError ( StopExportMsgID ); 04000 pRegion->StopRender (); 04001 if ( ShowProgress ) 04002 EndSlowJob (); 04003 return FALSE; 04004 } 04005 04006 nBandsCompleted ++; 04007 04008 // Check if there are any more bands 04009 } while (pRegion->GetNextBand()); 04010 04011 if (CreatingPalette) 04012 { 04013 CreatingPalette = FALSE; 04014 // let the optimiser fill in the palette in the export options 04015 pExportOptions->CreateValidPalette(); 04016 // set this as the palette being used in output dib 04017 AlterPaletteContents(pExportOptions->GetLogicalPalette()); 04018 // Reset the clip region to what it was when we started this 04019 pRegion->SetClipRect(rClipRect); 04020 } 04021 else 04022 break; // leave this for loop now 04023 } 04024 } 04025 04026 if (DidASwap) 04027 { 04028 pOptions->SwapEditedColoursInLogicalPalette(); 04029 AlterPaletteContents(pOptions->GetLogicalPalette()); 04030 } 04031 // Close down progress display 04032 // Do it before ending as then the TI GIF filter can show a progress bar on 04033 // its possible masked rendering for transparency and export of the GIF data 04034 // which happens in the EndWriteToFile. 04035 EndSlowJob(); 04036 } 04037 else 04038 { 04039 // Call the base class version to do the actual node exporting 04040 // Use the pass in version to say whether we need to start the progress bar or not. 04041 // Assume that we are the GIF filter renderer and so do not try and output the data 04042 // at all. We will ensure as this might be dangerous. 04043 PORTNOTE("filter", "Removed use of GIFFilter") 04044 #ifndef EXCLUDE_FROM_XARALX 04045 ERROR3IF(!(this->IS_KIND_OF(TI_GIFFilter)) && !(this->IS_KIND_OF(PNGFilter)), 04046 "BaseBitmapFilter::ExportRenderNodes rendering in strips off"); 04047 #else 04048 ERROR3IF(!(this->IS_KIND_OF(PNGFilter)), 04049 "BaseBitmapFilter::ExportRenderNodes rendering in strips off"); 04050 #endif 04051 04052 ok = Filter::ExportRenderNodes(pRegion, pDC, VisibleLayersOnly, 04053 CheckSelected, ShowProgress); 04054 04055 // SMFIX optimise the palette in the no strip based manner 04056 BOOL CreatingPalette = !pExportOptions->IsPaletteValid(); 04057 if (CreatingPalette) 04058 { 04059 // create a palette optimiser (or retrieve a valid one) 04060 if (pExportOptions->CreatePaletteOptimiser()) 04061 { 04062 // we need to gather stats as we have made a virgin new optimiser 04063 pExportOptions->GatherPaletteStats( ((GRenderRegion * )pRegion)->Get32BitRGBQuadData(), 04064 ((GRenderRegion * )pRegion)->GetSizeOfRGBQuadData()); 04065 } 04066 04067 // let the optimiser fill in the palette in the export options 04068 pExportOptions->CreateValidPalette(); 04069 // let the optimiser fill in the palette in the export options 04070 AlterPaletteContents(pExportOptions->GetLogicalPalette()); 04071 } 04072 04073 /* // SMFIX 04074 if(pRegion->m_DoCompression) 04075 { 04076 BITMAPINFO* pBMPInfo = NULL; 04077 BYTE* pBMPData = NULL; 04078 ((GRenderBitmap*)pRegion)->GetBitmapData(&pBMPInfo,&pBMPData); 04079 ((GRenderBitmap*)pRegion)->GetDrawContext()->ConvertBitmap(&pBMPInfo->bmiHeader,pBMPData,&pBMPInfo->bmiHeader,pBMPData,0); 04080 }*/ 04081 } 04082 04083 // return outcome to caller 04084 return ok; 04085 #else 04086 return FALSE; 04087 #endif 04088 } 04089 04090 04091 /******************************************************************************************** 04092 04093 > BOOL BaseBitmapFilter::WriteToFile( BOOL AtEnd) 04094 04095 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 04096 Created: 22/8/94 04097 Inputs: AtEnd is TRUE if this is the last chunk of the file, FALSE if not. 04098 Purpose: Writes out the bitmap to a file. Inherited classes override this to write 04099 in different file formats. 04100 AtEnd is ignored now and should always be set to TRUE. 04101 04102 Returns: TRUE if worked, FALSE if failed. 04103 04104 ********************************************************************************************/ 04105 04106 BOOL BaseBitmapFilter::WriteToFile( BOOL AtEnd) 04107 { 04108 ENSURE(FALSE, "Base class bitmap filter WriteToFile called"); 04109 return FALSE; 04110 } 04111 04112 /******************************************************************************************** 04113 04114 > BOOL BaseBitmapFilter::EndWriteToFile( ) 04115 04116 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04117 Created: 12/5/95 04118 Inputs: - 04119 Purpose: Cleans up after writing the bitmap data out to a file. Inherited classes 04120 override this to write in different file formats. 04121 Returns: TRUE if worked, FALSE if failed. 04122 04123 ********************************************************************************************/ 04124 04125 BOOL BaseBitmapFilter::EndWriteToFile( ) 04126 { 04127 ENSURE(FALSE, "Base class bitmap filter EndWriteToFile called"); 04128 return FALSE; 04129 } 04130 04131 04132 /******************************************************************************************** 04133 04134 > virtual BOOL BaseBitmapFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, double Dpi) 04135 04136 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04137 Created: 25/4/95 04138 Inputs: Pointer to the bitmap to be exported. 04139 Returns: TRUE if worked, FALSE if errored. 04140 Purpose: Physically put the bitmap into the disk. Inherited classes override this to write 04141 in different file formats. 04142 SeeAlso: WriteDataToFile(); AccusoftFilters::WriteToFile; AccusoftFilters::WriteDataToFile; 04143 04144 ********************************************************************************************/ 04145 04146 BOOL BaseBitmapFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, double Dpi) 04147 { 04148 ERROR3("Base class bitmap filter WriteBitmapToFile called"); 04149 return FALSE; 04150 } 04151 04152 /******************************************************************************************** 04153 04154 > virtual BOOL BaseBitmapFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, BaseCamelotFilter *pFilter, 04155 CCLexFile *pFile, INT32 Compression) 04156 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04157 Created: 20/6/96 04158 Inputs: pKernelBitmap - Pointer to the bitmap to be exported. 04159 pFilter - Pointer to the BaseCamelot filter which provides progress functions 04160 pFile - Pointer to the CCFile class to use for export 04161 Compression - used to flag how much compression of the data is required. 04162 Returns: TRUE if worked, FALSE if errored. 04163 Purpose: Physically put the bitmap into the disk. Inherited classes override this to write 04164 in different file formats. 04165 This is used by the native/web format to output the actual bitmap data content 04166 of a bitmap definition record. The function can assume that the CCFile is open 04167 and ready for writing and must use the functions provided by pFilter to update 04168 the progress system. 04169 This is the baseclass version and hence needs overiding, hence the error. 04170 SeeAlso: BitmapListComponent::SaveBitmapDefinition; 04171 04172 ********************************************************************************************/ 04173 04174 BOOL BaseBitmapFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, BaseCamelotFilter *pFilter, 04175 CCLexFile *pFile, INT32 Compression) 04176 { 04177 // Create a record of information about the export 04178 m_pExportOptions = CreateExportOptions(); 04179 if (GetBitmapExportOptions() == NULL) 04180 { 04181 return FALSE; 04182 } 04183 04184 OutputFile = pFile; 04185 04186 return TRUE; 04187 } 04188 04189 /******************************************************************************************** 04190 04191 > static DocRect BaseBitmapFilter::GetSizeOfDrawing(Spread *pSpread=NULL) 04192 04193 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04194 Created: 18/4/95 04195 Inputs: pointer to the spread to use 04196 Purpose: Works out the size of the rectangle encompassing the drawing. 04197 Code also used to work out the pixel size in the bitmap export options 04198 dialog box. 04199 04200 Added by Graham 11/4/97: If pSpread is NULL, we get the first 04201 spread of the current document to use 04202 04203 Returns: Size of the rectangle encompassing the drawing. 04204 SeeAlso: BmpPrefsDlg::RecalculateSize; BaseBitmapFilter::DoExport; 04205 04206 ********************************************************************************************/ 04207 04208 DocRect BaseBitmapFilter::GetSizeOfDrawing(Spread *pSpread) 04209 { 04210 // Start out with an empty clip rect 04211 DocRect SpreadRect; 04212 SpreadRect.MakeEmpty(); 04213 04214 //If we have not been passed a spread... 04215 if (pSpread == NULL) 04216 { 04217 //Then let's get the first spread of the current document 04218 Document* pdocCurrent=Document::GetCurrent(); 04219 ERROR2IF(pdocCurrent==NULL, DocRect(0,0,0,0), "BaseBitmapFilter - no current document"); 04220 04221 //And finally the current spread 04222 PORTNOTE("spread", "Multi-spread warning!") 04223 pSpread=GetFirstSpread(pdocCurrent); 04224 ERROR2IF(pSpread==NULL, DocRect(0,0,0,0), "BaseBitmapFilter - no spread"); 04225 } 04226 04227 // We need to take into account the fact that some layers may not be visible 04228 Layer* pLayer = pSpread->FindFirstLayer(); 04229 while (pLayer != NULL) 04230 { 04231 // We've got a layer so check to see if it is visible 04232 // Added 8/4/97 extra checks to see if we are the special layers 04233 // and so shouldn't be included in the bounding calulations 04234 if (pLayer->IncludeLayerInBoundingCalcs()) 04235 { 04236 // This one is visible, so union it in 04237 DocRect LayerRect = pLayer->GetBoundingRect(); 04238 SpreadRect = SpreadRect.Union(LayerRect); 04239 } 04240 04241 // Get the next sibling layer 04242 pLayer = pLayer->FindNextLayer(); 04243 } 04244 04245 // return the found rectangle to the caller. 04246 return SpreadRect; 04247 } 04248 04249 /******************************************************************************************** 04250 04251 > static DocRect BaseBitmapFilter::GetSizeOfSpread(Spread *pSpread) 04252 04253 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04254 Created: 18/4/95 04255 Inputs: pointer to the spread to use 04256 Purpose: Works out the size of the rectangle encompassing the spread. 04257 Code also used to work out the pixel size in the bitmap export options 04258 dialog box. 04259 Returns: Size of the rectangle encompassing the spread. 04260 SeeAlso: BmpPrefsDlg::RecalculateSize; BaseBitmapFilter::PrepareToExport; 04261 04262 ********************************************************************************************/ 04263 04264 DocRect BaseBitmapFilter::GetSizeOfSpread(Spread *pSpread) 04265 { 04266 // Start out with an empty clip rect 04267 DocRect SpreadRect; 04268 SpreadRect.MakeEmpty(); 04269 04270 if (pSpread == NULL) 04271 { 04272 ERROR3("BaseBitmapFilter::GetSizeOfSpread null spread"); 04273 return SpreadRect; 04274 } 04275 04276 // build a rectangle out of all the pages in the selected spread 04277 Node *pPage = pSpread->FindFirstPageInSpread(); 04278 ERROR3IF(pPage == NULL, "Spread has no pages"); 04279 04280 while (pPage) 04281 { 04282 if (pPage->GetRuntimeClass() == CC_RUNTIME_CLASS(Page) ) 04283 SpreadRect = SpreadRect.Union(( (Page*)pPage)->GetPageRect() ); 04284 04285 pPage = pPage->FindNext(); 04286 } 04287 04288 ERROR3IF(SpreadRect.IsEmpty(),"Current spread has no pages"); 04289 04290 return SpreadRect; 04291 } 04292 04293 /******************************************************************************************** 04294 04295 > static BOOL BaseBitmapFilter::GetSizeOfBitmap(INT32 *PixelWidth, INT32 *PixelHeight) 04296 04297 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04298 Created: 25/4/95 04299 Inputs: - 04300 Outputs: PixelWidth bitmap width in pixels 04301 PixelHeight bitmap height in pixels 04302 Purpose: Works out the size of the bitmap in the bitmap export options 04303 dialog box. 04304 Returns: True if completed ok. 04305 SeeAlso: BmpPrefsDlg::RecalculateSize; BaseBitmapFilter::PrepareToExport; 04306 04307 ********************************************************************************************/ 04308 BOOL BaseBitmapFilter::GetSizeOfBitmap(INT32 *PixelWidth, INT32 *PixelHeight) 04309 { 04310 #ifdef DO_EXPORT 04311 ERROR2IF(pExportBitmap==NULL,FALSE,"BaseBitmapFilter::GetSizeOfBitmap no bitmap"); 04312 ERROR2IF(PixelWidth==NULL,FALSE,"BaseBitmapFilter::GetSizeOfBitmap no PixelWidth"); 04313 ERROR2IF(PixelHeight==NULL,FALSE,"BaseBitmapFilter::GetSizeOfBitmap no PixelHeight"); 04314 04315 // Set return values in case of early exit 04316 *PixelWidth = 0; 04317 *PixelHeight = 0; 04318 04319 // Get a pointer to the actual bitmap so that we can get some details from it. 04320 OILBitmap *pOilBitmap = pExportBitmap->ActualBitmap; 04321 ERROR3IF(pOilBitmap == NULL,"BaseBitmapFilter::GetSizeOfBitmap null oil bitmap pointer"); 04322 if (pOilBitmap) 04323 { 04324 BitmapInfo BmInfo; 04325 pOilBitmap->GetInfo(&BmInfo); 04326 *PixelWidth = BmInfo.PixelWidth; 04327 *PixelHeight = BmInfo.PixelHeight; 04328 } 04329 04330 return TRUE; 04331 #else 04332 return FALSE; 04333 #endif 04334 } 04335 04336 /******************************************************************************************** 04337 04338 > virtual BOOL BaseBitmapFilter::IsThisBppOk(UINT32 Bpp) 04339 04340 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04341 Created: 27/4/95 04342 Inputs: Bpp or Colour depth. 04343 Returns: TRUE if this filter can cope with this colour depth, FALSE otherwise. 04344 Purpose: Check if this Bitmap filter can cope with saving at this Bpp/Colour depth. 04345 SeeAlso: OpMenuExport::DoWithParam; 04346 04347 ********************************************************************************************/ 04348 04349 BOOL BaseBitmapFilter::IsThisBppOk(UINT32 Bpp) 04350 { 04351 // Base class version so always return FALSE. 04352 return FALSE; 04353 } 04354 04355 /******************************************************************************************** 04356 04357 > virtual UINT32 BaseBitmapFilter::GetExportMsgID() 04358 04359 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04360 Created: 18/09/95 04361 Returns: The id of the message to put on the progress display whilst exporting. 04362 Purpose: Used to get the message id to be used during export. 04363 Virtual, so that two stage exporters can change the message. 04364 SeeAlso: DoExport; 04365 04366 ********************************************************************************************/ 04367 04368 UINT32 BaseBitmapFilter::GetExportMsgID() 04369 { 04370 if (GeneratingOptimisedPalette()) 04371 return _R(IDS_GENOPTPALMSGID); // "Generating optimised palette..." 04372 else 04373 return Filter::GetExportMsgID(); 04374 } 04375 04376 /******************************************************************************************** 04377 04378 > virtual BOOL BaseBitmapFilter::GenerateOptimisedPalette(Spread *pSpread, UINT32 Depth, double DPI, BOOL SnapToBrowserPalette, UINT32 NumColsInPalette = 0, BOOL UsePrimaryCols = TRUE) 04379 04380 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 04381 Created: 30/5/96 04382 Inputs: pSpread = ptr to spread 04383 Depth = The BPP of the bitmap 04384 DPI = the dpi of the bitmap 04385 NumColsInPalette = prefered number of cols in palette (0 = select maximum allowed) 04386 (only applies when Depth == 8) 04387 UsePrimaryCols = Put primary colours in palette 04388 (only applies when Depth == 8) 04389 SnapToBrowserPalette= TRUE if the palette should be snapped to the browser palette after generation 04390 04391 Returns: TRUE if Palette generated ok 04392 Purpose: Generates an optimised palette to use during export 04393 SeeAlso: - 04394 04395 ********************************************************************************************/ 04396 04397 BOOL BaseBitmapFilter::GenerateOptimisedPalette(Spread *pSpread, UINT32 Depth, double DPI, BOOL SnapToBrowserPalette, UINT32 NumColsInPalette, BOOL UsePrimaryCols) 04398 { 04399 #ifdef DO_EXPORT 04400 if (Depth > 8) 04401 { 04402 pOptimisedPalette = NULL; 04403 return TRUE; 04404 } 04405 04406 TRACEUSER( "Neville", _T("Trying to generate an optimised palette ...\n") ); 04407 04408 WeAreGeneratingOptPalette = TRUE; 04409 04410 // Don't use rendering matrix when exporting BMPs as it uses coordinates as is 04411 Matrix Identity; 04412 04413 // Don't use view scale; set to 1 04414 FIXED16 Scale(1); 04415 04416 // Only use special 8bpp palette if the UsePrimaryColours flag is TRUE 04417 BOOL use8bpp = ((Depth == 8) && UsePrimaryCols); 04418 GRenderOptPalette* pPalRegion = new GRenderOptPalette(ClipRect, Identity, Scale, 32, DPI, use8bpp); 04419 if (pPalRegion) 04420 { 04421 // we need a View to Attach to, so that: 04422 // default Quality setting 04423 // CalcPixelWidth etc get called 04424 04425 DocView *View = DocView::GetCurrent(); 04426 if (View) 04427 { 04428 // Attach to the right device. (note no DC) 04429 pPalRegion->AttachDevice(View, NULL, pSpread); 04430 } 04431 else 04432 ERROR2(FALSE,"BaseBitmapFilter::GenerateOptimisedPalette no current view"); 04433 04434 RenderInStrips = TRUE; 04435 04436 // Now do an export render pass, using the Palette Region 04437 if (ExportRender(pPalRegion)) 04438 { 04439 UINT32 MaxColours = 1U<<Depth; // let's not use floating point here - UINT32(pow(2,Depth)); 04440 04441 if (NumColsInPalette < 1) 04442 NumColsInPalette = MaxColours; 04443 04444 if (use8bpp && NumColsInPalette < 20) 04445 NumColsInPalette = 20; 04446 04447 if (NumColsInPalette > MaxColours) 04448 NumColsInPalette = MaxColours; 04449 04450 // All went ok, so extract the Optimised palette from the Region 04451 pOptimisedPalette = pPalRegion->GetOptimisedPalette(MaxColours, NumColsInPalette, GetNumReservedColours(), SnapToBrowserPalette); 04452 04453 if (pOptimisedPalette) TRACEUSER( "Neville", _T("Blimey. We got an optimised palette to use.\n") ); 04454 } 04455 04456 delete pPalRegion; 04457 } 04458 04459 WeAreGeneratingOptPalette = FALSE; 04460 #endif 04461 return TRUE; 04462 } 04463 04464 /******************************************************************************************** 04465 04466 > virtual BOOL BaseBitmapFilter::GenerateOptimisedPalette(Spread *pSpread, BitmapExportOptions *pOptions, BOOL SnapToBrowserPalette) 04467 04468 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04469 Created: 16/1/97 04470 Inputs: pSpread = ptr to spread 04471 pOptions = ptr to bitmap export options 04472 SnapToBrowserPalette = If TRUE, snap all optimised palette entries to the browser palette 04473 04474 Returns: TRUE if Palette generated ok 04475 Purpose: Generates an optimised palette to use during export 04476 04477 This is an alternative interface to GenerateOptimisedPalette(Spread *pSpread, UINT32 Depth, double DPI, UINT32 NumColsInPalette, BOOL UsePrimaryCols); 04478 04479 WEBSTER - markn 16/1/97 04480 SeeAlso: - 04481 04482 ********************************************************************************************/ 04483 04484 BOOL BaseBitmapFilter::GenerateOptimisedPalette(Spread *pSpread, BitmapExportOptions *pOptions, BOOL SnapToBrowserPalette) 04485 { 04486 if (pSpread != NULL && pOptions != NULL) 04487 { 04488 return GenerateOptimisedPalette(pSpread, 04489 pOptions->GetDepth(), 04490 pOptions->GetDPI(), 04491 SnapToBrowserPalette, 04492 pOptions->GetNumColsInPalette(), 04493 pOptions->GetUseSystemColours() 04494 ); 04495 } 04496 04497 return FALSE; 04498 } 04499 04500 void BaseBitmapFilter::AlterPaletteContents( LPLOGPALETTE pPalette ) 04501 { 04502 return; 04503 } 04504 04505 /******************************************************************************************** 04506 04507 > static BOOL BaseBitmapFilter::GeneratingOptimisedPalette() 04508 04509 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 04510 Created: 30/5/96 04511 Inputs: - 04512 Returns: TRUE if we are in the middle of generating an optimised Palette 04513 Purpose: Find out if we are currently generating an optimised palette or not 04514 SeeAlso: - 04515 04516 ********************************************************************************************/ 04517 04518 BOOL BaseBitmapFilter::GeneratingOptimisedPalette() 04519 { 04520 return WeAreGeneratingOptPalette; 04521 } 04522 04523 04524 /******************************************************************************************** 04525 04526 > virtual BOOL BaseBitmapFilter::WriteFileHeader(void) 04527 04528 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 04529 Created: 12/6/96 04530 Inputs: - 04531 Returns: FALSE if failed else TRUE 04532 Purpose: To write out the file specific header data 04533 SeeAlso: - 04534 04535 ********************************************************************************************/ 04536 04537 BOOL BaseBitmapFilter::WriteFileHeader(void) 04538 { 04539 return(TRUE); 04540 } 04541 04542 04543 /******************************************************************************************** 04544 04545 > virtual BOOL BaseBitmapFilter::WritePreFrame(void) 04546 04547 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 04548 Created: 12/6/96 04549 Inputs: - 04550 Returns: FALSE if failed else TRUE 04551 Purpose: To write out any frame specific info before the image 04552 SeeAlso: - 04553 04554 ********************************************************************************************/ 04555 04556 BOOL BaseBitmapFilter::WritePreFrame(void) 04557 { 04558 return(TRUE); 04559 } 04560 04561 04562 /******************************************************************************************** 04563 04564 > virtual BOOL BaseBitmapFilter::WriteFileHeader(void) 04565 04566 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 04567 Created: 12/6/96 04568 Inputs: - 04569 Returns: FALSE if failed else TRUE 04570 Purpose: To write out the image itself 04571 This base class version actually calls the WriteToFile() function so that 04572 derived classes do not have to implement any of the multi-image stuff 04573 SeeAlso: - 04574 04575 ********************************************************************************************/ 04576 04577 BOOL BaseBitmapFilter::WriteFrame(void) 04578 { 04579 return(WriteToFile(TRUE)); 04580 } 04581 04582 04583 /******************************************************************************************** 04584 04585 > virtual BOOL BaseBitmapFilter::WritePostFrame(void) 04586 04587 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 04588 Created: 12/6/96 04589 Inputs: - 04590 Returns: FALSE if failed else TRUE 04591 Purpose: To write out any frame specific info after the image 04592 SeeAlso: - 04593 04594 ********************************************************************************************/ 04595 04596 BOOL BaseBitmapFilter::WritePostFrame(void) 04597 { 04598 return(TRUE); 04599 } 04600 04601 04602 /******************************************************************************************** 04603 04604 > virtual BOOL BaseBitmapFilter::WriteFileEnd(void) 04605 04606 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 04607 Created: 12/6/96 04608 Inputs: - 04609 Returns: FALSE if failed else TRUE 04610 Purpose: To write out the file specific data at the end of the file 04611 This base class version calls EndWriteToFile() so that derived classes 04612 do not have to implement the multi-image stuff 04613 SeeAlso: - 04614 04615 ********************************************************************************************/ 04616 04617 BOOL BaseBitmapFilter::WriteFileEnd(void) 04618 { 04619 return(EndWriteToFile()); 04620 } 04621 04622 04623 /******************************************************************************************** 04624 04625 > virtual BOOL BaseBitmapFilter::WritePreSecondPass(void) 04626 04627 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 04628 Created: 17/6/96 04629 Inputs: - 04630 Returns: FALSE if failed else TRUE 04631 Purpose: Called before the second pass of a two pass export so the filter can reset 04632 itself 04633 SeeAlso: - 04634 04635 ********************************************************************************************/ 04636 04637 BOOL BaseBitmapFilter::WritePreSecondPass(void) 04638 { 04639 return(TRUE); 04640 } 04641 04642 04643 /******************************************************************************************** 04644 04645 > virtual BOOL BaseBitmapFilter::WritePostOptimisedPalette(void) 04646 04647 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 04648 Created: 17/6/96 04649 Inputs: - 04650 Returns: FALSE if failed else TRUE 04651 Purpose: Called after the optimised palette has been generated but before the export 04652 of the bitmap. 04653 SeeAlso: - 04654 04655 ********************************************************************************************/ 04656 04657 BOOL BaseBitmapFilter::WritePostOptimisedPalette(void) 04658 { 04659 return(TRUE); 04660 } 04661 04662 04663 /******************************************************************************************** 04664 > UINT32 BaseBitmapFilter::GetNumReservedColours() 04665 04666 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 04667 Created: 31/5/96 04668 Inputs: - 04669 Returns: The numbers of colours the filter would like to reserve. The base class 04670 reserves zero colours. 04671 Purpose: Override this to leave spaces in the palette. eg the GIF filter reserves an 04672 index for the transparency mask colour. 04673 SeeAlso: - 04674 ********************************************************************************************/ 04675 UINT32 BaseBitmapFilter::GetNumReservedColours() 04676 { 04677 return 0; 04678 } 04679 04680 04681 /******************************************************************************************** 04682 04683 > CCLexFile* BaseBitmapFilter::GetExportFile() const 04684 04685 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 04686 Created: 29/10/96 04687 Returns: A pointer to the file provided in the filter entry point (DoExport,etc.) 04688 Purpose: Support function to obtain file to export in WriteBitmapToFile 04689 04690 ********************************************************************************************/ 04691 CCLexFile* BaseBitmapFilter::GetExportFile() const 04692 { 04693 return OutputFile; 04694 } 04695 04696 04697 /******************************************************************************************** 04698 04699 > BOOL BaseBitmapFilter::GetCurrentStripInfo( ADDR* ppBits, 04700 BMP_SIZE* pWidth, BMP_SIZE* pHeight, 04701 BMP_DEPTH* pDepth) const 04702 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 04703 Created: 29/10/96 04704 Outputs: ppBits : address of ADDR variable to accept pointer to bitmap bits 04705 pWidth : address of BMP_SIZE variable to accept bitmap width 04706 pHeight: address of BMP_SIZE variable to accept bitmap height 04707 pDepth : address of BMP_DEPTH variable to accept bitmap depth 04708 Returns: TRUE if data is valid 04709 FALSE otherwise 04710 Purpose: Support function to obtain information regarding the strip we are currently 04711 exporting. 04712 Notes: This information is only valid in the WriteFrame member 04713 04714 ********************************************************************************************/ 04715 BOOL BaseBitmapFilter::GetCurrentStripInfo( ADDR* ppBits, 04716 BMP_SIZE* pWidth, BMP_SIZE* pHeight, 04717 BMP_DEPTH* pDepth) const 04718 { 04719 LPBITMAPINFO pBitmapInfo; 04720 LPBYTE pBitmapBits; 04721 04722 ExportRegion->GetBitmapData(&pBitmapInfo, &pBitmapBits); 04723 04724 if (pBitmapInfo == NULL || pBitmapBits == NULL) 04725 { 04726 ERROR3("pBitmapInfo == NULL || pBitmapBits == NULL"); 04727 return FALSE; 04728 } 04729 04730 *ppBits = pBitmapBits; 04731 *pWidth = pBitmapInfo->bmiHeader.biWidth; 04732 *pHeight = pBitmapInfo->bmiHeader.biHeight; 04733 *pDepth = pBitmapInfo->bmiHeader.biBitCount; 04734 return TRUE; 04735 } 04736 04737 04738 /******************************************************************************************** 04739 04740 > BitmapExportOptions* BaseBitmapFilter::GetBitmapExportOptions() const 04741 04742 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 04743 Created: 29/10/96 04744 Returns: Details of the data to be exported 04745 Purpose: Support function to obtain BitmapExportOptions 04746 04747 ********************************************************************************************/ 04748 BitmapExportOptions* BaseBitmapFilter::GetBitmapExportOptions() const 04749 { 04750 ERROR3IF(m_pExportOptions != NULL && !m_pExportOptions->IS_KIND_OF(BitmapExportOptions), 04751 "m_pExportOptions isn't"); 04752 return m_pExportOptions; 04753 } 04754 04755 04756 /******************************************************************************************** 04757 04758 > BOOL BaseBitmapFilter::SetExportOptions ( BitmapExportOptions* pOptions ) 04759 04760 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 04761 Created: 29/10/96 04762 Returns: TRUE if successful 04763 FALSE otherwise 04764 Purpose: To allow that f!?@$%g MakeBitmapFilter have its wicked way 04765 04766 ********************************************************************************************/ 04767 04768 BOOL BaseBitmapFilter::SetExportOptions ( BitmapExportOptions* pOptions ) 04769 { 04770 ERROR3IF ( pOptions != NULL && !pOptions->IS_KIND_OF ( BitmapExportOptions ), 04771 "BitmapExportOptions is wrong kind" ); 04772 04773 // Don't delete the old options unless specifically requested. This is to avoid the nasty 04774 // access violations that might occur otherwise. 04775 04776 //if (m_pExportOptions && pOptions != m_pExportOptions) 04777 // delete m_pExportOptions; 04778 04779 m_pExportOptions = pOptions; 04780 04781 return TRUE; 04782 } 04783 04784 04785 /******************************************************************************************** 04786 04787 > virtual BitmapExportOptions* BaseBitmapFilter::CreateExportOptions() const 04788 04789 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 04790 Created: 29/10/96 04791 Returns: A pointer to a new BitmapExportOptions class 04792 Purpose: Allows derived classes to override this function to provide their own class 04793 derived from BitmapExportOptions containing filter specific information. 04794 Notes: This should never be called 04795 04796 ********************************************************************************************/ 04797 BitmapExportOptions* BaseBitmapFilter::CreateExportOptions() const 04798 { 04799 TRACE( _T("BaseBitmapFilter::CreateExportOptions() called\n")); 04800 04801 BitmapExportOptions* pOptions = new BitmapExportOptions(_R(IDD_EXPORTBMPOPTS), FilterType(FilterID), &FilterName); 04802 04803 return pOptions; 04804 } 04805 04806 04807 /******************************************************************************************** 04808 04809 > static LPLOGPALETTE BaseBitmapFilter::Create8bppPalette() const 04810 04811 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04812 Created: 8/2/97 04813 Returns: A pointer to a 8bpp palette 04814 Purpose: Creates an 8bpp palette used when generating an 8bpp bitmap 04815 Centralises common code previously found in BMP, GIF & PNG filters 04816 04817 The palette returned is created using CCMalloc(). The caller should use 04818 CCFree() to discard the returned palette object when no longer needed. 04819 04820 Introduced for WEBSTER - markn 8/2/97. 04821 Made static so that the Accusoft filter can use it 04822 Notes: 04823 04824 ********************************************************************************************/ 04825 04826 LPLOGPALETTE BaseBitmapFilter::Create8bppPalette() 04827 { 04828 /* 04829 LPLOGPALETTE lpPalette = NULL; 04830 GDrawContext *GDC = GRenderRegion::GetDrawContext(); 04831 if (GDC != NULL) 04832 { 04833 // This should return a palette plus tell it what dithering we require 04834 // 0 = dither, not 0 for no dithering. 04835 LPLOGPALETTE lpGavPalette = GDC->SelectPalette( 0 ); 04836 04837 if (lpGavPalette != NULL) 04838 { 04839 const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * 256 ); 04840 lpPalette = (LPLOGPALETTE)CCMalloc( TotalPal ); 04841 if (lpPalette != NULL) 04842 { 04843 // Take a copy of that palette 04844 memcpy( lpPalette, lpGavPalette, TotalPal ); 04845 04846 // Always make 'browser' palette instead of 'standard' palette 04847 // - Harrison 8/10/97 04848 PaletteManager::MakePaletteBrowserCompatible(lpPalette,TRUE); 04849 } 04850 } 04851 } 04852 04853 ERROR3IF(lpPalette == NULL, "Didnt get a palette"); 04854 04855 // The section of code below is used when the user has deleted 1 or more colours, and then 04856 // clicked on 'Preview'. 04857 // Have to change the palette here before it is used to decide which palette colours 04858 // match each pixel in the image. 04859 if( ( BmapPrevDlg::GetNumberOfDeletedColours() ) && ( BmapPrevDlg::m_bUseExistingPalette ) ) 04860 { 04861 BOOL Deleted = FALSE; 04862 INT32 NewIndex = -1; 04863 INT32 Popularity = 0; 04864 04865 // Go through the palette in BmapPrevDlg. 04866 for( INT32 PaletteIndex = 0; PaletteIndex < ( lpPalette->palNumEntries ); PaletteIndex++ ) 04867 { 04868 // Has this colour been deleted by the user? 04869 Deleted = BmapPrevDlg::IsThisColourDeleted( PaletteIndex ); 04870 if( Deleted ) 04871 { 04872 // If this colour has been deleted, then we need to get its 04873 // original palette order. 04874 NewIndex = BmapPrevDlg::GetOriginalPaletteOrder( PaletteIndex ); 04875 // Set flags to 255 to tell the system that this colour is not 04876 // to be used in generating the exported image. 04877 lpPalette->palPalEntry[NewIndex].peFlags = 255; 04878 } 04879 else 04880 { 04881 // Not deleted, but is the popularity of this colour = 0? 04882 Popularity = BmapPrevDlg::GetPopularityValueForColour( PaletteIndex ); 04883 if( Popularity <= 0 ) 04884 { 04885 NewIndex = BmapPrevDlg::GetOriginalPaletteOrder( PaletteIndex ); 04886 lpPalette->palPalEntry[NewIndex].peFlags = 255; 04887 } 04888 } 04889 } 04890 } 04891 04892 ExtendedPalette LockedColoursInformation; 04893 if( BmapPrevDlg::GotLockedColours() && lpPalette) 04894 { 04895 // Copy all the locked colours information over. 04896 LockedColoursInformation = BmapPrevDlg::m_LockedColoursPalette; 04897 04898 ExtendedPalette LockedColoursInformation2 = BmapPrevDlg::m_LockedColoursPalette2; 04899 04900 // Go through all the locked colours that we have 04901 for( INT32 i = 0; i < LockedColoursInformation.NumberOfColours; i++ ) 04902 { 04903 // Make sure that we are not exceeding the number of colours in the current palette. 04904 if( i >= ( lpPalette->palNumEntries ) ) 04905 continue; 04906 04907 // We want to find the nearest colour in the current palette to this locked colour. 04908 double SmallestDistance = 0.0; 04909 BOOL FirstDistanceCalc = TRUE; 04910 INT32 ClosestColourIndex = 0; 04911 04912 // Some variables needed below 04913 INT32 Red1, Green1, Blue1; 04914 INT32 Red2, Green2, Blue2; 04915 double RedDistance, GreenDistance, BlueDistance; 04916 double Distance; 04917 04918 INT32 LockedIndex = LockedColoursInformation.Data[ i ].ExtraInformation; 04919 Red1 = LockedColoursInformation2.Data[ LockedIndex ].Red; 04920 Green1 = LockedColoursInformation2.Data[ LockedIndex ].Green; 04921 Blue1 = LockedColoursInformation2.Data[ LockedIndex ].Blue; 04922 04923 // Go through all the colours in the current palette. 04924 for( INT32 j = 0; j < lpPalette->palNumEntries; j++ ) 04925 { 04926 // The components of the palette colour we are looking at. 04927 Red2 = lpPalette->palPalEntry[j].peRed; 04928 Green2 = lpPalette->palPalEntry[j].peGreen; 04929 Blue2 = lpPalette->palPalEntry[j].peBlue; 04930 04931 // Calculate the distance between each of the colour components 04932 // ( Actually the square of this value - this does not matter since we 04933 // are not interested in the absolute values, only relative ones ). 04934 RedDistance = pow( double( Red1 - Red2 ), 2 ); 04935 GreenDistance = pow( double( Green1 - Green2 ), 2 ); 04936 BlueDistance = pow( double( Blue1 - Blue2 ), 2 ); 04937 04938 // The overall distance. 04939 Distance = ( INT32 )( RedDistance + GreenDistance + BlueDistance ); 04940 04941 if( FirstDistanceCalc ) 04942 { 04943 // First time around, so 'Distance' must be closest yet 04944 // However, there may be an occasion where this colour is already being used by one of 04945 // the existing locked colours. In this case, we just want to completely ignore this 04946 // colour, and carry on with the next loop 04947 BOOL BeingUsed = FALSE; 04948 for( INT32 Index = 0; Index < i; Index++ ) 04949 { 04950 if( LockedColoursInformation.Data[ Index ].ExtraInformation == j ) 04951 BeingUsed = TRUE; 04952 } 04953 // If it is being used, don't do anything. 04954 if( !BeingUsed ) 04955 { 04956 FirstDistanceCalc = FALSE; 04957 SmallestDistance = Distance; 04958 ClosestColourIndex = j; 04959 } 04960 } 04961 else if( Distance <= SmallestDistance ) 04962 { 04963 // Smallest distance so far? if so remember the distance & index 04964 // Do this only if this index is not being used by another locked colour 04965 // already. To do this, have to look through the currently assigned locked 04966 // colour indices. If this index is being used, then just do nothing. 04967 BOOL BeingUsed = FALSE; 04968 for( INT32 Index = 0; Index < i; Index++ ) 04969 { 04970 if( LockedColoursInformation.Data[ Index ].ExtraInformation == j ) 04971 BeingUsed = TRUE; 04972 } 04973 if( !BeingUsed ) 04974 { 04975 SmallestDistance = Distance; 04976 ClosestColourIndex = j; 04977 } 04978 } 04979 } 04980 04981 // Put the colour index into the locked colour palette 04982 INT32 Information = LockedColoursInformation.Data[ i ].ExtraInformation; 04983 04984 // Update the palette which holds the original values of the locked colours. 04985 INT32 r = BmapPrevDlg::m_LockedColoursPalette2.Data[ ClosestColourIndex ].Red; 04986 INT32 g = BmapPrevDlg::m_LockedColoursPalette2.Data[ ClosestColourIndex ].Green; 04987 INT32 b = BmapPrevDlg::m_LockedColoursPalette2.Data[ ClosestColourIndex ].Blue; 04988 04989 BmapPrevDlg::m_LockedColoursPalette2.Data[ ClosestColourIndex ].Red = 04990 BmapPrevDlg::m_LockedColoursPalette2.Data[ Information ].Red; 04991 BmapPrevDlg::m_LockedColoursPalette2.Data[ ClosestColourIndex ].Green = 04992 BmapPrevDlg::m_LockedColoursPalette2.Data[ Information ].Green; 04993 BmapPrevDlg::m_LockedColoursPalette2.Data[ ClosestColourIndex ].Blue = 04994 BmapPrevDlg::m_LockedColoursPalette2.Data[ Information ].Blue; 04995 04996 BmapPrevDlg::m_LockedColoursPalette2.Data[ Information ].Red = r; 04997 BmapPrevDlg::m_LockedColoursPalette2.Data[ Information ].Green = g; 04998 BmapPrevDlg::m_LockedColoursPalette2.Data[ Information ].Blue = b; 04999 05000 BmapPrevDlg::m_LockedColoursPalette.Data[ i ].ExtraInformation = ClosestColourIndex; 05001 LockedColoursInformation = BmapPrevDlg::m_LockedColoursPalette; 05002 } 05003 } 05004 05005 return lpPalette; 05006 */ 05007 return NULL; 05008 } 05009 05010 /******************************************************************************************** 05011 > BOOL BaseBitmapFilter::ExportImagemap(Operation *pOp, PathName* pPath, Document* pDoc) 05012 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 05013 Created: 9/4/97 05014 Returns: TRUE if export was successful 05015 FALSE if there was a problem 05016 Purpose: Calls on the Imagemap Filter to export an imagemap based on the current 05017 bitmap. 05018 ********************************************************************************************/ 05019 BOOL BaseBitmapFilter::ExportImagemap(Operation *pOp, PathName* pPath, Document* pDoc) 05020 { 05021 //Check our parameters 05022 ERROR2IF(pOp == NULL, FALSE,"BaseBitmapFilter::ExportImagemap no export operation"); 05023 ERROR2IF(pPath == NULL, FALSE,"BaseBitmapFilter::ExportImagemap no export pathname"); 05024 ERROR2IF(pDoc == NULL, FALSE,"BaseBitmapFilter::DoExport no document to export"); 05025 05026 //First, let's find the imagemap filter 05027 ImagemapFilter* pImagemapFilter=GetImagemapFilter(); 05028 05029 //And if we haven't found it, throw an error 05030 //Note that it is entirely possible that a future (modular) build might 05031 //not have an Imagemap filter, but for the moment it's worrying 05032 ERROR2IF(pImagemapFilter==NULL, FALSE, "OK. Own up. Who nicked the Imagemap filter?"); 05033 05034 //Create a file to export to 05035 CCDiskFile ImagemapFile(1024, FALSE, TRUE); 05036 05037 //Now we need to set up some Imagemap Filter Options 05038 //We base these on the last set of ImagemapFilterOptions that the user exported 05039 //with, so get those options from the ImagemapFilter 05040 ImagemapFilterOptions ifoToSet=pImagemapFilter->GetFilterOptions(); 05041 05042 // Check we are exporting an imagemap either to a file or to the clipboard 05043 if (!(ifoToSet.m_fFile || ifoToSet.m_fClipboard)) 05044 return TRUE; // Successfully done as requested (not exported an image map) 05045 05046 if (!GetBitmapExportOptions()) 05047 return FALSE; // can't export image map with out export options 05048 05049 //Set the DPI from our bitmap options 05050 ifoToSet.m_dDPI=GetBitmapExportOptions()->GetDPI(); 05051 05052 //And set the selection type 05053 ifoToSet.m_stExportArea=GetBitmapExportOptions()->GetSelectionType(); 05054 05055 05056 // Use the path set previously in the image map options -- Jonathan 6/12/2000 05057 //And give the filter a pointer to our export file 05058 ifoToSet.m_pfileFile=&ImagemapFile; 05059 05060 // tell the filter where the graphic is that it is describing 05061 ifoToSet.m_GraphicPath = *pPath; 05062 05063 //Then set our new options back into the imagemap filter 05064 pImagemapFilter->SetFilterOptions(ifoToSet); 05065 05066 //And tell the filter to export the file 05067 BOOL ok= pImagemapFilter->PrepareAndWriteData(pDoc); 05068 05069 //Then close the file if it's still open 05070 if (ImagemapFile.isOpen()) 05071 ImagemapFile.close(); 05072 05073 //And return 05074 return ok; 05075 } 05076 05077 /******************************************************************************************** 05078 05079 > ImagemapFilter* BaseBitmapFilter::GetImagemapFilter() 05080 05081 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 05082 Created: 10/4/97 05083 Returns: A pointer to the imagemap filter 05084 Purpose: Gets a pointer to the imagemap filter 05085 05086 This function may return NULL and the calling code should handle this case. 05087 05088 This is in case we ever build a version of Camelot without an Imagemap Filter. 05089 All our code should cope with the Imagemap Filter not being there. 05090 05091 ********************************************************************************************/ 05092 ImagemapFilter* BaseBitmapFilter::GetImagemapFilter() 05093 { 05094 //First get a pointer to the filter manager 05095 FilterManager* pFilterManager=Camelot.GetFilterManager(); 05096 05097 ERROR2IF(pFilterManager==NULL, NULL, "BaseBitmapFilter::GetImagemapFilter - FilterManager does not exist"); 05098 05099 //Then return a pointer to the imagemap filter 05100 return ((ImagemapFilter*) pFilterManager->FindFilterFromID(FILTERID_IMAGEMAP)); 05101 05102 } 05103 05104 05105 /******************************************************************************************** 05106 > void BaseBitmapFilter::ExportHTMLTag(PathName* ppthToUse) 05107 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 05108 Created: 21/5/97 05109 Purpose: Exports an HTML tag to the clipboard that can be 05110 used in a page of HTML to embed the bitmap that is 05111 being exported. 05112 Technical notes: 05113 Note that the width and height parameters of the bitmap 05114 come from the width and height member variables of 05115 the BitmapExportOptions member variable. 05116 05117 *But* Colin's comments say that it's at the filter author's 05118 discretion whether to use a BitmapExportOptions object or not. 05119 So, it seems we shouldn't throw an error if we can't find 05120 a BitmapExportOptions object. 05121 05122 So if we can't find a BFO object, we don't throw an error - 05123 we simply don't export. 05124 ********************************************************************************************/ 05125 void BaseBitmapFilter::ExportHTMLTag(PathName* ppthToUse) 05126 { 05127 //Check our parameter 05128 if (ppthToUse==NULL) 05129 { 05130 ERROR2RAW("BaseCamelotFilter::ExportHTMLTag - NULL parameter"); 05131 return; 05132 } 05133 05134 //First get the name of the file we are exporting to 05135 String_256 strFileName=ppthToUse->GetFileName(TRUE); 05136 05137 //Now, do we have sensible bitmap export dimensions? 05138 ERROR3IF(m_PixelWidth<=0 || m_PixelHeight<=0, "Width and Height are both 0 in BaseBitmapFilter::ExportHTMLTag"); 05139 05140 //And if they make sense 05141 if (m_PixelWidth>0 && m_PixelHeight>0) 05142 { 05143 //Then export a tag based on that width and height 05144 05145 String_256 strTag; 05146 strTag.MakeMsg(_R(IDS_BITMAPFILTER_HTMLTAG), &strFileName, m_PixelWidth, m_PixelHeight); 05147 05148 //And put that string on the clipboard 05149 PORTNOTE("clipboard","Removed InternalClipboard usage") 05150 #ifndef EXCLUDE_FROM_XARALX 05151 InternalClipboard::CopyText(strTag); 05152 #endif 05153 } 05154 } 05155 05156 void PixelAlignedFiddle(DocRect* r) 05157 { 05158 INT32 lox, loy, hix, hiy = 0; 05159 05160 #define INFLATE_ONLY 05161 05162 #ifdef INFLATE_ONLY 05163 INT32 fiddle = 0; // extends the export clipping box to surround the exported image 05164 // maintaining the screen antialiasing 05165 #else 05166 INT32 fiddle = 375; // shaves small amounts of aa if we think we dont need it 05167 #endif 05168 05169 lox = ((r->lo.x + fiddle)/750) * 750; 05170 loy = ((r->lo.y + fiddle)/750) * 750; 05171 hix = ((r->hi.x + 749 - fiddle)/750) * 750; 05172 hiy = ((r->hi.y + 749 - fiddle)/750) * 750; 05173 05174 DocRect newr(lox, loy, hix, hiy); 05175 *r = newr; 05176 } 05177 05178 05179 // Static function which is used by BmapPrevDlg to call the above function. 05180 void BaseBitmapFilter::CallPixelAlignedFiddle( DocRect * r ) 05181 { 05182 PixelAlignedFiddle( r ); 05183 } 05184