00001 // $Id: makebmp.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 // 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 #include "makebmp.h" 00106 //#include "resource.h" 00107 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 #include "page.h" 00110 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 #include "nodebmp.h" 00112 #include "bitmpinf.h" 00113 #include "bmpfiltr.h" 00114 //#include "simon.h" 00115 //#include "will3.h" 00116 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 //#include "clikmods.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 #include "nodetxtl.h" 00119 #include "grndbmp.h" 00120 #include "wrkrect.h" 00121 #include "colplate.h" 00122 #include "colcontx.h" 00123 #include "bmapprev.h" 00124 //#include "rrcaps.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00125 00126 //#include "resimmap.h" //_R(IDE_EXPORT_NODRAWING) 00127 00128 #include "palman.h" // PaletteManager::Get4bppBrowserPalette 00129 00130 DECLARE_SOURCE("$Revision: 1282 $"); 00131 00132 CC_IMPLEMENT_DYNCREATE(OpConvertToBitmap, SelOperation); 00133 CC_IMPLEMENT_DYNAMIC(MakeBitmapFilter, TI_GIFFilter); 00134 CC_IMPLEMENT_DYNCREATE(MakeBitmapExportOptions, MaskedFilterExportOptions) 00135 00136 #define new CAM_DEBUG_NEW 00137 00138 DPI MakeBitmapExportOptions::g_Dpi = 96.0; 00139 BMP_DEPTH MakeBitmapExportOptions::g_Depth = 8; 00140 DITHER MakeBitmapExportOptions::g_Dither = XARADITHER_ERROR_DIFFUSION; 00141 PALETTE MakeBitmapExportOptions::g_Palette = PAL_OPTIMISED; 00142 BOOL MakeBitmapExportOptions::g_TranspBkGnd = TRUE; 00143 FilterType MakeBitmapFilter::s_FilterType = MAKE_BITMAP_FILTER; 00144 00145 //----------------------------------------------------------------------------------------------- 00146 // OpConvertToBitmap - Convert one or more objects into a bitmap 00147 00148 /******************************************************************************************** 00149 00150 > OpConvertToBitmap::OpConvertToBitmap() 00151 00152 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00153 Created: 11/6/96 00154 Inputs: - 00155 Outputs: - 00156 Returns: - 00157 Purpose: OpConvertToBitmap constructor 00158 Errors: - 00159 SeeAlso: - 00160 00161 ********************************************************************************************/ 00162 OpConvertToBitmap::OpConvertToBitmap(): SelOperation() 00163 { 00164 } 00165 00166 /******************************************************************************************** 00167 00168 > BOOL OpConvertToBitmap::Init() 00169 00170 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00171 Created: 11/6/96 00172 Returns: TRUE if the operation could be successfully initialised 00173 FALSE if no more memory could be allocated 00174 Purpose: OpConvertToBitmap initialiser method 00175 Errors: ERROR will be called if there was insufficient memory to allocate the 00176 operation. 00177 SeeAlso: - 00178 00179 ********************************************************************************************/ 00180 BOOL OpConvertToBitmap::Init() 00181 { 00182 MakeBitmapFilter::Initialise(); 00183 00184 return (RegisterOpDescriptor( 00185 0, 00186 _R(IDS_CONVERTTOBITMAPOP), 00187 CC_RUNTIME_CLASS(OpConvertToBitmap), 00188 OPTOKEN_CONVERTTOBITMAP, 00189 OpConvertToBitmap::GetState, 00190 0, /* help ID */ 00191 0, 00192 0 /* bitmap ID */)); 00193 } 00194 00195 /******************************************************************************************** 00196 00197 > OpState OpConvertToBitmap::GetState(String_256*, OpDescriptor*) 00198 00199 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00200 Created: 11/6/96 00201 Returns: The state of the OpConvertToBitmap operation 00202 Purpose: For finding the OpConvertToBitmap's state. 00203 Errors: - 00204 SeeAlso: - 00205 00206 ********************************************************************************************/ 00207 OpState OpConvertToBitmap::GetState(String_256* UIDescription, OpDescriptor*) 00208 { 00209 OpState OpSt; 00210 String_256 DisableReason; 00211 00212 // Ensure that a document exists 00213 if (Document::GetSelected() == NULL) 00214 { 00215 // There is no selected document 00216 OpSt.Greyed = TRUE; 00217 00218 // Load reason why operation is disabled 00219 DisableReason = String_256(_R(IDS_NO_DOC)); 00220 *UIDescription = DisableReason; 00221 return OpSt; 00222 } 00223 00224 // Obtain the current selections 00225 Range Sel(*(GetApplication()->FindSelection())); 00226 00227 // This operation is disabled if there are no nodes selected, or if none of the selected 00228 // objects can become a NodePath. 00229 00230 Node* FirstSelected = Sel.FindFirst(); 00231 00232 OpSt.Greyed = FALSE; 00233 if (FirstSelected == NULL) 00234 { 00235 OpSt.Greyed = TRUE; 00236 // Load reason why operation is disabled 00237 DisableReason = String_256(_R(IDS_NO_OBJECTS_SELECTED)); 00238 *UIDescription = DisableReason; 00239 } 00240 00241 return(OpSt); 00242 } 00243 00244 /******************************************************************************************** 00245 00246 > void OpConvertToBitmap::Do(OpDescriptor*) 00247 00248 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00249 Created: 11/6/96 00250 Inputs: - 00251 Purpose: Convert the selection into a bitmap 00252 Errors: - 00253 SeeAlso: - 00254 00255 ********************************************************************************************/ 00256 void OpConvertToBitmap::Do(OpDescriptor*) 00257 { 00258 // We want to include bevel/contour/shadow controller nodes in our bitmap-copy 00259 // deliberations, so set PromoteToParent on a copy of the app's SelRange. 00260 SelRange Sel(*(GetApplication()->FindSelection())); 00261 RangeControl rg = Sel.GetRangeControlFlags(); 00262 rg.PromoteToParent = TRUE; 00263 Sel.Range::SetRangeControl(rg); 00264 00265 // Find the first node which is selected 00266 Node* CurrentNode = Sel.FindFirst(); 00267 00268 ERROR3IF(CurrentNode == NULL, "Called ConvertToBitmap with no nodes selected"); 00269 00270 // In the retail build it is best to do nothing if we find there are no selected nodes 00271 if (CurrentNode != NULL) // No nodes selected so End 00272 { 00273 // We need to invalidate the region 00274 if (!DoInvalidateNodesRegions(Sel, TRUE)) 00275 goto EndOperation; 00276 00277 if (!DoStartSelOp(FALSE,FALSE)) // Try to record the selection state , don't 00278 goto EndOperation; // render the blobs though 00279 00280 // Create a special Bitmap filter, that creates a bitmap 00281 // and puts it in the tree 00282 MakeBitmapFilter* pBitmapFilter = new MakeBitmapFilter(); 00283 if (pBitmapFilter == NULL) 00284 { 00285 FailAndExecute(); 00286 goto EndOperation; 00287 } 00288 00289 KernelBitmap* pBitmapToCreate = NULL; 00290 00291 if (!pBitmapFilter->DoCreateBitmap(this, Document::GetSelected(), &pBitmapToCreate)) 00292 { 00293 delete pBitmapFilter; 00294 FailAndExecute(); 00295 goto EndOperation; 00296 } 00297 00298 if (!pBitmapFilter->InsertBitmapIntoDocument(this, pBitmapToCreate, Document::GetSelected())) 00299 { 00300 delete pBitmapToCreate; 00301 delete pBitmapFilter; 00302 FailAndExecute(); 00303 goto EndOperation; 00304 } 00305 00306 delete pBitmapFilter; 00307 00308 if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE)) 00309 { 00310 // We need to invalidate the region 00311 FailAndExecute(); 00312 goto EndOperation; 00313 } 00314 } 00315 00316 EndOperation: 00317 00318 SelRange* pRng = GetApplication()->FindSelection(); 00319 00320 End(); 00321 } 00322 00323 /******************************************************************************************** 00324 00325 > static BOOL MakeBitmapExportOptions::Declare() 00326 00327 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (from Will) 00328 Created: 29/10/96 00329 Returns: TRUE if successfully declared preferences 00330 FALSE otherwise 00331 Purpose: To declare preferences associated with these export options 00332 00333 ********************************************************************************************/ 00334 BOOL MakeBitmapExportOptions::Declare() 00335 { 00336 if (Camelot.DeclareSection("Filters", 10)) 00337 { 00338 Camelot.DeclarePref( NULL, "CreateBitmapDPI", &g_Dpi, 1, 3000 ); 00339 Camelot.DeclarePref( NULL, "CreateBitmapDepth", &g_Depth, 1, 32 ); 00340 Camelot.DeclarePref( NULL, "CreateBitmapDither", (INT32*)&g_Dither, 0, XARADITHER_MAX ); 00341 Camelot.DeclarePref( NULL, "CreateBitmapPalette", (INT32*)&g_Palette, 0, 1 ); 00342 Camelot.DeclarePref( NULL, "CreateBitmapBkGnd", &g_TranspBkGnd, FALSE, TRUE ); 00343 } 00344 00345 // All ok 00346 return TRUE; 00347 } 00348 00349 /******************************************************************************************** 00350 00351 > MakeBitmapExportOptions::MakeBitmapExportOptions( const FilterType FilterID, 00352 const StringBase* pFilterName) 00353 00354 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00355 Created: 29/10/96 00356 Purpose: Default constructor for a MakeBitmapExportOptions object (mainly to allow 00357 CreateBitmapCopy to store its own defaults) 00358 00359 ********************************************************************************************/ 00360 MakeBitmapExportOptions::MakeBitmapExportOptions( const FilterType FilterID, 00361 const StringBase* pFilterName) : 00362 MaskedFilterExportOptions(_R(IDD_EXPORTBMPOPTS), FilterID, pFilterName) 00363 { 00364 } 00365 00366 /******************************************************************************************** 00367 00368 > BitmapExportOptions *MakeBitmapExportOptions::MakeCopy() 00369 00370 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Stefan code 00371 Created: 2/7/97 00372 Purpose: Makes a copy object of this object 00373 See Also: BitmapExportOptions::CopyFrom(); BitmapExportOptions::MakeCopy(); 00374 00375 ********************************************************************************************/ 00376 BitmapExportOptions *MakeBitmapExportOptions::MakeCopy() 00377 { 00378 // Get the runtime class info on this object 00379 CCRuntimeClass *pCCRuntimeClass = GetRuntimeClass(); 00380 00381 // Create another object of the same type 00382 MakeBitmapExportOptions *temp = (MakeBitmapExportOptions *) pCCRuntimeClass->CreateObject(); 00383 00384 if (temp != NULL) 00385 temp->CopyFrom(this); // copy the contents accross 00386 00387 return temp; 00388 } 00389 00390 /******************************************************************************************** 00391 00392 > virtual BOOL MakeBitmapExportOptions::CopyFrom(BitmapExportOptions *pSource) 00393 00394 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Stefan code 00395 Created: 2/7/97 00396 Inputs: pSource - the other BitmapExportOptions object to copy the data from 00397 Purpose: Sets the contents of this object from the passed object 00398 See Also: BitmapExportOptions::MakeCopy() 00399 00400 ********************************************************************************************/ 00401 BOOL MakeBitmapExportOptions::CopyFrom(BitmapExportOptions *pSource) 00402 { 00403 // copy the base class first 00404 if (!MaskedFilterExportOptions::CopyFrom(pSource)) 00405 return FALSE; 00406 00407 // must be the same class, otherwise the base class function above returns FALSE 00408 MakeBitmapExportOptions *pOther = (MakeBitmapExportOptions *)pSource; 00409 00410 return TRUE; 00411 } 00412 00413 00414 /******************************************************************************************** 00415 00416 > virtual BOOL MakeBitmapExportOptions::Equal(BitmapExportOptions *pSource) 00417 00418 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Stefan code 00419 Created: 2/7/97 00420 Inputs: pSource - the other BitmapExportOptions object to copy the data from 00421 Purpose: Compares the contents of this and pOther objects 00422 Returns: TRUE, if objects are equal, FALSE otherwise 00423 See Also: BitmapExportOptions::MakeCopy() 00424 00425 ********************************************************************************************/ 00426 /* 00427 BOOL MakeBitmapExportOptions::Equal(BitmapExportOptions *pSource) 00428 { 00429 BOOL ok = TRUE; 00430 00431 // compare the base classes first 00432 ok = MaskedFilterExportOptions::Equal(pSource); 00433 00434 // must be the same class, otherwise the base class function above returns FALSE 00435 MakeBitmapExportOptions *pOther = (MakeBitmapExportOptions *)pSource; 00436 00437 // Compare any variables unique to our class here 00438 return ok; 00439 } 00440 */ 00441 00442 /******************************************************************************************** 00443 00444 > virtual BOOL MakeBitmapExportOptions::RetrieveDefaults() 00445 00446 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00447 Created: 29/10/96 00448 Purpose: See BitmapExportInfo for interface details: gets GIF specific preferences 00449 00450 ********************************************************************************************/ 00451 BOOL MakeBitmapExportOptions::RetrieveDefaults() 00452 { 00453 BOOL ok = FALSE; 00454 00455 if (MaskedFilterExportOptions::RetrieveDefaults()) 00456 { 00457 SetDPI(g_Dpi); 00458 SetDepth(g_Depth); 00459 SetDither(g_Dither); 00460 ok = TRUE; 00461 } 00462 00463 return ok; 00464 } 00465 00466 00467 /******************************************************************************************** 00468 00469 > virtual BOOL MakeBitmapExportOptions::SetAsDefaults() const 00470 00471 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00472 Created: 29/10/96 00473 Purpose: Provides additional implementation to set GIF specific info as defaults 00474 See Also: BitmapExportInfo::SetAsDefaults() 00475 00476 ********************************************************************************************/ 00477 BOOL MakeBitmapExportOptions::SetAsDefaults() const 00478 { 00479 BOOL ok = FALSE; 00480 00481 if (MaskedFilterExportOptions::SetAsDefaults()) 00482 { 00483 g_Dpi = GetDPI(); 00484 g_Depth = GetDepth(); 00485 g_Dither = GetDither(); 00486 g_TranspBkGnd = WantTransparent(); 00487 ok = TRUE; 00488 } 00489 00490 return ok; 00491 } 00492 00493 00494 //----------------------------------------------------------------------------------------------- 00495 // MakeBitmapFilter - Dummy filter, used to render the selection into a bitmap 00496 00497 /******************************************************************************************** 00498 00499 > MakeBitmapFilter::MakeBitmapFilter() 00500 00501 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00502 Created: 11/6/96 00503 Purpose: Constructor for an MakeBitmapFilter object. The object should be initialised 00504 before use. 00505 SeeAlso: MakeBitmapFilter::Init 00506 00507 ********************************************************************************************/ 00508 MakeBitmapFilter::MakeBitmapFilter() : TI_GIFFilter () 00509 { 00510 pTheBitmap = NULL; 00511 } 00512 00513 /******************************************************************************************** 00514 00515 > static BOOL MakeBitmapFilter::Initialise() 00516 00517 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00518 Created: 11/6/96 00519 Returns: TRUE if the filter was initialised ok, FALSE otherwise. 00520 Purpose: Initialise an MakeBitmapFilter object. 00521 Errors: Will fail if not enough memory to initialise. 00522 SeeAlso: EPSStack 00523 00524 ********************************************************************************************/ 00525 BOOL MakeBitmapFilter::Initialise() 00526 { 00527 if (!MakeBitmapExportOptions::Declare()) 00528 return FALSE; 00529 00530 if (Camelot.DeclareSection("Filters", 10)) 00531 { 00532 Camelot.DeclarePref( NULL, "DoTwoColourRounding", 00533 &GRenderOptPalette::DoTwoColourRoundingToPrimary, FALSE, TRUE ); 00534 } 00535 00536 // All ok 00537 return TRUE; 00538 } 00539 00540 /******************************************************************************************** 00541 00542 > BOOL MakeBitmapFilter::DoCreateBitmap(Operation *pOp, Document *pDoc, KernelBitmap** ppBitmap) 00543 00544 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00545 Created: 11/6/96 00546 Purpose: Exports the current selection as a bitmap, via the virtual fns of the 00547 inherited class. 00548 Returns: TRUE if worked, FALSE if failed. 00549 SeeAlso: GetExportOptions; PrepareToExport; ExportRenderNodes; CleanUpAfterExport; 00550 00551 ********************************************************************************************/ 00552 BOOL MakeBitmapFilter::DoCreateBitmap(Operation *pOp, Document *pDoc, KernelBitmap** ppBitmap) 00553 { 00554 ERROR3IF(ppBitmap == NULL, "NULL bitmap pointer passed to MakeBitmapFilter::DoCreateBitmap"); 00555 if (ppBitmap == NULL) 00556 return FALSE; 00557 00558 pTheBitmap = NULL; 00559 *ppBitmap = NULL; 00560 00561 // Set the bitmap pointer to null just in case, usually only used by DoExportBitmap 00562 pExportBitmap = NULL; 00563 00564 // Get pointer to the spread to export. 00565 PORTNOTE("spread", "Multi-spread warning!") 00566 pSpread = GetFirstSpread(pDoc); 00567 00568 // remember the document in the class variable 00569 TheDocument = pDoc; 00570 00571 // We must now check if there is a selection present so that we can set up whether the 00572 // user gets the choice of exporting the selection, drawing or spread if there is a 00573 // selection present OR just a choice between the spread or drawing if no selection is 00574 // present. 00575 // If have a caret selected in a text story then the selection will be almost zero so trap 00576 // this case as well. 00577 RangeControl rg = GetApplication()->FindSelection()->GetRangeControlFlags(); 00578 rg.PromoteToParent = TRUE; 00579 GetApplication()->FindSelection()->Range::SetRangeControl(rg); 00580 SelRange Rng(*(GetApplication()->FindSelection())); 00581 00582 // now, run through the selection selecting all nodes under all compound nodes 00583 // if we don't do this then all compound nodes aren't rendered correctly with transparent 00584 // bitmaps 00585 Node * pNode = Rng.FindFirst(FALSE); 00586 00587 while (pNode) 00588 { 00589 pNode->SetSelected(FALSE); 00590 pNode->SetSelected(TRUE); 00591 pNode = Rng.FindNext(pNode, FALSE); 00592 } 00593 00594 rg.PromoteToParent = FALSE; 00595 GetApplication()->FindSelection()->Range::SetRangeControl(rg); 00596 GetApplication()->UpdateSelection(); 00597 00598 DocRect ClipRect = GetApplication()->FindSelection()->GetBoundingRect(); 00599 SelectionType Selection = DRAWING; 00600 if ( ClipRect.IsEmpty() || ClipRect.Width() < MinExportSize || 00601 ClipRect.Height() < MinExportSize) 00602 Selection = DRAWING; // no selection present, so choose drawing by default 00603 else 00604 Selection = SELECTION; // selection present, so choose this by default 00605 00606 if (Selection != SELECTION) 00607 { 00608 BOOL UseDrawingBounds = TRUE; 00609 00610 SelRange* pSel = GetApplication()->FindSelection(); 00611 if (pSel && pSel->Count()==1) 00612 { 00613 // Only one thing selected ... Is it the Text Caret per chance ? 00614 Node* pSelNode = pSel->FindFirst(); 00615 if (pSelNode && pSelNode->IsAVisibleTextNode()) 00616 { 00617 VisibleTextNode* pTextNode = (VisibleTextNode*)pSelNode; 00618 if (pTextNode->IsACaret()) 00619 { 00620 // Aha! It's the Caret that's selected. 00621 // We'll use the bounds of the parent text line instead then ... 00622 Node* pTextLine = pTextNode->FindParent(); 00623 ERROR3IF(!IS_A(pTextLine, TextLine), "Caret doesn't have a parent text line in DoCreateBitmap"); 00624 00625 // Get the bounds of the text line 00626 ClipRect = ((TextLine*)pTextLine)->GetBoundingRect(); 00627 00628 Selection = SELECTION; 00629 UseDrawingBounds = FALSE; 00630 } 00631 } 00632 } 00633 00634 if (UseDrawingBounds) 00635 { 00636 // Work out the size of the rectangle encompassing the drawing (visible layers only) 00637 ClipRect = GetSizeOfDrawing(pSpread); 00638 } 00639 } 00640 00641 // Create somewhere to put the user options and fill them up 00642 MakeBitmapExportOptions* pMakeBmpExportOptions = (MakeBitmapExportOptions*)CreateExportOptions(); 00643 if (pMakeBmpExportOptions == NULL) 00644 { 00645 Error::SetError(_R(IDS_OUT_OF_MEMORY)); 00646 return FALSE; 00647 } 00648 00649 pMakeBmpExportOptions->RetrieveDefaults(); 00650 pMakeBmpExportOptions->SetDepth(32); // create bmp copies shoulda always default to being 32 bit 00651 pMakeBmpExportOptions->SetSelectionType(Selection); 00652 00653 // Set the BaseBitmapFilter member so we can use base class functionality - blurghh 00654 SetExportOptions(pMakeBmpExportOptions); 00655 00656 BOOL ok = GetExportOptions( (BitmapExportOptions*)pMakeBmpExportOptions ); 00657 00658 BOOL IsAnimation = BmapPrevDlg::m_pExportOptions == NULL; 00659 BaseBitmapFilter * pNewFilter = this; 00660 BitmapExportOptions * pExportOptions = BmapPrevDlg::m_pExportOptions; 00661 if (!IsAnimation) 00662 { 00663 pNewFilter = pExportOptions->FindBitmapFilterForTheseExportOptions(); 00664 // from the exporting point of view we should always have been using png options 00665 // set them to the png options for the export part 00666 if (pNewFilter) 00667 pNewFilter->SetExportOptions(pExportOptions); 00668 // gets the real export options that the prevdlg has set up for us 00669 BmapPrevDlg::m_pExportOptions = NULL; // take responsibility for this data 00670 } 00671 else 00672 { 00673 // the animation export didn't bring up the dlg so never set BmapPrevDlg::m_pExportOptions 00674 // so continue with these options 00675 pExportOptions = (BitmapExportOptions*)pMakeBmpExportOptions; 00676 } 00677 00678 SetExportOptions(pExportOptions); 00679 00680 00681 if (!ok) 00682 { 00683 SetExportOptions(NULL); // deletes the filter ptr and nulls it 00684 delete pExportOptions; 00685 return FALSE; // if cancelled 00686 } 00687 00688 00690 00691 pExportOptions->MarkValid(); 00692 SetDepthToRender(pExportOptions->GetDepth()); 00693 00694 // Set up device context and render region for this export. 00695 // This will show a progress hourglass for the objects being rendered 00696 // THis will now also write the data out to file via our ExportRenderNodes function 00697 if (!PrepareToExport(pSpread, pExportOptions->GetDepth(), pExportOptions->GetDPI(), 00698 pExportOptions->GetSelectionType(), pExportOptions->GetDither())) 00699 { 00700 pNewFilter->SetExportOptions(NULL); 00701 SetExportOptions(NULL); 00702 delete pExportOptions; 00703 CleanUpAfterExport(); 00704 return FALSE; 00705 } 00706 00707 RenderInStrips = FALSE; 00708 00709 if (!ExportRender(ExportRegion)) 00710 { 00711 pNewFilter->SetExportOptions(NULL); // deletes the filter ptr and nulls it 00712 SetExportOptions(NULL); 00713 delete pExportOptions; 00714 CleanUpAfterExport(); 00715 return FALSE; 00716 } 00717 00718 // Now get the converted 32Bit BMP 00719 pTheBitmap = GetTheBitmap(pExportOptions); 00720 00721 // if we`ve got a transparency index AND we`ve got a 32 Bit Render region with alpha channel info 00722 // then we can quickly do 00723 if(pExportOptions->GetDepth() <= 8 && pExportOptions->GetTransparencyIndex() != -1 && pTheBitmap) 00724 { 00725 // What we do now is to go throught the bitmap setting the relavent pixels to transparent 00726 // depending on the alpha channel info held in the 32 bit version. 00727 if(!ApplyTransparentColoursToBitmap(pTheBitmap,pExportOptions)) 00728 { 00729 pNewFilter->SetExportOptions(NULL); // deletes the filter ptr and nulls it 00730 return FALSE; 00731 } 00732 00733 // Now make sure the bitmap knows that it has a transparent colour! 00734 pTheBitmap->SetTransparencyIndex(pExportOptions->GetTransparencyIndex()); 00735 } 00736 00737 // Set pointer to the bitmap we have created 00738 *ppBitmap = pTheBitmap; 00739 00740 pNewFilter->SetExportOptions(NULL); // deletes the filter ptr and nulls it 00741 SetExportOptions(NULL); 00742 delete pExportOptions; 00743 CleanUpAfterExport(); 00744 00745 return *ppBitmap != NULL; 00746 00748 } 00749 00750 /******************************************************************************************** 00751 00752 > virtual KernelBitmap* MakeBitmapFilter::GetTheBitmap () 00753 00754 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00755 Created: 16/6/96 00756 Purpose: Creates a kernel bitmap from the Export RenderRegion 00757 Returns: Ptr to the bitmap, or NULL if error 00758 00759 ********************************************************************************************/ 00760 KernelBitmap* MakeBitmapFilter::GetTheBitmap(BitmapExportOptions *pExportOptions) 00761 { 00762 // SMFIX dont use member vars of the class to store stuff like the palette 00763 // take all the info from the export options ptr 00764 OILBitmap* pOilBitmap = ExportRegion->ExtractBitmapCopy ( pExportOptions->GetLogicalPalette(), pDestBMInfo, 00765 pDestBMBytes, pExportOptions->GetTransparencyIndex()); 00766 if (pOilBitmap == NULL) 00767 { 00768 CleanUpAfterExport (); 00769 return NULL; 00770 } 00771 00772 // Err... Lets make sure that the DPI is set up correctly form the options! 00773 LPBITMAPINFOHEADER pInfoHeader = pOilBitmap->GetBitmapInfoHeader(); 00774 if(pInfoHeader) 00775 { 00776 INT32 NewPPM = (INT32)((10000.0 * pExportOptions->GetDPI()) / 254.0); 00777 pInfoHeader->biXPelsPerMeter = NewPPM; 00778 pInfoHeader->biYPelsPerMeter = NewPPM; 00779 } 00780 00781 // Make a kernel bitmap from the oily one 00782 return KernelBitmap::MakeKernelBitmap ( pOilBitmap ); 00783 } 00784 00785 /******************************************************************************************** 00786 00787 > BOOL MakeBitmapFilter::InsertBitmapIntoDocument(UndoableOperation *pOp, KernelBitmap* KernelBmp, Document* DestDoc) 00788 00789 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00790 Created: 11/6/96 00791 Purpose: Exports the current selection as a bitmap, via the virtual fns of the 00792 inherited class. 00793 Returns: TRUE if worked, FALSE if failed. 00794 SeeAlso: GetExportOptions; PrepareToExport; ExportRenderNodes; CleanUpAfterExport; 00795 00796 ********************************************************************************************/ 00797 BOOL MakeBitmapFilter::InsertBitmapIntoDocument(UndoableOperation *pOp, KernelBitmap* KernelBmp, Document* DestDoc) 00798 { 00799 Spread *pSpread; 00800 DocCoord Origin; 00801 00802 // Remember the selection rect, before we change it 00803 DocRect SelRect = GetApplication()->FindSelection()->GetBoundingRect(); 00804 00805 // For now, position Draw objects on 1st page of spread 1 00806 PORTNOTE("spread", "Multi-spread warning!") 00807 pSpread = GetFirstSpread(DestDoc); 00808 Page *pPage = (Page *) pSpread->FindFirstPageInSpread(); 00809 ERROR3IF(!pPage->IsKindOf(CC_RUNTIME_CLASS(Page)), 00810 "MakeBitmapFilter::InsertBitmapIntoDocument: Could not find first Page"); 00811 00812 // Use bottom left of page as origin 00813 DocRect PageRect = pPage->GetPageRect(); 00814 Origin.x = PageRect.lo.x; 00815 Origin.y = PageRect.hi.y; 00816 00817 // Get a new NodeBitmap object to import into. 00818 NodeBitmap *pNodeBitmap = new NodeBitmap; 00819 if ((pNodeBitmap == NULL) || (!pNodeBitmap->SetUpPath(12,12))) 00820 return FALSE; 00821 00822 // Attach the Imported Bitmap to our Node 00823 pNodeBitmap->GetBitmapRef()->Attach(KernelBmp, DestDoc); //GetDocument()); 00824 if (pNodeBitmap->GetBitmap() != KernelBmp) 00825 delete KernelBmp; // It didn't use the bitmap we gave it, so we can delete it 00826 00827 // Import worked - try to add the bitmap object into the tree. 00828 // First, set the rectangle to the right size for the bitmap... 00829 BitmapInfo Info; 00830 pNodeBitmap->GetBitmap()->ActualBitmap->GetInfo(&Info); 00831 00832 DocRect BoundsRect; 00833 BoundsRect.lo = Origin; 00834 BoundsRect.hi.x = BoundsRect.lo.x + Info.RecommendedWidth; 00835 BoundsRect.hi.y = BoundsRect.lo.y + Info.RecommendedHeight; 00836 00837 // And set this in our bitmap node 00838 pNodeBitmap->CreateShape(BoundsRect); 00839 00840 // Make sure that there is a layer to put the bitmap onto 00841 if (!MakeSureLayerExists(DestDoc)) 00842 { 00843 // There is no layer and one could not be made, so we will have to fail 00844 delete pNodeBitmap; 00845 return FALSE; 00846 } 00847 00848 // Set the default attrs 00849 // This MUST be done before the NodeBitmap is Inserted into the tree 00850 if (!pNodeBitmap->ApplyDefaultBitmapAttrs(pOp)) 00851 return FALSE; 00852 00853 // Insert the node, but don't invalidate its region 00854 if (!pOp->DoInsertNewNode(pNodeBitmap, pSpread, FALSE)) 00855 { 00856 // It didn't work - delete the sub-tree we just created, and report error. 00857 delete pNodeBitmap; 00858 return FALSE; 00859 } 00860 00861 // bitmap is currently positioned so its bottom left hand 00862 // corner is at the top left of the page 00863 00864 // By default we'll move it down so the top-left of the bitmap is on the top-left of the page 00865 INT32 XTranslate = 0; 00866 INT32 YTranslate = -Info.RecommendedHeight; 00867 00868 ClickModifiers ClickMods = ClickModifiers::GetClickModifiers(); 00869 00870 if (ClickMods.Adjust && !SelRect.IsEmpty()) 00871 { 00872 // If shift is down, then we'll try and place the bitmap exactly on top of the selection 00873 DocCoord SelectionCentre(SelRect.lo.x + (SelRect.Width()/2), SelRect.lo.y + (SelRect.Height()/2)); 00874 00875 XTranslate = SelectionCentre.x - Origin.x - (Info.RecommendedWidth/2); 00876 YTranslate = SelectionCentre.y - Origin.y - (Info.RecommendedHeight/2); 00877 } 00878 else 00879 { 00880 // Otherwise we'll try and centre it within the current view 00881 Spread* pCurrentSpread; 00882 DocCoord ViewCentre; 00883 00884 if (FindCentreInsertionPosition(&pCurrentSpread, &ViewCentre)) 00885 { 00886 /* Karim 19/01/2000 00887 * Ensure that the bmp is pixel-aligned as close to the centre as possible. 00888 * 00889 XTranslate = ViewCentre.x - Origin.x - (Info.RecommendedWidth/2); 00890 YTranslate = ViewCentre.y - Origin.y - (Info.RecommendedHeight/2); 00891 /**/ 00892 DocCoord PixAlignBmpOrigin( ViewCentre.x - Info.RecommendedWidth/2, 00893 ViewCentre.y - Info.RecommendedHeight/2 ); 00894 INT32 FullDPI = GRenderRegion::GetDefaultDPI(); 00895 MILLIPOINT PixWidth = (INT32)((IN_MP_VAL / (double)FullDPI) + 0.5); 00896 PixAlignBmpOrigin.x -= PixAlignBmpOrigin.x % PixWidth; 00897 PixAlignBmpOrigin.y -= PixAlignBmpOrigin.y % PixWidth; 00898 XTranslate = PixAlignBmpOrigin.x - Origin.x; 00899 YTranslate = PixAlignBmpOrigin.y - Origin.y; 00900 } 00901 } 00902 00903 Trans2DMatrix Xlate(XTranslate, YTranslate); 00904 pNodeBitmap->Transform(Xlate); 00905 00906 // Ensure Sel Bounds are correct after translation 00907 GetApplication()->UpdateSelection(); 00908 00909 return TRUE; 00910 } 00911 00912 /******************************************************************************************** 00913 00914 > BOOL MakeBitmapFilter::FindCentreInsertionPosition(Spread** Spread, DocCoord* Position) 00915 00916 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> (from Simon) 00917 Created: 12/6/96 00918 Inputs: - 00919 Outputs: Spread: The spread to place the clipboard objects on 00920 Position:The centre of the view (Spread coords) 00921 Purpose: Finds the centre insertion position for clipboard objects 00922 00923 ********************************************************************************************/ 00924 BOOL MakeBitmapFilter::FindCentreInsertionPosition(Spread** Spread, DocCoord* Position) 00925 { 00926 // --------------------------------------------------------------------------------- 00927 // Find out which spread is in the centre of the view 00928 // this is the spread that the pasted objects will be placed on 00929 00930 // Obtain the current DocView 00931 DocView* CurDocView = DocView::GetCurrent(); 00932 00933 ENSURE(CurDocView != NULL, "The current DocView is NULL"); 00934 if (CurDocView == NULL) 00935 return FALSE; // No DocView 00936 00937 // Get the view rect 00938 WorkRect WrkViewRect = CurDocView->GetViewRect(); 00939 00940 if (WrkViewRect.IsEmpty() || (!WrkViewRect.IsValid()) ) 00941 return FALSE; // Defensive 00942 00943 // Determine the centre of the view 00944 WorkCoord WrkCentreOfView; 00945 WrkCentreOfView.x = WrkViewRect.lox + (WrkViewRect.Width()/2); 00946 WrkCentreOfView.y = WrkViewRect.loy + (WrkViewRect.Height()/2); 00947 00948 // FindEnclosing spread requires an OilCoord 00949 OilCoord OilCentreOfView = WrkCentreOfView.ToOil(CurDocView->GetScrollOffsets()); 00950 00951 // Find out which spread to insert the pasteboard objects onto 00952 (*Spread) = CurDocView->FindEnclosingSpread(OilCentreOfView); 00953 if ((*Spread) == NULL) 00954 return FALSE; // There is no spread 00955 00956 // Phew 00957 // --------------------------------------------------------------------------------- 00958 // Now lets find the spread coordinate of the centre of the view 00959 DocRect DocViewRect = CurDocView->GetDocViewRect(*Spread); 00960 00961 if ( DocViewRect.IsEmpty() || (!DocViewRect.IsValid()) ) 00962 { 00963 ERROR3("DocViewRect is invalid"); 00964 return FALSE; // Defensive 00965 } 00966 00967 // Find the centre of the DocViewRect 00968 DocCoord DocCentreOfView; 00969 DocCentreOfView.x = DocViewRect.lox + (DocViewRect.Width()/2); 00970 DocCentreOfView.y = DocViewRect.loy + (DocViewRect.Height()/2); 00971 00972 // -------------------------------------------------------------------------------- 00973 // Now convert from DocCoords to spread coords 00974 00975 DocRect PhysSpreadRect = (*Spread)->GetPasteboardRect(); 00976 00977 (*Position).x = DocCentreOfView.x - PhysSpreadRect.lo.x; 00978 (*Position).y = DocCentreOfView.y - PhysSpreadRect.lo.y; 00979 00980 return TRUE; 00981 } 00982 00983 /******************************************************************************************** 00984 00985 > virtual void MakeBitmapFilter::CleanUpAfterExport() 00986 00987 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00988 Created: 11/6/96 00989 Purpose: Cleans up the memory allocated at the end of Exporting or when exporting has 00990 been aborted for some reason. Does its cleaning up and then calls the 00991 baseclass version to do its stuff, - used 00992 when the import process ends, either normally or abnormally. Override if 00993 extra things are required. 00994 SeeAlso: BaseBitmapFilter::PrepareToExport(); BaseBitmapFilter::CleanUpAfterExport(); 00995 Scope: Protected 00996 00997 ********************************************************************************************/ 00998 void MakeBitmapFilter::CleanUpAfterExport() 00999 { 01000 // Call the baseclass version to do its stuff 01001 MaskedFilter::CleanUpAfterExport(); 01002 } 01003 01004 /******************************************************************************************** 01005 01006 > virtual BOOL MakeBitmapFilter::GetExportOptions(BitmapExportOptions* pOptions) 01007 01008 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01009 Created: 12/11/96 01010 Purpose: See BaseBitmapFilter for interface details 01011 01012 ********************************************************************************************/ 01013 BOOL MakeBitmapFilter::GetExportOptions(BitmapExportOptions* pOptions) 01014 { 01015 ERROR2IF(pOptions == NULL, FALSE, "pOptions NULL"); 01016 ERROR3IF(!pOptions->IS_KIND_OF(MakeBitmapExportOptions), "pOptions isn't"); 01017 01018 BOOL Ok = FALSE; 01019 01020 OpDescriptor* pOpDes = OpDescriptor::FindOpDescriptor(OPTOKEN_GIFTABDLG); 01021 01022 if (pOpDes != NULL) 01023 { 01024 // Graeme (18-9-00) 01025 // We need to ensure that the correct file type is set up. The bitmap copy filter 01026 // uses the PNG settings, and so it's necessary to convince the dialogue that we 01027 // are exporting as a PNG to avoid relics from an earlier export to confuse matters. 01028 BmapPrevDlg::m_pthExport.SetType ( String_256 ( "png" ) ); 01029 01030 // set up the data for the export options dialog 01031 OpParam Param((INT32)pOptions, (INT32)this); 01032 01033 // invoke the dialog 01034 pOpDes->Invoke(&Param); 01035 01036 // SMFIX 01037 // we have brought the dlg up so get the options from the dlg as the graphic type may have changed 01038 pOptions = BmapPrevDlg::m_pExportOptions; 01039 Ok = BmapPrevDlg::m_bClickedOnExport; 01040 } 01041 else 01042 { 01043 ERROR3("Unable to find OPTOKEN_BMAPPREVDLG"); 01044 } 01045 01046 // Return whether or not it worked. 01047 return Ok; 01048 } 01049 01050 /******************************************************************************************** 01051 01052 > virtual UINT32 MakeBitmapFilter::GetExportMsgID() 01053 01054 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01055 Created: 11/6/96 01056 Returns: The id of the message to put on the progress display whilst exporting. 01057 Purpose: Used to get the message id to be used during export. 01058 Overides the baseclass form of the function so that during the two stage 01059 export process it can change the message. 01060 SeeAlso: DoExport; 01061 01062 ********************************************************************************************/ 01063 UINT32 MakeBitmapFilter::GetExportMsgID() 01064 { 01065 if (GeneratingOptimisedPalette()) 01066 return _R(IDS_GENOPTPALMSGID); // "Generating optimised palette..." 01067 else 01068 return _R(IDS_MAKEBITMAPMSGID); // "Creating bitmap ..." 01069 } 01070 01071 /******************************************************************************************** 01072 01073 > virtual BOOL MakeBitmapFilter::WriteToFile( BOOL End ) 01074 01075 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01076 Created: 11/6/96 01077 Inputs: End is TRUE if this is the last block of the file. 01078 Returns: TRUE if worked, FALSE if errored. 01079 Purpose: Physically put the bitmap into the disk. 01080 NOTE - ONLY COPES WITH End=TRUE currently 01081 Most of the work now is down by WriteDataToFile as this is a static form 01082 and there is a similar version in the Accusoft DLL. This can therefore be 01083 used to pass work onto the Accusoft DLL, for the cases we don't cope with. 01084 End is ignored now and should always be set to TRUE. 01085 SeeAlso: WriteDataToFile(); AccusoftFilters::WriteToFile; AccusoftFilters::WriteDataToFile; 01086 01087 ********************************************************************************************/ 01088 BOOL MakeBitmapFilter::WriteToFile( BOOL End ) 01089 { 01090 // All ok 01091 return TRUE; 01092 } 01093 01094 /******************************************************************************************** 01095 01096 > BOOL MakeBitmapFilter::EndWriteToFile( ) 01097 01098 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01099 Created: 11/6/96 01100 Inputs: - 01101 Purpose: Cleans up after writing the bitmap data out to a file. Inherited classes 01102 override this to write in different file formats. 01103 This is slightly different to most other bitmap filters in that it is here 01104 that the data actually gets written out to file, after doing the transparency 01105 translation, if required. 01106 Returns: TRUE if worked, FALSE if failed. 01107 01108 ********************************************************************************************/ 01109 BOOL MakeBitmapFilter::EndWriteToFile( ) 01110 { 01111 // All ok 01112 return TRUE; 01113 } 01114 01115 /******************************************************************************************** 01116 01117 > virtual BOOL MakeBitmapFilter::IsThisBppOk(UINT32 Bpp) 01118 01119 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01120 Created: 11/6/96 01121 Inputs: Bpp or Colour depth. 01122 Returns: TRUE if this filter can cope with this colour depth, FALSE otherwise. 01123 Purpose: Check if this Bitmap filter can cope with saving at this Bpp/Colour depth. 01124 SeeAlso: OpConvertToBitmap::DoWithParam; 01125 01126 ********************************************************************************************/ 01127 BOOL MakeBitmapFilter::IsThisBppOk(UINT32 Bpp) 01128 { 01129 return (Bpp == 24 || Bpp == 8 || Bpp == 4 || Bpp == 1); 01130 } 01131 01132 /******************************************************************************************** 01133 01134 > virtual BitmapExportOptions* MakeBitmapFilter::CreateExportOptions() const 01135 01136 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01137 Created: 29/10/96 01138 Purpose: See BaseBitmapFilter for details 01139 Notes: Provides a MakeBitmapExportOptions class 01140 01141 ********************************************************************************************/ 01142 BitmapExportOptions* MakeBitmapFilter::CreateExportOptions() const 01143 { 01144 MakeBitmapExportOptions* pExportOptions = new MakeBitmapExportOptions(MAKE_BITMAP_FILTER, &FilterName); 01145 return (BitmapExportOptions*)pExportOptions; 01146 }