00001 // $Id: ccdc.cpp 1354 2006-06-23 20:23:25Z 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 // CC super version of the MFC CDC class 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 #include "ccdc.h" 00106 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "gdimagic.h" 00109 //#include "tim.h" 00110 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 //#include "colmodel.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 #include "camelot.h" 00113 00114 00115 // How many individual regions should allow before we stick them all together 00116 // It is set to be 10 rectangles by default. 00117 #define MAX_REGIONS (sizeof(RGNDATAHEADER) + (40 * sizeof(RECT))) 00118 00119 00120 00121 /******************************************************************************************** 00122 00123 > class CCDC : public CDC 00124 00125 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00126 Created: 9/11/93 00127 Purpose: A layer above the MFC CDC class which contains additional information, 00128 including a type word (see RenderType) and rectangle list information. Note 00129 that is is derived from an MFC class, not CCObject so take care with 'new's 00130 and ISRUNTIME checks. 00131 SeeAlso: CDC;CCPaintDC 00132 00133 ********************************************************************************************/ 00134 00135 00136 00137 // so we can runtime-check it 00138 00139 CC_IMPLEMENT_DYNAMIC( CCDC, ListItem ) 00140 CC_IMPLEMENT_DYNAMIC( CCPaintDC, CCDC ) 00141 CC_IMPLEMENT_DYNAMIC( CCClientDC, CCDC ) 00142 CC_IMPLEMENT_DYNAMIC( CCDummyDC, CCDC ) 00143 00144 List CCDC::s_DCList; 00145 00146 00147 /********************************************************************************************* 00148 00149 > CCDC::CCDC(RenderType rType) 00150 00151 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00152 Created: 11/10/93 00153 Inputs: The type of CCDC that is required. 00154 Outputs: None 00155 Returns: None 00156 Purpose: Constructor for CCDC. Stores type and zeros rectangle list. 00157 Errors: - 00158 Scope: Public 00159 SeeAlso: RenderType 00160 00161 *********************************************************************************************/ 00162 00163 CCDC::CCDC( RenderType rType ) 00164 { 00165 lpRgnData = NULL; 00166 Type = rType; 00167 m_pDC = NULL; 00168 m_bDeleteDC = TRUE; 00169 } 00170 00171 /********************************************************************************************* 00172 00173 > CCDC::CCDC(CDC *cdc, RenderType rType) 00174 00175 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00176 Created: 11/10/93 00177 Inputs: An exisiting CDC and the type of CCDC that is required. 00178 Outputs: None 00179 Returns: None 00180 Purpose: Constructor for CCDC to base it on an existing CDC. The CDC on which this 00181 is based MUST stay in existance while this CCDC is in existence as it 00182 'borrows' the members from the doner CDC. 00183 Errors: - 00184 Scope: Public 00185 00186 *********************************************************************************************/ 00187 00188 CCDC::CCDC( CNativeDC *pDC, RenderType rType ) 00189 { 00190 lpRgnData = NULL; 00191 Type = rType; 00192 m_pDC=NULL; 00193 m_bDeleteDC = FALSE; 00194 SetDC(pDC, FALSE); // previously m_pDC = pDC; 00195 } 00196 00197 /********************************************************************************************* 00198 00199 > CCDC::~CCDC() 00200 00201 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00202 Created: 11/10/93 00203 Inputs: None 00204 Outputs: None 00205 Returns: None 00206 Purpose: Destructor for CCDC. 00207 Errors: - 00208 Scope: Public 00209 00210 *********************************************************************************************/ 00211 00212 CCDC::~CCDC() 00213 { 00214 SetDC(NULL); 00215 CCFree(lpRgnData); 00216 lpRgnData = NULL; 00217 00218 // Karim 06/06/2000 - NULLify our handles. 00219 // m_hDC = NULL; 00220 // m_hAttribDC = NULL; 00221 } 00222 00223 /********************************************************************************************* 00224 00225 > static CCDC *CCDC::ConvertFromNativeDC( CNativeDC* pDC ) 00226 00227 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00228 Created: 12/10/93 00229 Inputs: Pointer to a CDC. 00230 Outputs: None 00231 Returns: A pointer to a CCDC, or NULL if it cannot be safely cast. 00232 Purpose: See if a CDC* is really a CCDC* which we can get useful extra information 00233 from. 00234 Errors: - 00235 Scope: Public 00236 00237 *********************************************************************************************/ 00238 00239 CCDC *CCDC::ConvertFromNativeDC( CNativeDC* pDC ) 00240 { 00241 if (!pDC) 00242 return NULL; 00243 00244 // Scan the DCList to find the item 00245 CCDC * pItem = (CCDC*)s_DCList.GetHead(); 00246 while (pItem) 00247 { 00248 if (pItem->GetDC() == pDC) 00249 return pItem; 00250 00251 pItem = (CCDC*)s_DCList.GetNext(pItem); 00252 } 00253 00254 return NULL; 00255 } 00256 00257 /********************************************************************************************* 00258 00259 > static UINT32 CCDC::GetRectangleList( CDC*, wxRect **lpRect ) 00260 00261 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00262 Created: 11/10/93 00263 Inputs: None 00264 Outputs: lpRect will point to a rectangle list. XRECT is a 32-bit rectangle, defined 00265 in gdimagic.h 00266 Returns: Number of rectangles in list, or 0 for don't know. 00267 Purpose: The whole point of CCDCs over normal CDCs is to get additional information. 00268 This call allows access to the clipping rectangle list. A zero return is not 00269 an error, it just means that the rectangle list is not known. 00270 Errors: - 00271 Scope: Public 00272 00273 *********************************************************************************************/ 00274 00275 UINT32 CCDC::GetRectangleList( wxDC* pCDC, wxRect **lpRect) 00276 { 00277 const CCDC *pCCDC = ConvertFromNativeDC(pCDC); 00278 00279 if (pCCDC == NULL) 00280 return 0; // if not a CCDC 00281 00282 #ifndef EXCLUDE_FROM_XARALX 00283 // Multi-region draw hints are only supported on MSW 00284 #if defined( __WXMSW__ ) 00285 if (pCCDC->lpRgnData && (pCCDC->lpRgnData->rdh.iType == RDH_RECTANGLES) ) 00286 { 00287 *lpRect = (wxRect *)( &pCCDC->lpRgnData->Buffer ); // the address of the rectangle list 00288 return (UINT32)(pCCDC->lpRgnData->rdh.nCount); 00289 } 00290 #endif 00291 #endif 00292 return 0; 00293 } 00294 00295 /********************************************************************************************* 00296 00297 > static RenderType CCDC::GetType( CDC* pCDC, BOOL bCalculate) 00298 00299 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00300 Created: 11/10/93 00301 Inputs: Pointer to a wxDC, bCalculate makes it return a valid type for wxDCs by 00302 asking GDI what the pCDC really points to. If bCalculate is FALSE and pCDC 00303 cannot be safely cast to a CCDC, returns RENDERTYPE_NONE as we cannot tell. 00304 Outputs: None 00305 Returns: The type of the CCDC 00306 Purpose: Get an indication of the type of the render destination. 00307 Errors: - 00308 Scope: Public 00309 SeeAlso: RenderType 00310 00311 *********************************************************************************************/ 00312 00313 RenderType CCDC::GetType( CNativeDC* pDC, BOOL bCalculate) 00314 { 00315 const CCDC *pCCDC = ConvertFromNativeDC( pDC ); 00316 00317 if (pCCDC == NULL) 00318 { 00319 PORTNOTETRACE("other","CCDC::GetType - can't calculate device type yet"); 00320 #ifndef EXCLUDE_FROM_XARALX 00321 if (bCalculate) 00322 { 00323 // work out the type from the HDC if he can. We don't use the MFC fn as 00324 // it gets the type from the attrib, not the actual HDC, though this screws 00325 // up with Print Preview 00326 switch ( ::GetDeviceCaps( pDC->m_hDC, TECHNOLOGY ) ) 00327 { 00328 case DT_RASDISPLAY: 00329 return RENDERTYPE_SCREEN; 00330 00331 case DT_PLOTTER: 00332 case DT_RASPRINTER: 00333 // Need to detect if this is a PostScript printer - this requires 00334 // different code on different OSs. 00335 // (This code taken from MSDN - PSS ID Number: Q124135) 00336 WORD wEscape; 00337 00338 if (IsWin32NT() || IsWin32c()) 00339 { 00340 wEscape = POSTSCRIPT_PASSTHROUGH; // Fails with Win16 driver 00341 if (pDC->Escape(QUERYESCSUPPORT, sizeof(WORD), (LPCSTR) &wEscape, NULL) > 0) 00342 { 00343 // Found a PS printer 00344 return RENDERTYPE_PRINTER_PS; 00345 } 00346 } 00347 else if (IsWin32s()) 00348 { 00349 // use printer escape to determine printer type. 00350 wEscape = GETTECHNOLOGY; 00351 if (pDC->Escape(QUERYESCSUPPORT, sizeof(WORD), (LPCSTR) &wEscape, NULL) > 0) 00352 { 00353 // Supports Escapes - get the technology info. 00354 char Technology[256]; 00355 pDC->Escape(GETTECHNOLOGY, 0, NULL, 255, Technology); 00356 00357 // Does the technology description start with "postscript"? 00358 if (_tcsncicmp(Technology, "postscript", 10) == 0) 00359 { 00360 // Ok - does it support passthrough? 00361 wEscape = PASSTHROUGH; 00362 if (pDC->Escape(QUERYESCSUPPORT, sizeof(WORD), 00363 (LPCSTR) &wEscape, NULL) > 0) 00364 { 00365 // Found a PS printer 00366 return RENDERTYPE_PRINTER_PS; 00367 } 00368 } 00369 00370 // GETTECHNOLOGY might not work on some printer drivers, so 00371 // try another escape - EPSPRINTING - should only work on PS! 00372 wEscape = EPSPRINTING; 00373 if (pDC->Escape(QUERYESCSUPPORT, sizeof(WORD), (LPCSTR) &wEscape, NULL) > 0) 00374 { 00375 // Supports EPS printing - must be PostScript. 00376 return RENDERTYPE_PRINTER_PS; 00377 } 00378 } 00379 } 00380 00381 // If we've got here its a normal (non-PS) printer. 00382 return RENDERTYPE_PRINTER; 00383 00384 case DT_METAFILE: 00385 return RENDERTYPE_METAFILE16; // 32-bit metafiles return their 00386 // context device, which we 00387 // cannot create anyway as yet 00388 } 00389 } 00390 #endif 00391 00392 return RENDERTYPE_NONE; 00393 } 00394 00395 // its an actual CCDC so its type is well-known 00396 return pCCDC->Type; 00397 } 00398 00399 /********************************************************************************************* 00400 00401 > static BOOL CCDC::IsPaperWanted( RenderType ) 00402 00403 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00404 Created: 12/10/93 00405 Inputs: Type of rendering device 00406 Outputs: None 00407 Returns: TRUE if the device wants paper rendered (pages, backgrounds etc), FALSE 00408 if it does not. 00409 Purpose: Used by the document renderer to decide whether paper-like things should be 00410 drawn. 00411 Errors: - 00412 Scope: Public 00413 00414 *********************************************************************************************/ 00415 00416 BOOL CCDC::IsPaperWanted( RenderType rType ) 00417 { 00418 switch (rType) 00419 { 00420 case RENDERTYPE_SCREEN: 00421 case RENDERTYPE_SCREENXOR: 00422 return TRUE; 00423 00424 case RENDERTYPE_PRINTER: 00425 return FALSE; 00426 00427 case RENDERTYPE_MONOBITMAP: 00428 return FALSE; 00429 00430 case RENDERTYPE_HITDETECT: 00431 return FALSE; 00432 00433 case RENDERTYPE_COLOURBITMAP: 00434 return TRUE; 00435 00436 case RENDERTYPE_METAFILE16: 00437 case RENDERTYPE_METAFILE32: 00438 return FALSE; 00439 00440 default: 00441 TRACE( _T("Bad rendertype %d in IsPaperWanted\n"), rType ); 00442 return TRUE; 00443 } 00444 } 00445 00446 00447 BOOL CCDC::CleanUpDCs(void) 00448 { 00449 // Delete all the entries in the list (the item destructors will delete the DCs) 00450 s_DCList.DeleteAll(); 00451 00452 return(TRUE); 00453 } 00454 00455 00456 void CCDC::SetDC (CNativeDC * dc, BOOL bDeleteDC /*= TRUE*/) 00457 { 00458 if (m_pDC == dc) 00459 return; 00460 00461 if (m_pDC) 00462 { 00463 if (m_bDeleteDC) 00464 delete (m_pDC); 00465 // take us off the list 00466 s_DCList.RemoveItem(this); 00467 } 00468 m_pDC = dc; 00469 if (m_pDC) 00470 { 00471 m_bDeleteDC = bDeleteDC; 00472 // put us on the list 00473 s_DCList.AddTail(this); 00474 } 00475 } 00476 00477 /******************************************************************************************** 00478 00479 > class CCPaintDC : public CCDC 00480 00481 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00482 Created: 9/11/93 00483 Purpose: Similar to a CPaintDC but also gives us the functionality of a CCDC. In 00484 particular we can get at the clipping rectangle list. 00485 SeeAlso: CCDC;CPaintDC 00486 00487 ********************************************************************************************/ 00488 00489 00490 /********************************************************************************************* 00491 00492 > CCPaintDC::CCPaintDC(CWnd* pWnd) 00493 00494 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00495 Created: 11/10/93 00496 Inputs: Pointer to owner window. 00497 Outputs: None 00498 Returns: None 00499 Purpose: Constructor for CCPaintDC which gets the update rectangle list before doing 00500 a BeginPaint. 00501 Errors: - 00502 Scope: Public 00503 SeeAlso: CCDC;RenderType 00504 00505 *********************************************************************************************/ 00506 00507 CCPaintDC::CCPaintDC(wxWindow *pWnd) : CCDC(RENDERTYPE_SCREEN), m_DC(pWnd) 00508 { 00509 // Register this DC with the DC type system and set that it is temporary 00510 CCDC::SetDC(&m_DC, FALSE); 00511 00512 #ifndef EXCLUDE_FROM_XARALX 00513 // Loose the old region data 00514 CCFree( lpRgnData ); 00515 lpRgnData = NULL; 00516 00517 // Setup the DC 00518 // m_pDc = this; 00519 m_clipping = true; 00520 00521 #if defined(__WXMSW__) 00522 // before the BeginPaint we must extract 00523 // the update region. This is so we can more efficiently paint the window, especially after 00524 // diagonal scrolls. 00525 HRGN hRgn = CreateRectRgn(0,0,0,0); 00526 if( hRgn ) 00527 { 00528 INT32 result = ::GetUpdateRgn( HWND(pWnd->GetHandle()), hRgn, FALSE ); 00529 if (result==COMPLEXREGION) 00530 { 00531 // How many regions are there in there 00532 DWORD res = GetRegionData( hRgn, 0, NULL ); 00533 00534 // If there are some and there are less than our limit then get the info about them 00535 if ((res!=0) && (res<MAX_REGIONS)) 00536 { 00537 // alloc space to put the region data in 00538 lpRgnData = (LPRGNDATA)CCMalloc( res ); 00539 if (lpRgnData) 00540 { 00541 // alloced buffer - use it 00542 lpRgnData->rdh.dwSize = sizeof(RGNDATAHEADER); 00543 DWORD newres = GetRegionData( hRgn, res, lpRgnData ); 00544 00545 // Note GetRegionData is documented wrongly - when it works it returns the size, not 1 00546 if (newres!=res) 00547 { 00548 // error occurred somehow so tidy up heap 00549 CCFree( lpRgnData ); 00550 lpRgnData = NULL; 00551 00552 if (newres!=0) 00553 TRACE( _T("GetRegionData changed from %lu to %lu\n"), res, newres); 00554 } 00555 } 00556 } 00557 } 00558 DeleteObject( hRgn ); 00559 } 00560 #endif 00561 #endif 00562 } 00563 00564 00565 /********************************************************************************************* 00566 00567 > CCPaintDC::~CCPaintDC() 00568 00569 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00570 Created: 11/10/93 00571 Inputs: None 00572 Outputs: None 00573 Returns: None 00574 Purpose: Destructor for CCPaintDC which does an EndPaint. 00575 Errors: - 00576 Scope: Public 00577 00578 *********************************************************************************************/ 00579 00580 CCPaintDC::~CCPaintDC() 00581 { 00582 } 00583 00584 /********************************************************************************************* 00585 00586 > CCClientDC::CCClientDC(CWnd* pWnd) 00587 00588 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00589 Created: 11/10/93 00590 Inputs: Pointer to owner window. 00591 Outputs: None 00592 Returns: None 00593 Purpose: Constructor for CCClientDC which gets the update rectangle list before doing 00594 a BeginPaint. 00595 Errors: - 00596 Scope: Public 00597 SeeAlso: CCDC;RenderType 00598 00599 *********************************************************************************************/ 00600 00601 CCClientDC::CCClientDC(wxWindow *pWnd) : CCDC(RENDERTYPE_SCREEN), m_DC(pWnd) 00602 { 00603 // Register this DC with the DC type system and set that it is temporary 00604 CCDC::SetDC(&m_DC, FALSE); 00605 } 00606 00607 00608 /********************************************************************************************* 00609 00610 > CCClientDC::~CCClientDC() 00611 00612 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com> 00613 Created: 11/10/93 00614 Inputs: None 00615 Outputs: None 00616 Returns: None 00617 Purpose: Destructor for CCClientDC which does an EndPaint. 00618 Errors: - 00619 Scope: Public 00620 00621 *********************************************************************************************/ 00622 00623 CCClientDC::~CCClientDC() 00624 { 00625 }