grndwing.cpp

Go to the documentation of this file.
00001 // $Id: grndwing.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 // GDraw rendering via WinG libraries
00100 
00101 
00102 #include "camtypes.h"
00103 //#include "dibutil.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00104 #include "grndwing.h"
00105 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 #include "oilmods.h"
00107 #include "camelot.h"
00108 
00109 CC_IMPLEMENT_DYNAMIC( GRenderWinG, GRenderRegion )
00110 
00111 HDC GRenderWinG::OffScreenDC;
00112 
00113 
00114 
00115 
00116 
00117 HINSTANCE GRenderWinG::WinGDLL;                             // NULL if not loaded
00118 
00119 
00120 GRenderWinG::WING_CREATEDC      GRenderWinG::pWinGCreateDC;
00121 GRenderWinG::WING_CREATEBITMAP  GRenderWinG::pWinGCreateBitmap;
00122 GRenderWinG::WING_BITBLT        GRenderWinG::pWinGBitBlt;
00123 GRenderWinG::WING_RECOMMENDED   GRenderWinG::pWinGRecommendedDIBFormat;
00124 
00125 
00126 static BITMAPINFOHEADER RecommendedDIB;
00127 
00128 /********************************************************************************************
00129 
00130 >   BOOL GRenderWinG::Init(BOOL FirstTime)
00131 
00132     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00133     Created:    29/6/94
00134     Inputs:     FirstTime is TRUE if called on startup, FALSE if called subsequently
00135                 (e.g. screen mode change).
00136     Outputs:    -
00137     Returns:    TRUE if we can use WinG, FALSE if we cannot.
00138     Purpose:    Determines whether WinG is available on this platform.
00139     Errors:     -
00140     Scope:      Public static
00141 
00142 ********************************************************************************************/
00143 
00144 BOOL GRenderWinG::Init( BOOL FirstTime )
00145 {
00146     if (!FirstTime)
00147     {
00148         // only a screen mode change so don't redo DLL etc, just get new DC
00149         if (WinGDLL)
00150         {
00151             // kill old one
00152             if (OffScreenDC)
00153                 DeleteDC( OffScreenDC );
00154 
00155             // go get new one
00156             OffScreenDC = pWinGCreateDC();
00157             if (OffScreenDC)
00158                 return TRUE;
00159         }
00160         return FALSE;
00161     }
00162 
00163 #if WIN32
00164     // lets see if the DLL is there
00165 
00166     // on NT 3.1 the DLL init code fails the load and produces an ugly dialog, so we don't
00167     // bother
00168     if (IsWin32NT())
00169     {
00170         const WORD Ver = LOWORD( GetVersion() );
00171         if (
00172             (LOBYTE(Ver) == 3) &&                   // NT 3.5 is minimum requirement
00173             (HIBYTE(Ver) < 50)
00174            )
00175             return FALSE;
00176     }
00177 
00178     // try the DLL now
00179     WinGDLL = LoadLibrary("WING32.DLL");
00180     if (WinGDLL)
00181     {
00182         // (ordinal values extracted from DLL using DUMPBIN -export)
00183 
00184         pWinGCreateDC =     (WING_CREATEDC)     GetProcAddress( WinGDLL, MAKEINTRESOURCE(0x3e9) );
00185         pWinGCreateBitmap = (WING_CREATEBITMAP) GetProcAddress( WinGDLL, MAKEINTRESOURCE(0x3eb) );
00186         pWinGBitBlt =       (WING_BITBLT)       GetProcAddress( WinGDLL, MAKEINTRESOURCE(0x3f2) );
00187         pWinGRecommendedDIBFormat =
00188                             (WING_RECOMMENDED)  GetProcAddress( WinGDLL, MAKEINTRESOURCE( 0x3ea ) );
00189 
00190         if (
00191             (pWinGCreateDC == NULL)     ||
00192             (pWinGCreateBitmap == NULL) ||
00193             (pWinGBitBlt == NULL)       ||
00194             (pWinGRecommendedDIBFormat==NULL)
00195            )
00196         {
00197             TRACE( _T("WinG32 DLL entrypoints missing!\n"));
00198             FreeLibrary( WinGDLL );
00199             WinGDLL = NULL;
00200             return FALSE;
00201         }
00202     }
00203     else
00204     {
00205         TRACE( _T("WinG DLL not found (error %d)\n"), GetLastError() );
00206         return FALSE;
00207     }
00208 
00209     // remember the DLL handle so it gets cleaned up for us always on exit
00210     ExtraDLLs[ WinG_DLL ] = WinGDLL;
00211 
00212     RecommendedDIB.biSize = sizeof(BITMAPINFOHEADER);
00213 
00214     // excuse the seemingly rampant cast but I think the official prototype is wrong
00215     const BOOL ok = pWinGRecommendedDIBFormat( (LPBITMAPINFO)&RecommendedDIB );
00216         
00217     if (IsUserName("Andy"))
00218     {
00219         TRACE( _T("Recommended bitmap:\n"));
00220         if (ok)
00221         {
00222             TRACE( _T("%dx%d height=%d comp=%d\n"),
00223                     (INT32)RecommendedDIB.biPlanes,
00224                     (INT32)RecommendedDIB.biBitCount,
00225                     (INT32)RecommendedDIB.biHeight,
00226                     (INT32)RecommendedDIB.biCompression
00227                 );
00228         }
00229         else
00230             TRACE( _T("ERROR - isnt one\n"));
00231     }
00232 
00233     OffScreenDC = pWinGCreateDC();
00234     if (OffScreenDC)
00235         return TRUE;
00236 
00237 #endif
00238 
00239     // if we get here it means we failed
00240     return FALSE;
00241 }
00242 
00243 /********************************************************************************************
00244 
00245 >   void GRenderWinG::Deinit()
00246 
00247     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00248     Created:    29/6/94
00249     Purpose:    Tidies up WinG before exit. Frees up necessary resources etc.
00250     Errors:     -
00251     Scope:      Static
00252 
00253 ********************************************************************************************/
00254 
00255 void GRenderWinG::Deinit()
00256 {
00257     if (OffScreenDC)
00258     {
00259         DeleteDC(OffScreenDC);
00260         OffScreenDC = NULL;
00261     }
00262 }
00263 
00264 /********************************************************************************************
00265 
00266 >   BOOL GRenderWinG::CanWinG( UINT32 Depth )
00267 
00268     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00269     Created:    29/6/94
00270     Inputs:     Pixel depth required
00271     Returns:    TRUE if GRenderWinG can be done at such a depth, FALSE if cannot
00272     Purpose:    Use before creating GRenderWinGs inc case they are not supported. Currently
00273                 only uses WinG if depth matches the recommended format.
00274     Errors:     -
00275     Scope:      Static public
00276 
00277 ********************************************************************************************/
00278 
00279 BOOL GRenderWinG::CanWinG( UINT32 Depth )
00280 {
00281     if (
00282         WinGDLL                             &&      // must have DLL
00283         OffScreenDC                         &&      // and screen DC
00284         (RecommendedDIB.biPlanes == 1)      &&      // mono planar
00285         (Depth == RecommendedDIB.biBitCount)        // and correct depth
00286        )
00287         return TRUE;
00288 
00289     return FALSE;
00290 }
00291 
00292 /********************************************************************************************
00293 
00294 >   GRenderWinG::GRenderWinG(DocRect ClipRegion, Matrix ConvertMatrix, FIXED16 ViewScale, UINT32 Depth, double dpi)
00295 
00296     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00297     Created:    29/6/94
00298     Inputs:     -
00299     Outputs:    -
00300     Returns:    -
00301     Purpose:    GRenderWinG constructor. Doesn't do anything actually, just calls base class.
00302                 INT32 dpi changed to FIXED16 dpi (12/12/95) to improve the range of values allowed
00303                 at the < 1000dpi settings that we will be using.
00304     Errors:     -
00305     SeeAlso:    GRenderRegion::GRenderRegion
00306 
00307 ********************************************************************************************/
00308 
00309 GRenderWinG::GRenderWinG(DocRect ClipRegion, Matrix ConvertMatrix, FIXED16 ViewScale, UINT32 Depth, double dpi)
00310     : GRenderRegion( ClipRegion, ConvertMatrix, ViewScale, Depth, dpi)
00311 {
00312     WinGBitmap = NULL;
00313     Inverted = FALSE;
00314 }
00315 
00316 /********************************************************************************************
00317 
00318 >   LPBITMAPINFO GRenderWinG::GetLPBits( INT32 Width, INT32 Height, INT32 Depth, LPBYTE*lplpBits)
00319 
00320     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00321     Created:    29/6/94
00322     Inputs:     Bitmap characteristics.
00323     Outputs:    *lplpBits is made to point to the bytes of the bitmap.
00324     Returns:    The bitmap header, or NULL if not enough memory.
00325     Purpose:    Allocates a bitmap header and the bitmap bytes.
00326     Errors:     -
00327     SeeAlso:    GRenderWinG::FreeLPBits
00328 
00329 ********************************************************************************************/
00330 
00331 LPBITMAPINFO GRenderWinG::GetLPBits( INT32 Width, INT32 Height, INT32 Depth, LPBYTE*lplpBits)
00332 {
00333     // get a bitmap header with no bits
00334     const LPBITMAPINFO bmInfo = AllocDIB( Width, Height, Depth, NULL );
00335     if (!bmInfo)
00336         return NULL;
00337 
00338     // tell it the sort of palette we want - we want Gavin's
00339     if (Depth==8)
00340     {
00341     #if 0
00342         RGBQUAD *rgb = bmInfo->bmiColors;
00343         LPPALETTEENTRY lpPal = GetRecommendedPalette()->palPalEntry;
00344 
00345         size_t i ;
00346         for ( i=0 ; i<256 ; i++ )
00347         {
00348             rgb->rgbRed = lpPal->peRed;
00349             rgb->rgbGreen = lpPal->peGreen;
00350             rgb->rgbBlue = lpPal->peBlue;
00351             rgb->rgbReserved = 0;
00352             rgb ++;
00353             lpPal++;
00354         }
00355     #else
00356 
00357         GetSystemPaletteEntries (
00358             RenderDC->m_hDC, 0, 256, (LPPALETTEENTRY) bmInfo->bmiColors
00359         ) ;
00360         RGBQUAD *rgb = bmInfo->bmiColors ;                  // Swap R and B.
00361         size_t i ;
00362         for ( i=0 ; i<256 ; i++ )
00363         {
00364             BYTE t = rgb->rgbRed ;
00365             rgb->rgbRed = rgb->rgbBlue ;
00366             rgb->rgbBlue = t ;
00367             rgb ++ ;
00368         }
00369     #endif
00370     }
00371 
00372     // if WinG wants it upside-down then go for it
00373     if (RecommendedDIB.biHeight == -1)
00374     {
00375         Inverted = TRUE;
00376         bmInfo->bmiHeader.biHeight = -bmInfo->bmiHeader.biHeight;
00377     }
00378     else
00379         Inverted = FALSE;
00380 
00381     // now get a lovely WinG bitmap
00382     WinGBitmap = pWinGCreateBitmap( OffScreenDC, bmInfo, (void FAR* FAR *)lplpBits );
00383     if (WinGBitmap==NULL)
00384     {
00385         TRACE( _T("WinGCreateBitmap failed\n"));
00386         FreeDIB( bmInfo, NULL );
00387         return NULL;
00388     }
00389 
00390     // turn it back the other way else Gavin is likely to get confused
00391     if (Inverted)
00392         bmInfo->bmiHeader.biHeight = -bmInfo->bmiHeader.biHeight;
00393 
00394     //TRACE( _T("WinG Alloc %lx=%lx:%lx\n"), this, bmInfo, *lplpBits);
00395     return bmInfo;
00396 }
00397 
00398 /********************************************************************************************
00399 
00400 >   void GRenderWinG::FreeLPBits( LPBITMAPINFO lpBMI, LPBYTE lpB )
00401 
00402     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00403     Created:    29/6/94
00404     Inputs:     Bitmap characteristics.
00405     Outputs:    -
00406     Returns:    -
00407     Purpose:    Frees up a bitmap allocated with GetLPBits.
00408     Errors:     -
00409     SeeAlso:    GRenderWinG::FreeLPBits
00410 
00411 ********************************************************************************************/
00412 
00413 void GRenderWinG::FreeLPBits( LPBITMAPINFO lpBMI, LPBYTE lpB )
00414 {
00415     if (WinGBitmap)
00416     {
00417         DeleteObject( WinGBitmap );
00418         WinGBitmap = NULL;
00419     }
00420     FreeDIB( lpBMI, NULL );
00421 }
00422 
00423 /********************************************************************************************
00424 
00425 >   GRenderWinG::~GRenderWinG()
00426 
00427     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00428     Created:    2/6/94
00429     Inputs:     -
00430     Outputs:    -
00431     Returns:    -
00432     Purpose:    GRenderWinG destructor. Frees up the bitmap.
00433     Errors:     -
00434 
00435 ********************************************************************************************/
00436 
00437 GRenderWinG::~GRenderWinG()
00438 {
00439     if (LocalBitmap)
00440     {
00441         if (HaveRenderedSomething)
00442             // We're not clean - flush bitmap to screen
00443             DisplayBits();
00444 
00445 //      FreeLPBits( lpBitmapInfo, lpBits );
00446         FreeOffscreenState();
00447         lpBitmapInfo = NULL;
00448         lpBits = NULL;
00449     }
00450     // will call GRenderRegions destructor here
00451 }
00452 
00453 
00454 /********************************************************************************************
00455 
00456 >   BOOL GRenderWinG::StartRenderAfter(GMATRIX *GMat)
00457 
00458     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00459     Created:    30/6/94
00460     Inputs:     Pointer to Gavins matrix created by GRenderRegion::StartRender
00461     Outputs:    Update matrix if required.
00462     Returns:    TRUE if worked, FALSE if failed.
00463     Purpose:    Updates the Gavin matrix to cope with the upside-down nature of DIBs
00464                 if that is the recommended format
00465     Errors:     Always returns TRUE.
00466     SeeAlso:    GRenderDDB::StartRenderAfter
00467 
00468 ********************************************************************************************/
00469 
00470 BOOL GRenderWinG::StartRenderAfter(GMATRIX *GMat)
00471 {
00472     if (Inverted)
00473     {
00474         // flip up other way
00475         GMat->BY = -GMat->BY;
00476 
00477         // calculate the new offset
00478         //XLONG ydisp = (XLONG)( (WRect.bottom -  WRect.top ) * 72000 ) / (XLONG)(PixelsPerInch.MakeXlong() * ScaleFactor);
00479         FIXED16 ScaledDpi = FIXED16(PixelsPerInch) * ScaleFactor;
00480         XLONG Size = (WRect.bottom -  WRect.top ) * 72000;
00481         XLONG ydisp = Size / ScaledDpi.MakeXlong();
00482 
00483         GMat->CY = -GMat->CY + Mul(-GMat->BY, ydisp);
00484     }
00485 
00486     // we cannot fail
00487     return TRUE;
00488 }
00489 
00490 /********************************************************************************************
00491 
00492 >   BOOL GRenderWinG::DisplayBits(LPBITMAPINFO lpDisplayBitmapInfo = NULL, LPBYTE lpDisplayBits = NULL)
00493 
00494     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00495     Created:    29/6/94
00496     Inputs:     -
00497     Outputs:    -
00498     Returns:    TRUE if worked, FALSE if failed.
00499     Purpose:    Plots the DIB onto the owner device.
00500     Errors:     -
00501 
00502 ********************************************************************************************/
00503 
00504 BOOL GRenderWinG::DisplayBits(LPBITMAPINFO lpDisplayBitmapInfo, LPBYTE lpDisplayBits)
00505 {
00506     BOOL ok = FALSE;
00507 
00508     if (lpBitmapInfo && lpBits && RenderDC)
00509     {
00510         HBITMAP hOldBitmap;
00511 
00512         hOldBitmap = SelectBitmap( OffScreenDC, WinGBitmap );
00513         if (hOldBitmap)
00514         {
00515             ok = pWinGBitBlt( RenderDC->m_hDC,          // dest
00516                                 WRect.left, WRect.top,      // dest XY
00517                                 WRect.right-WRect.left,
00518                                 WRect.bottom-WRect.top,
00519                                 OffScreenDC,                // source
00520                                 0,0                         // source XY
00521                             );
00522             SelectBitmap( OffScreenDC, hOldBitmap );
00523         }
00524     }
00525     return ok;
00526 }

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