ccdc.cpp

Go to the documentation of this file.
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 }

Generated on Sat Nov 10 03:48:13 2007 for Camelot by  doxygen 1.4.4