// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
-// RCS-ID: $Id$
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/rawbmp.h"
+#include "wx/filename.h"
+
IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
friend class WXDLLIMPEXP_FWD_CORE wxIcon;
friend class WXDLLIMPEXP_FWD_CORE wxCursor;
public:
+ wxBitmapRefData(int width , int height , int depth, double logicalscale);
wxBitmapRefData(int width , int height , int depth);
+ wxBitmapRefData(CGContextRef context);
+ wxBitmapRefData(CGImageRef image, double scale);
wxBitmapRefData();
wxBitmapRefData(const wxBitmapRefData &tocopy);
int GetWidth() const { return m_width; }
int GetHeight() const { return m_height; }
int GetDepth() const { return m_depth; }
-
+ double GetScaleFactor() const { return m_scaleFactor; }
void *GetRawAccess() const;
void *BeginRawAccess();
void EndRawAccess();
// rescaled to 16 x 16
bool HasNativeSize();
+#ifndef __WXOSX_IPHONE__
// caller should increase ref count if needed longer
// than the bitmap exists
IconRef GetIconRef();
-
-#ifndef __WXOSX_IPHONE__
- // returns a Pict from the bitmap content
- PicHandle GetPictHandle();
#endif
CGContextRef GetBitmapContext() const;
int GetBytesPerRow() const { return m_bytesPerRow; }
private :
bool Create(int width , int height , int depth);
+ bool Create(int width , int height , int depth, double logicalScale);
+ bool Create( CGImageRef image, double scale );
+ bool Create( CGContextRef bitmapcontext);
void Init();
int m_width;
bool m_ok;
mutable CGImageRef m_cgImageRef;
- IconRef m_iconRef;
#ifndef __WXOSX_IPHONE__
- PicHandle m_pictHandle;
+ IconRef m_iconRef;
#endif
+
CGContextRef m_hBitmap;
+ double m_scaleFactor;
};
void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType )
{
memset( info , 0 , sizeof(ControlButtonContentInfo) ) ;
- if ( bitmap.Ok() )
+ if ( bitmap.IsOk() )
{
wxBitmapRefData * bmap = bitmap.GetBitmapData() ;
if ( bmap == NULL )
info->contentType = kControlContentCGImageRef ;
info->u.imageRef = (CGImageRef) bmap->CreateCGImage() ;
}
- else
- {
-#ifndef __LP64__
- info->contentType = kControlContentPictHandle ;
- info->u.picture = bmap->GetPictHandle() ;
-#endif
- }
}
}
#ifndef __WXOSX_IPHONE__
m_iconRef = NULL ;
- m_pictHandle = NULL ;
#endif
m_hBitmap = NULL ;
m_rawAccessCount = 0 ;
m_hasAlpha = false;
+ m_scaleFactor = 1.0;
}
-wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData &tocopy)
+wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData &tocopy) : wxGDIRefData()
{
Init();
- Create(tocopy.m_width, tocopy.m_height, tocopy.m_depth);
+ Create(tocopy.m_width, tocopy.m_height, tocopy.m_depth, tocopy.m_scaleFactor);
if (tocopy.m_bitmapMask)
m_bitmapMask = new wxMask(*tocopy.m_bitmapMask);
Create( w , h , d ) ;
}
+wxBitmapRefData::wxBitmapRefData(int w , int h , int d, double logicalscale)
+{
+ Init() ;
+ Create( w , h , d, logicalscale ) ;
+}
+
+wxBitmapRefData::wxBitmapRefData(CGContextRef context)
+{
+ Init();
+ Create( context );
+}
+
+wxBitmapRefData::wxBitmapRefData(CGImageRef image, double scale)
+{
+ Init();
+ Create( image, scale );
+}
+// code from Technical Q&A QA1509
+
+bool wxBitmapRefData::Create(CGImageRef image, double scale)
+{
+ if ( image != NULL )
+ {
+ m_width = CGImageGetWidth(image);
+ m_height = CGImageGetHeight(image);
+ m_depth = 32;
+ m_hBitmap = NULL;
+ m_scaleFactor = scale;
+
+ m_bytesPerRow = GetBestBytesPerRow( m_width * 4 ) ;
+ size_t size = m_bytesPerRow * m_height ;
+ void* data = m_memBuf.GetWriteBuf( size ) ;
+ if ( data != NULL )
+ {
+ memset( data , 0 , size ) ;
+ m_memBuf.UngetWriteBuf( size ) ;
+ CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image);
+ if ( alpha == kCGImageAlphaNone || alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast )
+ {
+ m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst );
+ }
+ else
+ {
+ m_hasAlpha = true;
+ m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaPremultipliedFirst );
+ }
+ CGRect rect = CGRectMake(0,0,m_width,m_height);
+ CGContextDrawImage(m_hBitmap, rect, image);
+
+ wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ;
+ CGContextTranslateCTM( m_hBitmap, 0, m_height );
+ CGContextScaleCTM( m_hBitmap, 1*m_scaleFactor, -1*m_scaleFactor );
+ } /* data != NULL */
+ }
+ m_ok = ( m_hBitmap != NULL ) ;
+
+ return m_ok ;
+
+}
+
+bool wxBitmapRefData::Create(CGContextRef context)
+{
+ if ( context != NULL && CGBitmapContextGetData(context) )
+ {
+ m_hBitmap = context;
+ m_bytesPerRow = CGBitmapContextGetBytesPerRow(context);
+ m_width = CGBitmapContextGetWidth(context);
+ m_height = CGBitmapContextGetHeight(context);
+ m_depth = CGBitmapContextGetBitsPerPixel(context) ;
+
+ // our own contexts conform to this, always.
+ wxASSERT( m_depth == 32 );
+
+ // determine content scale
+ CGRect userrect = CGRectMake(0, 0, 10, 10);
+ CGRect devicerect;
+ devicerect = CGContextConvertRectToDeviceSpace(context, userrect);
+ m_scaleFactor = devicerect.size.height / userrect.size.height;
+
+ CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(context);
+
+ if ( alpha == kCGImageAlphaNone || alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast )
+ {
+ // no alpha
+ }
+ else
+ {
+ m_hasAlpha = true;
+ }
+ }
+ m_ok = ( m_hBitmap != NULL ) ;
+
+ return m_ok ;
+}
+
bool wxBitmapRefData::Create( int w , int h , int d )
{
m_width = wxMax(1, w);
m_depth = d ;
m_hBitmap = NULL ;
- m_bytesPerRow = GetBestBytesPerRow( w * 4 ) ;
- size_t size = m_bytesPerRow * h ;
+ m_bytesPerRow = GetBestBytesPerRow( m_width * 4 ) ;
+ size_t size = m_bytesPerRow * m_height ;
void* data = m_memBuf.GetWriteBuf( size ) ;
if ( data != NULL )
{
m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst );
wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ;
CGContextTranslateCTM( m_hBitmap, 0, m_height );
- CGContextScaleCTM( m_hBitmap, 1, -1 );
+ CGContextScaleCTM( m_hBitmap, 1*m_scaleFactor, -1*m_scaleFactor );
} /* data != NULL */
m_ok = ( m_hBitmap != NULL ) ;
return m_ok ;
}
+bool wxBitmapRefData::Create( int w , int h , int d, double logicalScale )
+{
+ m_scaleFactor = logicalScale;
+ return Create(w*logicalScale,h*logicalScale,d);
+}
+
void wxBitmapRefData::UseAlpha( bool use )
{
if ( m_hasAlpha == use )
m_hBitmap = CGBitmapContextCreate((char*) m_memBuf.GetData(), m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), m_hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst );
wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ;
CGContextTranslateCTM( m_hBitmap, 0, m_height );
- CGContextScaleCTM( m_hBitmap, 1, -1 );
+ CGContextScaleCTM( m_hBitmap, 1*m_scaleFactor, -1*m_scaleFactor );
}
void *wxBitmapRefData::GetRawAccess() const
wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") ) ;
wxASSERT( m_rawAccessCount == 0 ) ;
#ifndef __WXOSX_IPHONE__
- wxASSERT_MSG( m_pictHandle == NULL && m_iconRef == NULL ,
- wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ;
+ wxASSERT_MSG( m_iconRef == NULL ,
+ wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ;
#endif
++m_rawAccessCount ;
OSType dataType = 0 ;
OSType maskType = 0 ;
+ // since we don't have PICT conversion available, use
+ // the next larger standard icon size
+ // TODO: Use NSImage
+ if (sz <= 16)
+ sz = 16;
+ else if ( sz <= 32)
+ sz = 32;
+ else if ( sz <= 48)
+ sz = 48;
+ else if ( sz <= 128)
+ sz = 128;
+ else if ( sz <= 256)
+ sz = 256;
+ else if ( sz <= 512)
+ sz = 512;
+ else if ( sz <= 1024)
+ sz = 1024;
+
switch (sz)
{
- case 128:
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if ( UMAGetSystemVersion() >= 0x1050 )
- {
- dataType = kIconServices128PixelDataARGB ;
- }
- else
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ case 1024:
+ dataType = kIconServices1024PixelDataARGB;
+ break;
#endif
- {
- dataType = kThumbnail32BitData ;
- maskType = kThumbnail8BitMask ;
- }
+ case 512:
+ dataType = kIconServices512PixelDataARGB;
+ break;
+
+ case 256:
+ dataType = kIconServices256PixelDataARGB;
+ break;
+
+ case 128:
+ dataType = kIconServices128PixelDataARGB ;
break;
case 48:
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if ( UMAGetSystemVersion() >= 0x1050 )
- {
- dataType = kIconServices48PixelDataARGB ;
- }
- else
-#endif
- {
- dataType = kHuge32BitData ;
- maskType = kHuge8BitMask ;
- }
+ dataType = kIconServices48PixelDataARGB ;
break;
case 32:
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if ( UMAGetSystemVersion() >= 0x1050 )
- {
- dataType = kIconServices32PixelDataARGB ;
- }
- else
-#endif
- {
- dataType = kLarge32BitData ;
- maskType = kLarge8BitMask ;
- }
+ dataType = kIconServices32PixelDataARGB ;
break;
case 16:
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if ( UMAGetSystemVersion() >= 0x1050 )
- {
- dataType = kIconServices16PixelDataARGB ;
- }
- else
-#endif
- {
- dataType = kSmall32BitData ;
- maskType = kSmall8BitMask ;
- }
+ dataType = kIconServices16PixelDataARGB ;
break;
default:
if ( dataType != 0 )
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if ( maskType == 0 && UMAGetSystemVersion() >= 0x1050 )
+ if ( maskType == 0 )
{
size_t datasize = sz * sz * 4 ;
Handle data = NewHandle( datasize ) ;
}
}
HUnlock( data );
+
OSStatus err = SetIconFamilyData( iconFamily, dataType , data );
- wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") );
+ if ( err != noErr )
+ {
+ wxFAIL_MSG("Error when adding bitmap");
+ }
+
DisposeHandle( data );
}
else
-#endif
{
// setup the header properly
DisposeHandle( maskdata ) ;
}
}
- else
- {
- PicHandle pic = GetPictHandle() ;
- SetIconFamilyData( iconFamily, 'PICT' , (Handle) pic ) ;
- }
// transform into IconRef
// cleaner version existing from 10.3 upwards
return m_iconRef ;
}
-PicHandle wxBitmapRefData::GetPictHandle()
-{
- if ( m_pictHandle == NULL )
- {
-#ifndef __LP64__
- GraphicsExportComponent exporter = 0;
- OSStatus err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePicture, &exporter);
- if (noErr == err)
- {
- m_pictHandle = (PicHandle) NewHandle(0);
- if ( m_pictHandle )
- {
- // QT does not correctly export the mask
- // TODO if we get around to it create a synthetic PICT with the CopyBits and Mask commands
- CGImageRef imageRef = CreateCGImage();
- err = GraphicsExportSetInputCGImage( exporter, imageRef );
- err = GraphicsExportSetOutputHandle(exporter, (Handle)m_pictHandle);
- err = GraphicsExportDoExport(exporter, NULL);
- CGImageRelease( imageRef );
-
- size_t handleSize = GetHandleSize( (Handle) m_pictHandle );
- // the 512 bytes header is only needed for pict files, but not in memory
- if ( handleSize >= 512 )
- {
- memmove( *m_pictHandle , (char*)(*m_pictHandle)+512, handleSize - 512 );
- SetHandleSize( (Handle) m_pictHandle, handleSize - 512 );
- }
- }
- CloseComponent( exporter );
- }
-#endif
- }
-
- return m_pictHandle ;
-}
#endif
CGImageRef wxBitmapRefData::CreateCGImage() const
{
if ( m_depth != 1 && m_bitmapMask == NULL )
{
+#if 0
+ // in order for this code to work properly, wxMask would have to invert black and white
+ // in the native bitmap
if ( m_bitmapMask )
{
CGImageRef tempImage = CGBitmapContextCreateImage( m_hBitmap );
CGImageRelease(tempImage);
}
else
+#endif
image = CGBitmapContextCreateImage( m_hBitmap );
}
else
ReleaseIconRef( m_iconRef ) ;
m_iconRef = NULL ;
}
-
-#ifndef __LP64__
- if ( m_pictHandle )
- {
- KillPicture( m_pictHandle ) ;
- m_pictHandle = NULL ;
- }
-#endif
#endif
if ( m_hBitmap )
{
m_hBitmap = NULL ;
}
- if (m_bitmapMask)
- {
- delete m_bitmapMask;
- m_bitmapMask = NULL;
- }
+ wxDELETE(m_bitmapMask);
}
wxBitmapRefData::~wxBitmapRefData()
Free() ;
}
+
+
+// ----------------------------------------------------------------------------
+// wxBitmap
+// ----------------------------------------------------------------------------
+
bool wxBitmap::CopyFromIcon(const wxIcon& icon)
{
bool created = false ;
return true;
}
-wxBitmap::wxBitmap()
-{
-}
-
-wxBitmap::~wxBitmap()
-{
-}
-
wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
{
wxBitmapRefData* bitmapRefData;
{
if ( no_bits == 1 )
{
- int linesize = ( the_width / (sizeof(unsigned char) * 8)) ;
- if ( the_width % (sizeof(unsigned char) * 8) )
- linesize += sizeof(unsigned char);
+ int linesize = the_width / 8;
+ if ( the_width % 8 )
+ linesize++;
unsigned char* linestart = (unsigned char*) bits ;
unsigned char* destptr = (unsigned char*) BeginRawAccess() ;
} /* bitmapRefData->IsOk() */
}
-wxBitmap::wxBitmap(int w, int h, int d)
+wxBitmap::wxBitmap(const void* data, wxBitmapType type, int width, int height, int depth)
{
- (void)Create(w, h, d);
+ (void) Create(data, type, width, height, depth);
}
-wxBitmap::wxBitmap(const void* data, wxBitmapType type, int width, int height, int depth)
+wxBitmap::wxBitmap(int width, int height, const wxDC& dc)
{
- (void) Create(data, type, width, height, depth);
+ (void)Create(width, height, dc);
}
wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
LoadFile(filename, type);
}
+wxBitmap::wxBitmap(CGImageRef image, double scale)
+{
+ (void) Create(image,scale);
+}
+
wxGDIRefData* wxBitmap::CreateGDIRefData() const
{
return new wxBitmapRefData;
void * wxBitmap::GetRawAccess() const
{
- wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ;
+ wxCHECK_MSG( IsOk() , NULL , wxT("invalid bitmap") ) ;
return M_BITMAPDATA->GetRawAccess() ;
}
void * wxBitmap::BeginRawAccess()
{
- wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ;
+ wxCHECK_MSG( IsOk() , NULL , wxT("invalid bitmap") ) ;
return M_BITMAPDATA->BeginRawAccess() ;
}
void wxBitmap::EndRawAccess()
{
- wxCHECK_RET( Ok() , wxT("invalid bitmap") ) ;
+ wxCHECK_RET( IsOk() , wxT("invalid bitmap") ) ;
M_BITMAPDATA->EndRawAccess() ;
}
CGImageRef wxBitmap::CreateCGImage() const
{
- wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ;
+ wxCHECK_MSG( IsOk(), NULL , wxT("invalid bitmap") ) ;
return M_BITMAPDATA->CreateCGImage() ;
}
#ifndef __WXOSX_IPHONE__
IconRef wxBitmap::GetIconRef() const
{
- wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ;
+ wxCHECK_MSG( IsOk(), NULL , wxT("invalid bitmap") ) ;
return M_BITMAPDATA->GetIconRef() ;
}
}
#endif
-#if wxOSX_USE_COCOA_OR_IPHONE
+#if wxOSX_USE_COCOA
+
+wxBitmap::wxBitmap(WX_NSImage image)
+{
+ (void)Create(image);
+}
+
+bool wxBitmap::Create(WX_NSImage image)
+{
+ return Create(wxOSXCreateBitmapContextFromNSImage(image));
+}
+
+wxBitmap::wxBitmap(CGContextRef bitmapcontext)
+{
+ (void)Create(bitmapcontext);
+}
+
+bool wxBitmap::Create(CGContextRef bitmapcontext)
+{
+ UnRef();
+
+ m_refData = new wxBitmapRefData( bitmapcontext );
+
+ return M_BITMAPDATA->IsOk() ;
+}
WX_NSImage wxBitmap::GetNSImage() const
{
wxCFRef< CGImageRef > cgimage(CreateCGImage());
- return wxOSXCreateNSImageFromCGImage( cgimage );
+ return wxOSXGetNSImageFromCGImage( cgimage, GetScaleFactor() );
}
#endif
+#if wxOSX_USE_IPHONE
+
+WX_UIImage wxBitmap::GetUIImage() const
+{
+ wxCFRef< CGImageRef > cgimage(CreateCGImage());
+ return wxOSXGetUIImageFromCGImage( cgimage );
+}
+
+#endif
wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
{
- wxCHECK_MSG( Ok() &&
+ wxCHECK_MSG( IsOk() &&
(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") );
+ wxBitmap ret;
+ double scale = GetScaleFactor();
+ ret.CreateScaled( rect.width, rect.height, GetDepth(), scale );
+ wxASSERT_MSG( ret.IsOk(), wxT("GetSubBitmap error") );
- int destwidth = rect.width ;
- int destheight = rect.height ;
+ int destwidth = rect.width*scale ;
+ int destheight = rect.height*scale ;
{
unsigned char *sourcedata = (unsigned char*) GetRawAccess() ;
unsigned char *destdata = (unsigned char*) ret.BeginRawAccess() ;
- wxASSERT( (sourcedata != NULL) && (destdata != NULL) ) ;
+ wxASSERT((sourcedata != NULL) && (destdata != NULL));
- int sourcelinesize = GetBitmapData()->GetBytesPerRow() ;
- int destlinesize = ret.GetBitmapData()->GetBytesPerRow() ;
- 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)
+ if ( (sourcedata != NULL) && (destdata != NULL) )
{
- memcpy( dest , source , destlinesize ) ;
+ int sourcelinesize = GetBitmapData()->GetBytesPerRow() ;
+ int destlinesize = ret.GetBitmapData()->GetBytesPerRow() ;
+ unsigned char *source = sourcedata + int(rect.x * scale * 4 + rect.y *scale * sourcelinesize) ;
+ unsigned char *dest = destdata ;
+
+ for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize)
+ {
+ memcpy( dest , source , destlinesize ) ;
+ }
}
+ ret.EndRawAccess() ;
}
- ret.EndRawAccess() ;
if ( M_BITMAPDATA->m_bitmapMask )
{
unsigned char *destdata = (unsigned char * ) maskbuf.GetWriteBuf( maskbufsize ) ;
wxASSERT( (source != NULL) && (destdata != NULL) ) ;
- source += rect.x * kMaskBytesPerPixel + rect.y * sourcelinesize ;
- unsigned char *dest = destdata ;
-
- for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize)
+ if ( (source != NULL) && (destdata != NULL) )
{
- memcpy( dest , source , destlinesize ) ;
- }
+ source += rect.x * kMaskBytesPerPixel + 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 ) ;
+ maskbuf.UngetWriteBuf( maskbufsize ) ;
+ }
ret.SetMask( new wxMask( maskbuf , destwidth , destheight , rowBytes ) ) ;
}
else if ( HasAlpha() )
return M_BITMAPDATA->IsOk() ;
}
+bool wxBitmap::Create(int w, int h, const wxDC& dc)
+{
+ double factor = dc.GetContentScaleFactor();
+ return CreateScaled(w,h,wxBITMAP_SCREEN_DEPTH, factor);
+}
+
+bool wxBitmap::CreateScaled(int w, int h, int d, double logicalScale)
+{
+ UnRef();
+
+ if ( d < 0 )
+ d = wxDisplayDepth() ;
+
+ m_refData = new wxBitmapRefData( w , h , d, logicalScale );
+
+ return M_BITMAPDATA->IsOk() ;
+}
+
+bool wxBitmap::Create(CGImageRef image, double scale)
+{
+ UnRef();
+
+ m_refData = new wxBitmapRefData( image, scale );
+
+ return M_BITMAPDATA->IsOk() ;
+}
+
bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
{
UnRef();
else
{
#if wxUSE_IMAGE
- wxImage loadimage(filename, type);
- if (loadimage.Ok())
+ double scale = 1.0;
+ wxString fname = filename;
+
+ if ( type == wxBITMAP_TYPE_PNG )
+ {
+ if ( wxOSXGetMainScreenContentScaleFactor() > 1.9 )
+ {
+ wxFileName fn(filename);
+ fn.MakeAbsolute();
+ fn.SetName(fn.GetName()+"@2x");
+
+ if ( fn.Exists() )
+ {
+ fname = fn.GetFullPath();
+ scale = 2.0;
+ }
+ }
+ }
+
+ wxImage loadimage(fname, type);
+ if (loadimage.IsOk())
{
- *this = loadimage;
+ *this = wxBitmap(loadimage,-1,scale);
return true;
}
#if wxUSE_IMAGE
-wxBitmap::wxBitmap(const wxImage& image, int depth)
+wxBitmap::wxBitmap(const wxImage& image, int depth, double scale)
{
- wxCHECK_RET( image.Ok(), wxT("invalid image") );
+ wxCHECK_RET( image.IsOk(), wxT("invalid image") );
// width and height of the device-dependent bitmap
int width = image.GetWidth();
int height = image.GetHeight();
wxBitmapRefData* bitmapRefData;
-
- m_refData = bitmapRefData = new wxBitmapRefData( width , height , depth ) ;
+
+ m_refData = bitmapRefData = new wxBitmapRefData( width/scale, height/scale, depth, scale) ;
if ( bitmapRefData->IsOk())
{
{
wxImage image;
- wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
+ wxCHECK_MSG( IsOk(), wxNullImage, wxT("invalid bitmap") );
// create an wxImage object
int width = GetWidth();
int wxBitmap::GetHeight() const
{
- wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+ wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
return M_BITMAPDATA->GetHeight();
}
int wxBitmap::GetWidth() const
{
- wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+ wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
return M_BITMAPDATA->GetWidth() ;
}
+double wxBitmap::GetScaleFactor() const
+{
+ wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
+
+ return M_BITMAPDATA->GetScaleFactor() ;
+}
+
int wxBitmap::GetDepth() const
{
- wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+ wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
return M_BITMAPDATA->GetDepth();
}
wxMask *wxBitmap::GetMask() const
{
- wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
+ wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") );
return M_BITMAPDATA->m_bitmapMask;
}
bool wxBitmap::HasAlpha() const
{
- wxCHECK_MSG( Ok(), false , wxT("invalid bitmap") );
+ wxCHECK_MSG( IsOk(), false , wxT("invalid bitmap") );
return M_BITMAPDATA->HasAlpha() ;
}
#if wxUSE_PALETTE
wxPalette *wxBitmap::GetPalette() const
{
- wxCHECK_MSG( Ok(), NULL, wxT("Invalid bitmap GetPalette()") );
+ wxCHECK_MSG( IsOk(), NULL, wxT("Invalid bitmap GetPalette()") );
return &M_BITMAPDATA->m_bitmapPalette;
}
Init() ;
}
-wxMask::wxMask(const wxMask &tocopy)
+wxMask::wxMask(const wxMask &tocopy) : wxObject()
{
Init();
size_t size = m_bytesPerRow * m_height ;
unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ;
wxASSERT( destdatabase != NULL ) ;
-
- memset( destdatabase , 0 , size ) ;
- unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ;
-
- for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow )
+
+ if ( destdatabase )
{
- unsigned char *destdata = destdatabase ;
- unsigned char r, g, b;
+ memset( destdatabase , 0 , size ) ;
+ unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ;
- for ( int x = 0 ; x < m_width ; ++x )
+ for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow )
{
- srcdata++ ;
- r = *srcdata++ ;
- g = *srcdata++ ;
- b = *srcdata++ ;
+ unsigned char *destdata = destdatabase ;
+ unsigned char r, g, b;
- if ( ( r + g + b ) > 0x10 )
- *destdata++ = 0xFF ;
- else
- *destdata++ = 0x00 ;
+ for ( int x = 0 ; x < m_width ; ++x )
+ {
+ srcdata++ ;
+ r = *srcdata++ ;
+ g = *srcdata++ ;
+ b = *srcdata++ ;
+
+ if ( ( r + g + b ) > 0x10 )
+ *destdata++ = 0xFF ;
+ else
+ *destdata++ = 0x00 ;
+ }
}
}
size_t size = m_bytesPerRow * m_height ;
unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ;
wxASSERT( destdatabase != NULL ) ;
-
- memset( destdatabase , 0 , size ) ;
- unsigned char * srcdatabase = (unsigned char*) bitmap.GetRawAccess() ;
- size_t sourceBytesRow = bitmap.GetBitmapData()->GetBytesPerRow();
-
- for ( int y = 0 ; y < m_height ; ++y , srcdatabase+= sourceBytesRow, destdatabase += m_bytesPerRow)
+ if ( destdatabase != NULL)
{
- unsigned char *srcdata = srcdatabase ;
- unsigned char *destdata = destdatabase ;
- unsigned char r, g, b;
+ memset( destdatabase , 0 , size ) ;
+ unsigned char * srcdatabase = (unsigned char*) bitmap.GetRawAccess() ;
+ size_t sourceBytesRow = bitmap.GetBitmapData()->GetBytesPerRow();
- for ( int x = 0 ; x < m_width ; ++x )
+ for ( int y = 0 ; y < m_height ; ++y , srcdatabase+= sourceBytesRow, destdatabase += m_bytesPerRow)
{
- srcdata++ ;
- r = *srcdata++ ;
- g = *srcdata++ ;
- b = *srcdata++ ;
+ unsigned char *srcdata = srcdatabase ;
+ unsigned char *destdata = destdatabase ;
+ unsigned char r, g, b;
- if ( colour == wxColour( r , g , b ) )
- *destdata++ = 0xFF ;
- else
- *destdata++ = 0x00 ;
+ for ( int x = 0 ; x < m_width ; ++x )
+ {
+ srcdata++ ;
+ r = *srcdata++ ;
+ g = *srcdata++ ;
+ b = *srcdata++ ;
+
+ if ( colour == wxColour( r , g , b ) )
+ *destdata++ = 0xFF ;
+ else
+ *destdata++ = 0x00 ;
+ }
}
}
-
m_memBuf.UngetWriteBuf( size ) ;
RealizeNative() ;
return true;
}
+wxBitmap wxMask::GetBitmap() const
+{
+ wxBitmap bitmap(m_width, m_height, 1);
+ unsigned char* dst = static_cast<unsigned char*>(bitmap.BeginRawAccess());
+ const int dst_stride = bitmap.GetBitmapData()->GetBytesPerRow();
+ const unsigned char* src = static_cast<unsigned char*>(GetRawAccess());
+ for (int j = 0; j < m_height; j++, src += m_bytesPerRow, dst += dst_stride)
+ {
+ unsigned char* d = dst;
+ for (int i = 0; i < m_width; i++)
+ {
+ const unsigned char byte = src[i];
+ *d++ = 0xff;
+ *d++ = byte;
+ *d++ = byte;
+ *d++ = byte;
+ }
+ }
+ bitmap.EndRawAccess();
+ return bitmap;
+}
+
WXHBITMAP wxMask::GetHBITMAP() const
{
return m_maskBitmap ;
// Standard Handlers
// ----------------------------------------------------------------------------
-#if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__)
-
-class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
+class WXDLLEXPORT wxBundleResourceHandler: public wxBitmapHandler
{
- DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
-
+ DECLARE_ABSTRACT_CLASS(wxBundleResourceHandler)
+
public:
- inline wxPICTResourceHandler()
+ inline wxBundleResourceHandler()
{
- SetName(wxT("Macintosh Pict resource"));
- SetExtension(wxEmptyString);
- SetType(wxBITMAP_TYPE_PICT_RESOURCE);
};
+
+ virtual bool LoadFile(wxBitmap *bitmap,
+ const wxString& name,
+ wxBitmapType type,
+ int desiredWidth,
+ int desiredHeight);
+};
+
+IMPLEMENT_ABSTRACT_CLASS(wxBundleResourceHandler, wxBitmapHandler);
- virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
- int desiredWidth, int desiredHeight);
+class WXDLLEXPORT wxPNGResourceHandler: public wxBundleResourceHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxPNGResourceHandler)
+
+public:
+ inline wxPNGResourceHandler()
+ {
+ SetName(wxT("PNG resource"));
+ SetExtension("PNG");
+ SetType(wxBITMAP_TYPE_PNG_RESOURCE);
+ };
};
-IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxPNGResourceHandler, wxBundleResourceHandler)
+
+class WXDLLEXPORT wxJPEGResourceHandler: public wxBundleResourceHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxJPEGResourceHandler)
+
+public:
+ inline wxJPEGResourceHandler()
+ {
+ SetName(wxT("JPEG resource"));
+ SetExtension("JPEG");
+ SetType(wxBITMAP_TYPE_JPEG_RESOURCE);
+ };
+};
+IMPLEMENT_DYNAMIC_CLASS(wxJPEGResourceHandler, wxBundleResourceHandler)
-bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap,
+bool wxBundleResourceHandler::LoadFile(wxBitmap *bitmap,
const wxString& name,
- long WXUNUSED(flags),
+ wxBitmapType WXUNUSED(type),
int WXUNUSED(desiredWidth),
int WXUNUSED(desiredHeight))
{
-#if wxUSE_METAFILE
- Str255 theName ;
- wxMacStringToPascal( name , theName ) ;
-
- PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ;
- if ( thePict )
+ wxString ext = GetExtension().Lower();
+ wxCFStringRef resname(name);
+ wxCFStringRef resname2x(name+"@2x");
+ wxCFStringRef restype(ext);
+ double scale = 1.0;
+
+ wxCFRef<CFURLRef> imageURL;
+
+ if ( wxOSXGetMainScreenContentScaleFactor() > 1.9 )
{
- wxMetafile mf ;
-
- mf.SetPICT( thePict ) ;
- bitmap->Create( mf.GetWidth() , mf.GetHeight() ) ;
- wxMemoryDC dc ;
- dc.SelectObject( *bitmap ) ;
- mf.Play( &dc ) ;
- dc.SelectObject( wxNullBitmap ) ;
-
- return true ;
+ imageURL.reset(CFBundleCopyResourceURL(CFBundleGetMainBundle(), resname2x, restype, NULL));
+ scale = 2.0;
}
-#endif
-
+
+ if ( imageURL.get() == NULL )
+ {
+ imageURL.reset(CFBundleCopyResourceURL(CFBundleGetMainBundle(), resname, restype, NULL));
+ scale = 1.0;
+ }
+
+ if ( imageURL.get() != NULL )
+ {
+ // Create the data provider object
+ wxCFRef<CGDataProviderRef> provider(CGDataProviderCreateWithURL (imageURL) );
+ CGImageRef image = NULL;
+
+ if ( ext == "jpeg" )
+ image = CGImageCreateWithJPEGDataProvider (provider, NULL, true,
+ kCGRenderingIntentDefault);
+ else if ( ext == "png" )
+ image = CGImageCreateWithPNGDataProvider (provider, NULL, true,
+ kCGRenderingIntentDefault);
+ if ( image != NULL )
+ {
+ bitmap->Create(image,scale);
+ CGImageRelease(image);
+ }
+ }
+
return false ;
}
-#endif
+
+/* static */
+wxBitmap wxBitmapHelpers::NewFromPNGData(const void* data, size_t size)
+{
+ wxCFRef<CGDataProviderRef>
+ provider(CGDataProviderCreateWithData(NULL, data, size, NULL) );
+ wxCFRef<CGImageRef>
+ image(CGImageCreateWithPNGDataProvider(provider, NULL, true,
+ kCGRenderingIntentDefault));
+
+ return wxBitmap(image);
+}
void wxBitmap::InitStandardHandlers()
{
-#if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__)
- AddHandler( new wxPICTResourceHandler ) ;
-#endif
-#if wxOSX_USE_CARBON
+#if wxOSX_USE_COCOA_OR_CARBON
AddHandler( new wxICONResourceHandler ) ;
#endif
+ AddHandler( new wxPNGResourceHandler );
+ AddHandler( new wxJPEGResourceHandler );
}
// ----------------------------------------------------------------------------
void *wxBitmap::GetRawData(wxPixelDataBase& data, int WXUNUSED(bpp))
{
- if ( !Ok() )
+ if ( !IsOk() )
// no bitmap, no data (raw or otherwise)
return NULL;