From 20b6985553b4e01e7960847e3211d940aeff8742 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sat, 12 Feb 2005 11:34:05 +0000 Subject: [PATCH] Mac Core Graphics Implementation git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31959 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/defs.h | 8 +- include/wx/mac/carbon/bitmap.h | 266 +++-- include/wx/mac/carbon/chkconf.h | 8 + include/wx/mac/carbon/cursor.h | 25 +- include/wx/mac/carbon/dc.h | 63 +- include/wx/mac/carbon/dcprint.h | 4 +- include/wx/mac/carbon/display.h | 4 +- include/wx/mac/carbon/icon.h | 60 +- include/wx/mac/carbon/private.h | 144 ++- include/wx/mac/carbon/statbmp.h | 6 +- include/wx/mac/carbon/textctrl.h | 3 +- include/wx/mac/carbon/window.h | 15 +- src/mac/carbon/bitmap.cpp | 1590 +++++++++++++--------------- src/mac/carbon/bmpbuttn.cpp | 10 +- src/mac/carbon/cursor.cpp | 35 +- src/mac/carbon/dataobj.cpp | 14 +- src/mac/carbon/dc.cpp | 112 +- src/mac/carbon/dccg.cpp | 1667 ++++++++---------------------- src/mac/carbon/dcclient.cpp | 78 +- src/mac/carbon/dcmemory.cpp | 56 +- src/mac/carbon/dcprint.cpp | 42 +- src/mac/carbon/dcscreen.cpp | 19 +- src/mac/carbon/display.cpp | 172 +++ src/mac/carbon/icon.cpp | 200 ++-- src/mac/carbon/listbox.cpp | 1 - src/mac/carbon/mediactrl.cpp | 4 + src/mac/carbon/menuitem.cpp | 1 + src/mac/carbon/metafile.cpp | 11 +- src/mac/carbon/notebmac.cpp | 37 +- src/mac/carbon/pnghand.cpp | 2 +- src/mac/carbon/radiobut.cpp | 25 +- src/mac/carbon/region.cpp | 62 +- src/mac/carbon/renderer.cpp | 3 + src/mac/carbon/scrolbar.cpp | 3 - src/mac/carbon/taskbar.cpp | 40 +- src/mac/carbon/textctrl.cpp | 4 +- src/mac/carbon/toolbar.cpp | 48 +- src/mac/carbon/window.cpp | 99 +- 38 files changed, 2320 insertions(+), 2621 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index a5ecd73a6d..91314e7f08 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -2218,9 +2218,10 @@ enum wxUpdateUI #define WX_OPAQUE_TYPE( name ) struct wxOpaque##name typedef unsigned char WXCOLORREF[6]; +typedef void* WXCGIMAGEREF; typedef void* WXHBITMAP; -typedef void* WXHMETAFILE; -typedef void* WXHICON; +//typedef void* WXHMETAFILE; +//typedef void* WXHICON; typedef void* WXHCURSOR; typedef void* WXHRGN; typedef void* WXRECTPTR; @@ -2236,6 +2237,9 @@ typedef unsigned int WXUINT; typedef unsigned long WXDWORD; typedef unsigned short WXWORD; +typedef WX_OPAQUE_TYPE(CIconHandle ) * WXHICON ; +typedef WX_OPAQUE_TYPE(PicHandle ) * WXHMETAFILE ; + /* typedef void* WXWidget; */ /* typedef void* WXWindow; */ diff --git a/include/wx/mac/carbon/bitmap.h b/include/wx/mac/carbon/bitmap.h index d3a9e8d953..d9d2db1f2e 100644 --- a/include/wx/mac/carbon/bitmap.h +++ b/include/wx/mac/carbon/bitmap.h @@ -20,6 +20,7 @@ // Bitmap class WXDLLEXPORT wxBitmap; +class wxBitmapRefData ; class WXDLLEXPORT wxBitmapHandler; class WXDLLEXPORT wxControl; class WXDLLEXPORT wxCursor; @@ -29,77 +30,57 @@ class WXDLLEXPORT wxImage; class WXDLLEXPORT wxPixelDataBase; // A mask is a bitmap used for drawing bitmaps -// it can be a monochrome bitmap or a multi-bit bitmap which transfers to alpha channels -// transparently. +// Internally it is stored as a 8 bit deep memory chunk, 0 = black means the source will be drawn +// 255 = white means the source will not be drawn, no other values will be present +// 8 bit is chosen only for performance reasons, note also that this is the inverse value range +// from alpha, where 0 = invisible , 255 = fully drawn + class WXDLLEXPORT wxMask: public wxObject { DECLARE_DYNAMIC_CLASS(wxMask) DECLARE_NO_COPY_CLASS(wxMask) public: - wxMask(); - - // Construct a mask from a bitmap and a colour indicating - // the transparent area - wxMask(const wxBitmap& bitmap, const wxColour& colour); - - // Construct a mask from a bitmap and a palette index indicating - // the transparent area - wxMask(const wxBitmap& bitmap, int paletteIndex); - - // Construct a mask from a mono bitmap (copies the bitmap). - wxMask(const wxBitmap& bitmap); - - ~wxMask(); - - bool Create(const wxBitmap& bitmap, const wxColour& colour); - bool Create(const wxBitmap& bitmap, int paletteIndex); - bool Create(const wxBitmap& bitmap); - - // Implementation - bool PointMasked(int x, int y); - inline WXHBITMAP GetMaskBitmap() const { return m_maskBitmap; } - inline void SetMaskBitmap(WXHBITMAP bmp) { m_maskBitmap = bmp; } - int GetDepth() const { return m_depth ; } - void SetDepth( int depth ) { m_depth = depth ; } -protected: - WXHBITMAP m_maskBitmap; - int m_depth ; -}; + wxMask(); -enum { kMacBitmapTypeUnknownType , kMacBitmapTypeGrafWorld, kMacBitmapTypePict , kMacBitmapTypeIcon } ; + // Construct a mask from a bitmap and a colour indicating + // the transparent area + wxMask(const wxBitmap& bitmap, const wxColour& colour); -class WXDLLEXPORT wxBitmapRefData: public wxGDIRefData -{ - DECLARE_NO_COPY_CLASS(wxBitmapRefData) - - friend class WXDLLEXPORT wxBitmap; - friend class WXDLLEXPORT wxIcon; - friend class WXDLLEXPORT wxCursor; -public: - wxBitmapRefData(); - ~wxBitmapRefData(); + // Construct a mask from a mono bitmap (black meaning show pixels, white meaning transparent) + wxMask(const wxBitmap& bitmap); + + // implementation helper only : construct a mask from a 8 bit memory buffer + wxMask(const wxMemoryBuffer& buf, int width , int height , int bytesPerRow ) ; -public: - int m_width; - int m_height; - int m_depth; - bool m_ok; - int m_numColors; -#if wxUSE_PALETTE - wxPalette m_bitmapPalette; -#endif // wxUSE_PALETTE - int m_quality; - - int m_bitmapType ; - WXHMETAFILE m_hPict ; - WXHBITMAP m_hBitmap; - WXHICON m_hIcon ; - wxMask * m_bitmapMask; // Optional mask - bool m_hasAlpha; -}; + ~wxMask(); + + bool Create(const wxBitmap& bitmap, const wxColour& colour); + bool Create(const wxBitmap& bitmap); + bool Create(const wxMemoryBuffer& buf, int width , int height , int bytesPerRow ) ; -#define M_BITMAPDATA ((wxBitmapRefData *)m_refData) + // Implementation below + + void Init() ; + + // a 8 bit depth mask + void* GetRawAccess() const; + int GetBytesPerRow() const { return m_bytesPerRow ; } + // renders/updates native representation when necessary + void RealizeNative() ; +#if !wxMAC_USE_CORE_GRAPHICS + WXHBITMAP GetHBITMAP() const ; +#endif + +private: + wxMemoryBuffer m_memBuf ; + int m_bytesPerRow ; + int m_width ; + int m_height ; +#if !wxMAC_USE_CORE_GRAPHICS + WXHBITMAP m_maskBitmap ; +#endif +}; class WXDLLEXPORT wxBitmapHandler: public wxBitmapHandlerBase { @@ -120,96 +101,113 @@ private: class WXDLLEXPORT wxBitmap: public wxBitmapBase { - DECLARE_DYNAMIC_CLASS(wxBitmap) + DECLARE_DYNAMIC_CLASS(wxBitmap) - friend class WXDLLEXPORT wxBitmapHandler; + friend class WXDLLEXPORT wxBitmapHandler; public: - wxBitmap(); // Platform-specific - - // Copy constructors - wxBitmap(const wxBitmap& bitmap) - : wxBitmapBase() - { Ref(bitmap); } - - // Initialize with raw data. - wxBitmap(const char bits[], int width, int height, int depth = 1); - - // Initialize with XPM data - bool CreateFromXpm(const char **bits); - wxBitmap(const char **bits); - wxBitmap(char **bits); - - // Load a file or resource - wxBitmap(const wxString& name, wxBitmapType type = wxBITMAP_TYPE_PICT_RESOURCE); - - // Constructor for generalised creation from data - wxBitmap(void *data, wxBitmapType type, int width, int height, int depth = 1); - - // If depth is omitted, will create a bitmap compatible with the display - wxBitmap(int width, int height, int depth = -1); - - // Convert from wxImage: - wxBitmap(const wxImage& image, int depth = -1); - - ~wxBitmap(); - - wxImage ConvertToImage() const; - - // get the given part of bitmap - wxBitmap GetSubBitmap( const wxRect& rect ) const; - - virtual bool Create(int width, int height, int depth = -1); - virtual bool Create(void *data, wxBitmapType type, int width, int height, int depth = 1); - virtual bool LoadFile(const wxString& name, wxBitmapType type = wxBITMAP_TYPE_BMP_RESOURCE); - virtual bool SaveFile(const wxString& name, wxBitmapType type, const wxPalette *cmap = NULL) const; - - // copies the contents and mask of the given (colour) icon to the bitmap - virtual bool CopyFromIcon(const wxIcon& icon); - - bool Ok() const; - int GetWidth() const; - int GetHeight() const; - int GetDepth() const; - int GetQuality() const; - void SetWidth(int w); - void SetHeight(int h); - void SetDepth(int d); - void SetQuality(int q); - void SetOk(bool isOk); + wxBitmap(); // Platform-specific + + // Copy constructors + wxBitmap(const wxBitmap& bitmap) + { Ref(bitmap); } + + // Initialize with raw data. + wxBitmap(const char bits[], int width, int height, int depth = 1); + + // Initialize with XPM data + bool CreateFromXpm(const char **bits); + wxBitmap(const char **bits); + wxBitmap(char **bits); + + // Load a file or resource + wxBitmap(const wxString& name, wxBitmapType type = wxBITMAP_TYPE_PICT_RESOURCE); + + // Constructor for generalised creation from data + wxBitmap(void *data, wxBitmapType type, int width, int height, int depth = 1); + + // If depth is omitted, will create a bitmap compatible with the display + wxBitmap(int width, int height, int depth = -1); + + // Convert from wxImage: + wxBitmap(const wxImage& image, int depth = -1); + + // Convert from wxIcon + wxBitmap(const wxIcon& icon) { CopyFromIcon(icon); } + + ~wxBitmap(); + + wxImage ConvertToImage() const; + + // get the given part of bitmap + wxBitmap GetSubBitmap( const wxRect& rect ) const; + + virtual bool Create(int width, int height, int depth = -1); + virtual bool Create(void *data, wxBitmapType type, int width, int height, int depth = 1); + // virtual bool Create( WXHICON icon) ; + virtual bool LoadFile(const wxString& name, wxBitmapType type = wxBITMAP_TYPE_BMP_RESOURCE); + virtual bool SaveFile(const wxString& name, wxBitmapType type, const wxPalette *cmap = NULL) const; + + wxBitmapRefData *GetBitmapData() const + { return (wxBitmapRefData *)m_refData; } + + // copies the contents and mask of the given (colour) icon to the bitmap + virtual bool CopyFromIcon(const wxIcon& icon); + + bool Ok() const; + int GetWidth() const; + int GetHeight() const; + int GetDepth() const; + void SetWidth(int w); + void SetHeight(int h); + void SetDepth(int d); + void SetOk(bool isOk); + +#if WXWIN_COMPATIBILITY_2_4 + // these functions do nothing and are only there for backwards + // compatibility + wxDEPRECATED( int GetQuality() const ); + wxDEPRECATED( void SetQuality(int quality) ); +#endif // WXWIN_COMPATIBILITY_2_4 #if wxUSE_PALETTE - wxPalette* GetPalette() const; - void SetPalette(const wxPalette& palette); + wxPalette* GetPalette() const; + void SetPalette(const wxPalette& palette); #endif // wxUSE_PALETTE - wxMask *GetMask() const; - void SetMask(wxMask *mask) ; + wxMask *GetMask() const; + void SetMask(wxMask *mask) ; - int GetBitmapType() const; - - inline wxBitmap& operator = (const wxBitmap& bitmap) { if (*this == bitmap) return (*this); Ref(bitmap); return *this; } - inline bool operator == (const wxBitmap& bitmap) const { return m_refData == bitmap.m_refData; } - inline bool operator != (const wxBitmap& bitmap) const { return m_refData != bitmap.m_refData; } + inline wxBitmap& operator = (const wxBitmap& bitmap) { if (*this == bitmap) return (*this); Ref(bitmap); return *this; } + inline bool operator == (const wxBitmap& bitmap) const { return m_refData == bitmap.m_refData; } + inline bool operator != (const wxBitmap& bitmap) const { return m_refData != bitmap.m_refData; } - static void InitStandardHandlers(); + static void InitStandardHandlers(); // raw bitmap access support functions, for internal use only void *GetRawData(wxPixelDataBase& data, int bpp); void UngetRawData(wxPixelDataBase& data); + // these functions are internal and shouldn't be used, they risk to + // disappear in the future + bool HasAlpha() const; void UseAlpha(); -public: - WXHBITMAP GetHBITMAP() const; - inline WXHICON GetHICON() const { return (M_BITMAPDATA ? M_BITMAPDATA->m_hIcon : 0); } - WXHMETAFILE GetPict(bool *created = NULL ) const; - - void SetHBITMAP(WXHBITMAP bmp); - void SetHICON(WXHICON ico); - void SetPict( WXHMETAFILE pict ) ; +#if !wxMAC_USE_CORE_GRAPHICS + // returns the 'native' implementation, a GWorldPtr for the content and one for the mask + WXHBITMAP GetHBITMAP( WXHBITMAP * mask = NULL ) const; +#endif - bool FreeResource(bool force = FALSE); +#if wxMAC_USE_CORE_GRAPHICS + // returns a CGImageRef which must released after usage with CGImageRelease + WXCGIMAGEREF CGImageCreate() const ; +#endif + // get read only access to the underlying buffer + void *GetRawAccess() const ; + // brackets to the underlying OS structure for read/write access + // makes sure that no cached images will be constructed until terminated + void *BeginRawAccess() ; + void EndRawAccess() ; }; #endif // _WX_BITMAP_H_ diff --git a/include/wx/mac/carbon/chkconf.h b/include/wx/mac/carbon/chkconf.h index e7c5d596c5..a3de7145fe 100644 --- a/include/wx/mac/carbon/chkconf.h +++ b/include/wx/mac/carbon/chkconf.h @@ -25,6 +25,14 @@ #define wxUSE_DEBUG_NEW_ALWAYS 0 #endif +/* + * use OS X CoreGraphics (1) or QuickDraw (0) for rendering + */ + +#ifndef wxMAC_USE_CORE_GRAPHICS +#define wxMAC_USE_CORE_GRAPHICS 0 +#endif + #endif /* _WX_MAC_CHKCONF_H_ */ diff --git a/include/wx/mac/carbon/cursor.h b/include/wx/mac/carbon/cursor.h index 7d1cff7bbe..8cda6b0761 100644 --- a/include/wx/mac/carbon/cursor.h +++ b/include/wx/mac/carbon/cursor.h @@ -18,27 +18,6 @@ #include "wx/bitmap.h" -class WXDLLEXPORT wxCursorRefData: public wxBitmapRefData -{ - DECLARE_NO_COPY_CLASS(wxCursorRefData) - - friend class WXDLLEXPORT wxBitmap; - friend class WXDLLEXPORT wxCursor; -public: - wxCursorRefData(); - ~wxCursorRefData(); - -protected: - WXHCURSOR m_hCursor; - bool m_disposeHandle; - bool m_releaseHandle; - bool m_isColorCursor ; - long m_themeCursor ; -}; - -#define M_CURSORDATA ((wxCursorRefData *)m_refData) -#define M_CURSORHANDLERDATA ((wxCursorRefData *)bitmap->m_refData) - // Cursor class WXDLLEXPORT wxCursor: public wxBitmap { @@ -65,7 +44,7 @@ public: ~wxCursor(); bool CreateFromXpm(const char **bits) ; - virtual bool Ok() const { return (m_refData != NULL && ( M_CURSORDATA->m_hCursor != NULL || M_CURSORDATA->m_themeCursor != -1 ) ) ; } + virtual bool Ok() const ; inline wxCursor& operator = (const wxCursor& cursor) { if (*this == cursor) return (*this); Ref(cursor); return *this; } inline bool operator == (const wxCursor& cursor) const { return m_refData == cursor.m_refData; } @@ -74,7 +53,7 @@ public: void MacInstall() const ; void SetHCURSOR(WXHCURSOR cursor); - inline WXHCURSOR GetHCURSOR() const { return (M_CURSORDATA ? M_CURSORDATA->m_hCursor : 0); } + inline WXHCURSOR GetHCURSOR() const ; private : void CreateFromImage(const wxImage & image) ; }; diff --git a/include/wx/mac/carbon/dc.h b/include/wx/mac/carbon/dc.h index 0532fffe13..3a6437507f 100644 --- a/include/wx/mac/carbon/dc.h +++ b/include/wx/mac/carbon/dc.h @@ -44,7 +44,43 @@ extern int wxPageNumber; class wxMacPortStateHelper ; -class wxMacCGContext ; + +class WXDLLEXPORT wxGraphicPath +{ +public : + virtual ~wxGraphicPath() {} + + virtual void MoveToPoint( wxCoord x1 , wxCoord y1 ) = 0 ; + + virtual void AddLineToPoint( wxCoord x1 , wxCoord y1 ) = 0 ; + + virtual void AddRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) = 0 ; + + virtual void AddCircle( wxCoord x, wxCoord y , wxCoord r ) = 0 ; + + virtual void CloseSubpath() = 0 ; +} ; + +class WXDLLEXPORT wxGraphicContext +{ +public: + virtual ~wxGraphicContext() {} + + virtual void Clip( const wxRegion ®ion ) = 0 ; + + virtual void StrokePath( const wxGraphicPath *path ) = 0 ; + + virtual void DrawPath( const wxGraphicPath *path , int fillStyle = wxWINDING_RULE ) = 0 ; + + virtual void FillPath( const wxGraphicPath *path , const wxColor &fillColor , int fillStyle = wxWINDING_RULE ) = 0 ; + + virtual void SetPen( const wxPen &pen ) = 0 ; + + virtual void SetBrush( const wxBrush &brush ) = 0 ; + + virtual wxGraphicPath* CreatePath() = 0 ; +} ; + //----------------------------------------------------------------------------- // wxDC //----------------------------------------------------------------------------- @@ -186,9 +222,10 @@ class WXDLLEXPORT wxDC: public wxDCBase else return (wxCoord)((double)(new_y) * m_scaleY - 0.5) * m_signY + m_deviceOriginY + m_macLocalOrigin.y ; } - +#if !wxMAC_USE_CORE_GRAPHICS WXHRGN MacGetCurrentClipRgn() { return m_macCurrentClipRgn ; } static void MacSetupBackgroundForCurrentPort(const wxBrush& background ) ; +#endif // protected: @@ -257,37 +294,45 @@ protected: // Begin implementation for Mac public: - WXHDC m_macPort ; +#if !wxMAC_USE_CORE_GRAPHICS WXHBITMAP m_macMask ; +#endif // in order to preserve the const inheritance of the virtual functions, we have to // use mutable variables starting from CWPro 5 void MacInstallFont() const ; +#if !wxMAC_USE_CORE_GRAPHICS void MacInstallPen() const ; void MacInstallBrush() const ; +#endif + + wxPoint m_macLocalOrigin ; + mutable void* m_macATSUIStyle ; +#if wxMAC_USE_CORE_GRAPHICS + // CoreGraphics + wxGraphicContext * m_graphicContext ; +#else + WXHDC m_macPort ; mutable bool m_macFontInstalled ; mutable bool m_macPenInstalled ; mutable bool m_macBrushInstalled ; WXHRGN m_macBoundaryClipRgn ; WXHRGN m_macCurrentClipRgn ; - wxPoint m_macLocalOrigin ; void MacSetupPort( wxMacPortStateHelper* ph ) const ; void MacCleanupPort( wxMacPortStateHelper* ph ) const ; - mutable void* m_macATSUIStyle ; mutable wxMacPortStateHelper* m_macCurrentPortStateHelper ; mutable bool m_macFormerAliasState ; mutable short m_macFormerAliasSize ; mutable bool m_macAliasWasEnabled ; mutable void* m_macForegroundPixMap ; mutable void* m_macBackgroundPixMap ; +#endif - // CoreGraphics - - wxMacCGContext * m_macGraphicContext ; - void MacSetupGraphicContext() ; +#if wxMAC_USE_CORE_GRAPHICS +#endif }; #endif diff --git a/include/wx/mac/carbon/dcprint.h b/include/wx/mac/carbon/dcprint.h index 0e2b5bcf0d..dfc39d4559 100644 --- a/include/wx/mac/carbon/dcprint.h +++ b/include/wx/mac/carbon/dcprint.h @@ -37,7 +37,9 @@ class WXDLLEXPORT wxPrinterDC: public wxDC virtual void EndPage(void) ; wxPrintData& GetPrintData() { return m_printData; } virtual void DoGetSize( int *width, int *height ) const; - +#if wxMAC_USE_CORE_GRAPHICS + void MacSetCGContext( void * cg ) ; +#endif protected: wxPrintData m_printData ; wxNativePrinterDC* m_nativePrinterDC ; diff --git a/include/wx/mac/carbon/display.h b/include/wx/mac/carbon/display.h index 5ea137e324..223e3c3281 100644 --- a/include/wx/mac/carbon/display.h +++ b/include/wx/mac/carbon/display.h @@ -1,8 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// // Name: display.h // Purpose: wxDisplay class customization for Mac -// Author: Brian Victor -// Modified by: Royce Mitchell III +// Author: Brian Victor/Royce Mitchel for non OSX / Ryan Norton for OS X +// Modified by: // Created: 06/21/02 // RCS-ID: $Id$ // Copyright: (c) wxWidgets team diff --git a/include/wx/mac/carbon/icon.h b/include/wx/mac/carbon/icon.h index 5b7a8106e8..cc90942c70 100644 --- a/include/wx/mac/carbon/icon.h +++ b/include/wx/mac/carbon/icon.h @@ -19,43 +19,53 @@ #include "wx/bitmap.h" // Icon -class WXDLLEXPORT wxIcon: public wxBitmap +class WXDLLEXPORT wxIcon: public wxGDIObject { public: - wxIcon(); + wxIcon(); - // Copy constructors - wxIcon(const wxIcon& icon) - : wxBitmap() + // Copy constructors + wxIcon(const wxIcon& icon) { Ref(icon); } - wxIcon(const char **data); - wxIcon(char **data); - wxIcon(const char bits[], int width , int height ); - wxIcon(const wxString& name, int flags = wxBITMAP_TYPE_ICON_RESOURCE, + wxIcon(const char **data); + wxIcon(char **data); + wxIcon(const char bits[], int width , int height ); + wxIcon(const wxString& name, int flags = wxBITMAP_TYPE_ICON_RESOURCE, int desiredWidth = -1, int desiredHeight = -1); - wxIcon(const wxIconLocation& loc) - { + wxIcon(const wxIconLocation& loc) + { LoadFile(loc.GetFileName(), wxBITMAP_TYPE_ICON); - } - ~wxIcon(); + } + ~wxIcon(); - bool LoadFile(const wxString& name, wxBitmapType flags /* = wxBITMAP_TYPE_ICON_RESOURCE */ , + bool LoadFile(const wxString& name, wxBitmapType flags /* = wxBITMAP_TYPE_ICON_RESOURCE */ , int desiredWidth /* = -1 */ , int desiredHeight = -1); - bool LoadFile(const wxString& name ,wxBitmapType flags = wxBITMAP_TYPE_ICON_RESOURCE ) + bool LoadFile(const wxString& name ,wxBitmapType flags = wxBITMAP_TYPE_ICON_RESOURCE ) { return LoadFile( name , flags , -1 , -1 ) ; } - wxIcon& operator=(const wxIcon& icon) + wxIcon& operator=(const wxIcon& icon) { if (this != &icon) Ref(icon); return *this; } - bool operator==(const wxIcon& icon) const { return m_refData == icon.m_refData; } - bool operator!=(const wxIcon& icon) const { return !(*this == icon); } - - // create from bitmap (which should have a mask unless it's monochrome): - // there shouldn't be any implicit bitmap -> icon conversion (i.e. no - // ctors, assignment operators...), but it's ok to have such function - void CopyFromBitmap(const wxBitmap& bmp); - - DECLARE_DYNAMIC_CLASS(wxIcon) + bool operator==(const wxIcon& icon) const { return m_refData == icon.m_refData; } + bool operator!=(const wxIcon& icon) const { return !(*this == icon); } + + // create from bitmap (which should have a mask unless it's monochrome): + // there shouldn't be any implicit bitmap -> icon conversion (i.e. no + // ctors, assignment operators...), but it's ok to have such function + void CopyFromBitmap(const wxBitmap& bmp); + + bool Ok() const; + int GetWidth() const; + int GetHeight() const; + int GetDepth() const; + void SetWidth(int w); + void SetHeight(int h); + void SetDepth(int d); + void SetOk(bool isOk); + + WXHICON GetHICON() const ; + + DECLARE_DYNAMIC_CLASS(wxIcon) }; /* diff --git a/include/wx/mac/carbon/private.h b/include/wx/mac/carbon/private.h index 3b9f965186..26b4452ce8 100644 --- a/include/wx/mac/carbon/private.h +++ b/include/wx/mac/carbon/private.h @@ -58,6 +58,7 @@ inline int FixedToInt( Fixed inFixed ) #if wxUSE_GUI +#include "wx/dc.h" #include "wx/window.h" class wxMacPortStateHelper @@ -345,19 +346,22 @@ private : typedef wxMacUPP wxMacNMUPP ; #if wxUSE_GUI - +/* GWorldPtr wxMacCreateGWorld( int width , int height , int depth ) ; void wxMacDestroyGWorld( GWorldPtr gw ) ; PicHandle wxMacCreatePict( GWorldPtr gw , GWorldPtr mask = NULL ) ; CIconHandle wxMacCreateCIcon(GWorldPtr image , GWorldPtr mask , short dstDepth , short iconSize ) ; void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green , int blue ) ; CTabHandle wxMacCreateColorTable( int numColors ) ; +*/ +IconRef wxMacCreateIconRef(const wxBitmap& bmp) ; void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType = 0 ) ; +void wxMacReleaseBitmapButton( ControlButtonContentInfo*info ) ; #define MAC_WXCOLORREF(a) (*((RGBColor*)&(a))) #define MAC_WXHBITMAP(a) (GWorldPtr(a)) #define MAC_WXHMETAFILE(a) (PicHandle(a)) -#define MAC_WXHICON(a) (CIconHandle(a)) +#define MAC_WXHICON(a) (IconRef(a)) #define MAC_WXHCURSOR(a) (CursHandle(a)) #define MAC_WXHRGN(a) (RgnHandle(a)) #define MAC_WXHWND(a) (WindowPtr(a)) @@ -540,6 +544,142 @@ protected : long m_windowStyle ; } ; +#if wxMAC_USE_CORE_GRAPHICS + +class WXDLLEXPORT wxMacCGPath : public wxGraphicPath +{ + DECLARE_NO_COPY_CLASS(wxMacCGPath) +public : + wxMacCGPath() ; + ~wxMacCGPath() ; + + // Starts a new subpath at + void MoveToPoint( wxCoord x1 , wxCoord y1 ) ; + void AddLineToPoint( wxCoord x1 , wxCoord y1 ) ; + void AddRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) ; + void AddCircle( wxCoord x, wxCoord y , wxCoord r ) ; + + // closes the current subpath + void CloseSubpath() ; + + CGPathRef GetPath() const ; +private : + CGMutablePathRef m_path ; +} ; + +class WXDLLEXPORT wxMacCGContext : public wxGraphicContext +{ + DECLARE_NO_COPY_CLASS(wxMacCGContext) + +public: + wxMacCGContext( CGrafPtr port ) ; + wxMacCGContext( CGContextRef cgcontext ) ; + wxMacCGContext() ; + ~wxMacCGContext() ; + + virtual void Clip( const wxRegion ®ion ) ; + virtual void StrokePath( const wxGraphicPath *p ) ; + virtual void DrawPath( const wxGraphicPath *p , int fillStyle = wxWINDING_RULE ) ; + virtual void FillPath( const wxGraphicPath *p , const wxColor &fillColor , int fillStyle = wxWINDING_RULE ) ; + + virtual wxGraphicPath* CreatePath() ; + virtual void SetPen( const wxPen &pen ) ; + virtual void SetBrush( const wxBrush &brush ) ; + CGContextRef GetNativeContext() ; + void SetNativeContext( CGContextRef cg ) ; + CGPathDrawingMode GetDrawingMode() const { return m_mode ; } +private: + CGContextRef m_cgContext ; + CGrafPtr m_qdPort ; + CGPathDrawingMode m_mode ; + wxPen m_pen ; + wxBrush m_brush ; +} ; + +CGColorSpaceRef wxMacGetGenericRGBColorSpace(void) ; + +#endif // wxMAC_USE_CORE_GRAPHICS + +class WXDLLEXPORT wxBitmapRefData: public wxGDIRefData +{ + DECLARE_NO_COPY_CLASS(wxBitmapRefData) + + friend class WXDLLEXPORT wxIcon; + friend class WXDLLEXPORT wxCursor; +public: + wxBitmapRefData(int width , int height , int depth); + wxBitmapRefData(); + ~wxBitmapRefData(); + + void Free() ; + bool Ok() const { return m_ok ; } + void SetOk( bool isOk) { m_ok = isOk ; } + + void SetWidth( int width ) { m_width = width ; } + void SetHeight( int height ) { m_height = height ; } + void SetDepth( int depth ) { m_depth = depth ; } + + int GetWidth() const { return m_width ; } + int GetHeight() const { return m_height ; } + int GetDepth() const { return m_depth ; } + + void *GetRawAccess() const ; + void *BeginRawAccess() ; + void EndRawAccess() ; + + bool HasAlpha() const { return m_hasAlpha ; } + void UseAlpha( bool useAlpha ) ; + +public: +#if wxUSE_PALETTE + wxPalette m_bitmapPalette; +#endif // wxUSE_PALETTE + + wxMask * m_bitmapMask; // Optional mask +#if wxMAC_USE_CORE_GRAPHICS + CGImageRef CGImageCreate() const ; +#else + GWorldPtr GetHBITMAP(GWorldPtr * mask = NULL ) const ; + void UpdateAlphaMask() const ; +#endif +private : + bool Create(int width , int height , int depth) ; + void Init() ; + + int m_width; + int m_height; + int m_bytesPerRow ; + int m_depth; + bool m_hasAlpha; + wxMemoryBuffer m_memBuf ; + int m_rawAccessCount ; + bool m_ok; +#if wxMAC_USE_CORE_GRAPHICS + mutable CGImageRef m_cgImageRef ; +#else + GWorldPtr m_hBitmap; + GWorldPtr m_hMaskBitmap ; + wxMemoryBuffer m_maskMemBuf ; + int m_maskBytesPerRow ; +#endif +}; + +#define M_BITMAPDATA ((wxBitmapRefData *)m_refData) + +class WXDLLEXPORT wxIconRefData : public wxGDIRefData +{ +public: + wxIconRefData() ; + wxIconRefData( WXHICON ) ; + virtual ~wxIconRefData() { Free(); } + + void Init() ; + virtual void Free(); + WXHICON GetHICON() const { return (WXHICON) m_iconRef ; } +private : + IconRef m_iconRef ; +}; + #endif // wxUSE_GUI //--------------------------------------------------------------------------- diff --git a/include/wx/mac/carbon/statbmp.h b/include/wx/mac/carbon/statbmp.h index 8a16726c57..4e07e018a0 100644 --- a/include/wx/mac/carbon/statbmp.h +++ b/include/wx/mac/carbon/statbmp.h @@ -22,9 +22,9 @@ class WXDLLEXPORT wxStaticBitmap: public wxStaticBitmapBase { DECLARE_DYNAMIC_CLASS(wxStaticBitmap) public: - inline wxStaticBitmap() { } + wxStaticBitmap() { } - inline wxStaticBitmap(wxWindow *parent, wxWindowID id, + wxStaticBitmap(wxWindow *parent, wxWindowID id, const wxBitmap& label, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -60,7 +60,7 @@ class WXDLLEXPORT wxStaticBitmap: public wxStaticBitmapBase virtual wxSize DoGetBestSize() const ; protected: - wxBitmap m_bitmap; + wxBitmap m_bitmap; DECLARE_EVENT_TABLE() }; diff --git a/include/wx/mac/carbon/textctrl.h b/include/wx/mac/carbon/textctrl.h index 4930d5693b..cace96463b 100644 --- a/include/wx/mac/carbon/textctrl.h +++ b/include/wx/mac/carbon/textctrl.h @@ -163,7 +163,7 @@ public: virtual void MacVisibilityChanged() ; virtual void MacEnabledStateChanged() ; - +#ifndef __WXMAC_OSX__ virtual void MacControlUserPaneDrawProc(wxInt16 part) ; virtual wxInt16 MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) ; virtual wxInt16 MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc) ; @@ -172,6 +172,7 @@ public: virtual void MacControlUserPaneActivateProc(bool activating) ; virtual wxInt16 MacControlUserPaneFocusProc(wxInt16 action) ; virtual void MacControlUserPaneBackgroundProc(void* info) ; +#endif wxMacTextControl* GetPeer() const { return (wxMacTextControl*) m_peer ; } protected: diff --git a/include/wx/mac/carbon/window.h b/include/wx/mac/carbon/window.h index 9b5e20c9cb..60d0652bd3 100644 --- a/include/wx/mac/carbon/window.h +++ b/include/wx/mac/carbon/window.h @@ -17,6 +17,7 @@ #endif #include "wx/brush.h" +#include "wx/dc.h" // --------------------------------------------------------------------------- // forward declarations @@ -161,7 +162,6 @@ public: public: virtual void MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool mouseStillDown ) ; virtual bool MacDoRedraw( WXHRGN updatergn , long time ) ; - virtual void MacRedraw( WXHRGN updatergn , long time , bool erase) ; virtual bool MacCanFocus() const ; // this should not be overriden in classes above wxWindowMac because it is called from its destructor via DeleteChildren @@ -212,10 +212,9 @@ public: wxList& GetSubcontrols() { return m_subControls; } virtual void MacInstallEventHandler(WXWidget native) ; - virtual void MacRedrawControl(); WXEVENTHANDLERREF MacGetControlEventHandler() { return m_macControlEventHandler ; } void MacPostControlCreate(const wxPoint& pos, const wxSize& size) ; - +#ifndef __WXMAC_OSX__ virtual void MacControlUserPaneDrawProc(wxInt16 part) ; virtual wxInt16 MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) ; virtual wxInt16 MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc) ; @@ -224,7 +223,7 @@ public: virtual void MacControlUserPaneActivateProc(bool activating) ; virtual wxInt16 MacControlUserPaneFocusProc(wxInt16 action) ; virtual void MacControlUserPaneBackgroundProc(void* info) ; - +#endif // translate wxWidgets coords into ones suitable to be passed to // the CreateControl calls // @@ -241,7 +240,10 @@ public: // flash the current invalid area, useful for debugging in OSX double buffered situation void MacFlashInvalidAreas() ; - +#if wxMAC_USE_CORE_GRAPHICS + void * MacGetCGContextRef() { return m_cgContextRef ; } + void MacSetCGContextRef(void * cg) { m_cgContextRef = cg ; } +#endif protected: // For controls like radiobuttons which are really composite wxList m_subControls; @@ -249,6 +251,9 @@ protected: unsigned int m_frozenness; // the peer object, allowing for cleaner API support wxMacControl* m_peer ; +#if wxMAC_USE_CORE_GRAPHICS + void * m_cgContextRef ; +#endif // true if is is not a native control but a wxWindow control bool m_macIsUserPane ; wxBrush m_macBackgroundBrush ; diff --git a/src/mac/carbon/bitmap.cpp b/src/mac/carbon/bitmap.cpp index a43d731eb3..d98e6fd2dd 100644 --- a/src/mac/carbon/bitmap.cpp +++ b/src/mac/carbon/bitmap.cpp @@ -19,6 +19,7 @@ #include "wx/icon.h" #include "wx/log.h" #include "wx/image.h" +#include "wx/metafile.h" #include "wx/xpmdecod.h" #include "wx/rawbmp.h" @@ -35,399 +36,497 @@ IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject ) #include "wx/mac/uma.h" -CTabHandle wxMacCreateColorTable( int numColors ) -{ - CTabHandle newColors; /* Handle to the new color table */ - - /* Allocate memory for the color table */ - newColors = (CTabHandle)NewHandleClear( sizeof (ColorTable) + - sizeof (ColorSpec) * (numColors - 1) ); - if (newColors != nil) +// Implementation Notes +// -------------------- +// +// we are always working with a 32 bit deep pixel buffer +// under QuickDraw its alpha parts are going to be ignored in the GWorld, +// therefore we have a separate GWorld there for blitting the mask in + +// under Quartz then content is transformed into a CGImageRef representing the same data +// which can be transferred to the GPU by the OS for fast rendering + +// we don't dare premultiplied alpha yet +#define wxMAC_USE_PREMULTIPLIED_ALPHA 0 + +IconRef wxMacCreateIconRef(const wxBitmap& bmp) +{ + // setup the header properly + + IconFamilyHandle iconFamily = (IconFamilyHandle) NewHandle(8) ; + (**iconFamily).resourceType = kIconFamilyType ; + (**iconFamily).resourceSize = sizeof(OSType) + sizeof(Size); + + int w = bmp.GetWidth() ; + int h = bmp.GetHeight() ; + int sz = wxMax( w , h ) ; + if ( sz > 128 ) { - /* Initialize the fields */ - (**newColors).ctSeed = GetCTSeed(); - (**newColors).ctFlags = 0; - (**newColors).ctSize = numColors - 1; - /* Initialize the table of colors */ + wxFAIL_MSG( wxT("Currently only 128 pixels wide images are supported") ) ; + } + + Handle data = NULL ; + Handle maskdata = NULL ; + unsigned char * maskptr = NULL ; + unsigned char * ptr = NULL ; + size_t size ; + size_t masksize ; + OSType dataType ; + OSType maskType ; + + bool hasAlpha = bmp.HasAlpha() ; + wxMask *mask = bmp.GetMask() ; + // thumbnail is 128 x 128 with 32 bits per pixel + + if ( sz > 48 ) + { + sz = 128 ; + dataType = kThumbnail32BitData ; + maskType = kThumbnail8BitMask ; + } + else if ( sz > 32 ) + { + sz = 48 ; + dataType = kHuge32BitData ; + maskType = kHuge8BitMask ; + } + else if ( sz > 16 ) + { + sz = 32 ; + dataType = kLarge32BitData ; + maskType = kLarge8BitMask ; + } + else + { + sz = 16 ; + dataType = kSmall32BitData ; + maskType = kSmall8BitMask ; } - return newColors ; -} -void wxMacDestroyColorTable( CTabHandle colors ) -{ - DisposeHandle( (Handle) colors ) ; + size = sz * sz * 4 ; + data = NewHandle( size) ; + HLock( data ) ; + ptr = (unsigned char*) *data ; + memset( ptr , 0, size ) ; + + masksize = sz * sz ; + maskdata = NewHandle( masksize ) ; + HLock( maskdata ) ; + maskptr = (unsigned char*) *maskdata ; + memset( maskptr , 0 , masksize ) ; + + unsigned char * source = (unsigned char*) bmp.GetRawAccess() ; + unsigned char * masksource = mask ? (unsigned char*) mask->GetRawAccess() : NULL ; + for ( int y = 0 ; y < h ; ++y ) + { + unsigned char * dest = ptr + y * sz * 4 ; + unsigned char * maskdest = maskptr + y * sz ; + for ( int x = 0 ; x < w ; ++x ) + { + unsigned char a = *source ++ ; + unsigned char r = *source ++ ; + unsigned char g = *source ++ ; + unsigned char b = *source ++ ; + + *dest++ = 0 ; + *dest++ = r ; + *dest++ = g ; + *dest++ = b ; + + if ( mask ) + *maskdest++ = *masksource++ ; + else if ( hasAlpha ) + *maskdest++ = a ; + else + *maskdest++ = 0xFF ; + } + } + + OSStatus err = SetIconFamilyData( iconFamily, dataType , data ) ; + wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; + + err = SetIconFamilyData( iconFamily, maskType , maskdata ) ; + wxASSERT_MSG( err == noErr , wxT("Error when adding mask") ) ; + HUnlock( data ) ; + HUnlock( maskdata ) ; + DisposeHandle( data ) ; + DisposeHandle( maskdata ) ; + + IconRef iconRef ; + static int iconCounter = 2 ; + + err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) iconCounter, iconFamily, &iconRef ) ; + UInt16 owners ; + err = GetIconRefOwners(iconRef , &owners ) ; + + wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; + // we have to retain a reference, as Unregister will decrement it + AcquireIconRef( iconRef ) ; + UnregisterIconRef( 'WXNG' , (OSType) iconCounter ) ; + DisposeHandle( (Handle) iconFamily ) ; + ++iconCounter ; + + return iconRef ; } -void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green , int blue ) +void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType ) { - (**newColors).ctTable[index].value = index; - (**newColors).ctTable[index].rgb.red = red ; // someRedValue; - (**newColors).ctTable[index].rgb.green = green ; // someGreenValue; - (**newColors).ctTable[index].rgb.blue = blue ; // someBlueValue; + memset( info , 0 , sizeof(ControlButtonContentInfo) ) ; + if ( bitmap.Ok() ) + { + wxBitmapRefData * bmap = (wxBitmapRefData*) ( bitmap.GetRefData()) ; + if ( bmap == NULL ) + return ; + info->contentType = kControlContentIconRef ; + info->u.iconRef = wxMacCreateIconRef( bitmap ) ; + +#if wxMAC_USE_CORE_GRAPHICS + /* + // only on 10.4 more controls will accept a CGImage + + info->contentType = kControlContentCGImageRef ; + info->u.imageRef = (CGImageRef) bmap->CGImageCreate() ; + */ +#endif + } } -GWorldPtr wxMacCreateGWorld( int width , int height , int depth ) +void wxMacReleaseBitmapButton( ControlButtonContentInfo*info ) { - OSErr err = noErr ; - GWorldPtr port ; - Rect rect = { 0 , 0 , height , width } ; - - if ( depth < 0 ) + if ( info->contentType == kControlContentIconRef ) { - depth = wxDisplayDepth() ; + ReleaseIconRef(info->u.iconRef) ; } - - err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ; - if ( err == noErr ) +#if wxMAC_USE_CORE_GRAPHICS + else if ( info->contentType == kControlContentCGImageRef ) + { + CGImageRelease( info->u.imageRef ) ; + } +#endif + else { - return port ; + wxFAIL_MSG(wxT("Unexpected bitmap type") ) ; } - return NULL ; } -void wxMacDestroyGWorld( GWorldPtr gw ) + +void wxBitmapRefData::Init() { - if ( gw ) - DisposeGWorld( gw ) ; + m_width = 0 ; + m_height = 0 ; + m_depth = 0 ; + m_ok = false ; + m_bitmapMask = NULL ; +#if wxMAC_USE_CORE_GRAPHICS + m_cgImageRef = NULL ; +#else + m_hBitmap = NULL ; + m_hMaskBitmap = NULL; + m_maskBytesPerRow = NULL ; +#endif + m_rawAccessCount = 0 ; + m_hasAlpha = false; } -#define kDefaultRes 0x00480000 /* Default resolution is 72 DPI; Fixed type */ - -OSErr SetupCIconHandlePixMap( CIconHandle icon , short depth , Rect *bounds , CTabHandle colors ) +wxBitmapRefData::wxBitmapRefData() { - CTabHandle newColors; /* Color table used for the off-screen PixMap */ - Ptr offBaseAddr; /* Pointer to the off-screen pixel image */ - OSErr error; /* Returns error code */ - short bytesPerRow; /* Number of bytes per row in the PixMap */ - - - error = noErr; - newColors = nil; - offBaseAddr = nil; - - bytesPerRow = ((depth * (bounds->right - bounds->left) + 31) / 32) * 4; - - /* Clone the clut if indexed color; allocate a dummy clut if direct color*/ - if (depth <= 8) - { - newColors = colors; - error = HandToHand((Handle *) &newColors); - } - else - { - newColors = (CTabHandle) NewHandle(sizeof(ColorTable) - - sizeof(CSpecArray)); - error = MemError(); - } - if (error == noErr) - { - /* Allocate pixel image; long integer multiplication avoids overflow */ - (**icon).iconData = NewHandle((unsigned long) bytesPerRow * (bounds->bottom - - bounds->top)); - if ((**icon).iconData != nil) - { - /* Initialize fields common to indexed and direct PixMaps */ - (**icon).iconPMap.baseAddr = 0; /* Point to image */ - (**icon).iconPMap.rowBytes = bytesPerRow | /* MSB set for PixMap */ - 0x8000; - (**icon).iconPMap.bounds = *bounds; /* Use given bounds */ - (**icon).iconPMap.pmVersion = 0; /* No special stuff */ - (**icon).iconPMap.packType = 0; /* Default PICT pack */ - (**icon).iconPMap.packSize = 0; /* Always zero in mem */ - (**icon).iconPMap.hRes = kDefaultRes; /* 72 DPI default res */ - (**icon).iconPMap.vRes = kDefaultRes; /* 72 DPI default res */ - (**icon).iconPMap.pixelSize = depth; /* Set # bits/pixel */ - - /* Initialize fields specific to indexed and direct PixMaps */ - if (depth <= 8) - { - /* PixMap is indexed */ - (**icon).iconPMap.pixelType = 0; /* Indicates indexed */ - (**icon).iconPMap.cmpCount = 1; /* Have 1 component */ - (**icon).iconPMap.cmpSize = depth; /* Component size=depth */ - (**icon).iconPMap.pmTable = newColors; /* Handle to CLUT */ - } - else - { - /* PixMap is direct */ - (**icon).iconPMap.pixelType = RGBDirect; /* Indicates direct */ - (**icon).iconPMap.cmpCount = 3; /* Have 3 components */ - if (depth == 16) - (**icon).iconPMap.cmpSize = 5; /* 5 bits/component */ - else - (**icon).iconPMap.cmpSize = 8; /* 8 bits/component */ - (**newColors).ctSeed = 3 * (**icon).iconPMap.cmpSize; - (**newColors).ctFlags = 0; - (**newColors).ctSize = 0; - (**icon).iconPMap.pmTable = newColors; - } - } - else - error = MemError(); - } - else - newColors = nil; - - /* If no errors occured, return a handle to the new off-screen PixMap */ - if (error != noErr) - { - if (newColors != nil) - DisposeCTable(newColors); - } - - /* Return the error code */ - return error; + Init() ; } -CIconHandle wxMacCreateCIcon(GWorldPtr image , GWorldPtr mask , short dstDepth , short iconSize ) +wxBitmapRefData::wxBitmapRefData( int w , int h , int d ) { - GWorldPtr saveWorld; - GDHandle saveHandle; - - GetGWorld(&saveWorld,&saveHandle); // save Graphics env state - SetGWorld(image,nil); - - Rect frame = { 0 , 0 , iconSize , iconSize } ; - Rect imageBounds = frame ; - GetPortBounds( image , &imageBounds ) ; - - int bwSize = iconSize / 8 * iconSize ; - CIconHandle icon = (CIconHandle) NewHandleClear( sizeof ( CIcon ) + 2 * bwSize) ; - HLock((Handle)icon) ; - SetupCIconHandlePixMap( icon , dstDepth , &frame,GetCTable(dstDepth)) ; - HLock( (**icon).iconData ) ; - (**icon).iconPMap.baseAddr = *(**icon).iconData ; - - LockPixels(GetGWorldPixMap(image)); - - CopyBits(GetPortBitMapForCopyBits(image), - (BitMapPtr)&((**icon).iconPMap), - &imageBounds, - &imageBounds, - srcCopy | ditherCopy, nil); - - - UnlockPixels(GetGWorldPixMap(image)); - HUnlock( (**icon).iconData ) ; + Init() ; + Create( w , h , d ) ; +} - (**icon).iconMask.rowBytes = iconSize / 8 ; - (**icon).iconMask.bounds = frame ; +bool wxBitmapRefData::Create( int w , int h , int d ) +{ + m_width = w ; + m_height = h ; + m_depth = d ; - (**icon).iconBMap.rowBytes = iconSize / 8 ; - (**icon).iconBMap.bounds = frame ; - (**icon).iconMask.baseAddr = (char*) &(**icon).iconMaskData ; - (**icon).iconBMap.baseAddr = (char*) &(**icon).iconMaskData + bwSize ; + m_bytesPerRow = w * 4 ; + size_t size = m_bytesPerRow * h ; + void* data = m_memBuf.GetWriteBuf(size) ; + memset( data , 0 , size) ; + m_memBuf.UngetWriteBuf(size) ; +#if wxMAC_USE_CORE_GRAPHICS + m_ok = true ; +#else + m_hBitmap = NULL ; + Rect rect = { 0 , 0 , m_height , m_width } ; + verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 , + (char*) data , m_bytesPerRow ) ) ; + wxASSERT_MSG( m_hBitmap , wxT("Unable to create GWorld context") ) ; + m_ok = ( m_hBitmap != NULL ) ; +#endif + return m_ok ; +} - if ( mask ) +void wxBitmapRefData::UseAlpha( bool use ) +{ + if ( m_hasAlpha == use ) + return ; + + m_hasAlpha = use ; +#if !wxMAC_USE_CORE_GRAPHICS + if ( m_hasAlpha ) { - Rect r ; - GetPortBounds( image , &r ) ; - LockPixels(GetGWorldPixMap(mask) ) ; - CopyBits(GetPortBitMapForCopyBits(mask) , - &(**icon).iconBMap , &r , &r, srcCopy , nil ) ; - CopyBits(GetPortBitMapForCopyBits(mask) , - &(**icon).iconMask , &r , &r, srcCopy , nil ) ; - UnlockPixels(GetGWorldPixMap( mask ) ) ; + int width = GetWidth() ; + int height = GetHeight() ; + m_maskBytesPerRow = ( width + 3 ) & 0xFFFFFFC ; + size_t size = height * m_maskBytesPerRow ; + unsigned char * data = (unsigned char * ) m_maskMemBuf.GetWriteBuf( size ) ; + memset( data , 0 , size ) ; + wxASSERT( m_hMaskBitmap == NULL ) ; + Rect rect = { 0 , 0 , height , width } ; + verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hMaskBitmap , k8IndexedGrayPixelFormat , &rect , NULL , NULL , 0 , + (char*) data , m_maskBytesPerRow ) ) ; + wxASSERT_MSG( m_hMaskBitmap , wxT("Unable to create GWorld context for alpha mask") ) ; + m_maskMemBuf.UngetWriteBuf(size) ; + UpdateAlphaMask() ; } else { - Rect r ; - GetPortBounds( image , &r ) ; - LockPixels(GetGWorldPixMap(image)); - CopyBits(GetPortBitMapForCopyBits(image) , - &(**icon).iconBMap , &r , &r, srcCopy , nil ) ; - CopyBits(GetPortBitMapForCopyBits(image) , - &(**icon).iconMask , &r , &r, srcCopy , nil ) ; - UnlockPixels(GetGWorldPixMap(image)); + DisposeGWorld( m_hMaskBitmap ) ; + m_hMaskBitmap = NULL ; + m_maskBytesPerRow = 0 ; } - - (**icon).iconMask.baseAddr = NULL ; - (**icon).iconBMap.baseAddr = NULL ; - (**icon).iconPMap.baseAddr = NULL ; - HUnlock((Handle)icon) ; - SetGWorld(saveWorld,saveHandle); - - return icon; +#endif } -PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask) +void *wxBitmapRefData::GetRawAccess() const { - CGrafPtr origPort ; - GDHandle origDev ; - - PicHandle pict; - - RGBColor white = { 0xffff ,0xffff , 0xffff } ; - RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; - - GetGWorld( &origPort , &origDev ) ; - - RgnHandle clipRgn = NULL ; + wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ; + return m_memBuf.GetData() ; +} - if ( mask ) - { - clipRgn = NewRgn() ; - LockPixels( GetGWorldPixMap( mask ) ) ; - BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( mask ) ) ; - UnlockPixels( GetGWorldPixMap( mask ) ) ; - } +void *wxBitmapRefData::BeginRawAccess() +{ + wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ) ; + wxASSERT( m_rawAccessCount == 0 ) ; + ++m_rawAccessCount ; +#if wxMAC_USE_CORE_GRAPHICS + // we must destroy an existing cached image, as + // the bitmap data may change now + if ( m_cgImageRef ) + { + CGImageRelease( m_cgImageRef ) ; + m_cgImageRef = NULL ; + } +#endif + return m_memBuf.GetData() ; +} - SetGWorld( wp , NULL ) ; - Rect portRect ; - if ( clipRgn ) - GetRegionBounds( clipRgn , &portRect ) ; - else - GetPortBounds( wp , &portRect ) ; - pict = OpenPicture(&portRect); - if(pict) - { - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; +void wxBitmapRefData::EndRawAccess() +{ + wxCHECK_RET( Ok() , wxT("invalid bitmap") ) ; + wxASSERT( m_rawAccessCount == 1 ) ; + --m_rawAccessCount ; +#if !wxMAC_USE_CORE_GRAPHICS + UpdateAlphaMask() ; +#endif +} - if ( clipRgn ) - SetClip( clipRgn ) ; - LockPixels( GetGWorldPixMap( wp ) ) ; - CopyBits(GetPortBitMapForCopyBits(wp), - GetPortBitMapForCopyBits(wp), - &portRect, - &portRect, - srcCopy,clipRgn); - UnlockPixels( GetGWorldPixMap( wp ) ) ; - ClosePicture(); - } - SetGWorld( origPort , origDev ) ; - if ( clipRgn ) - DisposeRgn( clipRgn ) ; - return pict; +#if wxMAC_USE_CORE_GRAPHICS +static void FreeImageMemoryBufferInstance(void *info, const void *data, size_t size) +{ + delete ((wxMemoryBuffer*)info) ; } -void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType ) +CGImageRef wxBitmapRefData::CGImageCreate() const { - memset( info , 0 , sizeof(ControlButtonContentInfo) ) ; - if ( bitmap.Ok() ) + wxASSERT( m_ok ) ; + wxASSERT( m_rawAccessCount >= 0 ) ; + CGImageRef image ; + if ( m_rawAccessCount > 0 || m_cgImageRef == NULL ) { - wxBitmapRefData * bmap = (wxBitmapRefData*) ( bitmap.GetRefData()) ; - if ( bmap == NULL ) - return ; - - if ( bmap->m_bitmapType == kMacBitmapTypePict ) - { - info->contentType = kControlContentPictHandle ; - info->u.picture = MAC_WXHMETAFILE(bmap->m_hPict) ; - } - else if ( bmap->m_bitmapType == kMacBitmapTypeGrafWorld ) + size_t imageSize = m_width * m_height * 4 ; + void * dataBuffer = m_memBuf.GetData() ; + int w = m_width ; + int h = m_height ; + CGImageAlphaInfo alphaInfo = kCGImageAlphaNoneSkipFirst ; + wxMemoryBuffer* membuf = NULL ; + + if ( m_bitmapMask ) { - if ( (forceType == kControlContentCIconHandle || ( bmap->m_width == bmap->m_height && forceType != kControlContentPictHandle ) ) && ((bmap->m_width & 0x3) == 0) ) - { - info->contentType = kControlContentCIconHandle ; - if ( bitmap.GetMask() ) - { - info->u.cIconHandle = wxMacCreateCIcon( MAC_WXHBITMAP(bmap->m_hBitmap) , MAC_WXHBITMAP(bitmap.GetMask()->GetMaskBitmap()) , - 8 , bmap->m_width ) ; - } - else - { - info->u.cIconHandle = wxMacCreateCIcon( MAC_WXHBITMAP(bmap->m_hBitmap) , NULL , - 8 , bmap->m_width ) ; - } - } - else + membuf = new wxMemoryBuffer( imageSize ) ; + memcpy( membuf->GetData() , dataBuffer , imageSize ) ; + unsigned char *sourcemaskstart = (unsigned char *) m_bitmapMask->GetRawAccess() ; + int maskrowbytes = m_bitmapMask->GetBytesPerRow() ; + unsigned char *destalpha = (unsigned char *) membuf->GetData() ; + alphaInfo = kCGImageAlphaFirst ; + for ( int y = 0 ; y < h ; ++y , sourcemaskstart += maskrowbytes) { - info->contentType = kControlContentPictHandle ; - if ( bitmap.GetMask() ) + unsigned char *sourcemask = sourcemaskstart ; + for( int x = 0 ; x < w ; ++x , sourcemask++ , destalpha += 4 ) { - info->u.picture = wxMacCreatePict( MAC_WXHBITMAP(bmap->m_hBitmap) , MAC_WXHBITMAP(bitmap.GetMask()->GetMaskBitmap() ) ) ; - } - else - { - info->u.picture = wxMacCreatePict( MAC_WXHBITMAP(bmap->m_hBitmap) , NULL ) ; + *destalpha = *sourcemask ; } } } - else if ( bmap->m_bitmapType == kMacBitmapTypeIcon ) + else if ( m_hasAlpha ) { - info->contentType = kControlContentCIconHandle ; - info->u.cIconHandle = MAC_WXHICON(bmap->m_hIcon) ; +#if wxMAC_USE_PREMULTIPLIED_ALPHA + alphaInfo = kCGImageAlphaPremultipliedFirst ; +#else + alphaInfo = kCGImageAlphaFirst ; +#endif + membuf = new wxMemoryBuffer( m_memBuf ) ; } + else + { + membuf = new wxMemoryBuffer( m_memBuf ) ; + } + CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace(); + CGDataProviderRef dataProvider = + CGDataProviderCreateWithData( membuf , (const void *)membuf->GetData() , imageSize, FreeImageMemoryBufferInstance ); + image = + ::CGImageCreate( w, h, 8 , 32 , 4 * m_width , colorSpace, alphaInfo , + dataProvider, NULL , false , kCGRenderingIntentDefault ); + CGDataProviderRelease( dataProvider); + } + else + { + image = m_cgImageRef ; + CGImageRetain( image ) ; } + if ( m_rawAccessCount == 0 && m_cgImageRef == NULL) + { + // we keep it for later use + m_cgImageRef = image ; + CGImageRetain( image ) ; + } + return image ; } +#endif -wxBitmapRefData::wxBitmapRefData() - : m_width(0) - , m_height(0) - , m_depth(0) - , m_ok(FALSE) - , m_numColors(0) - , m_quality(0) -{ - m_bitmapMask = NULL; - m_hBitmap = NULL ; - m_hPict = NULL ; - m_hIcon = NULL ; - m_bitmapType = kMacBitmapTypeUnknownType ; - m_hasAlpha = false; +#if !wxMAC_USE_CORE_GRAPHICS +GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const +{ + wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); + if ( mask ) + { + *mask = NULL ; + if ( m_bitmapMask ) + *mask = (GWorldPtr) m_bitmapMask->GetHBITMAP() ; + else if ( m_hasAlpha ) + { + if ( m_rawAccessCount > 0 ) + UpdateAlphaMask() ; + *mask = m_hMaskBitmap ; + } + } + return m_hBitmap ; } -// TODO move this to a public function of Bitmap Ref -static void DisposeBitmapRefData(wxBitmapRefData *data) +void wxBitmapRefData::UpdateAlphaMask() const { - if ( !data ) - return ; - - switch (data->m_bitmapType) + if ( m_hasAlpha ) { - case kMacBitmapTypePict : - { - if ( data->m_hPict ) - { - KillPicture( MAC_WXHMETAFILE( data->m_hPict ) ) ; - data->m_hPict = NULL ; - } - } - break ; - case kMacBitmapTypeGrafWorld : - { - if ( data->m_hBitmap ) - { - wxMacDestroyGWorld( MAC_WXHBITMAP(data->m_hBitmap) ) ; - data->m_hBitmap = NULL ; - } - } - break ; - case kMacBitmapTypeIcon : - if ( data->m_hIcon ) + unsigned char *sourcemask = (unsigned char *) GetRawAccess() ; + unsigned char *destalphabase = (unsigned char *) m_maskMemBuf.GetData() ; + + int h = GetHeight() ; + int w = GetWidth() ; + + for ( int y = 0 ; y < h ; ++y , destalphabase += m_maskBytesPerRow ) + { + unsigned char* destalpha = destalphabase ; + for( int x = 0 ; x < w ; ++x , sourcemask += 4, ++destalpha ) { - DisposeCIcon( MAC_WXHICON(data->m_hIcon) ) ; - data->m_hIcon = NULL ; + *destalpha = *sourcemask ; } + } + } +} + +#endif - default : - // unkown type ? - break ; +void wxBitmapRefData::Free() +{ + wxASSERT_MSG( m_rawAccessCount == 0 , wxT("Bitmap still selected when destroyed") ) ; + +#if wxMAC_USE_CORE_GRAPHICS + if ( m_cgImageRef ) + { + CGImageRelease( m_cgImageRef ) ; + m_cgImageRef = NULL ; } +#else + if ( m_hBitmap ) + { + DisposeGWorld( MAC_WXHBITMAP(m_hBitmap) ) ; + m_hBitmap = NULL ; + } + if ( m_hMaskBitmap ) + { + DisposeGWorld( MAC_WXHBITMAP(m_hMaskBitmap) ) ; + m_hMaskBitmap = NULL ; + } +#endif - if (data->m_bitmapMask) + if (m_bitmapMask) { - delete data->m_bitmapMask; - data->m_bitmapMask = NULL; + delete m_bitmapMask; + m_bitmapMask = NULL; } } wxBitmapRefData::~wxBitmapRefData() { - DisposeBitmapRefData( this ) ; + Free() ; } bool wxBitmap::CopyFromIcon(const wxIcon& icon) { - Ref(icon) ; + int w = icon.GetWidth() ; + int h = icon.GetHeight() ; + Create( icon.GetWidth() , icon.GetHeight() ) ; + + if ( w == h && w == 32 ) + { + IconFamilyHandle iconFamily = NULL ; + Handle imagehandle = NewHandle(0) ; + Handle maskhandle = NewHandle(0) ; + OSStatus err = ( IconRefToIconFamily( MAC_WXHICON(icon.GetHICON()) , kSelectorLarge32Bit | kSelectorLarge8BitMask , &iconFamily ) ) ; + err =( GetIconFamilyData( iconFamily , kLarge32BitData , imagehandle ) ) ; + err =( GetIconFamilyData( iconFamily , kLarge8BitMask , maskhandle ) ) ; + wxASSERT( GetHandleSize( imagehandle ) == w * 4 * h ) ; + wxASSERT( GetHandleSize( maskhandle ) == w * h ) ; + UseAlpha() ; + unsigned char *source = (unsigned char *) *imagehandle ; + unsigned char *sourcemask = (unsigned char *) *maskhandle ; + + unsigned char* destination = (unsigned char*) BeginRawAccess() ; + for ( int y = 0 ; y < h ; ++y ) + { + for ( int x = 0 ; x < w ; ++x ) + { + *destination++ = *sourcemask++ ; + source++ ; + *destination++ = *source++ ; + *destination++ = *source++ ; + *destination++ = *source++ ; + } + } + EndRawAccess() ; + DisposeHandle( imagehandle ) ; + DisposeHandle( maskhandle ) ; + } + else + { + wxMemoryDC dc ; + dc.SelectObject( *this ) ; + dc.DrawIcon( icon , 0 , 0 ) ; + dc.SelectObject( wxNullBitmap ) ; + } return true; } wxBitmap::wxBitmap() { - m_refData = NULL; } wxBitmap::~wxBitmap() @@ -436,38 +535,16 @@ wxBitmap::~wxBitmap() wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits) { - m_refData = new wxBitmapRefData; + m_refData = new wxBitmapRefData( the_width , the_height , no_bits ) ; - M_BITMAPDATA->m_width = the_width ; - M_BITMAPDATA->m_height = the_height ; - M_BITMAPDATA->m_depth = no_bits ; - M_BITMAPDATA->m_numColors = 0; if ( no_bits == 1 ) { - M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; - M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ; - M_BITMAPDATA->m_ok = (MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) != NULL ) ; - - CGrafPtr origPort ; - GDHandle origDevice ; - - GetGWorld( &origPort , &origDevice ) ; - SetGWorld( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , NULL ) ; - LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) ) ) ; - - // bits is a char array - - unsigned char* linestart = (unsigned char*) bits ; int linesize = ( the_width / (sizeof(unsigned char) * 8)) ; if ( the_width % (sizeof(unsigned char) * 8) ) { linesize += sizeof(unsigned char); } - - RGBColor colors[2] = { - { 0xFFFF , 0xFFFF , 0xFFFF } , - { 0, 0 , 0 } - } ; - + unsigned char* linestart = (unsigned char*) bits ; + unsigned char* destination = (unsigned char*) BeginRawAccess() ; for ( int y = 0 ; y < the_height ; ++y , linestart += linesize ) { for ( int x = 0 ; x < the_width ; ++x ) @@ -477,17 +554,21 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits int mask = 1 << bit ; if ( linestart[index] & mask ) { - SetCPixel( x , y , &colors[1] ) ; + *destination++ = 0xFF ; + *destination++ = 0 ; + *destination++ = 0 ; + *destination++ = 0 ; } else { - SetCPixel( x , y , &colors[0] ) ; + *destination++ = 0xFF ; + *destination++ = 0xFF ; + *destination++ = 0xFF ; + *destination++ = 0xFF ; } } } - UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) ) ) ; - - SetGWorld( origPort , origDevice ) ; + EndRawAccess() ; } else { @@ -510,6 +591,34 @@ wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type) LoadFile(filename, type); } +wxBitmap::wxBitmap(const char **bits) +{ + (void) CreateFromXpm(bits); +} + +wxBitmap::wxBitmap(char **bits) +{ + (void) CreateFromXpm((const char **)bits); +} + +void* wxBitmap::GetRawAccess() const +{ + wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ; + return M_BITMAPDATA->GetRawAccess() ; +} + +void* wxBitmap::BeginRawAccess() +{ + wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ; + return M_BITMAPDATA->BeginRawAccess() ; +} + +void wxBitmap::EndRawAccess() +{ + wxCHECK_RET( Ok() , wxT("invalid bitmap") ) ; + M_BITMAPDATA->EndRawAccess() ; +} + bool wxBitmap::CreateFromXpm(const char **bits) { wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") ) @@ -520,163 +629,80 @@ bool wxBitmap::CreateFromXpm(const char **bits) return TRUE; } -wxBitmap::wxBitmap(const char **bits) -{ - (void) CreateFromXpm(bits); -} - -wxBitmap::wxBitmap(char **bits) +#if wxMAC_USE_CORE_GRAPHICS +WXCGIMAGEREF wxBitmap::CGImageCreate() const { - (void) CreateFromXpm((const char **)bits); + wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ; + return M_BITMAPDATA->CGImageCreate() ; } +#endif wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const { - wxCHECK_MSG( Ok() && + wxCHECK_MSG( Ok() && (rect.x >= 0) && (rect.y >= 0) && (rect.x+rect.width <= GetWidth()) && (rect.y+rect.height <= GetHeight()), wxNullBitmap, wxT("invalid bitmap or bitmap region") ); - wxBitmap ret( rect.width, rect.height, GetDepth() ); - wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") ); - - GWorldPtr origPort; - GDHandle origDevice; + wxBitmap ret( rect.width, rect.height, GetDepth() ); + wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") ); - GetGWorld( &origPort, &origDevice ); - // Update the subbitmaps reference data - wxBitmapRefData *ref = (wxBitmapRefData *)ret.GetRefData(); + int sourcewidth = GetWidth() ; + int destwidth = rect.width ; + int destheight = rect.height ; + { + unsigned char * sourcedata = (unsigned char*) GetRawAccess() ; + unsigned char * destdata = (unsigned char*) ret.BeginRawAccess() ; + int sourcelinesize = sourcewidth * 4 ; + int destlinesize = destwidth * 4 ; + unsigned char *source = sourcedata + rect.x * 4 + rect.y * sourcelinesize ; + unsigned char *dest = destdata ; + for(int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize) + { + memcpy( dest , source , destlinesize ) ; + } + } + ret.EndRawAccess() ; + + if ( M_BITMAPDATA->m_bitmapMask ) + { + wxMemoryBuffer maskbuf ; + int rowBytes = ( destwidth + 3 ) & 0xFFFFFFC ; + size_t maskbufsize = rowBytes * destheight ; + unsigned char * destdata = (unsigned char * ) maskbuf.GetWriteBuf( maskbufsize ) ; + + int sourcelinesize = M_BITMAPDATA->m_bitmapMask->GetBytesPerRow() ; + int destlinesize = rowBytes ; + unsigned char *source = (unsigned char *) M_BITMAPDATA->m_bitmapMask->GetRawAccess() ; + source += rect.x + rect.y * sourcelinesize ; + unsigned char *dest = destdata ; + + for(int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize) + { + memcpy( dest , source , destlinesize ) ; + } + maskbuf.UngetWriteBuf( maskbufsize ) ; + ret.SetMask( new wxMask( maskbuf , destwidth , destheight , rowBytes ) ) ; + } + else if ( HasAlpha() ) + ret.UseAlpha() ; - ref->m_numColors = M_BITMAPDATA->m_numColors; -#if wxUSE_PALETTE - ref->m_bitmapPalette = M_BITMAPDATA->m_bitmapPalette; -#endif // wxUSE_PALETTE - ref->m_bitmapType = M_BITMAPDATA->m_bitmapType; - - // Copy sub region of this bitmap - if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) - { - printf("GetSubBitmap: Copy a region of a Pict structure - TODO\n"); - } - else if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypeGrafWorld) - { - // Copy mask - if(GetMask()) - { - GWorldPtr submask, mask; - RGBColor color; - - mask = (GWorldPtr) GetMask()->GetMaskBitmap(); - submask = wxMacCreateGWorld(rect.width, rect.height, GetMask()->GetDepth() ); - LockPixels(GetGWorldPixMap(mask)); - LockPixels(GetGWorldPixMap(submask)); - - for(int yy = 0; yy < rect.height; yy++) - { - for(int xx = 0; xx < rect.width; xx++) - { - SetGWorld(mask, NULL); - GetCPixel(rect.x + xx, rect.y + yy, &color); - SetGWorld(submask, NULL); - SetCPixel(xx,yy, &color); - } - } - UnlockPixels(GetGWorldPixMap(mask)); - UnlockPixels(GetGWorldPixMap(submask)); - ref->m_bitmapMask = new wxMask; - ref->m_bitmapMask->SetMaskBitmap(submask); - } - - // Copy bitmap - if(GetHBITMAP()) - { - GWorldPtr subbitmap, bitmap; - RGBColor color; - - bitmap = (GWorldPtr) GetHBITMAP(); - subbitmap = (GWorldPtr) ref->m_hBitmap ; - LockPixels(GetGWorldPixMap(bitmap)); - LockPixels(GetGWorldPixMap(subbitmap)); - - for(int yy = 0; yy < rect.height; yy++) - { - for(int xx = 0; xx < rect.width; xx++) - { - SetGWorld(bitmap, NULL); - GetCPixel(rect.x + xx, rect.y + yy, &color); - SetGWorld(subbitmap, NULL); - SetCPixel(xx, yy, &color); - } - } - UnlockPixels(GetGWorldPixMap(bitmap)); - UnlockPixels(GetGWorldPixMap(subbitmap)); - } - } - SetGWorld( origPort, origDevice ); - - return ret; + return ret; } bool wxBitmap::Create(int w, int h, int d) { UnRef(); - m_refData = new wxBitmapRefData; - - M_BITMAPDATA->m_width = w; - M_BITMAPDATA->m_height = h; - M_BITMAPDATA->m_depth = d; - - M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; - M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( w , h , d ) ; - M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ; - return M_BITMAPDATA->m_ok; -} - -int wxBitmap::GetBitmapType() const -{ - wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType, wxT("invalid bitmap") ); - - return M_BITMAPDATA->m_bitmapType; -} - -void wxBitmap::SetHBITMAP(WXHBITMAP bmp) -{ - if (!M_BITMAPDATA) - m_refData = new wxBitmapRefData; - else - DisposeBitmapRefData( M_BITMAPDATA ) ; - - M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; - M_BITMAPDATA->m_hBitmap = bmp ; - M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ; -} + if ( d < 0 ) + d = wxDisplayDepth() ; -void wxBitmap::SetHICON(WXHICON ico) -{ - if (!M_BITMAPDATA) - m_refData = new wxBitmapRefData; - else - DisposeBitmapRefData( M_BITMAPDATA ) ; + m_refData = new wxBitmapRefData( w , h , d ); - M_BITMAPDATA->m_bitmapType = kMacBitmapTypeIcon ; - M_BITMAPDATA->m_hIcon = ico ; - M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hIcon != NULL ) ; -} - -void wxBitmap::SetPict(WXHMETAFILE pict) -{ - if (!M_BITMAPDATA) - m_refData = new wxBitmapRefData; - else - DisposeBitmapRefData( M_BITMAPDATA ) ; - - M_BITMAPDATA->m_bitmapType = kMacBitmapTypePict ; - M_BITMAPDATA->m_hPict = pict ; - M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hPict != NULL ) ; + return M_BITMAPDATA->Ok() ; } bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) @@ -724,101 +750,64 @@ wxBitmap::wxBitmap(const wxImage& image, int depth) { wxCHECK_RET( image.Ok(), wxT("invalid image") ) - m_refData = new wxBitmapRefData(); - // width and height of the device-dependent bitmap int width = image.GetWidth(); int height = image.GetHeight(); - // Create picture - - Create( width , height , 32 ) ; + m_refData = new wxBitmapRefData( width , height , depth ) ;; - CGrafPtr origPort ; - GDHandle origDevice ; - - PixMapHandle pixMap = GetGWorldPixMap((GWorldPtr)GetHBITMAP()) ; - LockPixels( pixMap ); + // Create picture - GetGWorld( &origPort , &origDevice ) ; - SetGWorld( (GWorldPtr) GetHBITMAP() , NULL ) ; + bool hasAlpha = false ; + + if ( image.HasMask() ) + { + // takes precedence, don't mix with alpha info + } + else + { + hasAlpha = image.HasAlpha() ; + } + + if ( hasAlpha ) + UseAlpha() ; + + unsigned char* destination = (unsigned char*) BeginRawAccess() ; - // Render image register unsigned char* data = image.GetData(); - char* destinationBase = GetPixBaseAddr( pixMap ); - register unsigned char* destination = (unsigned char*) destinationBase ; + const unsigned char *alpha = hasAlpha ? image.GetAlpha() : NULL ; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { - *destination++ = 0 ; - *destination++ = *data++ ; - *destination++ = *data++ ; - *destination++ = *data++ ; + if ( hasAlpha ) + { + const unsigned char a = *alpha++; + *destination++ = a ; +#if wxMAC_USE_PREMULTIPLIED_ALPHA + *destination++ = ((*data++) * a + 127 ) / 255 ; + *destination++ = ((*data++) * a + 127 ) / 255 ; + *destination++ = ((*data++) * a + 127 ) / 255 ; +#else + *destination++ = *data++ ; + *destination++ = *data++ ; + *destination++ = *data++ ; +#endif + } + else + { + *destination++ = 0xFF ; + *destination++ = *data++ ; + *destination++ = *data++ ; + *destination++ = *data++ ; + } } - destinationBase += ((**pixMap).rowBytes & 0x7fff); - destination = (unsigned char*) destinationBase ; } - if ( image.HasAlpha() ) + EndRawAccess() ; + if ( image.HasMask() ) { - unsigned char *alpha = image.GetAlpha(); - - wxColour maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue()); - RGBColor color ; - wxBitmap maskBitmap ; - - maskBitmap.Create( width, height, 24); - LockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) ); - SetGWorld( (GWorldPtr) maskBitmap.GetHBITMAP(), NULL); - - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - memset( &color , 255 - *alpha , sizeof( color ) ); - SetCPixel(x,y, &color); - - alpha += 1 ; - } - } // for height - SetGWorld( (GWorldPtr) GetHBITMAP(), NULL); - SetMask(new wxMask( maskBitmap )); - UnlockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) ); + SetMask( new wxMask( *this , wxColour( image.GetMaskRed() , image.GetMaskGreen() , image.GetMaskBlue() ) ) ) ; } - else if ( image.HasMask() ) - { - data = image.GetData(); - - wxColour maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue()); - RGBColor white = { 0xffff, 0xffff, 0xffff }; - RGBColor black = { 0 , 0 , 0 }; - wxBitmap maskBitmap ; - - maskBitmap.Create( width, height, 1); - LockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) ); - SetGWorld( (GWorldPtr) maskBitmap.GetHBITMAP(), NULL); - - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - if ( data[0] == image.GetMaskRed() && data[1] == image.GetMaskGreen() && data[2] == image.GetMaskBlue() ) - { - SetCPixel(x,y, &white); - } - else { - SetCPixel(x,y, &black); - } - data += 3 ; - } - } // for height - SetGWorld( (GWorldPtr) GetHBITMAP(), NULL); - SetMask(new wxMask( maskBitmap )); - UnlockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) ); - } - - UnlockPixels( GetGWorldPixMap( (GWorldPtr) GetHBITMAP()) ); - SetGWorld( origPort, origDevice ); } wxImage wxBitmap::ConvertToImage() const @@ -833,101 +822,75 @@ wxImage wxBitmap::ConvertToImage() const image.Create( width, height ); unsigned char *data = image.GetData(); - wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") ); - GWorldPtr origPort; - GDHandle origDevice; - RgnHandle maskRgn = NULL ; - GWorldPtr tempPort = NULL ; - int index; - RGBColor color; - // background color set to RGB(16,16,16) in consistent with wxGTK - unsigned char mask_r=16, mask_g=16, mask_b=16; - SInt16 r,g,b; - wxMask *mask = GetMask(); - - GetGWorld( &origPort, &origDevice ); - if ( GetBitmapType() != kMacBitmapTypeGrafWorld ) + unsigned char* source = (unsigned char*) GetRawAccess() ; + + bool hasAlpha = false ; + bool hasMask = false ; + unsigned char *alpha = NULL ; + unsigned char *mask = NULL ; + if ( HasAlpha() ) { - tempPort = wxMacCreateGWorld( width , height , -1) ; + hasAlpha = true ; } - else + + if ( GetMask() ) { - tempPort = (GWorldPtr) GetHBITMAP() ; + hasMask = true ; + mask = (unsigned char*) GetMask()->GetRawAccess() ; } - LockPixels(GetGWorldPixMap(tempPort)); - SetGWorld( tempPort, NULL); - if ( GetBitmapType() == kMacBitmapTypePict || GetBitmapType() == kMacBitmapTypeIcon ) + + if ( hasAlpha ) { - Rect bitmaprect = { 0 , 0 , height, width }; - if ( GetBitmapType() == kMacBitmapTypeIcon ) - { - ::PlotCIconHandle( &bitmaprect , atNone , ttNone , MAC_WXHICON(GetHICON()) ) ; - maskRgn = NewRgn() ; - BitMapToRegion( maskRgn , &(**(MAC_WXHICON(GetHICON()))).iconMask ) ; - } - else - ::DrawPicture( (PicHandle) GetPict(), &bitmaprect ) ; + image.SetAlpha() ; + alpha = image.GetAlpha() ; } - // Copy data into image - index = 0; + int index = 0; + + // The following masking algorithm is the same as well in msw/gtk: + // the colour used as transparent one in wxImage and the one it is + // replaced with when it really occurs in the bitmap + static const int MASK_RED = 1; + static const int MASK_GREEN = 2; + static const int MASK_BLUE = 3; + static const int MASK_BLUE_REPLACEMENT = 2; + for (int yy = 0; yy < height; yy++) { for (int xx = 0; xx < width; xx++) { - GetCPixel(xx,yy, &color); - r = ((color.red ) >> 8); - g = ((color.green ) >> 8); - b = ((color.blue ) >> 8); - data[index ] = r; - data[index + 1] = g; - data[index + 2] = b; - if ( maskRgn ) + long color = *((long*) source) ; + unsigned char a = ((color&0xFF000000) >> 24) ; + unsigned char r = ((color&0x00FF0000) >> 16) ; + unsigned char g = ((color&0x0000FF00) >> 8) ; + unsigned char b = (color&0x000000FF); + if ( hasMask ) { - Point pt ; - pt.h = xx ; - pt.v = yy ; - if ( !PtInRgn( pt , maskRgn ) ) + if ( *mask++ == 0 ) { - data[index ] = mask_r; - data[index + 1] = mask_g; - data[index + 2] = mask_b; + if ( r == MASK_RED && g == MASK_GREEN && b == MASK_BLUE ) + b = MASK_BLUE_REPLACEMENT ; } - } - else - { - if (mask) + else { - if (mask->PointMasked(xx,yy)) - { - data[index ] = mask_r; - data[index + 1] = mask_g; - data[index + 2] = mask_b; - } + r = MASK_RED ; + g = MASK_GREEN ; + b = MASK_BLUE ; } } + else if ( hasAlpha ) + *alpha++ = a ; + + data[index ] = r ; + data[index + 1] = g ; + data[index + 2] = b ; index += 3; + source += 4 ; } } - if (mask || maskRgn ) - { - image.SetMaskColour( mask_r, mask_g, mask_b ); - image.SetMask( true ); - } - - // Free resources - UnlockPixels(GetGWorldPixMap( tempPort )); - SetGWorld(origPort, origDevice); - if ( GetBitmapType() != kMacBitmapTypeGrafWorld ) - { - wxMacDestroyGWorld( tempPort ) ; - } - if ( maskRgn ) - { - DisposeRgn( maskRgn ) ; - } - + if ( hasMask ) + image.SetMaskColour( MASK_RED, MASK_GREEN, MASK_BLUE ); return image; } @@ -954,35 +917,33 @@ bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, bool wxBitmap::Ok() const { - return (M_BITMAPDATA && M_BITMAPDATA->m_ok); + return (M_BITMAPDATA && M_BITMAPDATA->Ok()); } int wxBitmap::GetHeight() const { wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); - return M_BITMAPDATA->m_height; + return M_BITMAPDATA->GetHeight(); } int wxBitmap::GetWidth() const { wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); - return M_BITMAPDATA->m_width; + return M_BITMAPDATA->GetWidth() ; } int wxBitmap::GetDepth() const { wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); - return M_BITMAPDATA->m_depth; + return M_BITMAPDATA->GetDepth(); } int wxBitmap::GetQuality() const { - wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); - - return M_BITMAPDATA->m_quality; + return 0; } wxMask *wxBitmap::GetMask() const @@ -992,12 +953,19 @@ wxMask *wxBitmap::GetMask() const return M_BITMAPDATA->m_bitmapMask; } +bool wxBitmap::HasAlpha() const +{ + wxCHECK_MSG( Ok(), false , wxT("invalid bitmap") ); + + return M_BITMAPDATA->HasAlpha() ; +} + void wxBitmap::SetWidth(int w) { if (!M_BITMAPDATA) m_refData = new wxBitmapRefData; - M_BITMAPDATA->m_width = w; + M_BITMAPDATA->SetWidth(w); } void wxBitmap::SetHeight(int h) @@ -1005,7 +973,7 @@ void wxBitmap::SetHeight(int h) if (!M_BITMAPDATA) m_refData = new wxBitmapRefData; - M_BITMAPDATA->m_height = h; + M_BITMAPDATA->SetHeight(h); } void wxBitmap::SetDepth(int d) @@ -1013,15 +981,11 @@ void wxBitmap::SetDepth(int d) if (!M_BITMAPDATA) m_refData = new wxBitmapRefData; - M_BITMAPDATA->m_depth = d; + M_BITMAPDATA->SetDepth(d); } -void wxBitmap::SetQuality(int q) +void wxBitmap::SetQuality(int WXUNUSED(quality)) { - if (!M_BITMAPDATA) - m_refData = new wxBitmapRefData; - - M_BITMAPDATA->m_quality = q; } void wxBitmap::SetOk(bool isOk) @@ -1029,7 +993,7 @@ void wxBitmap::SetOk(bool isOk) if (!M_BITMAPDATA) m_refData = new wxBitmapRefData; - M_BITMAPDATA->m_ok = isOk; + M_BITMAPDATA->SetOk(isOk); } #if wxUSE_PALETTE @@ -1060,202 +1024,167 @@ void wxBitmap::SetMask(wxMask *mask) M_BITMAPDATA->m_bitmapMask = mask ; } -WXHBITMAP wxBitmap::GetHBITMAP() const +#if !wxMAC_USE_CORE_GRAPHICS +WXHBITMAP wxBitmap::GetHBITMAP(WXHBITMAP* mask) const { - wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); - - return MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap); -} - -WXHMETAFILE wxBitmap::GetPict( bool *created ) const -{ - wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); - - PicHandle picture = NULL ; // This is the returned picture - if ( created ) - (*created) = false ; - // If bitmap already in Pict format return pointer - if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) { - return M_BITMAPDATA->m_hPict; - } - else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) { - // Invalid bitmap - return NULL; - } - else - { - if ( GetMask() ) - { - picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , MAC_WXHBITMAP(GetMask()->GetMaskBitmap() ) ) ; - } - else - { - picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , NULL ) ; - } - if ( created && picture ) - (*created) = true ; - } - return picture ; + return WXHBITMAP(M_BITMAPDATA->GetHBITMAP((GWorldPtr*)mask)); } +#endif -/* - * wxMask - */ +// ---------------------------------------------------------------------------- +// wxMask +// ---------------------------------------------------------------------------- wxMask::wxMask() - : m_maskBitmap(NULL) { + Init() ; } // Construct a mask from a bitmap and a colour indicating // the transparent area wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour) - : m_maskBitmap(NULL) { + Init() ; Create(bitmap, colour); } -// Construct a mask from a bitmap and a palette index indicating -// the transparent area -wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) - : m_maskBitmap(NULL) +// Construct a mask from a mono bitmap (copies the bitmap). +wxMask::wxMask(const wxBitmap& bitmap) { - Create(bitmap, paletteIndex); + Init() ; + Create(bitmap); } // Construct a mask from a mono bitmap (copies the bitmap). -wxMask::wxMask(const wxBitmap& bitmap) - : m_maskBitmap(NULL) +wxMask::wxMask(const wxMemoryBuffer& data, int width , int height , int bytesPerRow ) { - Create(bitmap); + Init() ; + Create(data, width , height , bytesPerRow ); } wxMask::~wxMask() { +#if !wxMAC_USE_CORE_GRAPHICS if ( m_maskBitmap ) { - wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ; + DisposeGWorld( (GWorldPtr) m_maskBitmap ) ; m_maskBitmap = NULL ; } +#endif } -// Create a mask from a mono bitmap (copies the bitmap). -bool wxMask::Create(const wxBitmap& bitmap) +void wxMask::Init() { - if ( m_maskBitmap ) - { - wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ; - m_maskBitmap = NULL ; - } - wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false, - wxT("Cannot create mask from this bitmap type (TODO)")); - // other types would require a temporary bitmap. not yet implemented - - wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid bitmap")); + m_width = m_height = m_bytesPerRow = 0 ; +#if !wxMAC_USE_CORE_GRAPHICS + m_maskBitmap = NULL ; +#endif + +} - m_depth = bitmap.GetDepth() ; - m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), bitmap.GetDepth() ); - Rect rect = { 0,0, bitmap.GetHeight(), bitmap.GetWidth() }; +void *wxMask::GetRawAccess() const +{ + return m_memBuf.GetData() ; +} - LockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap) ); - LockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP()) ); - CopyBits(GetPortBitMapForCopyBits( (GWorldPtr) bitmap.GetHBITMAP()), - GetPortBitMapForCopyBits( (GWorldPtr) m_maskBitmap), - &rect, &rect, srcCopy, 0); - UnlockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap) ); - UnlockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP()) ); +void wxMask::RealizeNative() +{ +#if !wxMAC_USE_CORE_GRAPHICS + if ( m_maskBitmap ) + { + DisposeGWorld( (GWorldPtr) m_maskBitmap ) ; + m_maskBitmap = NULL ; + } + Rect rect = { 0 , 0 , m_height , m_width } ; + verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_maskBitmap , k8IndexedGrayPixelFormat , &rect , NULL , NULL , 0 , + (char*) m_memBuf.GetData() , m_bytesPerRow ) ) ; +#endif +} - return FALSE; +// Create a mask from a mono bitmap (copies the bitmap). +bool wxMask::Create(const wxMemoryBuffer& data,int width , int height , int bytesPerRow) +{ + m_memBuf = data ; + m_width = width ; + m_height = height ; + m_bytesPerRow = bytesPerRow ; + wxASSERT( data.GetDataLen() == (size_t)(height * bytesPerRow) ) ; + RealizeNative() ; + return true ; } -// Create a mask from a bitmap and a palette index indicating -// the transparent area -bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) +// Create a mask from a mono bitmap (copies the bitmap). +bool wxMask::Create(const wxBitmap& bitmap) { - // TODO - wxCHECK_MSG( 0, false, wxT("wxMask::Create not yet implemented")); - return FALSE; + m_width = bitmap.GetWidth() ; + m_height = bitmap.GetHeight() ; + m_bytesPerRow = ( m_width + 3 ) & 0xFFFFFFC ; + size_t size = m_bytesPerRow * m_height ; + unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ; + memset( destdatabase , 0 , size ) ; + unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ; + for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow ) + { + unsigned char *destdata= destdatabase ; + for( int x = 0 ; x < m_width ; ++x ) + { + srcdata++ ; + unsigned char r = *srcdata++ ; + unsigned char g = *srcdata++ ; + unsigned char b = *srcdata++ ; + if ( ( r + g + b ) > 0x10 ) + *destdata++ = 0x00 ; + else + *destdata++ = 0xFF ; + } + } + m_memBuf.UngetWriteBuf( size ) ; + RealizeNative() ; + return TRUE; } // Create a mask from a bitmap and a colour indicating // the transparent area bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) { - if ( m_maskBitmap ) - { - wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ; - m_maskBitmap = NULL ; - } - wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false, - wxT("Cannot create mask from this bitmap type (TODO)")); - // other types would require a temporary bitmap. not yet implemented - - wxCHECK_MSG( bitmap.Ok(), false, wxT("Illigal bitmap")); - - m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 ); - m_depth = 1 ; - LockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap ) ); - LockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP() ) ); - RGBColor maskColor = MAC_WXCOLORREF(colour.GetPixel()); - - // this is not very efficient, but I can't think - // of a better way of doing it - CGrafPtr origPort ; - GDHandle origDevice ; - RGBColor col; - RGBColor colors[2] = { - { 0xFFFF, 0xFFFF, 0xFFFF }, - { 0, 0, 0 }}; - - GetGWorld( &origPort , &origDevice ) ; - for (int w = 0; w < bitmap.GetWidth(); w++) + m_width = bitmap.GetWidth() ; + m_height = bitmap.GetHeight() ; + m_bytesPerRow = ( m_width + 3 ) & 0xFFFFFFC ; + size_t size = m_bytesPerRow * m_height ; + + unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ; + memset( destdatabase , 0 , size ) ; + unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ; + for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow) { - for (int h = 0; h < bitmap.GetHeight(); h++) + unsigned char *destdata= destdatabase ; + for( int x = 0 ; x < m_width ; ++x ) { - SetGWorld( (GWorldPtr) bitmap.GetHBITMAP(), NULL ) ; - GetCPixel( w , h , &col ) ; - SetGWorld( (GWorldPtr) m_maskBitmap , NULL ) ; - if (col.red == maskColor.red && col.green == maskColor.green && col.blue == maskColor.blue) - { - SetCPixel( w , h , &colors[0] ) ; - } + srcdata++ ; + unsigned char r = *srcdata++ ; + unsigned char g = *srcdata++ ; + unsigned char b = *srcdata++ ; + if ( colour == wxColour( r , g , b) ) + *destdata++ = 0x00 ; else - { - SetCPixel( w , h , &colors[1] ) ; - } + *destdata++ = 0xFF ; } } - UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ; - UnlockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP() ) ) ; - SetGWorld( origPort , origDevice ) ; - + m_memBuf.UngetWriteBuf( size ) ; + RealizeNative() ; return TRUE; } -bool wxMask::PointMasked(int x, int y) +#if !wxMAC_USE_CORE_GRAPHICS +WXHBITMAP wxMask::GetHBITMAP() const { - GWorldPtr origPort; - GDHandle origDevice; - RGBColor color; - bool masked = true; - - GetGWorld( &origPort, &origDevice); - - //Set port to mask and see if it masked (1) or not ( 0 ) - SetGWorld( (GWorldPtr) m_maskBitmap, NULL); - LockPixels(GetGWorldPixMap( (GWorldPtr) m_maskBitmap)); - GetCPixel(x,y, &color); - masked = !(color.red == 0 && color.green == 0 && color.blue == 0); - UnlockPixels(GetGWorldPixMap( (GWorldPtr) m_maskBitmap)); - - SetGWorld( origPort, origDevice); - - return masked; + return m_maskBitmap ; } +#endif -/* - * wxBitmapHandler - */ +// ---------------------------------------------------------------------------- +// wxBitmapHandler +// ---------------------------------------------------------------------------- wxBitmapHandler::~wxBitmapHandler() { @@ -1277,9 +1206,9 @@ bool wxBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int return FALSE; } -/* - * Standard handlers - */ +// ---------------------------------------------------------------------------- +// Standard Handlers +// ---------------------------------------------------------------------------- class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler { @@ -1306,20 +1235,13 @@ bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, lo PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ; if ( thePict ) { - PictInfo theInfo ; - - GetPictInfo( thePict , &theInfo , 0 , 0 , systemMethod , 0 ) ; - DetachResource( (Handle) thePict ) ; - M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypePict ; - M_BITMAPHANDLERDATA->m_hPict = thePict ; - M_BITMAPHANDLERDATA->m_width = theInfo.sourceRect.right - theInfo.sourceRect.left ; - M_BITMAPHANDLERDATA->m_height = theInfo.sourceRect.bottom - theInfo.sourceRect.top ; - - M_BITMAPHANDLERDATA->m_depth = theInfo.depth ; - M_BITMAPHANDLERDATA->m_ok = true ; - M_BITMAPHANDLERDATA->m_numColors = theInfo.uniqueColors ; -// M_BITMAPHANDLERDATA->m_bitmapPalette; -// M_BITMAPHANDLERDATA->m_quality; + wxMetafile mf ; + mf.SetHMETAFILE((WXHMETAFILE) thePict ) ; + bitmap->Create( mf.GetWidth() , mf.GetHeight() ) ; + wxMemoryDC dc ; + dc.SelectObject( *bitmap ) ; + mf.Play( &dc ) ; + dc.SelectObject( wxNullBitmap ) ; return TRUE ; } return FALSE ; @@ -1343,35 +1265,10 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp) return NULL; } - if ( M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld ) - { - wxFAIL_MSG( _T("GetRawData() only supported for GWorlds") ); - - return NULL; - } - - GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap); - PixMapHandle hPixMap = GetGWorldPixMap(gworld); - wxCHECK_MSG( hPixMap && *hPixMap, NULL, - _T("GetRawData(): failed to get PixMap from GWorld?") ); - - wxCHECK_MSG( (*hPixMap)->pixelSize == bpp, NULL, - _T("GetRawData(): pixel format mismatch") ); - - if ( !LockPixels(hPixMap) ) - { - wxFAIL_MSG( _T("failed to lock PixMap in GetRawData()") ); - - return NULL; - } - - data.m_width = GetWidth(); - data.m_height = GetHeight(); - data.m_stride = (*hPixMap)->rowBytes & 0x7fff; - - M_BITMAPDATA->m_hasAlpha = false; - - return GetPixBaseAddr(hPixMap); + data.m_width = GetWidth() ; + data.m_height = GetHeight() ; + data.m_stride = GetWidth() * 4 ; + return GetRawAccess() ; } void wxBitmap::UngetRawData(wxPixelDataBase& dataBase) @@ -1379,7 +1276,10 @@ void wxBitmap::UngetRawData(wxPixelDataBase& dataBase) if ( !Ok() ) return; - if ( M_BITMAPDATA->m_hasAlpha ) + // TODO : if we have some information about the API we should check + // this code looks strange... + + if ( M_BITMAPDATA->HasAlpha() ) { wxAlphaPixelData& data = (wxAlphaPixelData&)dataBase; @@ -1417,19 +1317,11 @@ void wxBitmap::UngetRawData(wxPixelDataBase& dataBase) SetMask(new wxMask(bmpMask)); } - - GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap); - PixMapHandle hPixMap = GetGWorldPixMap(gworld); - if ( hPixMap ) - { - UnlockPixels(hPixMap); - } } void wxBitmap::UseAlpha() { // remember that we are using alpha channel, we'll need to create a proper // mask in UngetRawData() - M_BITMAPDATA->m_hasAlpha = true; + M_BITMAPDATA->UseAlpha( true ); } - diff --git a/src/mac/carbon/bmpbuttn.cpp b/src/mac/carbon/bmpbuttn.cpp index 6f8bd14088..9d944f40b5 100644 --- a/src/mac/carbon/bmpbuttn.cpp +++ b/src/mac/carbon/bmpbuttn.cpp @@ -65,12 +65,7 @@ bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxBitmap& bit } m_bmpNormal = bitmap; - - wxBitmapRefData * bmap = NULL ; - - if ( m_bmpNormal.Ok() ) - bmap = (wxBitmapRefData*) ( m_bmpNormal.GetRefData()) ; - + ControlButtonContentInfo info ; wxMacCreateBitmapButton( &info , m_bmpNormal ) ; @@ -80,7 +75,7 @@ bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxBitmap& bit (( style & wxBU_AUTODRAW ) ? kControlBevelButtonSmallBevel : kControlBevelButtonNormalBevel ) , kControlBehaviorOffsetContents , &info , 0 , 0 , 0 , m_peer->GetControlRefAddr() ) ); - + wxMacReleaseBitmapButton( &info ) ; wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ; MacPostControlCreate(pos,size) ; @@ -99,6 +94,7 @@ void wxBitmapButton::SetBitmapLabel(const wxBitmap& bitmap) { m_peer->SetData( kControlButtonPart , kControlBevelButtonContentTag , info ) ; } + wxMacReleaseBitmapButton( &info ) ; } diff --git a/src/mac/carbon/cursor.cpp b/src/mac/carbon/cursor.cpp index 839673c2dd..8c6d751197 100644 --- a/src/mac/carbon/cursor.cpp +++ b/src/mac/carbon/cursor.cpp @@ -27,6 +27,27 @@ IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap) #endif +class WXDLLEXPORT wxCursorRefData: public wxBitmapRefData +{ + DECLARE_NO_COPY_CLASS(wxCursorRefData) + + friend class WXDLLEXPORT wxBitmap; + friend class WXDLLEXPORT wxCursor; +public: + wxCursorRefData(); + ~wxCursorRefData(); + +protected: + WXHCURSOR m_hCursor; + bool m_disposeHandle; + bool m_releaseHandle; + bool m_isColorCursor ; + long m_themeCursor ; +}; + +#define M_CURSORDATA ((wxCursorRefData *)m_refData) +#define M_CURSORHANDLERDATA ((wxCursorRefData *)bitmap->m_refData) + const short kwxCursorBullseye = 0 ; const short kwxCursorBlank = 1 ; const short kwxCursorPencil = 2 ; @@ -181,8 +202,8 @@ CursHandle wxGetStockCursor( int number ) wxCursorRefData::wxCursorRefData() { - m_width = 16; - m_height = 16; + SetWidth( 16 ); + SetHeight( 16 ); m_hCursor = NULL ; m_disposeHandle = false ; m_releaseHandle = false ; @@ -242,6 +263,16 @@ bool wxCursor::CreateFromXpm(const char **bits) return TRUE; } +WXHCURSOR wxCursor::GetHCURSOR() const +{ + return (M_CURSORDATA ? M_CURSORDATA->m_hCursor : 0); +} + +bool wxCursor::Ok() const +{ + return (m_refData != NULL && ( M_CURSORDATA->m_hCursor != NULL || M_CURSORDATA->m_themeCursor != -1 ) ) ; +} + short GetCTabIndex( CTabHandle colors , RGBColor *col ) { short retval = 0 ; diff --git a/src/mac/carbon/dataobj.cpp b/src/mac/carbon/dataobj.cpp index c7f7eb3961..234f49899a 100644 --- a/src/mac/carbon/dataobj.cpp +++ b/src/mac/carbon/dataobj.cpp @@ -250,7 +250,9 @@ wxBitmapDataObject::wxBitmapDataObject( Init(); if ( m_bitmap.Ok() ) { - m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ; + /* + m_pictHandle = m_bitmap.GetBitmapData()->GetPict( &m_pictCreated ) ; + */ } } @@ -267,7 +269,9 @@ void wxBitmapDataObject::SetBitmap( wxBitmapDataObjectBase::SetBitmap(rBitmap); if ( m_bitmap.Ok() ) { - m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ; + /* + m_pictHandle = m_bitmap.GetBitmapData()->GetPict( &m_pictCreated ) ; + */ } } @@ -313,11 +317,13 @@ bool wxBitmapDataObject::SetData( PicHandle picHandle = (PicHandle) NewHandle( nSize ) ; memcpy( *picHandle , pBuf , nSize ) ; m_pictHandle = picHandle ; + // ownership is transferred to the bitmap m_pictCreated = false ; Rect frame = (**picHandle).picFrame ; - - m_bitmap.SetPict( picHandle ) ; + /* + m_bitmap.GetBitmapData()->SetPict( (WXHMETAFILE) picHandle ) ; m_bitmap.SetWidth( frame.right - frame.left ) ; m_bitmap.SetHeight( frame.bottom - frame.top ) ; + */ return m_bitmap.Ok(); } diff --git a/src/mac/carbon/dc.cpp b/src/mac/carbon/dc.cpp index 98de588c51..da8c9f138b 100644 --- a/src/mac/carbon/dc.cpp +++ b/src/mac/carbon/dc.cpp @@ -16,6 +16,8 @@ #include "wx/wxprec.h" #include "wx/dc.h" + +#if !wxMAC_USE_CORE_GRAPHICS #include "wx/app.h" #include "wx/mac/uma.h" #include "wx/dcmemory.h" @@ -285,11 +287,6 @@ wxDC::~wxDC(void) DisposeRgn( (RgnHandle) m_macCurrentClipRgn ) ; } -void wxDC::MacSetupGraphicContext() -{ - // no-op for QuickDraw -} - void wxDC::MacSetupPort(wxMacPortStateHelper* help) const { #ifdef __WXDEBUG__ @@ -360,62 +357,51 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask //m_logicalFunction == wxSRC_OR ? srcOr : //m_logicalFunction == wxSRC_AND ? SRCAND : srcCopy ); - if ( bmp.GetBitmapType() == kMacBitmapTypePict ) { - Rect bitmaprect = { 0 , 0 , hh, ww }; - ::OffsetRect( &bitmaprect, xx, yy ) ; - ::DrawPicture( (PicHandle) bmp.GetPict(), &bitmaprect ) ; - } - else if ( bmp.GetBitmapType() == kMacBitmapTypeGrafWorld ) + + GWorldPtr maskworld = NULL ; + GWorldPtr bmapworld = MAC_WXHBITMAP( bmp.GetHBITMAP((WXHBITMAP*)&maskworld) ); + PixMapHandle bmappixels ; + // Set foreground and background colours (for bitmaps depth = 1) + if(bmp.GetDepth() == 1) + { + RGBColor fore = MAC_WXCOLORREF(m_textForegroundColour.GetPixel()); + RGBColor back = MAC_WXCOLORREF(m_textBackgroundColour.GetPixel()); + RGBForeColor(&fore); + RGBBackColor(&back); + } + else { - GWorldPtr bmapworld = MAC_WXHBITMAP( bmp.GetHBITMAP() ); - PixMapHandle bmappixels ; - // Set foreground and background colours (for bitmaps depth = 1) - if(bmp.GetDepth() == 1) - { - RGBColor fore = MAC_WXCOLORREF(m_textForegroundColour.GetPixel()); - RGBColor back = MAC_WXCOLORREF(m_textBackgroundColour.GetPixel()); - RGBForeColor(&fore); - RGBBackColor(&back); - } - else - { - RGBColor white = { 0xFFFF, 0xFFFF,0xFFFF} ; - RGBColor black = { 0,0,0} ; - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - } - bmappixels = GetGWorldPixMap( bmapworld ) ; - wxCHECK_RET(LockPixels(bmappixels), - wxT("DoDrawBitmap: Unable to lock pixels")); - Rect source = { 0, 0, h, w }; - Rect dest = { yy, xx, yy + hh, xx + ww }; - if ( useMask && bmp.GetMask() ) + RGBColor white = { 0xFFFF, 0xFFFF,0xFFFF} ; + RGBColor black = { 0,0,0} ; + RGBForeColor( &black ) ; + RGBBackColor( &white ) ; + } + bmappixels = GetGWorldPixMap( bmapworld ) ; + wxCHECK_RET(LockPixels(bmappixels), + wxT("DoDrawBitmap: Unable to lock pixels")); + Rect source = { 0, 0, h, w }; + Rect dest = { yy, xx, yy + hh, xx + ww }; + if ( useMask && maskworld ) + { + if( LockPixels(GetGWorldPixMap(MAC_WXHBITMAP(maskworld)))) { - if( LockPixels(GetGWorldPixMap(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap())))) - { - CopyDeepMask - ( - GetPortBitMapForCopyBits(bmapworld), - GetPortBitMapForCopyBits(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap())), - GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ), - &source, &source, &dest, mode, NULL - ); - UnlockPixels(GetGWorldPixMap(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap()))); - } - } - else { - CopyBits( GetPortBitMapForCopyBits( bmapworld ), - GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ), - &source, &dest, mode, NULL ) ; + CopyDeepMask + ( + GetPortBitMapForCopyBits(bmapworld), + GetPortBitMapForCopyBits(MAC_WXHBITMAP(maskworld)), + GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ), + &source, &source, &dest, mode, NULL + ); + UnlockPixels(GetGWorldPixMap(MAC_WXHBITMAP(maskworld))); } - UnlockPixels( bmappixels ) ; } - else if ( bmp.GetBitmapType() == kMacBitmapTypeIcon ) - { - Rect bitmaprect = { 0 , 0 , bmp.GetHeight(), bmp.GetWidth() } ; - OffsetRect( &bitmaprect, xx, yy ) ; - PlotCIconHandle( &bitmaprect , atNone , ttNone , MAC_WXHICON(bmp.GetHICON()) ) ; + else { + CopyBits( GetPortBitMapForCopyBits( bmapworld ), + GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ), + &source, &dest, mode, NULL ) ; } + UnlockPixels( bmappixels ) ; + m_macPenInstalled = false ; m_macBrushInstalled = false ; m_macFontInstalled = false ; @@ -425,7 +411,13 @@ void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ) { wxCHECK_RET(Ok(), wxT("Invalid dc wxDC::DoDrawIcon")); wxCHECK_RET(icon.Ok(), wxT("Invalid icon wxDC::DoDrawIcon")); - DoDrawBitmap( icon , x , y , icon.GetMask() != NULL ) ; + wxMacFastPortSetter helper(this) ; + + wxCoord xx = XLOG2DEVMAC(x); + wxCoord yy = YLOG2DEVMAC(y); + + Rect r = { yy , xx, yy + 32 , xx + 32 } ; + PlotIconRef( &r , kAlignNone , kTransformNone , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) ) ; } void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) @@ -1942,9 +1934,9 @@ void wxDC::MacInstallBrush() const int height = bitmap->GetHeight() ; GWorldPtr gw = NULL ; if ( m_brush.GetStyle() == wxSTIPPLE ) - gw = MAC_WXHBITMAP(bitmap->GetHBITMAP()) ; + gw = MAC_WXHBITMAP(bitmap->GetHBITMAP(NULL)) ; else - gw = MAC_WXHBITMAP(bitmap->GetMask()->GetMaskBitmap()) ; + gw = MAC_WXHBITMAP(bitmap->GetMask()->GetHBITMAP()) ; PixMapHandle gwpixmaphandle = GetGWorldPixMap( gw ) ; LockPixels( gwpixmaphandle ) ; bool isMonochrome = !IsPortColor( gw ) ; @@ -2098,3 +2090,5 @@ wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const { return ((wxDC *)this)->YLOG2DEVREL(y); } + +#endif // !wxMAC_USE_CORE_GRAPHICS diff --git a/src/mac/carbon/dccg.cpp b/src/mac/carbon/dccg.cpp index 2f890c7514..0ccfcd24e6 100755 --- a/src/mac/carbon/dccg.cpp +++ b/src/mac/carbon/dccg.cpp @@ -13,7 +13,12 @@ #pragma implementation "dc.h" #endif +#include "wx/wxprec.h" + #include "wx/dc.h" + +#if wxMAC_USE_CORE_GRAPHICS + #include "wx/app.h" #include "wx/mac/uma.h" #include "wx/dcmemory.h" @@ -22,6 +27,7 @@ #include "wx/image.h" #include "wx/log.h" + #if __MSL__ >= 0x6000 #include "math.h" using namespace std ; @@ -53,52 +59,8 @@ const short kUnsupportedMode = -2 ; extern TECObjectRef s_TECNativeCToUnicode ; -// set to 0 if problems arise -#define wxMAC_EXPERIMENTAL_DC 1 - -wxMacPortSetter::wxMacPortSetter( const wxDC* dc ) : - m_ph( (GrafPtr) dc->m_macPort ) -{ - wxASSERT( dc->Ok() ) ; - m_dc = dc ; - dc->MacSetupPort(&m_ph) ; -} -wxMacPortSetter::~wxMacPortSetter() -{ - m_dc->MacCleanupPort(&m_ph) ; -} - -#if wxMAC_EXPERIMENTAL_DC -class wxMacFastPortSetter -{ -public : - wxMacFastPortSetter( const wxDC *dc ) - { - wxASSERT( dc->Ok() ) ; - GetPort( &m_oldPort ) ; - SetPort( (GrafPtr) dc->m_macPort ) ; - m_clipRgn = NewRgn() ; - GetClip( m_clipRgn ) ; - m_dc = dc ; - dc->MacSetupPort( NULL ) ; - } - ~wxMacFastPortSetter() - { - SetPort( (GrafPtr) m_dc->m_macPort ) ; - SetClip( m_clipRgn ) ; - SetPort( m_oldPort ) ; - m_dc->MacCleanupPort( NULL ) ; - DisposeRgn( m_clipRgn ) ; - } -private : - RgnHandle m_clipRgn ; - GrafPtr m_oldPort ; - const wxDC* m_dc ; -} ; - -#else -typedef wxMacPortSetter wxMacFastPortSetter ; -#endif +// TODO Update +// The text ctrl implementation still needs that for the non hiview implementation wxMacWindowClipper::wxMacWindowClipper( const wxWindow* win ) : wxMacPortSaver( (GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) ) @@ -146,259 +108,174 @@ wxMacWindowStateSaver::~wxMacWindowStateSaver() //----------------------------------------------------------------------------- // Local functions //----------------------------------------------------------------------------- + static inline double dmin(double a, double b) { return a < b ? a : b; } static inline double dmax(double a, double b) { return a > b ? a : b; } static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; } //----------------------------------------------------------------------------- -// wxDC +// device context implementation +// +// more and more of the dc functionality should be implemented by calling +// the appropricate wxMacCGContext, but we will have to do that step by step +// also coordinate conversions should be moved to native matrix ops //----------------------------------------------------------------------------- -// this function emulates all wx colour manipulations, used to verify the implementation -// by setting the mode in the blitting functions to kEmulatedMode -void wxMacCalculateColour( int logical_func , const RGBColor &srcColor , RGBColor &dstColor ) ; -void wxMacCalculateColour( int logical_func , const RGBColor &srcColor , RGBColor &dstColor ) +wxMacCGPath::wxMacCGPath() { - switch ( logical_func ) - { - case wxAND: // src AND dst - dstColor.red = dstColor.red & srcColor.red ; - dstColor.green = dstColor.green & srcColor.green ; - dstColor.blue = dstColor.blue & srcColor.blue ; - break ; - case wxAND_INVERT: // (NOT src) AND dst - dstColor.red = dstColor.red & ~srcColor.red ; - dstColor.green = dstColor.green & ~srcColor.green ; - dstColor.blue = dstColor.blue & ~srcColor.blue ; - break ; - case wxAND_REVERSE:// src AND (NOT dst) - dstColor.red = ~dstColor.red & srcColor.red ; - dstColor.green = ~dstColor.green & srcColor.green ; - dstColor.blue = ~dstColor.blue & srcColor.blue ; - break ; - case wxCLEAR: // 0 - dstColor.red = 0 ; - dstColor.green = 0 ; - dstColor.blue = 0 ; - break ; - case wxCOPY: // src - dstColor.red = srcColor.red ; - dstColor.green = srcColor.green ; - dstColor.blue = srcColor.blue ; - break ; - case wxEQUIV: // (NOT src) XOR dst - dstColor.red = dstColor.red ^ ~srcColor.red ; - dstColor.green = dstColor.green ^ ~srcColor.green ; - dstColor.blue = dstColor.blue ^ ~srcColor.blue ; - break ; - case wxINVERT: // NOT dst - dstColor.red = ~dstColor.red ; - dstColor.green = ~dstColor.green ; - dstColor.blue = ~dstColor.blue ; - break ; - case wxNAND: // (NOT src) OR (NOT dst) - dstColor.red = ~dstColor.red | ~srcColor.red ; - dstColor.green = ~dstColor.green | ~srcColor.green ; - dstColor.blue = ~dstColor.blue | ~srcColor.blue ; - break ; - case wxNOR: // (NOT src) AND (NOT dst) - dstColor.red = ~dstColor.red & ~srcColor.red ; - dstColor.green = ~dstColor.green & ~srcColor.green ; - dstColor.blue = ~dstColor.blue & ~srcColor.blue ; - break ; - case wxNO_OP: // dst - break ; - case wxOR: // src OR dst - dstColor.red = dstColor.red | srcColor.red ; - dstColor.green = dstColor.green | srcColor.green ; - dstColor.blue = dstColor.blue | srcColor.blue ; - break ; - case wxOR_INVERT: // (NOT src) OR dst - dstColor.red = dstColor.red | ~srcColor.red ; - dstColor.green = dstColor.green | ~srcColor.green ; - dstColor.blue = dstColor.blue | ~srcColor.blue ; - break ; - case wxOR_REVERSE: // src OR (NOT dst) - dstColor.red = ~dstColor.red | srcColor.red ; - dstColor.green = ~dstColor.green | srcColor.green ; - dstColor.blue = ~dstColor.blue | srcColor.blue ; - break ; - case wxSET: // 1 - dstColor.red = 0xFFFF ; - dstColor.green = 0xFFFF ; - dstColor.blue = 0xFFFF ; - break ; - case wxSRC_INVERT: // (NOT src) - dstColor.red = ~srcColor.red ; - dstColor.green = ~srcColor.green ; - dstColor.blue = ~srcColor.blue ; - break ; - case wxXOR: // src XOR dst - dstColor.red = dstColor.red ^ srcColor.red ; - dstColor.green = dstColor.green ^ srcColor.green ; - dstColor.blue = dstColor.blue ^ srcColor.blue ; - break ; - } + m_path = CGPathCreateMutable() ; } -class WXDLLEXPORT wxMacCGPath +wxMacCGPath::~wxMacCGPath() { - DECLARE_NO_COPY_CLASS(wxMacCGPath) -public : + CGPathRelease( m_path ) ; +} - wxMacCGPath() - { - m_path = CGPathCreateMutable() ; - } - - ~wxMacCGPath() - { - CGPathRelease( m_path ) ; - } - - // Starts a new subpath at - void MoveToPoint( wxCoord x1 , wxCoord y1 ) - { - CGPathMoveToPoint( m_path , NULL , x1 , y1 ) ; - } - - void AddLineToPoint( wxCoord x1 , wxCoord y1 ) - { - CGPathAddLineToPoint( m_path , NULL , x1 , y1 ) ; - } - - void AddRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) - { - CGRect cgRect = { { x , y } , { w , h } } ; - CGPathAddRect( m_path , NULL , cgRect ) ; - } +// Starts a new subpath at +void wxMacCGPath::MoveToPoint( wxCoord x1 , wxCoord y1 ) +{ + CGPathMoveToPoint( m_path , NULL , x1 , y1 ) ; +} - void AddRectangle( CGRect cgRect ) - { - CGPathAddRect( m_path , NULL , cgRect ) ; - } - - void AddCircle( CGPoint center , float r ) - { - CGPathAddArc( m_path , NULL , center.x , center.y , r , 0.0 , 2 * M_PI , true ) ; - } - - // closes the current subpath - void CloseSubpath() - { - CGPathCloseSubpath( m_path ) ; - } - - CGPathRef GetPath() const - { - return m_path ; - } -private : - CGMutablePathRef m_path ; -} ; +void wxMacCGPath::AddLineToPoint( wxCoord x1 , wxCoord y1 ) +{ + CGPathAddLineToPoint( m_path , NULL , x1 , y1 ) ; +} -class WXDLLEXPORT wxMacCGContext +void wxMacCGPath::AddRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) { - DECLARE_NO_COPY_CLASS(wxMacCGContext) - -public: - wxMacCGContext( const wxDC* dc ) ; - ~wxMacCGContext() ; + CGRect cgRect = { { x , y } , { w , h } } ; + CGPathAddRect( m_path , NULL , cgRect ) ; +} - void StrokePath( const wxMacCGPath &path ) - { - - CGContextBeginPath( m_cgContext ) ; - CGContextAddPath( m_cgContext , path.GetPath() ) ; - CGContextClosePath( m_cgContext ) ; - CGContextStrokePath( m_cgContext ) ; - } - - void DrawPath( const wxMacCGPath &path , int fillStyle = wxWINDING_RULE ) - { - CGPathDrawingMode mode = m_mode ; - if ( fillStyle == wxODDEVEN_RULE ) - { - if ( mode == kCGPathFill ) - mode = kCGPathEOFill ; - else if ( mode == kCGPathFillStroke ) - mode = kCGPathEOFillStroke ; - } - CGContextBeginPath( m_cgContext ) ; - CGContextAddPath( m_cgContext , path.GetPath() ) ; - CGContextClosePath( m_cgContext ) ; - CGContextDrawPath( m_cgContext , mode ) ; - } - - void FillPath( const wxMacCGPath &path , const wxColor &fillColor , int fillStyle = wxWINDING_RULE ) - { - RGBColor col = MAC_WXCOLORREF( fillColor.GetPixel() ) ; - CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; - CGPathDrawingMode mode = kCGPathFill ; +void wxMacCGPath::AddCircle( wxCoord x, wxCoord y , wxCoord r ) +{ + CGPathAddArc( m_path , NULL , x , y , r , 0.0 , 2 * M_PI , true ) ; +} - if ( fillStyle == wxODDEVEN_RULE ) - mode = kCGPathEOFill ; - - CGContextBeginPath( m_cgContext ) ; - CGContextAddPath( m_cgContext , path.GetPath() ) ; - CGContextClosePath( m_cgContext ) ; - CGContextDrawPath( m_cgContext , mode ) ; - if ( m_dc->GetBrush().GetStyle() ) - { - RGBColor col = MAC_WXCOLORREF( m_dc->GetBrush().GetColour().GetPixel() ) ; - CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; - } - } - - void SetupPenAndBrush() ; - CGContextRef GetNativeContext() { return m_cgContext ; } -private: - CGContextRef m_cgContext ; - CGPathDrawingMode m_mode ; - const wxDC* m_dc ; -} ; +// closes the current subpath +void wxMacCGPath::CloseSubpath() +{ + CGPathCloseSubpath( m_path ) ; +} -wxMacCGContext::wxMacCGContext( const wxDC* dc ) +CGPathRef wxMacCGPath::GetPath() const { - wxASSERT( dc->Ok() ) ; + return m_path ; +} + +wxMacCGContext::wxMacCGContext( CGrafPtr port ) +{ + m_qdPort = port ; Rect bounds ; - GetPortBounds( (CGrafPtr) dc->m_macPort , &bounds ) ; - OSStatus status = QDBeginCGContext( (CGrafPtr) dc->m_macPort , &m_cgContext ) ; - wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") ) ; - ClipCGContextToRegion ( m_cgContext, &bounds , (RgnHandle) dc->m_macCurrentClipRgn ) ; + GetPortBounds( (CGrafPtr) port , &bounds ) ; + OSStatus status = QDBeginCGContext( (CGrafPtr) port , &m_cgContext ) ; + wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") ) ; CGContextTranslateCTM( m_cgContext , 0 , bounds.bottom - bounds.top ) ; CGContextScaleCTM( m_cgContext , 1 , -1 ) ; +} + +wxMacCGContext::wxMacCGContext( CGContextRef cgcontext ) +{ + m_qdPort = NULL ; + m_cgContext = cgcontext ; +} + +wxMacCGContext::wxMacCGContext() +{ + m_qdPort = NULL ; + m_cgContext = NULL ; +} - m_dc = dc ; - SetupPenAndBrush() ; +wxMacCGContext::~wxMacCGContext() +{ + if ( m_qdPort ) + QDEndCGContext( m_qdPort , &m_cgContext ) ; +} + + +void wxMacCGContext::Clip( const wxRegion ®ion ) +{ +// ClipCGContextToRegion ( m_cgContext, &bounds , (RgnHandle) dc->m_macCurrentClipRgn ) ; +} + +void wxMacCGContext::StrokePath( const wxGraphicPath *p ) +{ + const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ; + CGContextBeginPath( m_cgContext ) ; + CGContextAddPath( m_cgContext , path->GetPath() ) ; + CGContextClosePath( m_cgContext ) ; + CGContextStrokePath( m_cgContext ) ; +} + +void wxMacCGContext::DrawPath( const wxGraphicPath *p , int fillStyle ) +{ + const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ; + CGPathDrawingMode mode = m_mode ; + if ( fillStyle == wxODDEVEN_RULE ) + { + if ( mode == kCGPathFill ) + mode = kCGPathEOFill ; + else if ( mode == kCGPathFillStroke ) + mode = kCGPathEOFillStroke ; + } + CGContextBeginPath( m_cgContext ) ; + CGContextAddPath( m_cgContext , path->GetPath() ) ; + CGContextClosePath( m_cgContext ) ; + CGContextDrawPath( m_cgContext , mode ) ; } -void wxMacCGContext::SetupPenAndBrush() +void wxMacCGContext::FillPath( const wxGraphicPath *p , const wxColor &fillColor , int fillStyle ) { - bool fill = m_dc->GetBrush().GetStyle() != wxTRANSPARENT ; - bool stroke = m_dc->GetPen().GetStyle() != wxTRANSPARENT ; + const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ; + CGContextSaveGState( m_cgContext ) ; + + RGBColor col = MAC_WXCOLORREF( fillColor.GetPixel() ) ; + CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; + CGPathDrawingMode mode = kCGPathFill ; + + if ( fillStyle == wxODDEVEN_RULE ) + mode = kCGPathEOFill ; + + CGContextBeginPath( m_cgContext ) ; + CGContextAddPath( m_cgContext , path->GetPath() ) ; + CGContextClosePath( m_cgContext ) ; + CGContextDrawPath( m_cgContext , mode ) ; + + CGContextRestoreGState( m_cgContext ) ; +} +wxGraphicPath* wxMacCGContext::CreatePath() { return new wxMacCGPath() ; } +CGContextRef wxMacCGContext::GetNativeContext() { return m_cgContext ; } +void wxMacCGContext::SetNativeContext( CGContextRef cg ) { m_cgContext = cg ; } + +void wxMacCGContext::SetPen( const wxPen &pen ) +{ + bool fill = m_brush.GetStyle() != wxTRANSPARENT ; + bool stroke = pen.GetStyle() != wxTRANSPARENT ; + +#if 0 + // we can benchmark performance, should go into a setting later + CGContextSetShouldAntialias( m_cgContext , false ) ; +#endif if ( fill | stroke ) { - // setup brushes m_mode = kCGPathFill ; // just a default if ( fill ) { - RGBColor col = MAC_WXCOLORREF( m_dc->GetBrush().GetColour().GetPixel() ) ; - CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; m_mode = kCGPathFill ; } if ( stroke ) { - RGBColor col = MAC_WXCOLORREF( m_dc->GetPen().GetColour().GetPixel() ) ; + RGBColor col = MAC_WXCOLORREF( pen.GetColour().GetPixel() ) ; CGContextSetRGBStrokeColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; CGLineCap cap ; - switch( m_dc->GetPen().GetCap() ) + switch( pen.GetCap() ) { case wxCAP_ROUND : cap = kCGLineCapRound ; @@ -416,7 +293,7 @@ void wxMacCGContext::SetupPenAndBrush() CGContextSetLineCap( m_cgContext , cap ) ; CGLineJoin join ; - switch( m_dc->GetPen().GetJoin() ) + switch( pen.GetJoin() ) { case wxJOIN_BEVEL : join = kCGLineJoinBevel ; @@ -433,40 +310,41 @@ void wxMacCGContext::SetupPenAndBrush() } CGContextSetLineJoin( m_cgContext , join ) ; - CGContextSetLineWidth( m_cgContext , m_dc->GetPen().GetWidth() == 0 ? 0.1 : m_dc->GetPen().GetWidth() /* TODO * m_dc->m_scaleX */ ) ; + CGContextSetLineWidth( m_cgContext , pen.GetWidth() == 0 ? 0.1 : pen.GetWidth() /* TODO * m_dc->m_scaleX */ ) ; m_mode = kCGPathStroke ; int count = 0 ; const float *lengths = NULL ; float *userLengths = NULL ; - switch( m_dc->GetPen().GetStyle() ) + const float dotted[] = { 3 , 3 }; + const float dashed[] = { 19 , 9 }; + const float short_dashed[] = { 9 , 6 }; + const float dotted_dashed[] = { 9 , 6 , 3 , 3 }; + + switch( pen.GetStyle() ) { case wxSOLID : break ; case wxDOT : - const float dotted[] = { 3 , 3 }; lengths = dotted ; count = WXSIZEOF(dotted); break ; case wxLONG_DASH : - const float dashed[] = { 19 , 9 }; lengths = dashed ; count = WXSIZEOF(dashed) ; break ; case wxSHORT_DASH : - const float short_dashed[] = { 9 , 6 }; lengths = short_dashed ; count = WXSIZEOF(short_dashed) ; break ; case wxDOT_DASH : - const float dotted_dashed[] = { 9 , 6 , 3 , 3 }; lengths = dotted_dashed ; count = WXSIZEOF(dotted_dashed); break ; case wxUSER_DASH : wxDash *dashes ; - count = m_dc->GetPen().GetDashes( &dashes ) ; + count = pen.GetDashes( &dashes ) ; if ( count >0 ) { userLengths = new float[count] ; @@ -493,15 +371,100 @@ void wxMacCGContext::SetupPenAndBrush() } } +void wxMacCGContext::SetBrush( const wxBrush &brush ) +{ + bool fill = brush.GetStyle() != wxTRANSPARENT ; + bool stroke = m_pen.GetStyle() != wxTRANSPARENT ; -wxMacCGContext::~wxMacCGContext() +#if 0 + // we can benchmark performance, should go into a setting later + CGContextSetShouldAntialias( m_cgContext , false ) ; +#endif + if ( fill | stroke ) + { + + // setup brushes + m_mode = kCGPathFill ; // just a default + + if ( fill ) + { + RGBColor col = MAC_WXCOLORREF( brush.GetColour().GetPixel() ) ; + CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; + m_mode = kCGPathFill ; + } + if ( stroke ) + { + m_mode = kCGPathStroke ; + } + if ( fill && stroke ) + { + m_mode = kCGPathFillStroke ; + } + + } +} + +// snippets from Sketch Sample from Apple : + +#define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc" +/* + This function locates, opens, and returns the profile reference for the calibrated + Generic RGB color space. It is up to the caller to call CMCloseProfile when done + with the profile reference this function returns. +*/ +CMProfileRef wxMacOpenGenericProfile(void) { - QDEndCGContext( (CGrafPtr) m_dc->m_macPort , &m_cgContext ) ; + static CMProfileRef cachedRGBProfileRef = NULL; + + // we only create the profile reference once + if (cachedRGBProfileRef == NULL) + { + CMProfileLocation loc; + + loc.locType = cmPathBasedProfile; + strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr); + + verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) ); + } + + if (cachedRGBProfileRef) + { + // clone the profile reference so that the caller has their own reference, not our cached one + CMCloneProfileRef(cachedRGBProfileRef); + } + + return cachedRGBProfileRef; } +/* + Return the generic RGB color space. This is a 'get' function and the caller should + not release the returned value unless the caller retains it first. Usually callers + of this routine will immediately use the returned colorspace with CoreGraphics + so they typically do not need to retain it themselves. + + This function creates the generic RGB color space once and hangs onto it so it can + return it whenever this function is called. +*/ -#define wxMacGraphicContext wxMacCGContext -#define wxMacGraphicPath wxMacCGPath +CGColorSpaceRef wxMacGetGenericRGBColorSpace() +{ + static CGColorSpaceRef genericRGBColorSpace = NULL; + + if (genericRGBColorSpace == NULL) + { + CMProfileRef genericRGBProfile = wxMacOpenGenericProfile(); + + if (genericRGBProfile) + { + genericRGBColorSpace = CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile); + wxASSERT_MSG( genericRGBColorSpace != NULL, wxT("couldn't create the generic RGB color space") ) ; + + // we opened the profile so it is up to us to close it + CMCloseProfile(genericRGBProfile); + } + } + return genericRGBColorSpace; +} void AddEllipticArcToPath(CGContextRef c, CGPoint center, float a, float b, float fromDegree , float toDegree ) { @@ -555,180 +518,69 @@ wxDC::wxDC() m_scaleY = 1.0; m_needComputeScaleX = FALSE; m_needComputeScaleY = FALSE; - m_macPort = NULL ; - m_macMask = NULL ; + m_ok = FALSE ; - m_macFontInstalled = false ; - m_macBrushInstalled = false ; - m_macPenInstalled = false ; + m_macLocalOrigin.x = m_macLocalOrigin.y = 0 ; - m_macBoundaryClipRgn = NewRgn() ; - m_macCurrentClipRgn = NewRgn() ; - SetRectRgn( (RgnHandle) m_macBoundaryClipRgn , -32000 , -32000 , 32000 , 32000 ) ; - SetRectRgn( (RgnHandle) m_macCurrentClipRgn , -32000 , -32000 , 32000 , 32000 ) ; + m_pen = *wxBLACK_PEN; m_font = *wxNORMAL_FONT; m_brush = *wxWHITE_BRUSH; -#ifdef __WXDEBUG__ - // needed to debug possible errors with two active drawing methods at the same time on - // the same DC - m_macCurrentPortStateHelper = NULL ; -#endif - m_macATSUIStyle = NULL ; - m_macAliasWasEnabled = false; - m_macForegroundPixMap = NULL ; - m_macBackgroundPixMap = NULL ; - m_macGraphicContext = NULL ; -} -wxDC::~wxDC(void) -{ - DisposeRgn( (RgnHandle) m_macBoundaryClipRgn ) ; - DisposeRgn( (RgnHandle) m_macCurrentClipRgn ) ; - delete m_macGraphicContext ; - -} + m_macATSUIStyle = NULL ; -void wxDC::MacSetupGraphicContext() -{ - m_macGraphicContext = new wxMacCGContext( this ) ; + m_graphicContext = NULL ; } -void wxDC::MacSetupPort(wxMacPortStateHelper* help) const -{ -#ifdef __WXDEBUG__ - wxASSERT( m_macCurrentPortStateHelper == NULL ) ; - m_macCurrentPortStateHelper = help ; -#endif - SetClip( (RgnHandle) m_macCurrentClipRgn); -#if ! wxMAC_EXPERIMENTAL_DC - m_macFontInstalled = false ; - m_macBrushInstalled = false ; - m_macPenInstalled = false ; -#endif -} -void wxDC::MacCleanupPort(wxMacPortStateHelper* help) const +wxDC::~wxDC(void) { -#ifdef __WXDEBUG__ - wxASSERT( m_macCurrentPortStateHelper == help ) ; - m_macCurrentPortStateHelper = NULL ; -#endif if( m_macATSUIStyle ) { ::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle); m_macATSUIStyle = NULL ; } - if ( m_macAliasWasEnabled ) - { - SetAntiAliasedTextEnabled(m_macFormerAliasState, m_macFormerAliasSize); - m_macAliasWasEnabled = false ; - } - if ( m_macForegroundPixMap ) - { - Pattern blackColor ; - ::PenPat(GetQDGlobalsBlack(&blackColor)); - DisposePixPat( (PixPatHandle) m_macForegroundPixMap ) ; - m_macForegroundPixMap = NULL ; - } - if ( m_macBackgroundPixMap ) - { - Pattern whiteColor ; - ::BackPat(GetQDGlobalsWhite(&whiteColor)); - DisposePixPat( (PixPatHandle) m_macBackgroundPixMap ) ; - m_macBackgroundPixMap = NULL ; - } + + delete m_graphicContext ; } void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask ) { - wxCHECK_RET( Ok(), wxT("invalid window dc") ); - wxCHECK_RET( bmp.Ok(), wxT("invalid bitmap") ); - wxCoord xx = XLOG2DEVMAC(x); - wxCoord yy = YLOG2DEVMAC(y); - wxCoord w = bmp.GetWidth(); - wxCoord h = bmp.GetHeight(); - wxCoord ww = XLOG2DEVREL(w); - wxCoord hh = YLOG2DEVREL(h); - // Set up drawing mode - short mode = (m_logicalFunction == wxCOPY ? srcCopy : - //m_logicalFunction == wxCLEAR ? WHITENESS : - //m_logicalFunction == wxSET ? BLACKNESS : - m_logicalFunction == wxINVERT ? hilite : - //m_logicalFunction == wxAND ? MERGECOPY : - m_logicalFunction == wxOR ? srcOr : - m_logicalFunction == wxSRC_INVERT ? notSrcCopy : - m_logicalFunction == wxXOR ? srcXor : - m_logicalFunction == wxOR_REVERSE ? notSrcOr : - //m_logicalFunction == wxAND_REVERSE ? SRCERASE : - //m_logicalFunction == wxSRC_OR ? srcOr : - //m_logicalFunction == wxSRC_AND ? SRCAND : - srcCopy ); - if ( bmp.GetBitmapType() == kMacBitmapTypePict ) { - Rect bitmaprect = { 0 , 0 , hh, ww }; - ::OffsetRect( &bitmaprect, xx, yy ) ; - ::DrawPicture( (PicHandle) bmp.GetPict(), &bitmaprect ) ; - } - else if ( bmp.GetBitmapType() == kMacBitmapTypeGrafWorld ) - { - GWorldPtr bmapworld = MAC_WXHBITMAP( bmp.GetHBITMAP() ); - PixMapHandle bmappixels ; - // Set foreground and background colours (for bitmaps depth = 1) - if(bmp.GetDepth() == 1) - { - RGBColor fore = MAC_WXCOLORREF(m_textForegroundColour.GetPixel()); - RGBColor back = MAC_WXCOLORREF(m_textBackgroundColour.GetPixel()); - RGBForeColor(&fore); - RGBBackColor(&back); - } - else - { - RGBColor white = { 0xFFFF, 0xFFFF,0xFFFF} ; - RGBColor black = { 0,0,0} ; - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - } - bmappixels = GetGWorldPixMap( bmapworld ) ; - wxCHECK_RET(LockPixels(bmappixels), - wxT("DoDrawBitmap: Unable to lock pixels")); - Rect source = { 0, 0, h, w }; - Rect dest = { yy, xx, yy + hh, xx + ww }; - if ( useMask && bmp.GetMask() ) - { - if( LockPixels(GetGWorldPixMap(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap())))) - { - CopyDeepMask - ( - GetPortBitMapForCopyBits(bmapworld), - GetPortBitMapForCopyBits(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap())), - GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ), - &source, &source, &dest, mode, NULL - ); - UnlockPixels(GetGWorldPixMap(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap()))); - } - } - else { - CopyBits( GetPortBitMapForCopyBits( bmapworld ), - GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ), - &source, &dest, mode, NULL ) ; - } - UnlockPixels( bmappixels ) ; - } - else if ( bmp.GetBitmapType() == kMacBitmapTypeIcon ) - { - Rect bitmaprect = { 0 , 0 , bmp.GetHeight(), bmp.GetWidth() } ; - OffsetRect( &bitmaprect, xx, yy ) ; - PlotCIconHandle( &bitmaprect , atNone , ttNone , MAC_WXHICON(bmp.GetHICON()) ) ; - } - m_macPenInstalled = false ; - m_macBrushInstalled = false ; - m_macFontInstalled = false ; + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + wxCHECK_RET( bmp.Ok(), wxT("invalid bitmap") ); + wxCoord xx = XLOG2DEVMAC(x); + wxCoord yy = YLOG2DEVMAC(y); + wxCoord w = bmp.GetWidth(); + wxCoord h = bmp.GetHeight(); + wxCoord ww = XLOG2DEVREL(w); + wxCoord hh = YLOG2DEVREL(h); + + CGContextRef cg = dynamic_cast(m_graphicContext)->GetNativeContext() ; + CGImageRef image = (CGImageRef)( bmp.CGImageCreate() ) ; + HIRect r = CGRectMake( xx , yy , ww , hh ) ; + HIViewDrawCGImage( cg , &r , image ) ; + CGImageRelease( image ) ; } void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ) { wxCHECK_RET(Ok(), wxT("Invalid dc wxDC::DoDrawIcon")); wxCHECK_RET(icon.Ok(), wxT("Invalid icon wxDC::DoDrawIcon")); - DoDrawBitmap( icon , x , y , icon.GetMask() != NULL ) ; + + wxCoord xx = XLOG2DEVMAC(x); + wxCoord yy = YLOG2DEVMAC(y); + wxCoord w = icon.GetWidth(); + wxCoord h = icon.GetHeight(); + wxCoord ww = XLOG2DEVREL(w); + wxCoord hh = YLOG2DEVREL(h); + + CGContextRef cg = dynamic_cast(m_graphicContext)->GetNativeContext() ; + CGRect r = CGRectMake( 00 , 00 , ww , hh ) ; + CGContextSaveGState(cg); + CGContextTranslateCTM(cg, xx , yy + hh ); + CGContextScaleCTM(cg, 1, -1); + PlotIconRefInContext( cg , &r , kAlignNone , kTransformNone , + NULL , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) ) ; + CGContextRestoreGState( cg ) ; } void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) @@ -739,8 +591,8 @@ void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord hei yy = YLOG2DEVMAC(y); ww = XLOG2DEVREL(width); hh = YLOG2DEVREL(height); - SetRectRgn( (RgnHandle) m_macCurrentClipRgn , xx , yy , xx + ww , yy + hh ) ; - SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; +// SetRectRgn( (RgnHandle) m_macCurrentClipRgn , xx , yy , xx + ww , yy + hh ) ; +// SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; if( m_clipping ) { m_clipX1 = wxMax( m_clipX1 , xx ); @@ -783,12 +635,14 @@ void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) } else { + /* CopyRgn( (RgnHandle) region.GetWXHRGN() , (RgnHandle) m_macCurrentClipRgn ) ; if ( xx != x || yy != y ) { OffsetRgn( (RgnHandle) m_macCurrentClipRgn , xx - x , yy - y ) ; } SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; + */ if( m_clipping ) { m_clipX1 = wxMax( m_clipX1 , xx ); @@ -809,7 +663,7 @@ void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) void wxDC::DestroyClippingRegion() { - CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; +// CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; m_clipping = FALSE; } @@ -825,15 +679,17 @@ void wxDC::DoGetSizeMM( int* width, int* height ) const void wxDC::SetTextForeground( const wxColour &col ) { wxCHECK_RET(Ok(), wxT("Invalid DC")); - m_textForegroundColour = col; - m_macFontInstalled = false ; + if ( col != m_textForegroundColour ) + { + m_textForegroundColour = col; + MacInstallFont() ; + } } void wxDC::SetTextBackground( const wxColour &col ) { wxCHECK_RET(Ok(), wxT("Invalid DC")); m_textBackgroundColour = col; - m_macFontInstalled = false ; } void wxDC::SetMapMode( int mode ) @@ -908,11 +764,7 @@ wxSize wxDC::GetPPI() const int wxDC::GetDepth() const { - if ( IsPortColor( (CGrafPtr) m_macPort ) ) - { - return ( (**GetPortPixMap( (CGrafPtr) m_macPort)).pixelSize ) ; - } - return 1 ; + return 32 ; } void wxDC::ComputeScaleAndOrigin() @@ -947,7 +799,7 @@ void wxDC::SetBackgroundMode( int mode ) void wxDC::SetFont( const wxFont &font ) { m_font = font; - m_macFontInstalled = false ; + MacInstallFont() ; } void wxDC::SetPen( const wxPen &pen ) @@ -955,8 +807,10 @@ void wxDC::SetPen( const wxPen &pen ) if ( m_pen == pen ) return ; m_pen = pen; - m_macPenInstalled = false ; - m_macGraphicContext->SetupPenAndBrush() ; + if ( m_graphicContext ) + { + m_graphicContext->SetPen( m_pen ) ; + } } void wxDC::SetBrush( const wxBrush &brush ) @@ -964,8 +818,10 @@ void wxDC::SetBrush( const wxBrush &brush ) if (m_brush == brush) return; m_brush = brush; - m_macBrushInstalled = false ; - m_macGraphicContext->SetupPenAndBrush() ; + if ( m_graphicContext ) + { + m_graphicContext->SetBrush( m_brush ) ; + } } void wxDC::SetBackground( const wxBrush &brush ) @@ -975,7 +831,6 @@ void wxDC::SetBackground( const wxBrush &brush ) m_backgroundBrush = brush; if (!m_backgroundBrush.Ok()) return; - m_macBrushInstalled = false ; } void wxDC::SetLogicalFunction( int function ) @@ -983,9 +838,6 @@ void wxDC::SetLogicalFunction( int function ) if (m_logicalFunction == function) return; m_logicalFunction = function ; - m_macFontInstalled = false ; - m_macBrushInstalled = false ; - m_macPenInstalled = false ; } extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y, @@ -1000,13 +852,8 @@ bool wxDC::DoFloodFill(wxCoord x, wxCoord y, bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const { wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel Invalid DC") ); - RGBColor colour; - GetCPixel( XLOG2DEVMAC(x), YLOG2DEVMAC(y), &colour ); - // Convert from Mac colour to wx - col->Set( colour.red >> 8, - colour.green >> 8, - colour.blue >> 8); - return true ; + wxFAIL_MSG( wxT("GetPixel not implemented on Core Graphics") ) ; + return false ; } void wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) @@ -1018,11 +865,12 @@ void wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) wxCoord xx2 = XLOG2DEVMAC(x2) ; wxCoord yy2 = YLOG2DEVMAC(y2) ; - wxMacGraphicPath path ; - path.MoveToPoint( xx1 , yy1 ) ; - path.AddLineToPoint( xx2 , yy2 ) ; - path.CloseSubpath() ; - m_macGraphicContext->StrokePath( path ) ; + wxGraphicPath* path = m_graphicContext->CreatePath() ; + path->MoveToPoint( xx1 , yy1 ) ; + path->AddLineToPoint( xx2 , yy2 ) ; + path->CloseSubpath() ; + m_graphicContext->StrokePath( path ) ; + delete path ; CalcBoundingBox(x1, y1); CalcBoundingBox(x2, y2); @@ -1039,14 +887,15 @@ void wxDC::DoCrossHair( wxCoord x, wxCoord y ) wxCoord xx = XLOG2DEVMAC(x); wxCoord yy = YLOG2DEVMAC(y); - wxMacGraphicPath path ; - path.MoveToPoint( XLOG2DEVMAC(0), yy ) ; - path.AddLineToPoint( XLOG2DEVMAC(w), yy ) ; - path.CloseSubpath() ; - path.MoveToPoint( xx, YLOG2DEVMAC(0) ) ; - path.AddLineToPoint( xx, YLOG2DEVMAC(h) ) ; - path.CloseSubpath() ; - m_macGraphicContext->StrokePath( path ) ; + wxGraphicPath* path = m_graphicContext->CreatePath() ; + path->MoveToPoint( XLOG2DEVMAC(0), yy ) ; + path->AddLineToPoint( XLOG2DEVMAC(w), yy ) ; + path->CloseSubpath() ; + path->MoveToPoint( xx, YLOG2DEVMAC(0) ) ; + path->AddLineToPoint( xx, YLOG2DEVMAC(h) ) ; + path->CloseSubpath() ; + m_graphicContext->StrokePath( path ) ; + delete path ; CalcBoundingBox(x, y); CalcBoundingBox(x+w, y+h); @@ -1109,23 +958,17 @@ void wxDC::DoDrawArc( wxCoord x1, wxCoord y1, alpha2 *= -1; } Rect r = { yyc - rad, xxc - rad, yyc + rad, xxc + rad }; - /* - CGPathDrawingMode mode ; - CGContextRef cgContext = wxBeginCGContext( this , &mode ) ; - - AddEllipticArcToPath( cgContext , CGPointMake( xxc , yyc ) , rad , rad , 0 , 180 ) ; - - CGContextDrawPath( cgContext , mode ) ; - - QDEndCGContext( (CGrafPtr) m_macPort , &cgContext ) ; - */ + wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ; + CGContextRef ctx = mctx->GetNativeContext() ; + AddEllipticArcToPath( ctx , CGPointMake( xxc , yyc ) , rad , rad , 0 , 180 ) ; + CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ; } void wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, double sa, double ea ) { wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllepticArc Invalid DC")); - Rect r; + double angle = sa - ea; // Order important Mac in opposite direction to wx // we have to make sure that the filling is always counter-clockwise if ( angle > 0 ) @@ -1138,16 +981,10 @@ void wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, if (ww < 0) { ww = -ww; xx = xx - ww; } if (hh < 0) { hh = -hh; yy = yy - hh; } sa = wxConvertWXangleToMACangle(sa); - /* - CGPathDrawingMode mode ; - CGContextRef cgContext = wxBeginCGContext( this , &mode ) ; - - AddEllipticArcToPath( cgContext , CGPointMake( xx + ww / 2 , yy + hh / 2 ) , ww / 2 , hh / 2 , sa , angle) ; - - CGContextDrawPath( cgContext , mode ) ; - - QDEndCGContext( (CGrafPtr) m_macPort , &cgContext ) ; - */ + wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ; + CGContextRef ctx = mctx->GetNativeContext() ; + AddEllipticArcToPath( ctx , CGPointMake( xx + ww / 2 , yy + hh / 2 ) , ww / 2 , hh / 2 , sa , angle) ; + CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ; } void wxDC::DoDrawPoint( wxCoord x, wxCoord y ) @@ -1164,17 +1001,17 @@ void wxDC::DoDrawLines(int n, wxPoint points[], wxCoord x1, x2 , y1 , y2 ; x1 = XLOG2DEVMAC(points[0].x + xoffset); y1 = YLOG2DEVMAC(points[0].y + yoffset); - wxMacGraphicPath path ; - path.MoveToPoint( x1 , y1 ) ; + wxGraphicPath* path = m_graphicContext->CreatePath() ; + path->MoveToPoint( x1 , y1 ) ; for (int i = 1; i < n; i++) { x2 = XLOG2DEVMAC(points[i].x + xoffset); y2 = YLOG2DEVMAC(points[i].y + yoffset); - path.AddLineToPoint( x2 , y2 ) ; + path->AddLineToPoint( x2 , y2 ) ; } - path.CloseSubpath() ; - m_macGraphicContext->StrokePath( path ) ; + m_graphicContext->StrokePath( path ) ; + delete path ; } void wxDC::DoDrawPolygon(int n, wxPoint points[], @@ -1189,21 +1026,22 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[], x2 = x1 = XLOG2DEVMAC(points[0].x + xoffset); y2 = y1 = YLOG2DEVMAC(points[0].y + yoffset); - wxMacGraphicPath path ; - path.MoveToPoint( x1 , y1 ) ; + wxGraphicPath* path = m_graphicContext->CreatePath() ; + path->MoveToPoint( x1 , y1 ) ; for (int i = 1; i < n; i++) { x2 = XLOG2DEVMAC(points[i].x + xoffset); y2 = YLOG2DEVMAC(points[i].y + yoffset); - path.AddLineToPoint( x2 , y2 ) ; + path->AddLineToPoint( x2 , y2 ) ; } if ( x1 != x2 || y1 != y2 ) { - path.AddLineToPoint( x1,y1 ) ; + path->AddLineToPoint( x1,y1 ) ; } - path.CloseSubpath() ; - m_macGraphicContext->DrawPath( path , fillStyle ) ; + path->CloseSubpath() ; + m_graphicContext->DrawPath( path , fillStyle ) ; + delete path ; } void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) @@ -1227,10 +1065,11 @@ void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) hh = -hh; yy = yy - hh; } - wxMacGraphicPath path ; - path.AddRectangle(xx ,yy , ww , hh ) ; - path.CloseSubpath() ; - m_macGraphicContext->DrawPath( path ) ; + wxGraphicPath* path = m_graphicContext->CreatePath() ; + path->AddRectangle(xx ,yy , ww , hh ) ; + path->CloseSubpath() ; + m_graphicContext->DrawPath( path ) ; + delete path ; } void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, @@ -1259,16 +1098,10 @@ void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, yy = yy - hh; } Rect rect = { yy , xx , yy + hh , xx + ww } ; - if (m_brush.GetStyle() != wxTRANSPARENT) - { - MacInstallBrush() ; - ::PaintRoundRect( &rect , int(radius * 2) , int(radius * 2) ) ; - } - if (m_pen.GetStyle() != wxTRANSPARENT) - { - MacInstallPen() ; - ::FrameRoundRect( &rect , int(radius * 2) , int(radius * 2) ) ; - } + wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ; + CGContextRef ctx = mctx->GetNativeContext() ; + AddRoundedRectToPath( ctx , CGRectMake( xx , yy , ww , hh ) , 16 ,16 ) ; + CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ; } void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height) @@ -1292,24 +1125,28 @@ void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height) hh = -hh; yy = yy - hh; } - CGPoint center = CGPointMake( xx + ww / 2 , yy + hh / 2 ) ; - - wxMacGraphicPath path ; + + wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ; + CGContextRef ctx = mctx->GetNativeContext() ; if ( width == height ) - path.AddCircle( center , width / 2.0 ) ; - path.CloseSubpath() ; - m_macGraphicContext->DrawPath( path ) ; - - /* - CGPathDrawingMode mode ; - CGContextRef cgContext = wxBeginCGContext( this , &mode ) ; - - AddEllipticArcToPath( cgContext , CGPointMake( xx + ww / 2 , yy + hh / 2 ) , ww / 2 , hh / 2 , 0 , 360) ; + { + CGContextBeginPath(ctx); + CGContextAddArc(ctx , + xx + ww / 2, + yy + hh / 2, + ww / 2, + 0, + 2 * M_PI, + 0 ) ; + CGContextClosePath(ctx); - CGContextDrawPath( cgContext , mode ) ; - - QDEndCGContext( (CGrafPtr) m_macPort , &cgContext ) ; - */ + CGContextDrawPath( ctx , kCGPathFillStroke ) ; + } + else + { + AddEllipticArcToPath( ctx , CGPointMake( xx + ww / 2 , yy + hh / 2 ) , ww / 2 , hh / 2 , 0 , 360) ; + CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ; + } } bool wxDC::CanDrawBitmap(void) const @@ -1329,254 +1166,41 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, { xsrcMask = xsrc; ysrcMask = ysrc; } - // correct the parameter in case this dc does not have a mask at all - if ( useMask && !source->m_macMask ) - useMask = false ; - Rect srcrect , dstrect ; - srcrect.top = source->YLOG2DEVMAC(ysrc) ; - srcrect.left = source->XLOG2DEVMAC(xsrc) ; - srcrect.right = source->XLOG2DEVMAC(xsrc + width ) ; - srcrect.bottom = source->YLOG2DEVMAC(ysrc + height) ; - dstrect.top = YLOG2DEVMAC(ydest) ; - dstrect.left = XLOG2DEVMAC(xdest) ; - dstrect.bottom = YLOG2DEVMAC(ydest + height ) ; - dstrect.right = XLOG2DEVMAC(xdest + width ) ; - short mode = kUnsupportedMode ; - bool invertDestinationFirst = false ; - switch ( logical_func ) - { - case wxAND: // src AND dst - mode = adMin ; // ok - break ; - case wxAND_INVERT: // (NOT src) AND dst - mode = notSrcOr ; // ok - break ; - case wxAND_REVERSE:// src AND (NOT dst) - invertDestinationFirst = true ; - mode = srcOr ; - break ; - case wxCLEAR: // 0 - mode = kEmulatedMode ; - break ; - case wxCOPY: // src - mode = srcCopy ; // ok - break ; - case wxEQUIV: // (NOT src) XOR dst - mode = srcXor ; // ok - break ; - case wxINVERT: // NOT dst - mode = kEmulatedMode ; //or hilite ; - break ; - case wxNAND: // (NOT src) OR (NOT dst) - invertDestinationFirst = true ; - mode = srcBic ; - break ; - case wxNOR: // (NOT src) AND (NOT dst) - invertDestinationFirst = true ; - mode = notSrcOr ; - break ; - case wxNO_OP: // dst - mode = kEmulatedMode ; // this has already been handled upon entry - break ; - case wxOR: // src OR dst - mode = notSrcBic ; - break ; - case wxOR_INVERT: // (NOT src) OR dst - mode = srcBic ; - break ; - case wxOR_REVERSE: // src OR (NOT dst) - invertDestinationFirst = true ; - mode = notSrcBic ; - break ; - case wxSET: // 1 - mode = kEmulatedMode ; - break ; - case wxSRC_INVERT: // (NOT src) - mode = notSrcCopy ; // ok - break ; - case wxXOR: // src XOR dst - mode = notSrcXor ; // ok - break ; - default : - break ; - } - if ( mode == kUnsupportedMode ) - { - wxFAIL_MSG(wxT("unsupported blitting mode" )); - return FALSE ; - } - CGrafPtr sourcePort = (CGrafPtr) source->m_macPort ; - PixMapHandle bmappixels = GetGWorldPixMap( sourcePort ) ; - if ( LockPixels(bmappixels) ) + + wxMemoryDC* memdc = dynamic_cast(source) ; + if ( memdc ) { - if ( source->GetDepth() == 1 ) - { - RGBForeColor( &MAC_WXCOLORREF(m_textForegroundColour.GetPixel()) ) ; - RGBBackColor( &MAC_WXCOLORREF(m_textBackgroundColour.GetPixel()) ) ; - } - else - { - // the modes need this, otherwise we'll end up having really nice colors... - RGBColor white = { 0xFFFF, 0xFFFF,0xFFFF} ; - RGBColor black = { 0,0,0} ; - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - } - if ( useMask && source->m_macMask ) - { - if ( mode == srcCopy ) - { - if ( LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ) - { - CopyMask( GetPortBitMapForCopyBits( sourcePort ) , - GetPortBitMapForCopyBits( MAC_WXHBITMAP(source->m_macMask) ) , - GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) , - &srcrect, &srcrect , &dstrect ) ; - UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ; - } - } - else - { - RgnHandle clipRgn = NewRgn() ; - LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ; - BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ; - UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ; - OffsetRgn( clipRgn , -srcrect.left + dstrect.left, -srcrect.top + dstrect.top ) ; - if ( mode == kEmulatedMode ) - { - Pattern pat ; - ::PenPat(GetQDGlobalsBlack(&pat)); - if ( logical_func == wxSET ) - { - RGBColor col= { 0xFFFF, 0xFFFF, 0xFFFF } ; - ::RGBForeColor( &col ) ; - ::PaintRgn( clipRgn ) ; - } - else if ( logical_func == wxCLEAR ) - { - RGBColor col= { 0x0000, 0x0000, 0x0000 } ; - ::RGBForeColor( &col ) ; - ::PaintRgn( clipRgn ) ; - } - else if ( logical_func == wxINVERT ) - { - MacInvertRgn( clipRgn ) ; - } - else - { - for ( int y = 0 ; y < srcrect.right - srcrect.left ; ++y ) - { - for ( int x = 0 ; x < srcrect.bottom - srcrect.top ; ++x ) - { - Point dstPoint = { dstrect.top + y , dstrect.left + x } ; - Point srcPoint = { srcrect.top + y , srcrect.left + x } ; - if ( PtInRgn( dstPoint , clipRgn ) ) - { - RGBColor srcColor ; - RGBColor dstColor ; - SetPort( (GrafPtr) sourcePort ) ; - GetCPixel( srcPoint.h , srcPoint.v , &srcColor) ; - SetPort( (GrafPtr) m_macPort ) ; - GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; - wxMacCalculateColour( logical_func , srcColor , dstColor ) ; - SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; - } - } - } - } - } - else - { - if ( invertDestinationFirst ) - { - MacInvertRgn( clipRgn ) ; - } - CopyBits( GetPortBitMapForCopyBits( sourcePort ) , - GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) , - &srcrect, &dstrect, mode, clipRgn ) ; - } - DisposeRgn( clipRgn ) ; - } - } - else + wxBitmap blit = memdc->GetSelectedObject() ; + wxASSERT_MSG( blit.Ok() , wxT("Invalid bitmap for blitting") ) ; + + wxCoord xxdest = XLOG2DEVMAC(xdest); + wxCoord yydest = YLOG2DEVMAC(ydest); + wxCoord ww = XLOG2DEVREL(width); + wxCoord hh = YLOG2DEVREL(height); + + wxCoord bmpwidth = blit.GetWidth(); + wxCoord bmpheight = blit.GetHeight(); + + if ( xsrc != 0 || ysrc != 0 || bmpwidth != width || bmpheight != height ) { - RgnHandle clipRgn = NewRgn() ; - SetRectRgn( clipRgn , dstrect.left , dstrect.top , dstrect.right , dstrect.bottom ) ; - if ( mode == kEmulatedMode ) - { - Pattern pat ; - ::PenPat(GetQDGlobalsBlack(&pat)); - if ( logical_func == wxSET ) - { - RGBColor col= { 0xFFFF, 0xFFFF, 0xFFFF } ; - ::RGBForeColor( &col ) ; - ::PaintRgn( clipRgn ) ; - } - else if ( logical_func == wxCLEAR ) - { - RGBColor col= { 0x0000, 0x0000, 0x0000 } ; - ::RGBForeColor( &col ) ; - ::PaintRgn( clipRgn ) ; - } - else if ( logical_func == wxINVERT ) - { - MacInvertRgn( clipRgn ) ; - } - else - { - for ( int y = 0 ; y < srcrect.right - srcrect.left ; ++y ) - { - for ( int x = 0 ; x < srcrect.bottom - srcrect.top ; ++x ) - { - Point dstPoint = { dstrect.top + y , dstrect.left + x } ; - Point srcPoint = { srcrect.top + y , srcrect.left + x } ; - { - RGBColor srcColor ; - RGBColor dstColor ; - SetPort( (GrafPtr) sourcePort ) ; - GetCPixel( srcPoint.h , srcPoint.v , &srcColor) ; - SetPort( (GrafPtr) m_macPort ) ; - GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; - wxMacCalculateColour( logical_func , srcColor , dstColor ) ; - SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; - } - } - } - } - } - else - { - if ( invertDestinationFirst ) - { - MacInvertRgn( clipRgn ) ; - } - CopyBits( GetPortBitMapForCopyBits( sourcePort ) , - GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) , - &srcrect, &dstrect, mode, NULL ) ; - } - DisposeRgn( clipRgn ) ; + wxRect subrect( xsrc, ysrc, width , height ) ; + blit = blit.GetSubBitmap( subrect ) ; } - UnlockPixels( bmappixels ) ; + + CGContextRef cg = dynamic_cast(m_graphicContext)->GetNativeContext() ; + CGImageRef image = (CGImageRef)( blit.CGImageCreate() ) ; + HIRect r = CGRectMake( xxdest , yydest , ww , hh ) ; + HIViewDrawCGImage( cg , &r , image ) ; + CGImageRelease( image ) ; + + } + else + { + wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ; } - m_macPenInstalled = false ; - m_macBrushInstalled = false ; - m_macFontInstalled = false ; return TRUE; } -#ifndef FixedToInt -// as macro in FixMath.h for 10.3 -inline Fixed IntToFixed( int inInt ) -{ - return (((SInt32) inInt) << 16); -} - -inline int FixedToInt( Fixed inFixed ) -{ - return (((SInt32) inFixed) >> 16); -} -#endif - void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, double angle) { @@ -1585,6 +1209,8 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, if ( str.Length() == 0 ) return ; + wxCHECK_RET( m_macATSUIStyle != NULL , wxT("No valid font set") ) ; + OSStatus status = noErr ; ATSUTextLayout atsuLayout ; UniCharCount chars = str.Length() ; @@ -1615,8 +1241,6 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, int drawX = XLOG2DEVMAC(x) ; int drawY = YLOG2DEVMAC(y) ; - MacInstallFont() ; - status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ; @@ -1625,7 +1249,6 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, - CGContextSaveGState(m_macGraphicContext->GetNativeContext()); if ( abs(iAngle) > 0 ) { Fixed atsuAngle = IntToFixed( iAngle ) ; @@ -1645,7 +1268,7 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, atsuTags, atsuSizes, atsuValues ) ; } { - CGContextRef cgContext = m_macGraphicContext->GetNativeContext() ; + CGContextRef cgContext = dynamic_cast(m_graphicContext)->GetNativeContext() ; ATSUAttributeTag atsuTags[] = { kATSUCGContextTag , @@ -1675,34 +1298,38 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, if ( m_backgroundMode == wxSOLID ) { - wxMacGraphicPath path ; - path.MoveToPoint( + wxGraphicPath* path = m_graphicContext->CreatePath() ; + path->MoveToPoint( drawX , drawY ) ; - path.AddLineToPoint( + path->AddLineToPoint( drawX + sin(angle/RAD2DEG) * FixedToInt(ascent + descent) , drawY + cos(angle/RAD2DEG) * FixedToInt(ascent + descent) ) ; - path.AddLineToPoint( + path->AddLineToPoint( drawX + sin(angle/RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle/RAD2DEG) * FixedToInt(textAfter) , drawY + cos(angle/RAD2DEG) * FixedToInt(ascent + descent) - sin(angle/RAD2DEG) * FixedToInt(textAfter) ) ; - path.AddLineToPoint( + path->AddLineToPoint( drawX + cos(angle/RAD2DEG) * FixedToInt(textAfter) , drawY - sin(angle/RAD2DEG) * FixedToInt(textAfter) ) ; - m_macGraphicContext->FillPath( path , m_textBackgroundColour ) ; + m_graphicContext->FillPath( path , m_textBackgroundColour ) ; + delete path ; } drawX += (int)(sin(angle/RAD2DEG) * FixedToInt(ascent)); drawY += (int)(cos(angle/RAD2DEG) * FixedToInt(ascent)); + status = ::ATSUMeasureTextImage( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, IntToFixed(drawX) , IntToFixed(drawY) , &rect ); wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") ); - CGContextTranslateCTM(m_macGraphicContext->GetNativeContext(), drawX, drawY); - CGContextScaleCTM(m_macGraphicContext->GetNativeContext(), 1, -1); + CGContextSaveGState(dynamic_cast(m_graphicContext)->GetNativeContext()); + CGContextTranslateCTM(dynamic_cast(m_graphicContext)->GetNativeContext(), drawX, drawY); + CGContextScaleCTM(dynamic_cast(m_graphicContext)->GetNativeContext(), 1, -1); status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, IntToFixed(0) , IntToFixed(0) ); wxASSERT_MSG( status == noErr , wxT("couldn't draw the rotated text") ); + CGContextRestoreGState( dynamic_cast(m_graphicContext)->GetNativeContext() ) ; CalcBoundingBox(XDEV2LOG(rect.left), YDEV2LOG(rect.top) ); CalcBoundingBox(XDEV2LOG(rect.right), YDEV2LOG(rect.bottom) ); @@ -1711,7 +1338,6 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, #if SIZEOF_WCHAR_T == 4 free( ubuf ) ; #endif - CGContextRestoreGState( m_macGraphicContext->GetNativeContext() ) ; } void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y) @@ -1736,12 +1362,14 @@ void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *heigh { // work around the constness *((wxFont*)(&m_font)) = *theFont ; + MacInstallFont() ; } - if ( str.Length() == 0 ) return ; + wxCHECK_RET( m_macATSUIStyle != NULL , wxT("No valid font set") ) ; + OSStatus status = noErr ; ATSUTextLayout atsuLayout ; UniCharCount chars = str.Length() ; @@ -1769,7 +1397,6 @@ void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *heigh #endif #endif - MacInstallFont() ; status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ; @@ -1801,7 +1428,7 @@ void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *heigh { // work around the constness *((wxFont*)(&m_font)) = formerFont ; - m_macFontInstalled = false ; + MacInstallFont() ; } } @@ -1816,56 +1443,11 @@ bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) con if (text.Length() == 0) return false; - MacInstallFont() ; -#if TARGET_CARBON - bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ; - if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || ((wxFont*)&m_font)->GetNoAntiAliasing() ) - useGetThemeText = false ; - - if ( useGetThemeText ) - { - // If anybody knows how to do this more efficiently yet still handle - // the fractional glyph widths that may be present when using AA - // fonts, please change it. Currently it is measuring from the - // begining of the string for each succeding substring, which is much - // slower than this should be. - for (size_t i=0; iGetNativeContext() , + HIThemeDrawBackground( &rect , &drawInfo, dynamic_cast(m_graphicContext)->GetNativeContext() , kHIThemeOrientationNormal) ; } @@ -1907,12 +1489,12 @@ void wxDC::Clear(void) case kwxMacBrushColour : { RGBColor col = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) ; - CGContextSetRGBFillColor( m_macGraphicContext->GetNativeContext() , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; - CGContextFillRect(m_macGraphicContext->GetNativeContext(), rect); + CGContextSetRGBFillColor( dynamic_cast(m_graphicContext)->GetNativeContext() , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; + CGContextFillRect(dynamic_cast(m_graphicContext)->GetNativeContext(), rect); // reset to normal value col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ; - CGContextSetRGBFillColor( m_macGraphicContext->GetNativeContext() , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; + CGContextSetRGBFillColor( dynamic_cast(m_graphicContext)->GetNativeContext() , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ; } break ; } @@ -1923,439 +1505,41 @@ void wxDC::MacInstallFont() const { wxCHECK_RET(Ok(), wxT("Invalid DC")); -/* - // if ( m_macFontInstalled ) - // return ; - Pattern blackColor ; - MacSetupBackgroundForCurrentPort(m_backgroundBrush) ; - if ( m_font.Ok() ) - { - ::TextFont( m_font.MacGetFontNum() ) ; - ::TextSize( (short)(m_scaleY * m_font.MacGetFontSize()) ) ; - ::TextFace( m_font.MacGetFontStyle() ) ; - m_macFontInstalled = true ; - m_macBrushInstalled = false ; - m_macPenInstalled = false ; - RGBColor forecolor = MAC_WXCOLORREF( m_textForegroundColour.GetPixel()); - RGBColor backcolor = MAC_WXCOLORREF( m_textBackgroundColour.GetPixel()); - ::RGBForeColor( &forecolor ); - ::RGBBackColor( &backcolor ); - } - else - { - FontFamilyID fontId ; - Str255 fontName ; - SInt16 fontSize ; - Style fontStyle ; - GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ; - GetFNum( fontName, &fontId ); - ::TextFont( fontId ) ; - ::TextSize( short(m_scaleY * fontSize) ) ; - ::TextFace( fontStyle ) ; - // todo reset after spacing changes - or store the current spacing somewhere - m_macFontInstalled = true ; - m_macBrushInstalled = false ; - m_macPenInstalled = false ; - RGBColor forecolor = MAC_WXCOLORREF( m_textForegroundColour.GetPixel()); - RGBColor backcolor = MAC_WXCOLORREF( m_textBackgroundColour.GetPixel()); - ::RGBForeColor( &forecolor ); - ::RGBBackColor( &backcolor ); - } - short mode = patCopy ; - // todo : - switch( m_logicalFunction ) + if( m_macATSUIStyle ) { - case wxCOPY: // src - mode = patCopy ; - break ; - case wxINVERT: // NOT dst - ::PenPat(GetQDGlobalsBlack(&blackColor)); - mode = patXor ; - break ; - case wxXOR: // src XOR dst - mode = patXor ; - break ; - case wxOR_REVERSE: // src OR (NOT dst) - mode = notPatOr ; - break ; - case wxSRC_INVERT: // (NOT src) - mode = notPatCopy ; - break ; - case wxAND: // src AND dst - mode = adMin ; - break ; - // unsupported TODO - case wxCLEAR: // 0 - case wxAND_REVERSE:// src AND (NOT dst) - case wxAND_INVERT: // (NOT src) AND dst - case wxNO_OP: // dst - case wxNOR: // (NOT src) AND (NOT dst) - case wxEQUIV: // (NOT src) XOR dst - case wxOR_INVERT: // (NOT src) OR dst - case wxNAND: // (NOT src) OR (NOT dst) - case wxOR: // src OR dst - case wxSET: // 1 - // case wxSRC_OR: // source _bitmap_ OR destination - // case wxSRC_AND: // source _bitmap_ AND destination - break ; + ::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle); + m_macATSUIStyle = NULL ; } - ::PenMode( mode ) ; -*/ + OSStatus status = noErr ; + status = ATSUCreateAndCopyStyle( (ATSUStyle) m_font.MacGetATSUStyle() , (ATSUStyle*) &m_macATSUIStyle ) ; + wxASSERT_MSG( status == noErr , wxT("couldn't set create ATSU style") ) ; + Fixed atsuSize = IntToFixed( int(m_scaleY * m_font.MacGetFontSize()) ) ; - Style qdStyle = m_font.MacGetFontStyle() ; - ATSUFontID atsuFont = m_font.MacGetATSUFontID() ; - status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUIStyle) ; - wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") ) ; + RGBColor atsuColor = MAC_WXCOLORREF( m_textForegroundColour.GetPixel() ) ; ATSUAttributeTag atsuTags[] = { - kATSUFontTag , kATSUSizeTag , kATSUColorTag , - // kATSUBaselineClassTag , - kATSUVerticalCharacterTag, - kATSUQDBoldfaceTag , - kATSUQDItalicTag , - kATSUQDUnderlineTag , - kATSUQDCondensedTag , - kATSUQDExtendedTag , } ; ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { - sizeof( ATSUFontID ) , sizeof( Fixed ) , sizeof( RGBColor ) , - // sizeof( BslnBaselineClass ) , - sizeof( ATSUVerticalCharacterType), - sizeof( Boolean ) , - sizeof( Boolean ) , - sizeof( Boolean ) , - sizeof( Boolean ) , - sizeof( Boolean ) , } ; - Boolean kTrue = true ; - Boolean kFalse = false ; - //BslnBaselineClass kBaselineDefault = kBSLNHangingBaseline ; - ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal; +// Boolean kTrue = true ; +// Boolean kFalse = false ; + +// ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal; ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { - &atsuFont , &atsuSize , - &MAC_WXCOLORREF( m_textForegroundColour.GetPixel() ) , - // &kBaselineDefault , - &kHorizontal, - (qdStyle & bold) ? &kTrue : &kFalse , - (qdStyle & italic) ? &kTrue : &kFalse , - (qdStyle & underline) ? &kTrue : &kFalse , - (qdStyle & condense) ? &kTrue : &kFalse , - (qdStyle & extend) ? &kTrue : &kFalse , + &atsuColor , } ; status = ::ATSUSetAttributes((ATSUStyle)m_macATSUIStyle, sizeof(atsuTags)/sizeof(ATSUAttributeTag) , atsuTags, atsuSizes, atsuValues); - wxASSERT_MSG( status == noErr , wxT("couldn't set create ATSU style") ) ; -} - -Pattern gPatterns[] = -{ // hatch patterns - { { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } } , - { { 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 } } , - { { 0x80 , 0x40 , 0x20 , 0x10 , 0x08 , 0x04 , 0x02 , 0x01 } } , - { { 0x10 , 0x10 , 0x10 , 0xFF , 0x10 , 0x10 , 0x10 , 0x10 } } , - { { 0x00 , 0x00 , 0x00 , 0xFF , 0x00 , 0x00 , 0x00 , 0x00 } } , - { { 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 } } , - { { 0x81 , 0x42 , 0x24 , 0x18 , 0x18 , 0x24 , 0x42 , 0x81 } } , - // dash patterns - { { 0xCC , 0x99 , 0x33 , 0x66 , 0xCC , 0x99 , 0x33 , 0x66 } } , // DOT - { { 0xFE , 0xFD , 0xFB , 0xF7 , 0xEF , 0xDF , 0xBF , 0x7F } } , // LONG_DASH - { { 0xEE , 0xDD , 0xBB , 0x77 , 0xEE , 0xDD , 0xBB , 0x77 } } , // SHORT_DASH - { { 0xDE , 0xBD , 0x7B , 0xF6 , 0xED , 0xDB , 0xB7 , 0x6F } } , // DOT_DASH -} ; - -static void wxMacGetPattern(int penStyle, Pattern *pattern) -{ - int index = 0; // solid pattern by default - switch(penStyle) - { - // hatches - case wxBDIAGONAL_HATCH: index = 1; break; - case wxFDIAGONAL_HATCH: index = 2; break; - case wxCROSS_HATCH: index = 3; break; - case wxHORIZONTAL_HATCH: index = 4; break; - case wxVERTICAL_HATCH: index = 5; break; - case wxCROSSDIAG_HATCH: index = 6; break; - // dashes - case wxDOT: index = 7; break; - case wxLONG_DASH: index = 8; break; - case wxSHORT_DASH: index = 9; break; - case wxDOT_DASH: index = 10; break; - } - *pattern = gPatterns[index]; -} - -void wxDC::MacInstallPen() const -{ -/* - wxCHECK_RET(Ok(), wxT("Invalid DC")); - //Pattern blackColor; - // if ( m_macPenInstalled ) - // return ; - RGBColor forecolor = MAC_WXCOLORREF( m_pen.GetColour().GetPixel()); - RGBColor backcolor = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()); - ::RGBForeColor( &forecolor ); - ::RGBBackColor( &backcolor ); - ::PenNormal() ; - int penWidth = (int) (m_pen.GetWidth() * m_scaleX) ; ; - // null means only one pixel, at whatever resolution - if ( penWidth == 0 ) - penWidth = 1 ; - ::PenSize(penWidth, penWidth); - - int penStyle = m_pen.GetStyle(); - Pattern pat; - if (penStyle == wxUSER_DASH) - { - // FIXME: there should be exactly 8 items in the dash - wxDash* dash ; - int number = m_pen.GetDashes(&dash) ; - int index = 0; - for ( int i = 0 ; i < 8 ; ++i ) - { - pat.pat[i] = dash[index] ; - if (index < number - 1) - index++; - } - } - else - { - wxMacGetPattern(penStyle, &pat); - } - ::PenPat(&pat); - - short mode = patCopy ; - // todo : - switch( m_logicalFunction ) - { - case wxCOPY: // only foreground color, leave background (thus not patCopy) - mode = patOr ; - break ; - case wxINVERT: // NOT dst - // ::PenPat(GetQDGlobalsBlack(&blackColor)); - mode = patXor ; - break ; - case wxXOR: // src XOR dst - mode = patXor ; - break ; - case wxOR_REVERSE: // src OR (NOT dst) - mode = notPatOr ; - break ; - case wxSRC_INVERT: // (NOT src) - mode = notPatCopy ; - break ; - case wxAND: // src AND dst - mode = adMin ; - break ; - // unsupported TODO - case wxCLEAR: // 0 - case wxAND_REVERSE:// src AND (NOT dst) - case wxAND_INVERT: // (NOT src) AND dst - case wxNO_OP: // dst - case wxNOR: // (NOT src) AND (NOT dst) - case wxEQUIV: // (NOT src) XOR dst - case wxOR_INVERT: // (NOT src) OR dst - case wxNAND: // (NOT src) OR (NOT dst) - case wxOR: // src OR dst - case wxSET: // 1 - // case wxSRC_OR: // source _bitmap_ OR destination - // case wxSRC_AND: // source _bitmap_ AND destination - break ; - } - ::PenMode( mode ) ; - m_macPenInstalled = true ; - m_macBrushInstalled = false ; - m_macFontInstalled = false ; -*/ -} - -void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background ) -{ - Pattern whiteColor ; - switch( background.MacGetBrushKind() ) - { - case kwxMacBrushTheme : - { - ::SetThemeBackground( background.MacGetTheme() , wxDisplayDepth() , true ) ; - break ; - } - case kwxMacBrushThemeBackground : - { - Rect extent ; - ThemeBackgroundKind bg = background.MacGetThemeBackground( &extent ) ; - ::ApplyThemeBackground( bg , &extent ,kThemeStateActive , wxDisplayDepth() , true ) ; - break ; - } - case kwxMacBrushColour : - { - ::RGBBackColor( &MAC_WXCOLORREF( background.GetColour().GetPixel()) ); - int brushStyle = background.GetStyle(); - if (brushStyle == wxSOLID) - ::BackPat(GetQDGlobalsWhite(&whiteColor)); - else if (IS_HATCH(brushStyle)) - { - Pattern pat ; - wxMacGetPattern(brushStyle, &pat); - ::BackPat(&pat); - } - else - { - ::BackPat(GetQDGlobalsWhite(&whiteColor)); - } - break ; - } - } -} -void wxDC::MacInstallBrush() const -{ - wxCHECK_RET(Ok(), wxT("Invalid DC")); - Pattern blackColor ; - // if ( m_macBrushInstalled ) - // return ; - // foreground - bool backgroundTransparent = (GetBackgroundMode() == wxTRANSPARENT) ; - ::RGBForeColor( &MAC_WXCOLORREF( m_brush.GetColour().GetPixel()) ); - ::RGBBackColor( &MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) ); - int brushStyle = m_brush.GetStyle(); - if (brushStyle == wxSOLID) - { - ::PenPat(GetQDGlobalsBlack(&blackColor)); - } - else if (IS_HATCH(brushStyle)) - { - Pattern pat ; - wxMacGetPattern(brushStyle, &pat); - ::PenPat(&pat); - } - else if ( m_brush.GetStyle() == wxSTIPPLE || m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) - { - // we force this in order to be compliant with wxMSW - backgroundTransparent = false ; - // for these the text fore (and back for MASK_OPAQUE) colors are used - wxBitmap* bitmap = m_brush.GetStipple() ; - int width = bitmap->GetWidth() ; - int height = bitmap->GetHeight() ; - GWorldPtr gw = NULL ; - if ( m_brush.GetStyle() == wxSTIPPLE ) - gw = MAC_WXHBITMAP(bitmap->GetHBITMAP()) ; - else - gw = MAC_WXHBITMAP(bitmap->GetMask()->GetMaskBitmap()) ; - PixMapHandle gwpixmaphandle = GetGWorldPixMap( gw ) ; - LockPixels( gwpixmaphandle ) ; - bool isMonochrome = !IsPortColor( gw ) ; - if ( !isMonochrome ) - { - if ( (**gwpixmaphandle).pixelSize == 1 ) - isMonochrome = true ; - } - if ( isMonochrome && width == 8 && height == 8 ) - { - ::RGBForeColor( &MAC_WXCOLORREF( m_textForegroundColour.GetPixel()) ); - ::RGBForeColor( &MAC_WXCOLORREF( m_textBackgroundColour.GetPixel()) ); - BitMap* gwbitmap = (BitMap*) *gwpixmaphandle ; // since the color depth is 1 it is a BitMap - UInt8 *gwbits = (UInt8*) gwbitmap->baseAddr ; - int alignment = gwbitmap->rowBytes & 0x7FFF ; - Pattern pat ; - for ( int i = 0 ; i < 8 ; ++i ) - { - pat.pat[i] = gwbits[i*alignment+0] ; - } - UnlockPixels( GetGWorldPixMap( gw ) ) ; - ::PenPat( &pat ) ; - } - else - { - // this will be the code to handle power of 2 patterns, we will have to arrive at a nice - // caching scheme before putting this into production - Handle image; - long imageSize; - PixPatHandle pixpat = NewPixPat() ; - CopyPixMap(gwpixmaphandle, (**pixpat).patMap); - imageSize = GetPixRowBytes((**pixpat).patMap) * - ((**(**pixpat).patMap).bounds.bottom - - (**(**pixpat).patMap).bounds.top); - PtrToHand( (**gwpixmaphandle).baseAddr, &image, imageSize ); - (**pixpat).patData = image; - if ( isMonochrome ) - { - CTabHandle ctable = ((**((**pixpat).patMap)).pmTable) ; - ColorSpecPtr ctspec = (ColorSpecPtr) &(**ctable).ctTable ; - if ( ctspec[0].rgb.red == 0x0000 ) - { - ctspec[1].rgb = MAC_WXCOLORREF( m_textBackgroundColour.GetPixel()) ; - ctspec[0].rgb = MAC_WXCOLORREF( m_textForegroundColour.GetPixel()) ; - } - else - { - ctspec[0].rgb = MAC_WXCOLORREF( m_textBackgroundColour.GetPixel()) ; - ctspec[1].rgb = MAC_WXCOLORREF( m_textForegroundColour.GetPixel()) ; - } - ::CTabChanged( ctable ) ; - } - ::PenPixPat(pixpat); - m_macForegroundPixMap = pixpat ; - } - UnlockPixels( gwpixmaphandle ) ; - } - else - { - ::PenPat(GetQDGlobalsBlack(&blackColor)); - } - short mode = patCopy ; - switch( m_logicalFunction ) - { - case wxCOPY: // src - if ( backgroundTransparent ) - mode = patOr ; - else - mode = patCopy ; - break ; - case wxINVERT: // NOT dst - if ( !backgroundTransparent ) - { - ::PenPat(GetQDGlobalsBlack(&blackColor)); - } - mode = patXor ; - break ; - case wxXOR: // src XOR dst - mode = patXor ; - break ; - case wxOR_REVERSE: // src OR (NOT dst) - mode = notPatOr ; - break ; - case wxSRC_INVERT: // (NOT src) - mode = notPatCopy ; - break ; - case wxAND: // src AND dst - mode = adMin ; - break ; - // unsupported TODO - case wxCLEAR: // 0 - case wxAND_REVERSE:// src AND (NOT dst) - case wxAND_INVERT: // (NOT src) AND dst - case wxNO_OP: // dst - case wxNOR: // (NOT src) AND (NOT dst) - case wxEQUIV: // (NOT src) XOR dst - case wxOR_INVERT: // (NOT src) OR dst - case wxNAND: // (NOT src) OR (NOT dst) - case wxOR: // src OR dst - case wxSET: // 1 - // case wxSRC_OR: // source _bitmap_ OR destination - // case wxSRC_AND: // source _bitmap_ AND destination - break ; - } - ::PenMode( mode ) ; - m_macBrushInstalled = true ; - m_macPenInstalled = false ; - m_macFontInstalled = false ; + wxASSERT_MSG( status == noErr , wxT("couldn't Modify ATSU style") ) ; } // --------------------------------------------------------------------------- @@ -2401,3 +1585,6 @@ wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const { return ((wxDC *)this)->YLOG2DEVREL(y); } + +#endif // wxMAC_USE_CORE_GRAPHICS + diff --git a/src/mac/carbon/dcclient.cpp b/src/mac/carbon/dcclient.cpp index 1d9ee2a5f4..ac107c5cdf 100644 --- a/src/mac/carbon/dcclient.cpp +++ b/src/mac/carbon/dcclient.cpp @@ -109,9 +109,20 @@ wxWindowDC::wxWindowDC() wxWindowDC::wxWindowDC(wxWindow *window) { m_window = window ; +#if wxMAC_USE_CORE_GRAPHICS + if ( window->MacGetCGContextRef() ) + { + m_graphicContext = new wxMacCGContext( (CGContextRef) window->MacGetCGContextRef() ) ; + m_graphicContext->SetPen( m_pen ) ; + m_graphicContext->SetBrush( m_brush ) ; + SetBackground(MacGetBackgroundBrush(window)); + } + else + m_graphicContext = NULL ; + // there is no out-of-order drawing on OSX +#else wxTopLevelWindowMac* rootwindow = window->MacGetTopLevelWindow() ; WindowRef windowref = (WindowRef) rootwindow->MacGetWindowRef() ; - int x , y ; x = y = 0 ; window->MacWindowToRootWindow( &x , &y ) ; @@ -121,9 +132,10 @@ wxWindowDC::wxWindowDC(wxWindow *window) OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , m_macLocalOrigin.x , m_macLocalOrigin.y ) ; CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; m_macPort = UMAGetWindowPort( windowref ) ; - m_ok = TRUE ; - MacSetupGraphicContext() ; SetBackground(MacGetBackgroundBrush(window)); +#endif + m_ok = TRUE ; + SetFont( window->GetFont() ) ; } wxWindowDC::~wxWindowDC() @@ -149,6 +161,41 @@ wxClientDC::wxClientDC() wxClientDC::wxClientDC(wxWindow *window) { m_window = window ; +#if wxMAC_USE_CORE_GRAPHICS + m_graphicContext = NULL ; + if ( window->MacGetCGContextRef() ) + { + m_graphicContext = new wxMacCGContext( (CGContextRef) window->MacGetCGContextRef() ) ; + m_graphicContext->SetPen( m_pen ) ; + m_graphicContext->SetBrush( m_brush ) ; + SetBackground(MacGetBackgroundBrush(window)); + } + else + { + /* + wxTopLevelWindowMac* rootwindow = window->MacGetTopLevelWindow() ; + if (!rootwindow) + return; + WindowRef windowref = (WindowRef) rootwindow->MacGetWindowRef() ; + wxPoint origin = window->GetClientAreaOrigin() ; + wxSize size = window->GetClientSize() ; + int x , y ; + x = origin.x ; + y = origin.y ; + window->MacWindowToRootWindow( &x , &y ) ; + m_macLocalOrigin.x = x ; + m_macLocalOrigin.y = y ; + CGrafPtr port = UMAGetWindowPort( windowref ) ; + + m_graphicContext = new wxMacCGContext( port ) ; + m_graphicContext->SetPen( m_pen ) ; + m_graphicContext->SetBrush( m_brush ) ; + SetBackground(MacGetBackgroundBrush(window)); + m_ok = TRUE ; + */ + } + m_ok = TRUE ; +#else wxTopLevelWindowMac* rootwindow = window->MacGetTopLevelWindow() ; if (!rootwindow) return; @@ -167,9 +214,8 @@ wxClientDC::wxClientDC(wxWindow *window) OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , m_macLocalOrigin.x , m_macLocalOrigin.y ) ; CopyRgn( (RgnHandle) m_macBoundaryClipRgn ,(RgnHandle) m_macCurrentClipRgn ) ; m_macPort = UMAGetWindowPort( windowref ) ; - m_ok = TRUE ; - MacSetupGraphicContext() ; +#endif SetBackground(MacGetBackgroundBrush(window)); SetFont( window->GetFont() ) ; } @@ -198,6 +244,23 @@ wxPaintDC::wxPaintDC() wxPaintDC::wxPaintDC(wxWindow *window) { m_window = window ; +#if wxMAC_USE_CORE_GRAPHICS + if ( window->MacGetCGContextRef() ) + { + m_graphicContext = new wxMacCGContext( (CGContextRef) window->MacGetCGContextRef() ) ; + m_graphicContext->SetPen( m_pen ) ; + m_graphicContext->SetBrush( m_brush ) ; + SetBackground(MacGetBackgroundBrush(window)); + m_ok = TRUE ; + } + else + { + wxLogDebug(wxT("You cannot create a wxPaintDC outside an OS-draw event") ) ; + m_graphicContext = NULL ; + m_ok = TRUE ; + } + // there is no out-of-order drawing on OSX +#else wxTopLevelWindowMac* rootwindow = window->MacGetTopLevelWindow() ; WindowRef windowref = (WindowRef) rootwindow->MacGetWindowRef() ; wxPoint origin = window->GetClientAreaOrigin() ; @@ -215,10 +278,9 @@ wxPaintDC::wxPaintDC(wxWindow *window) OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , m_macLocalOrigin.x , m_macLocalOrigin.y ) ; CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; m_macPort = UMAGetWindowPort( windowref ) ; - - m_ok = TRUE ; - MacSetupGraphicContext() ; SetBackground(MacGetBackgroundBrush(window)); + m_ok = TRUE ; +#endif SetFont( window->GetFont() ) ; } diff --git a/src/mac/carbon/dcmemory.cpp b/src/mac/carbon/dcmemory.cpp index 5cf3336129..7fb6a99482 100644 --- a/src/mac/carbon/dcmemory.cpp +++ b/src/mac/carbon/dcmemory.cpp @@ -31,6 +31,7 @@ wxMemoryDC::wxMemoryDC(void) SetBackground(*wxWHITE_BRUSH); SetBrush(*wxWHITE_BRUSH); SetPen(*wxBLACK_PEN); + SetFont(*wxNORMAL_FONT) ; m_ok = FALSE; }; @@ -41,6 +42,7 @@ wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) ) SetBackground(*wxWHITE_BRUSH); SetBrush(*wxWHITE_BRUSH); SetPen(*wxBLACK_PEN); + SetFont(*wxNORMAL_FONT) ; m_ok = FALSE; }; @@ -48,7 +50,15 @@ wxMemoryDC::~wxMemoryDC() { if ( m_selected.Ok() ) { - UnlockPixels( GetGWorldPixMap(MAC_WXHBITMAP(m_selected.GetHBITMAP())) ); +#if wxMAC_USE_CORE_GRAPHICS + m_selected.EndRawAccess() ; + CGContextRef bmCtx = dynamic_cast(m_graphicContext)->GetNativeContext() ; + delete m_graphicContext ; + m_graphicContext = NULL ; + CGContextRelease( bmCtx ) ; +#else +// TODO UnlockPixels( GetGWorldPixMap(MAC_WXHBITMAP(m_selected.GetHBITMAP())) ); +#endif } }; @@ -56,20 +66,55 @@ void wxMemoryDC::SelectObject( const wxBitmap& bitmap ) { if ( m_selected.Ok() ) { - UnlockPixels( GetGWorldPixMap(MAC_WXHBITMAP(m_selected.GetHBITMAP())) ); +#if wxMAC_USE_CORE_GRAPHICS + m_selected.EndRawAccess() ; + CGContextRef bmCtx = dynamic_cast(m_graphicContext)->GetNativeContext() ; + delete m_graphicContext ; + m_graphicContext = NULL ; + CGContextRelease( bmCtx ) ; +#else +// TODO UnlockPixels( GetGWorldPixMap(MAC_WXHBITMAP(m_selected.GetHBITMAP())) ); +#endif } m_selected = bitmap; if (m_selected.Ok()) { - if ( m_selected.GetHBITMAP() ) +#if wxMAC_USE_CORE_GRAPHICS + m_selected.UseAlpha() ; + void * data = m_selected.BeginRawAccess() ; + + int bitsPerComp = 8 ; + int bytesPerPixel = 4 ; + int w = bitmap.GetWidth() ; + int h = bitmap.GetHeight() ; + CGImageAlphaInfo a = kCGImageAlphaNoneSkipFirst ; + CGColorSpaceRef genericColorSpace = wxMacGetGenericRGBColorSpace(); + CGContextRef bmCtx = CGBitmapContextCreate(data , w, h, bitsPerComp , bytesPerPixel * w , genericColorSpace, a); + wxASSERT_MSG( bmCtx , wxT("Unable to create bitmap context") ) ; + + CGContextSetFillColorSpace(bmCtx, genericColorSpace); + CGContextSetStrokeColorSpace(bmCtx, genericColorSpace); + + if( bmCtx ) + { + CGContextTranslateCTM( bmCtx , 0 , m_selected.GetHeight() ) ; + CGContextScaleCTM( bmCtx , 1 , -1 ) ; + m_graphicContext = new wxMacCGContext( bmCtx ) ; + m_graphicContext->SetPen( m_pen ) ; + m_graphicContext->SetBrush( m_brush ) ; + } + m_ok = (m_graphicContext != NULL) ; +#else + if ( ( m_macPort = m_selected.GetHBITMAP( &m_macMask ) ) != NULL ) { - m_macPort = (GrafPtr) m_selected.GetHBITMAP() ; LockPixels( GetGWorldPixMap( (CGrafPtr) m_macPort ) ) ; + /* wxMask * mask = bitmap.GetMask() ; if ( mask ) { - m_macMask = mask->GetMaskBitmap() ; + m_macMask = mask->GetHBITMAP() ; } + */ SetRectRgn( (RgnHandle) m_macBoundaryClipRgn , 0 , 0 , m_selected.GetWidth() , m_selected.GetHeight() ) ; CopyRgn( (RgnHandle) m_macBoundaryClipRgn ,(RgnHandle) m_macCurrentClipRgn ) ; m_ok = TRUE ; @@ -78,6 +123,7 @@ void wxMemoryDC::SelectObject( const wxBitmap& bitmap ) { m_ok = FALSE; } +#endif } else { diff --git a/src/mac/carbon/dcprint.cpp b/src/mac/carbon/dcprint.cpp index aa3af95619..d4f9108987 100644 --- a/src/mac/carbon/dcprint.cpp +++ b/src/mac/carbon/dcprint.cpp @@ -106,6 +106,15 @@ bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ; +#if wxMAC_USE_CORE_GRAPHICS + { + CFStringRef s[1] = { kPMGraphicsContextCoreGraphics }; + CFArrayRef graphicsContextsArray = CFArrayCreate(NULL, (const void**)s, 1, &kCFTypeArrayCallBacks); + PMSessionSetDocumentFormatGeneration(native->m_macPrintSession, kPMDocumentFormatPDF, graphicsContextsArray, NULL); + CFRelease(graphicsContextsArray); + } +#endif + m_err = PMSessionBeginDocument(native->m_macPrintSession, native->m_macPrintSettings, native->m_macPageFormat); @@ -143,11 +152,21 @@ void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc ) native->m_macPageFormat, nil); +#if wxMAC_USE_CORE_GRAPHICS + CGContextRef pageContext; +#endif if ( m_err == noErr ) { +#if wxMAC_USE_CORE_GRAPHICS m_err = PMSessionGetGraphicsContext(native->m_macPrintSession, - nil, + kPMGraphicsContextCoreGraphics, + (void**) &pageContext ); + dc->MacSetCGContext(pageContext) ; +#else + m_err = PMSessionGetGraphicsContext(native->m_macPrintSession, + kPMGraphicsContextQuickdraw, (void**) &dc->m_macPort ); +#endif } if ( m_err != noErr ) @@ -162,8 +181,13 @@ void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc ) m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); if ( !m_err ) { +#if wxMAC_USE_CORE_GRAPHICS + CGContextTranslateCTM( pageContext , 0 , rPage.bottom - rPage.top ) ; + CGContextScaleCTM( pageContext , 1 , -1 ) ; +#else dc->m_macLocalOrigin.x = (int) rPage.left; dc->m_macLocalOrigin.y = (int) rPage.top; +#endif } // since this is a non-critical error, we set the flag back m_err = noErr ; @@ -313,7 +337,6 @@ wxPrinterDC::wxPrinterDC(const wxPrintData& printdata) if ( m_nativePrinterDC ) { m_ok = m_nativePrinterDC->Ok() ; - if ( !m_ok ) { wxString message ; @@ -321,6 +344,10 @@ wxPrinterDC::wxPrinterDC(const wxPrintData& printdata) wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; dialog.ShowModal(); } +#if wxMAC_USE_CORE_GRAPHICS + // the cgContext will only be handed over page by page + m_graphicContext = new wxMacCGContext() ; +#endif } } @@ -329,6 +356,14 @@ wxPrinterDC::~wxPrinterDC(void) delete m_nativePrinterDC ; } +#if wxMAC_USE_CORE_GRAPHICS +void wxPrinterDC::MacSetCGContext( void * cg ) +{ + dynamic_cast(m_graphicContext)->SetNativeContext( (CGContextRef) cg ) ; + m_graphicContext->SetPen( m_pen ) ; + m_graphicContext->SetBrush( m_brush ) ; +} +#endif bool wxPrinterDC::StartDoc( const wxString& message ) { wxASSERT_MSG( Ok() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ; @@ -384,10 +419,11 @@ void wxPrinterDC::StartPage(void) m_font = *wxNORMAL_FONT; m_brush = *wxTRANSPARENT_BRUSH; m_backgroundBrush = *wxWHITE_BRUSH; - +#if !wxMAC_USE_CORE_GRAPHICS m_macFontInstalled = false ; m_macBrushInstalled = false ; m_macPenInstalled = false ; +#endif m_nativePrinterDC->StartPage(this) ; m_ok = m_nativePrinterDC->Ok() ; diff --git a/src/mac/carbon/dcscreen.cpp b/src/mac/carbon/dcscreen.cpp index 437e612a3a..451f2d7989 100644 --- a/src/mac/carbon/dcscreen.cpp +++ b/src/mac/carbon/dcscreen.cpp @@ -25,7 +25,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxWindowDC) // Create a DC representing the whole screen wxScreenDC::wxScreenDC() { -#if TARGET_CARBON +#if wxMAC_USE_CORE_GRAPHICS +#else m_macPort = CreateNewPort() ; GrafPtr port ; GetPort( &port ) ; @@ -35,31 +36,29 @@ wxScreenDC::wxScreenDC() SetPort( port ) ; m_macLocalOrigin.x = -pt.h ; m_macLocalOrigin.y = -pt.v ; -#else - m_macPort = LMGetWMgrPort() ; - m_macLocalOrigin.x = 0 ; - m_macLocalOrigin.y = 0 ; -#endif + m_ok = TRUE ; BitMap screenBits; GetQDGlobalsScreenBits( &screenBits ); m_minX = screenBits.bounds.left ; - #if TARGET_CARBON + SInt16 height ; GetThemeMenuBarHeight( &height ) ; m_minY = screenBits.bounds.top + height ; - #else - m_minY = screenBits.bounds.top + LMGetMBarHeight() ; - #endif + m_maxX = screenBits.bounds.right ; m_maxY = screenBits.bounds.bottom ; MacSetRectRgn( (RgnHandle) m_macBoundaryClipRgn , m_minX , m_minY , m_maxX , m_maxY ) ; OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , m_macLocalOrigin.x , m_macLocalOrigin.y ) ; CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; +#endif } wxScreenDC::~wxScreenDC() { +#if wxMAC_USE_CORE_GRAPHICS +#else DisposePort( (CGrafPtr) m_macPort ) ; +#endif } diff --git a/src/mac/carbon/display.cpp b/src/mac/carbon/display.cpp index 8c6bc2b09e..f09d7b1f75 100644 --- a/src/mac/carbon/display.cpp +++ b/src/mac/carbon/display.cpp @@ -46,6 +46,176 @@ // private classes // ---------------------------------------------------------------------------- +#ifdef __WXMAC_OSX__ + +class wxDisplayMacPriv +{ +public: + CGDirectDisplayID m_id; +}; + +size_t wxDisplayBase::GetCount() +{ + CGDisplayCount count; +#ifdef __WXDEBUG__ + CGDisplayErr err = +#endif + CGGetActiveDisplayList(0, NULL, &count); + + wxASSERT(err == CGDisplayNoErr); + return count; +} + +int wxDisplayBase::GetFromPoint(const wxPoint &p) +{ + CGPoint thePoint = {(float)p.x, (float)p.y}; + CGDirectDisplayID theID; + CGDisplayCount theCount; + CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount); + wxASSERT(err == CGDisplayNoErr); + int nWhich = -1; + + if (theCount) + { + theCount = GetCount(); + CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; + err = CGGetActiveDisplayList(theCount, theIDs, &theCount); + wxASSERT(err == CGDisplayNoErr); + + for(nWhich = 0; nWhich < (int) theCount; ++nWhich) + { + if(theIDs[nWhich] == theID) + break; + } + + delete[] theIDs; + + if(nWhich == (int) theCount) + { + wxFAIL_MSG(wxT("Failed to find display in display list")); + nWhich = -1; + } + } + + return nWhich; +}//CFUserNotification[NSBundle bundleForClass:[self class]] + +wxDisplay::wxDisplay(size_t index) : wxDisplayBase ( index ) , + m_priv ( new wxDisplayMacPriv() ) +{ + CGDisplayCount theCount = GetCount(); + CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; +#ifdef __WXDEBUG__ + CGDisplayErr err = +#endif + CGGetActiveDisplayList(theCount, theIDs, &theCount); + + wxASSERT(err == CGDisplayNoErr); + wxASSERT(index < theCount); + + m_priv->m_id = theIDs[index]; + + delete[] theIDs; +} + +wxRect wxDisplay::GetGeometry() const +{ + CGRect theRect = CGDisplayBounds(m_priv->m_id); + return wxRect( (int)theRect.origin.x, + (int)theRect.origin.y, + (int)theRect.size.width, + (int)theRect.size.height ); //floats +} + +int wxDisplay::GetDepth() const +{ + return (int) CGDisplayBitsPerPixel(m_priv->m_id); //size_t +} + +wxString wxDisplay::GetName() const +{ + // Macs don't name their displays... + return wxEmptyString; +} + +static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key ) +{ + CFNumberRef value; + int num = 0; + + if ( (value = (CFNumberRef) CFDictionaryGetValue(desc, key)) == NULL ) + return 0; + CFNumberGetValue(value, kCFNumberIntType, &num); + return num; +} + +wxArrayVideoModes + wxDisplay::GetModes(const wxVideoMode& mode) const +{ + wxArrayVideoModes Modes; + + CFArrayRef theArray = CGDisplayAvailableModes(m_priv->m_id); + + for(CFIndex i = 0; i < CFArrayGetCount(theArray); ++i) + { + CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex(theArray, i); + + wxVideoMode theMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth), + wxCFDictKeyToInt(theValue, kCGDisplayHeight), + wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel), + wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate)); + + if (theMode.Matches(mode)) + Modes.Add(theMode); + } + + return Modes; +} + +wxVideoMode wxDisplay::GetCurrentMode() const +{ + CFDictionaryRef theValue = CGDisplayCurrentMode (m_priv->m_id); + + return wxVideoMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth), + wxCFDictKeyToInt(theValue, kCGDisplayHeight), + wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel), + wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate)); +} + +bool wxDisplay::ChangeMode(const wxVideoMode& mode) +{ + //Changing to default mode (wxDefualtVideoMode) doesn't + //work because we don't have access to the system's 'scrn' + //resource which holds the user's mode which the system + //will return to after this app is done + boolean_t bExactMatch; + CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate ( + m_priv->m_id, + (size_t)mode.bpp, + (size_t)mode.w, + (size_t)mode.h, + (double)mode.refresh, + &bExactMatch); + + bool bOK = bExactMatch; + + if(bOK) + bOK = CGDisplaySwitchToMode(m_priv->m_id, theCGMode) == CGDisplayNoErr; + + return bOK; +} + +wxDisplay::~wxDisplay() +{ + if ( m_priv ) + { + delete m_priv; + m_priv = 0; + } +} + +#else + class wxDisplayMacPriv { public: @@ -460,4 +630,6 @@ wxDisplay::~wxDisplay() } } +#endif // !OSX + #endif // wxUSE_DISPLAY diff --git a/src/mac/carbon/icon.cpp b/src/mac/carbon/icon.cpp index 25543c1e95..914b40b46b 100644 --- a/src/mac/carbon/icon.cpp +++ b/src/mac/carbon/icon.cpp @@ -33,20 +33,22 @@ wxIcon::wxIcon() { } -wxIcon::wxIcon(const char bits[], int width, int height) : - wxBitmap(bits, width, height) +wxIcon::wxIcon(const char bits[], int width, int height) { - + wxBitmap bmp(bits,width,height) ; + CopyFromBitmap( bmp ) ; } -wxIcon::wxIcon( const char **bits ) : - wxBitmap(bits) +wxIcon::wxIcon( const char **bits ) { + wxBitmap bmp(bits) ; + CopyFromBitmap( bmp ) ; } -wxIcon::wxIcon( char **bits ) : - wxBitmap(bits) +wxIcon::wxIcon( char **bits ) { + wxBitmap bmp(bits) ; + CopyFromBitmap( bmp ) ; } wxIcon::wxIcon(const wxString& icon_file, int flags, @@ -59,42 +61,135 @@ wxIcon::~wxIcon() { } +WXHICON wxIcon::GetHICON() const +{ + wxASSERT( Ok() ) ; + return (WXHICON) ((wxIconRefData*)m_refData)->GetHICON() ; +} + +int wxIcon::GetWidth() const +{ + return 32 ; +} + +int wxIcon::GetHeight() const +{ + return 32 ; +} + +bool wxIcon::Ok() const +{ + return m_refData != NULL ; +} + bool wxIcon::LoadFile(const wxString& filename, wxBitmapType type, int desiredWidth, int desiredHeight) { UnRef(); - wxBitmapHandler *handler = FindHandler(type); - - if ( handler ) + if ( type == wxBITMAP_TYPE_ICON_RESOURCE ) { - m_refData = new wxBitmapRefData; - return handler->LoadFile(this, filename, type, desiredWidth, desiredHeight ); + OSType theId = 0 ; + if ( filename == wxT("wxICON_INFORMATION") ) + { + theId = kAlertNoteIcon ; + } + else if ( filename == wxT("wxICON_QUESTION") ) + { + theId = kAlertCautionIcon ; + } + else if ( filename == wxT("wxICON_WARNING") ) + { + theId = kAlertCautionIcon ; + } + else if ( filename == wxT("wxICON_ERROR") ) + { + theId = kAlertStopIcon ; + } + else + {/* + Str255 theName ; + OSType theType ; + wxMacStringToPascal( name , theName ) ; + + Handle resHandle = GetNamedResource( 'cicn' , theName ) ; + if ( resHandle != 0L ) + { + GetResInfo( resHandle , &theId , &theType , theName ) ; + ReleaseResource( resHandle ) ; + } + */ + } + if ( theId != 0 ) + { + IconRef iconRef = NULL ; + verify_noerr(GetIconRef(kOnSystemDisk,kSystemIconsCreator,theId, &iconRef)) ; + if ( iconRef ) + { + m_refData = new wxIconRefData( (WXHICON) iconRef ) ; + return TRUE ; + } + } + return FALSE ; } else { - wxImage loadimage(filename, type); - if (loadimage.Ok()) + wxBitmapHandler *handler = wxBitmap::FindHandler(type); + + if ( handler ) { - if ( desiredWidth == -1 ) - desiredWidth = loadimage.GetWidth() ; - if ( desiredHeight == -1 ) - desiredHeight = loadimage.GetHeight() ; - if ( desiredWidth != loadimage.GetWidth() || desiredHeight != loadimage.GetHeight() ) - loadimage.Rescale( desiredWidth , desiredHeight ) ; - wxBitmap bmp( loadimage ); - wxIcon *icon = (wxIcon*)(&bmp); - *this = *icon; - return true; + wxBitmap bmp ; + if ( handler->LoadFile(&bmp , filename, type, desiredWidth, desiredHeight )) + { + CopyFromBitmap( bmp ) ; + return true ; + } + return false ; + } + else + { + wxImage loadimage(filename, type); + if (loadimage.Ok()) + { + if ( desiredWidth == -1 ) + desiredWidth = loadimage.GetWidth() ; + if ( desiredHeight == -1 ) + desiredHeight = loadimage.GetHeight() ; + if ( desiredWidth != loadimage.GetWidth() || desiredHeight != loadimage.GetHeight() ) + loadimage.Rescale( desiredWidth , desiredHeight ) ; + wxBitmap bmp( loadimage ); + CopyFromBitmap( bmp ) ; + return true; + } } } - return false ; + return true ; } void wxIcon::CopyFromBitmap(const wxBitmap& bmp) { - wxIcon *icon = (wxIcon*)(&bmp); - *this = *icon; + UnRef() ; + + m_refData = new wxIconRefData( (WXHICON) wxMacCreateIconRef( bmp ) ) ; +} + +wxIconRefData::wxIconRefData( WXHICON icon ) +{ + m_iconRef = MAC_WXHICON( icon ) ; +} + +void wxIconRefData::Init() +{ + m_iconRef = NULL ; +} + +void wxIconRefData::Free() +{ + if ( m_iconRef ) + { + ReleaseIconRef( m_iconRef ) ; + m_iconRef = NULL ; + } } IMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler, wxBitmapHandler) @@ -102,51 +197,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler, wxBitmapHandler) bool wxICONResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags, int desiredWidth, int desiredHeight) { - short theId = -1 ; - if ( name == wxT("wxICON_INFORMATION") ) - { - theId = kNoteIcon ; - } - else if ( name == wxT("wxICON_QUESTION") ) - { - theId = kCautionIcon ; - } - else if ( name == wxT("wxICON_WARNING") ) - { - theId = kCautionIcon ; - } - else if ( name == wxT("wxICON_ERROR") ) - { - theId = kStopIcon ; - } - else - { - Str255 theName ; - OSType theType ; - wxMacStringToPascal( name , theName ) ; - - Handle resHandle = GetNamedResource( 'cicn' , theName ) ; - if ( resHandle != 0L ) - { - GetResInfo( resHandle , &theId , &theType , theName ) ; - ReleaseResource( resHandle ) ; - } - } - if ( theId != -1 ) - { - CIconHandle theIcon = (CIconHandle ) GetCIcon( theId ) ; - if ( theIcon ) - { - M_BITMAPHANDLERDATA->m_hIcon = theIcon ; - M_BITMAPHANDLERDATA->m_width = 32 ; - M_BITMAPHANDLERDATA->m_height = 32 ; - - M_BITMAPHANDLERDATA->m_depth = 8 ; - M_BITMAPHANDLERDATA->m_ok = true ; - M_BITMAPHANDLERDATA->m_numColors = 256 ; - M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypeIcon ; - return TRUE ; - } - } - return FALSE ; + wxIcon icon ; + icon.LoadFile( name , wxBITMAP_TYPE_ICON_RESOURCE , desiredWidth , desiredHeight ) ; + bitmap->CopyFromIcon( icon ) ; + return bitmap->Ok() ; } diff --git a/src/mac/carbon/listbox.cpp b/src/mac/carbon/listbox.cpp index b4b4edc23d..7e88b14f92 100644 --- a/src/mac/carbon/listbox.cpp +++ b/src/mac/carbon/listbox.cpp @@ -609,7 +609,6 @@ int wxListBox::GetCount() const void wxListBox::Refresh(bool eraseBack, const wxRect *rect) { wxControl::Refresh( eraseBack , rect ) ; - // MacRedrawControl() ; } #if wxUSE_OWNER_DRAWN diff --git a/src/mac/carbon/mediactrl.cpp b/src/mac/carbon/mediactrl.cpp index 4124a096ee..db6aed6903 100644 --- a/src/mac/carbon/mediactrl.cpp +++ b/src/mac/carbon/mediactrl.cpp @@ -118,7 +118,11 @@ public: void FinishLoad(); wxSize m_bestSize; //Original movie size +#ifdef __WXMAC_OSX__ struct MovieType** m_movie; //QT Movie handle/instance +#else + Movie m_movie ; +#endif wxControl* m_ctrl; //Parent control bool m_bVideo; //Whether or not we have video class _wxQTTimer* m_timer; //Timer for streaming the movie diff --git a/src/mac/carbon/menuitem.cpp b/src/mac/carbon/menuitem.cpp index 36c90003f5..6974e7870c 100644 --- a/src/mac/carbon/menuitem.cpp +++ b/src/mac/carbon/menuitem.cpp @@ -94,6 +94,7 @@ void wxMenuItem::UpdateItemBitmap() SetMenuItemIconHandle( mhandle , index , kMenuColorIconType , (Handle) info.u.cIconHandle ) ; } + wxMacReleaseBitmapButton( &info ) ; } } diff --git a/src/mac/carbon/metafile.cpp b/src/mac/carbon/metafile.cpp index b5e3e7c779..354e4e5b1f 100644 --- a/src/mac/carbon/metafile.cpp +++ b/src/mac/carbon/metafile.cpp @@ -121,9 +121,12 @@ bool wxMetaFile::Play(wxDC *dc) return FALSE; { +#if wxMAC_USE_CORE_GRAPHICS +#else wxMacPortSetter helper( dc ) ; PicHandle pict = (PicHandle) GetHMETAFILE() ; DrawPicture( pict , &(**pict).picFrame ) ; +#endif } return TRUE; } @@ -158,15 +161,17 @@ wxMetaFileDC::wxMetaFileDC(const wxString& filename , wxASSERT_MSG( filename.IsEmpty() , _T("no file based metafile support yet")) ; m_metaFile = new wxMetaFile(filename) ; +#if wxMAC_USE_CORE_GRAPHICS +#else Rect r={0,0,height,width} ; RectRgn( (RgnHandle) m_macBoundaryClipRgn , &r ) ; CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; - m_metaFile->SetHMETAFILE( OpenPicture( &r ) ) ; + m_metaFile->SetHMETAFILE( (WXHMETAFILE) OpenPicture( &r ) ) ; ::GetPort( (GrafPtr*) &m_macPort ) ; m_ok = TRUE ; - +#endif SetMapMode(wxMM_TEXT); } @@ -207,7 +212,7 @@ bool wxMetafileDataObject::SetData(size_t len, const void *buf) Handle handle = NewHandle( len ) ; SetHandleSize( handle , len ) ; memcpy( *handle , buf , len ) ; - m_metafile.SetHMETAFILE( handle ) ; + m_metafile.SetHMETAFILE( (WXHMETAFILE) handle ) ; return true ; } #endif diff --git a/src/mac/carbon/notebmac.cpp b/src/mac/carbon/notebmac.cpp index 6f2685f3c0..752b676d79 100644 --- a/src/mac/carbon/notebmac.cpp +++ b/src/mac/carbon/notebmac.cpp @@ -346,46 +346,21 @@ void wxNotebook::MacSetupTabs() wxMacStringToPascal( page->GetLabel() , info.name ) ; m_peer->SetData( ii+1, kControlTabInfoTag, &info ) ; m_peer->SetTabEnabled( ii + 1 , true ) ; -#if TARGET_CARBON + if ( GetImageList() && GetPageImage(ii) >= 0 && UMAGetSystemVersion() >= 0x1020 ) { - // tab controls only support very specific types of images, therefore we are doing an odyssee - // accross the icon worlds (even Apple DTS did not find a shorter path) - // in order not to pollute the icon registry we put every icon into (OSType) 1 and immediately - // afterwards Unregister it (IconRef is ref counted, so it will stay on the tab even if we - // unregister it) in case this will ever lead to having the same icon everywhere add some kind - // of static counter const wxBitmap* bmap = GetImageList()->GetBitmap( GetPageImage(ii ) ) ; if ( bmap ) { - wxBitmap scaledBitmap ; - if ( bmap->GetWidth() != 16 || bmap->GetHeight() != 16 ) - { - scaledBitmap = wxBitmap( bmap->ConvertToImage().Scale(16,16) ) ; - bmap = &scaledBitmap ; - } ControlButtonContentInfo info ; - wxMacCreateBitmapButton( &info , *bmap , kControlContentPictHandle) ; - IconFamilyHandle iconFamily = (IconFamilyHandle) NewHandle(0) ; - OSErr err = SetIconFamilyData( iconFamily, 'PICT' , (Handle) info.u.picture ) ; - wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; - IconRef iconRef ; - err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) 1, iconFamily, &iconRef ) ; - wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; - info.contentType = kControlContentIconRef ; - info.u.iconRef = iconRef ; - m_peer->SetData( ii+1,kControlTabImageContentTag, &info ); + + wxMacCreateBitmapButton( &info , *bmap ) ; + OSStatus err = m_peer->SetData( ii+1,kControlTabImageContentTag, &info ); wxASSERT_MSG( err == noErr , wxT("Error when setting icon on tab") ) ; - if ( UMAGetSystemVersion() < 0x1030 ) - { - UnregisterIconRef( 'WXNG' , (OSType) 1 ) ; - } - - ReleaseIconRef( iconRef ) ; - DisposeHandle( (Handle) iconFamily ) ; + wxMacReleaseBitmapButton( &info ) ; } } -#endif + } Rect bounds; m_peer->GetRectInWindowCoords( &bounds ) ; diff --git a/src/mac/carbon/pnghand.cpp b/src/mac/carbon/pnghand.cpp index 084f5e4bb8..bbcfcbec45 100644 --- a/src/mac/carbon/pnghand.cpp +++ b/src/mac/carbon/pnghand.cpp @@ -21,7 +21,7 @@ # pragma hdrstop #endif -#if wxUSE_LIBPNG +#if 0 // wxUSE_LIBPNG #include #include diff --git a/src/mac/carbon/radiobut.cpp b/src/mac/carbon/radiobut.cpp index 3fd1a3fae2..6819f25a91 100644 --- a/src/mac/carbon/radiobut.cpp +++ b/src/mac/carbon/radiobut.cpp @@ -75,21 +75,22 @@ bool wxRadioButton::Create(wxWindow *parent, wxWindowID id, void wxRadioButton::SetValue(bool val) { wxRadioButton *cycle; - if ( m_peer->GetValue() == val ) + if ( m_peer->GetValue() == val ) return ; - m_peer->SetValue( val ) ; - if (val) - { - cycle=this->NextInCycle(); - if (cycle!=NULL) { - while (cycle!=this) { - cycle->SetValue(false); - cycle=cycle->NextInCycle(); - } - } + m_peer->SetValue( val ) ; + if (val) + { + cycle=this->NextInCycle(); + if (cycle!=NULL) + { + while (cycle!=this) + { + cycle->SetValue(false); + cycle=cycle->NextInCycle(); } - MacRedrawControl() ; + } + } } bool wxRadioButton::GetValue() const diff --git a/src/mac/carbon/region.cpp b/src/mac/carbon/region.cpp index f0054d35bc..ab42453470 100644 --- a/src/mac/carbon/region.cpp +++ b/src/mac/carbon/region.cpp @@ -399,6 +399,40 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region) /*! * Reset iterator for a new /e region. */ + +OSStatus wxMacRegionToRectsCounterCallback ( + UInt16 message, RgnHandle region, const Rect *rect, void *data) +{ + long *m_numRects = (long*) data ; + if ( message == kQDRegionToRectsMsgInit ) + { + (*m_numRects) = 0 ; + } + else if (message == kQDRegionToRectsMsgParse) + { + (*m_numRects) += 1 ; + } + return noErr; +} + +class RegionToRectsCallbackData +{ +public : + wxRect* m_rects ; + long m_current ; +} ; + +OSStatus wxMacRegionToRectsSetterCallback ( + UInt16 message, RgnHandle region, const Rect *rect, void *data) +{ + if (message == kQDRegionToRectsMsgParse) + { + RegionToRectsCallbackData *cb = (RegionToRectsCallbackData*) data ; + cb->m_rects[cb->m_current] = wxRect( rect->left , rect->top , rect->right - rect->left , rect->bottom - rect->top ) ; + } + return noErr; +} + void wxRegionIterator::Reset(const wxRegion& region) { m_current = 0; @@ -413,15 +447,25 @@ void wxRegionIterator::Reset(const wxRegion& region) m_numRects = 0; else { - // we cannot dissolve it into rects on mac - m_rects = new wxRect[1]; - Rect rect ; - GetRegionBounds( OTHER_M_REGION( region ) , &rect ) ; - m_rects[0].x = rect.left; - m_rects[0].y = rect.top; - m_rects[0].width = rect.right - rect.left; - m_rects[0].height = rect.bottom - rect.top; - m_numRects = 1; + RegionToRectsUPP proc = NewRegionToRectsUPP (wxMacRegionToRectsCounterCallback); + + OSStatus err = noErr; + err = QDRegionToRects (OTHER_M_REGION( region ) , kQDParseRegionFromTopLeft, proc, (void*)&m_numRects); + if (err == noErr) + { + DisposeRegionToRectsUPP (proc); + proc = NewRegionToRectsUPP (wxMacRegionToRectsSetterCallback); + m_rects = new wxRect[m_numRects]; + RegionToRectsCallbackData data ; + data.m_rects = m_rects ; + data.m_current = 0 ; + QDRegionToRects (OTHER_M_REGION( region ) , kQDParseRegionFromTopLeft, proc, (void*)&data); + } + else + { + m_numRects = 0 ; + } + DisposeRegionToRectsUPP (proc); } } diff --git a/src/mac/carbon/renderer.cpp b/src/mac/carbon/renderer.cpp index 571c40c75d..c1cf97a2e4 100644 --- a/src/mac/carbon/renderer.cpp +++ b/src/mac/carbon/renderer.cpp @@ -270,6 +270,8 @@ wxRendererMac::DrawSplitterSash(wxWindow *win, } else { +#if wxMAC_USE_CORE_GRAPHICS +#else CGContextRef cgContext ; Rect bounds ; GetPortBounds( (CGrafPtr) dc.m_macPort , &bounds ) ; @@ -285,6 +287,7 @@ wxRendererMac::DrawSplitterSash(wxWindow *win, HIThemeDrawPaneSplitter( &splitterRect , &drawInfo , cgContext , kHIThemeOrientationNormal ) ; } QDEndCGContext( (CGrafPtr) dc.m_macPort , &cgContext ) ; +#endif } } else diff --git a/src/mac/carbon/scrolbar.cpp b/src/mac/carbon/scrolbar.cpp index 4dd6127cfb..1b253bad4f 100644 --- a/src/mac/carbon/scrolbar.cpp +++ b/src/mac/carbon/scrolbar.cpp @@ -84,9 +84,6 @@ void wxScrollBar::SetScrollbar(int position, int thumbSize, int range, int pageS m_peer->SetMinimum( 0 ) ; m_peer->SetValue( position ) ; m_peer->SetViewSize( m_viewSize ) ; - - if ( refresh ) - MacRedrawControl() ; } diff --git a/src/mac/carbon/taskbar.cpp b/src/mac/carbon/taskbar.cpp index e94ae77d65..c110b0c535 100644 --- a/src/mac/carbon/taskbar.cpp +++ b/src/mac/carbon/taskbar.cpp @@ -176,39 +176,45 @@ wxMenu* wxTaskBarIcon::DoCreatePopupMenu() // Operations: bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip) { - wxMask* mask = icon.GetMask(); + wxBitmap bmp( icon ) ; + OSStatus err = noErr ; + + CGImageRef pImage; + +#if wxMAC_USE_CORE_GRAPHICS + pImage = bmp.CGImageCreate() ; +#else + wxMask* mask = bmp.GetMask(); if (!mask) { // Make a mask with no transparent pixels - wxBitmap bmp(icon.GetWidth(), icon.GetHeight()); + wxBitmap mbmp(icon.GetWidth(), icon.GetHeight()); wxMemoryDC dc; - dc.SelectObject(bmp); + dc.SelectObject(mbmp); dc.SetBackground(*wxBLACK_BRUSH); dc.Clear(); dc.SelectObject(wxNullBitmap); - mask = new wxMask(bmp, *wxWHITE); + bmp.SetMask( new wxMask(mbmp, *wxWHITE) ) ; } - - CGImageRef pImage; //create the icon from the bitmap and mask bitmap contained within - OSStatus err = CreateCGImageFromPixMaps( - GetGWorldPixMap(MAC_WXHBITMAP(icon.GetHBITMAP())), - GetGWorldPixMap(MAC_WXHBITMAP(mask->GetMaskBitmap())), - &pImage - ); - + WXHBITMAP iconport ; + WXHBITMAP maskport ; + iconport = bmp.GetHBITMAP( &maskport ) ; + err = CreateCGImageFromPixMaps( + GetGWorldPixMap(MAC_WXHBITMAP(iconport)), + GetGWorldPixMap(MAC_WXHBITMAP(maskport)), + &pImage + ); wxASSERT(err == 0); - +#endif + wxASSERT(pImage != NULL ); err = SetApplicationDockTileImage(pImage); - + wxASSERT(err == 0); if (pImage != NULL) CGImageRelease(pImage); - - if (!icon.GetMask()) - delete mask; return m_iconAdded = err == noErr; } diff --git a/src/mac/carbon/textctrl.cpp b/src/mac/carbon/textctrl.cpp index 90551cf59c..159e35685b 100644 --- a/src/mac/carbon/textctrl.cpp +++ b/src/mac/carbon/textctrl.cpp @@ -967,7 +967,7 @@ bool wxTextCtrl::MacSetupCursor( const wxPoint& pt ) { return true ; } - +#if !TARGET_API_MAC_OSX // user pane implementation void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part) @@ -1005,7 +1005,7 @@ wxInt16 wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action) void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info) { } - +#endif // ---------------------------------------------------------------------------- // implementation base class // ---------------------------------------------------------------------------- diff --git a/src/mac/carbon/toolbar.cpp b/src/mac/carbon/toolbar.cpp index ef6f7623c4..7cfd6a9594 100644 --- a/src/mac/carbon/toolbar.cpp +++ b/src/mac/carbon/toolbar.cpp @@ -260,6 +260,8 @@ wxToolBarTool::wxToolBarTool(wxToolBar *tbar, CreateBevelButtonControl( window , &toolrect , CFSTR("") , kControlBevelButtonNormalBevel , behaviour , &info , 0 , 0 , 0 , &m_controlHandle ) ; + wxMacReleaseBitmapButton( &info ) ; + InstallControlEventHandler( (ControlRef) m_controlHandle, GetwxMacToolBarToolEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this,NULL); @@ -555,6 +557,8 @@ bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) void wxToolBar::OnPaint(wxPaintEvent& event) { wxPaintDC dc(this) ; +#if wxMAC_USE_CORE_GRAPHICS +#else wxMacPortSetter helper(&dc) ; int w, h ; GetSize( &w , &h ) ; @@ -575,33 +579,35 @@ void wxToolBar::OnPaint(wxPaintEvent& event) { #if TARGET_API_MAC_OSX #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 - if ( UMAGetSystemVersion() >= 0x1030 ) - { - HIRect hiToolbarrect = CGRectMake( dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) , - dc.YLOG2DEVREL(h) , dc.XLOG2DEVREL(w) ); - CGContextRef cgContext ; - Rect bounds ; - GetPortBounds( (CGrafPtr) dc.m_macPort , &bounds ) ; - QDBeginCGContext( (CGrafPtr) dc.m_macPort , &cgContext ) ; - CGContextTranslateCTM( cgContext , 0 , bounds.bottom - bounds.top ) ; - CGContextScaleCTM( cgContext , 1 , -1 ) ; + if ( UMAGetSystemVersion() >= 0x1030 ) + { + HIRect hiToolbarrect = CGRectMake( dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) , + dc.YLOG2DEVREL(h) , dc.XLOG2DEVREL(w) ); + CGContextRef cgContext ; + Rect bounds ; + GetPortBounds( (CGrafPtr) dc.m_macPort , &bounds ) ; + QDBeginCGContext( (CGrafPtr) dc.m_macPort , &cgContext ) ; + CGContextTranslateCTM( cgContext , 0 , bounds.bottom - bounds.top ) ; + CGContextScaleCTM( cgContext , 1 , -1 ) ; + { + HIThemeBackgroundDrawInfo drawInfo ; + drawInfo.version = 0 ; + drawInfo.state = kThemeStateActive ; + drawInfo.kind = kThemeBackgroundMetal ; + HIThemeApplyBackground( &hiToolbarrect, &drawInfo , cgContext,kHIThemeOrientationNormal) ; + } + QDEndCGContext( (CGrafPtr) dc.m_macPort , &cgContext ) ; + } + else +#endif { - HIThemeBackgroundDrawInfo drawInfo ; - drawInfo.version = 0 ; - drawInfo.state = kThemeStateActive ; - drawInfo.kind = kThemeBackgroundMetal ; - HIThemeApplyBackground( &hiToolbarrect, &drawInfo , cgContext,kHIThemeOrientationNormal) ; + UMADrawThemePlacard( &toolbarrect , IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; } - QDEndCGContext( (CGrafPtr) dc.m_macPort , &cgContext ) ; - } - else #endif - { - UMADrawThemePlacard( &toolbarrect , IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; } #endif - } + event.Skip() ; } diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 7f8e6417d8..f963eb9beb 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -218,9 +218,9 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl #if 0 // in case we would need a coregraphics compliant background erase first // now usable to track redraws - CGContextRef cgContext = cEvent.GetParameter(kEventParamCGContextRef) ; if ( thisWindow->MacIsUserPane() ) { + CGContextRef cgContext = cEvent.GetParameter(kEventParamCGContextRef) ; static float color = 0.5 ; static channel = 0 ; HIRect bounds; @@ -237,9 +237,16 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl channel = 0 ; } } +#endif +#if wxMAC_USE_CORE_GRAPHICS + CGContextRef cgContext = cEvent.GetParameter(kEventParamCGContextRef) ; + thisWindow->MacSetCGContextRef( cgContext ) ; #endif if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) ) result = noErr ; +#if wxMAC_USE_CORE_GRAPHICS + thisWindow->MacSetCGContextRef( NULL ) ; +#endif if ( allocatedRgn ) DisposeRgn( allocatedRgn ) ; } @@ -406,6 +413,8 @@ pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler ) +#if !TARGET_API_MAC_OSX + // --------------------------------------------------------------------------- // UserPane events for non OSX builds // --------------------------------------------------------------------------- @@ -517,6 +526,8 @@ ControlUserPaneActivateUPP gControlUserPaneActivateUPP = NULL ; ControlUserPaneFocusUPP gControlUserPaneFocusUPP = NULL ; ControlUserPaneBackgroundUPP gControlUserPaneBackgroundUPP = NULL ; +#endif + // =========================================================================== // implementation // =========================================================================== @@ -690,9 +701,12 @@ void wxWindowMac::Init() m_macBackgroundBrush = wxNullBrush ; m_macIsUserPane = TRUE; - +#if wxMAC_USE_CORE_GRAPHICS + m_cgContextRef = NULL ; +#endif // make sure all proc ptrs are available +#if !TARGET_API_MAC_OSX if ( gControlUserPaneDrawUPP == NULL ) { gControlUserPaneDrawUPP = NewControlUserPaneDrawUPP( wxMacControlUserPaneDrawProc ) ; @@ -704,6 +718,7 @@ void wxWindowMac::Init() gControlUserPaneFocusUPP = NewControlUserPaneFocusUPP( wxMacControlUserPaneFocusProc ) ; gControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP( wxMacControlUserPaneBackgroundProc ) ; } +#endif if ( wxMacLiveScrollbarActionUPP == NULL ) { wxMacLiveScrollbarActionUPP = NewControlActionUPP( wxMacLiveScrollbarActionProc ); @@ -2210,24 +2225,6 @@ void wxWindowMac::Thaw() #endif } -void wxWindowMac::MacRedrawControl() -{ -/* - if ( *m_peer && MacGetTopLevelWindowRef() && m_peer->IsVisible()) - { -#if TARGET_API_MAC_CARBON - Update() ; -#else - wxClientDC dc(this) ; - wxMacPortSetter helper(&dc) ; - wxMacWindowClipper clipper(this) ; - wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ; - UMADrawControl( *m_peer ) ; -#endif - } -*/ -} - /* TODO void wxWindowMac::OnPaint(wxPaintEvent& event) { @@ -2482,8 +2479,29 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) SectRect( &scrollrect , &r , &scrollrect ) ; } ScrollRect( &scrollrect , dx , dy , updateRgn ) ; + + // now scroll the former update region as well and add the new update region + + WindowRef rootWindow = (WindowRef) MacGetTopLevelWindowRef() ; + RgnHandle formerUpdateRgn = NewRgn() ; + RgnHandle scrollRgn = NewRgn() ; + RectRgn( scrollRgn , &scrollrect ) ; + GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ; + Point pt = {0,0} ; + LocalToGlobal( &pt ) ; + OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ; + SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ; + if ( !EmptyRgn( formerUpdateRgn ) ) + { + MacOffsetRgn( formerUpdateRgn , dx , dy ) ; + SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ; + InvalWindowRgn(rootWindow , formerUpdateRgn ) ; + } + InvalWindowRgn(rootWindow , updateRgn ) ; + DisposeRgn( updateRgn ) ; + DisposeRgn( formerUpdateRgn ) ; + DisposeRgn( scrollRgn ) ; } - // ScrollWindowRect( (WindowRef) MacGetTopLevelWindowRef() , &scrollrect , dx , dy , kScrollWindowInvalidate, updateRgn ) ; #endif } @@ -2819,6 +2837,7 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) bool handled = false ; Rect updatebounds ; GetRegionBounds( updatergn , &updatebounds ) ; + // wxLogDebug("update for %s bounds %d , %d , %d , %d",typeid(*this).name() , updatebounds.left , updatebounds.top , updatebounds.right , updatebounds.bottom ) ; if ( !EmptyRgn(updatergn) ) { @@ -2886,6 +2905,8 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) { if ( RectInRgn( &childRect , updatergn ) ) { +#if wxMAC_USE_CORE_GRAPHICS +#else // paint custom borders wxNcPaintEvent eventNc( child->GetId() ); eventNc.SetEventObject( child ); @@ -2896,54 +2917,26 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) wxMacPortSetter helper(&dc) ; child->MacPaintBorders( dc.m_macLocalOrigin.x + childRect.left , dc.m_macLocalOrigin.y + childRect.top) ; } +#endif } } if ( child->m_peer->NeedsFocusRect() && child->m_peer->HasFocus() ) { +#if wxMAC_USE_CORE_GRAPHICS +#else wxWindowDC dc(this) ; dc.SetClippingRegion(wxRegion(updatergn)); wxMacPortSetter helper(&dc) ; Rect r = childRect ; OffsetRect( &r , dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y ) ; DrawThemeFocusRect( &r , true ) ; +#endif } } } return handled ; } -void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase) -{ - RgnHandle updatergn = (RgnHandle) updatergnr ; - // updatergn is always already clipped to our boundaries - // if we are in compositing mode then it is in relative to the upper left of the control - // if we are in non-compositing, then it is relatvie to the uppder left of the content area - // of the toplevel window - // it is in window coordinates, not in client coordinates - - // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates - RgnHandle ownUpdateRgn = NewRgn() ; - CopyRgn( updatergn , ownUpdateRgn ) ; - - if ( MacGetTopLevelWindow()->MacUsesCompositing() == false ) - { - Rect bounds; - m_peer->GetRectInWindowCoords( &bounds ); - RgnHandle controlRgn = NewRgn(); - RectRgn( controlRgn, &bounds ); - //KO: This sets the ownUpdateRgn to the area of this control that is inside - // the window update region - SectRgn( ownUpdateRgn, controlRgn, ownUpdateRgn ); - DisposeRgn( controlRgn ); - - //KO: convert ownUpdateRgn to local coordinates - OffsetRgn( ownUpdateRgn, -bounds.left, -bounds.top ); - } - - MacDoRedraw( ownUpdateRgn , time ) ; - DisposeRgn( ownUpdateRgn ) ; - -} WXWindow wxWindowMac::MacGetTopLevelWindowRef() const { -- 2.45.2