diff --git a/docs/changes.txt b/docs/changes.txt index ee1ff7bf2e..93051c569f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -536,6 +536,7 @@ All: All (GUI): +- Add wxBITMAP_PNG() macro similar to wxBITMAP() but for PNG files. - Add new wxSimplebook class. - Support hexadecimal numbers in wxSpinCtrl. - Respect window max size in wxBoxSizer (Nathan Ridge). diff --git a/docs/doxygen/overviews/bitmap.h b/docs/doxygen/overviews/bitmap.h index 2a375ca777..f7229d2c8c 100644 --- a/docs/doxygen/overviews/bitmap.h +++ b/docs/doxygen/overviews/bitmap.h @@ -78,8 +78,17 @@ wxBitmap bmp(wxBITMAP(bmpname)); You should always use wxICON() and wxBITMAP() macros because they work for any platform (unlike the code above which doesn't deal with wxMac, wxX11, ...) and -are shorter and more clear than versions with many @ifdef_ blocks. Even better, -use the same XPMs on all platforms. +are shorter and more clear than versions with many @ifdef_ blocks. +Alternatively, you could use the same XPMs on all platforms and avoid dealing +with Windows resource files. + +If you'd like to embed bitmaps with alpha transparency in your program, neither +XPM nor BMP formats are appropriate as they don't have support for alpha and +another format, typically PNG, should be used. wxWidgets provides a similar +helper for PNG bitmaps called wxBITMAP_PNG() that can be used to either load +PNG files embedded in resources (meaning either Windows resource section of the +executable file or OS X "Resource" subdirectory of the application bundle) or +arrays containing PNG data included into the program code itself. @li @ref overview_bitmap_supportedformats @li @ref overview_bitmap_handlers diff --git a/include/wx/bitmap.h b/include/wx/bitmap.h index 82943ca228..fc2110755b 100644 --- a/include/wx/bitmap.h +++ b/include/wx/bitmap.h @@ -89,7 +89,7 @@ protected: // Unfortunately, currently wxBitmap does not inherit from wxBitmapBase on all // platforms and this is not easy to fix. So we extract at least some common -// methods into this class from which both wxBitmapBase (and hase wxBitmap on +// methods into this class from which both wxBitmapBase (and hence wxBitmap on // all platforms where it does inherit from it) and wxBitmap in wxMSW and other // exceptional ports (only wxPM and old wxCocoa) inherit. class WXDLLIMPEXP_CORE wxBitmapHelpers diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 24ff44ab5c..624c495072 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -218,6 +218,28 @@ enum wxStockCursor #define wxBITMAP(name) wxBitmap(name##_xpm, wxBITMAP_TYPE_XPM) #endif // platform +// Macro for creating wxBitmap from in-memory PNG data. +// +// It reads PNG data from name_png static byte arrays that can be created using +// e.g. misc/scripts/png2c.py. +// +// This macro exists mostly as a helper for wxBITMAP_PNG() below but also +// because it's slightly more convenient to use than NewFromPNGData() directly. +#define wxBITMAP_PNG_FROM_DATA(name) \ + wxBitmap::NewFromPNGData(name##_png, WXSIZEOF(name##_png)) + +// Similar to wxBITMAP but used for the bitmaps in PNG format. +// +// Under Windows they should be embedded into the resource file using RT_RCDATA +// resource type and under OS X the PNG file with the specified name must be +// available in the resource subdirectory of the bundle. Elsewhere, this is +// exactly the same thing as wxBITMAP_PNG_FROM_DATA() described above. +#if defined(__WINDOWS__) || defined(__WXOSX__) + #define wxBITMAP_PNG(name) wxBitmap(wxS(#name), wxBITMAP_TYPE_PNG_RESOURCE) +#else + #define wxBITMAP_PNG(name) wxBITMAP_PNG_FROM_DATA(name) +#endif + // =========================================================================== // classes // =========================================================================== diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index f69ace97be..80b93b3be7 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -1021,6 +1021,73 @@ const wxSize wxDefaultSize; */ #define wxBITMAP(bitmapName) +/** + Creates a bitmap from either application resources or embedded image data + in PNG format. + + This macro is similar to wxBITMAP() but works with bitmap data in PNG + format and not BMP or XPM. + + Under Windows the given @a bitmapName must be present in the application + resource file with the type @c RCDATA and refer to a PNG image. I.e. you + should have a definition similar to the following in your @c .rc file: + @code + mybitmap RCDATA "mybitmap.png" + @endcode + to be able to use @c wxBITMAP_PNG(mybitmap) in the code. + + Under OS X the file with the specified name and "png" extension must be + present in the "Resources" subdirectory of the application bundle. + + Under the other platforms, this is equivalent to wxBITMAP_PNG_FROM_DATA() + and so loads the image data from the array called @c bitmapName_png that + must exist. Notice that it @e must be an array and not a pointer as the + macro needs to be able to determine its size. Such an array can be produced + by a number of conversion programs. A very simple one is included in + wxWidgets distribution as @c misc/scripts/png2c.py. + + Finally notice that you must register PNG image handler to be able to + load bitmaps from PNG data. This can be done either by calling + wxInitAllImageHandlers() which also registers all the other image formats + or including the necessary header: + @code + #include + @endcode + and calling + @code + wxImage::AddHandler(new wxPNGHandler); + @endcode + in your application startup code. + + @see wxBITMAP_PNG_FROM_DATA() + + @header{wx/gdicmn.h} + + @since 2.9.5 + */ +#define wxBITMAP_PNG(bitmapName) + +/** + Creates a bitmap from embedded image data in PNG format. + + This macro is a thin wrapper around wxBitmap::NewFromPNGData() and takes + just the base name of the array containing the image data and computes its + size internally. In other words, the array called @c bitmapName_png must + exist. Notice that it @e must be an array and not a pointer as the macro + needs to be able to determine its size. Such an array can be produced by a + number of conversion programs. A very simple one is included in wxWidgets + distribution as @c misc/scripts/png2c.py. + + You can use wxBITMAP_PNG() to load the PNG bitmaps from resources on the + platforms that support this and only fall back to loading them from data + under the other ones (i.e. not Windows and not OS X). + + @header{wx/gdicmn.h} + + @since 2.9.5 + */ +#define wxBITMAP_PNG_FROM_DATA(bitmapName) + /** This macro loads an icon from either application resources (on the platforms for which they exist, i.e. Windows and OS2) or from an XPM file. diff --git a/samples/image/Makefile.in b/samples/image/Makefile.in index 9270aefec5..c0451961f6 100644 --- a/samples/image/Makefile.in +++ b/samples/image/Makefile.in @@ -48,10 +48,10 @@ IMAGE_CXXFLAGS = -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) \ -I$(srcdir) $(__DLLFLAG_p) -I$(srcdir)/../../samples $(CXXWARNINGS) \ $(CPPFLAGS) $(CXXFLAGS) IMAGE_OBJECTS = \ - $(__image___win32rc) \ $(__image_os2_lib_res) \ image_image.o \ - image_canvas.o + image_canvas.o \ + $(__image___win32rc) ### Conditionally set variables: ### @@ -88,7 +88,6 @@ COND_PLATFORM_OS2_1___image___os2_emxbindcmd = $(NM) image$(EXEEXT) | if grep -q @COND_PLATFORM_OS2_1@__image___os2_emxbindcmd = $(COND_PLATFORM_OS2_1___image___os2_emxbindcmd) @COND_TOOLKIT_MSW@__RCDEFDIR_p_1 = --include-dir \ @COND_TOOLKIT_MSW@ $(LIBDIRNAME)/wx/include/$(TOOLCHAIN_FULLNAME) -@COND_PLATFORM_WIN32_1@__image___win32rc = image_sample_rc.o @COND_PLATFORM_OS2_1@__image_os2_lib_res = \ @COND_PLATFORM_OS2_1@ $(top_srcdir)/include/wx/os2/wx.res @COND_PLATFORM_MACOSX_1@__image_app_Contents_PkgInfo___depname \ @@ -110,6 +109,7 @@ COND_MONOLITHIC_0___WXLIB_CORE_p = \ COND_MONOLITHIC_0___WXLIB_BASE_p = \ -lwx_base$(WXBASEPORT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) @COND_MONOLITHIC_0@__WXLIB_BASE_p = $(COND_MONOLITHIC_0___WXLIB_BASE_p) +@COND_PLATFORM_WIN32_1@__image___win32rc = image_image_rc.o COND_MONOLITHIC_1___WXLIB_MONO_p = \ -lwx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) @COND_MONOLITHIC_1@__WXLIB_MONO_p = $(COND_MONOLITHIC_1___WXLIB_MONO_p) @@ -155,7 +155,7 @@ image$(EXEEXT): $(IMAGE_OBJECTS) $(__image___win32rc) $(__image___mac_setfilecmd) $(__image___os2_emxbindcmd) -@COND_PLATFORM_MACOSX_1@image.app/Contents/PkgInfo: image$(EXEEXT) $(top_srcdir)/src/osx/carbon/Info.plist.in $(top_srcdir)/src/osx/carbon/wxmac.icns +@COND_PLATFORM_MACOSX_1@image.app/Contents/PkgInfo: image$(EXEEXT) $(top_srcdir)/src/osx/carbon/Info.plist.in $(top_srcdir)/src/osx/carbon/wxmac.icns $(srcdir)/cursor.png @COND_PLATFORM_MACOSX_1@ mkdir -p image.app/Contents @COND_PLATFORM_MACOSX_1@ mkdir -p image.app/Contents/MacOS @COND_PLATFORM_MACOSX_1@ mkdir -p image.app/Contents/Resources @@ -174,6 +174,7 @@ image$(EXEEXT): $(IMAGE_OBJECTS) $(__image___win32rc) @COND_PLATFORM_MACOSX_1@ @COND_PLATFORM_MACOSX_1@ @COND_PLATFORM_MACOSX_1@ cp -f $(top_srcdir)/src/osx/carbon/wxmac.icns image.app/Contents/Resources/wxmac.icns +@COND_PLATFORM_MACOSX_1@ cp -f $(srcdir)/cursor.png image.app/Contents/Resources @COND_PLATFORM_MACOSX_1@image_bundle: $(____image_BUNDLE_TGT_REF_DEP) @@ -189,15 +190,15 @@ data: esac; \ done -image_sample_rc.o: $(srcdir)/../../samples/sample.rc - $(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_2) $(__DEBUG_DEFINE_p_2) $(__EXCEPTIONS_DEFINE_p_2) $(__RTTI_DEFINE_p_2) $(__THREAD_DEFINE_p_2) --include-dir $(srcdir) $(__DLLFLAG_p_2) --include-dir $(srcdir)/../../samples $(__RCDEFDIR_p_1) --include-dir $(top_srcdir)/include - image_image.o: $(srcdir)/image.cpp $(CXXC) -c -o $@ $(IMAGE_CXXFLAGS) $(srcdir)/image.cpp image_canvas.o: $(srcdir)/canvas.cpp $(CXXC) -c -o $@ $(IMAGE_CXXFLAGS) $(srcdir)/canvas.cpp +image_image_rc.o: $(srcdir)/image.rc + $(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_2) $(__DEBUG_DEFINE_p_2) $(__EXCEPTIONS_DEFINE_p_2) $(__RTTI_DEFINE_p_2) $(__THREAD_DEFINE_p_2) --include-dir $(srcdir) $(__DLLFLAG_p_2) --include-dir $(srcdir)/../../samples $(__RCDEFDIR_p_1) --include-dir $(top_srcdir)/include + # Include dependency info, if present: @IF_GNU_MAKE@-include ./.deps/*.d diff --git a/samples/image/canvas.cpp b/samples/image/canvas.cpp index 2fc194423c..cdba69aa43 100644 --- a/samples/image/canvas.cpp +++ b/samples/image/canvas.cpp @@ -35,6 +35,7 @@ #include "smile.xbm" #include "smile.xpm" +#include "cursor_png.c" #include "canvas.h" @@ -376,6 +377,19 @@ MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id, free(data); } + + // This macro loads PNG from either resources on the platforms that support + // this (Windows and OS X) or from in-memory data (coming from cursor_png.c + // included above in our case). + my_png_from_res = wxBITMAP_PNG(cursor); + + // This one always loads PNG from memory but exists for consistency with + // the above one and also because it frees you from the need to specify the + // length explicitly, without it you'd have to do it and also spell the + // array name in full, like this: + // + // my_png_from_mem = wxBitmap::NewFromPNGData(cursor_png, WXSIZEOF(cursor_png)); + my_png_from_mem = wxBITMAP_PNG_FROM_DATA(cursor); } MyCanvas::~MyCanvas() @@ -635,6 +649,13 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) dc.DrawBitmap( my_horse_ani[i], 230 + i * 2 * my_horse_ani[i].GetWidth() , 2420, true ); } } + + dc.DrawText("PNG from resources", 30, 2460); + if ( my_png_from_res.IsOk() ) + dc.DrawBitmap(my_png_from_res, 30, 2480, true); + dc.DrawText("PNG from memory", 230, 2460); + if ( my_png_from_mem.IsOk() ) + dc.DrawBitmap(my_png_from_mem, 230, 2480, true); } void MyCanvas::CreateAntiAliasedBitmap() diff --git a/samples/image/canvas.h b/samples/image/canvas.h index 6a81148d33..a737ff5105 100644 --- a/samples/image/canvas.h +++ b/samples/image/canvas.h @@ -38,6 +38,8 @@ public: wxBitmap my_horse_ico16; wxBitmap my_horse_ico; wxBitmap my_horse_cur; + wxBitmap my_png_from_res, + my_png_from_mem; wxBitmap my_smile_xbm; wxBitmap my_square; diff --git a/samples/image/cursor_png.c b/samples/image/cursor_png.c new file mode 100644 index 0000000000..ad580377dd --- /dev/null +++ b/samples/image/cursor_png.c @@ -0,0 +1,72 @@ +/* + This file was created using the following command: + + ./misc/scripts/png2c.py samples/image/cursor.png > samples/image/cursor_png.c + + (and then edited to add this comment). + */ + +/* cursor.png - 489 bytes */ +static const unsigned char cursor_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, + 0xf4, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, + 0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64, + 0x88, 0x00, 0x00, 0x01, 0xa0, 0x49, 0x44, 0x41, + 0x54, 0x58, 0x85, 0xc5, 0x97, 0x5b, 0xb2, 0x84, + 0x20, 0x0c, 0x44, 0x1b, 0xeb, 0xee, 0x48, 0xd6, + 0x24, 0x6b, 0xc2, 0x35, 0xc1, 0x9a, 0x72, 0x3f, + 0x24, 0x4c, 0x80, 0x80, 0x8f, 0x51, 0x27, 0x55, + 0xd6, 0x94, 0x32, 0xda, 0x27, 0x1d, 0x08, 0x0a, + 0x00, 0x44, 0xc1, 0x13, 0x00, 0x32, 0x00, 0xde, + 0x3e, 0x26, 0xa4, 0xa0, 0xe0, 0x41, 0x00, 0xe1, + 0xe5, 0x98, 0xe4, 0xc9, 0x2f, 0x20, 0x26, 0x00, + 0x30, 0xd6, 0xfd, 0x0c, 0x62, 0x32, 0x5b, 0x29, + 0x8a, 0x78, 0x13, 0x22, 0x97, 0x40, 0xba, 0x20, + 0x21, 0x9e, 0x06, 0x31, 0x9c, 0x3e, 0x0b, 0x51, + 0xf0, 0xed, 0x9f, 0xac, 0x83, 0xe6, 0xd4, 0x1d, + 0xf1, 0x71, 0x20, 0x09, 0xd4, 0x4e, 0x30, 0xd4, + 0x53, 0x4e, 0x98, 0x3a, 0x2d, 0xcd, 0x89, 0x18, + 0x23, 0x00, 0xc0, 0xba, 0xb5, 0x80, 0x7d, 0x04, + 0x40, 0x42, 0x04, 0xbf, 0x14, 0xc2, 0x0c, 0xc5, + 0x2e, 0xdd, 0x02, 0xd2, 0xeb, 0x50, 0x1b, 0xc7, + 0x76, 0x50, 0xf0, 0x14, 0xfc, 0x52, 0x9c, 0xdf, + 0xd5, 0x3d, 0xff, 0x7a, 0xd9, 0x73, 0xc6, 0x31, + 0xc6, 0x9c, 0xb1, 0x2c, 0x4b, 0xbe, 0xb6, 0x41, + 0x5c, 0x76, 0xa2, 0x00, 0x90, 0xf5, 0xdf, 0x15, + 0x2e, 0xaf, 0x5d, 0x86, 0x28, 0xe6, 0x00, 0x01, + 0x14, 0xfc, 0xd2, 0xd4, 0xbc, 0x27, 0x5c, 0x3c, + 0xe8, 0xe2, 0x52, 0x6d, 0x00, 0xce, 0x0a, 0x03, + 0x00, 0xe6, 0x19, 0x10, 0x8e, 0x9d, 0x01, 0x69, + 0xe6, 0xc0, 0x29, 0x61, 0x21, 0x8e, 0x79, 0x96, + 0xab, 0xe4, 0x70, 0x49, 0xa6, 0xd1, 0x60, 0xb7, + 0x2b, 0xca, 0x66, 0x95, 0xc4, 0xf3, 0x2f, 0xce, + 0x35, 0xae, 0x21, 0xc0, 0x50, 0x58, 0xc6, 0x17, + 0x10, 0x87, 0x01, 0x34, 0xa0, 0x3b, 0x20, 0x0e, + 0x01, 0x18, 0xeb, 0x10, 0xfc, 0x92, 0x3b, 0xa3, + 0x1a, 0x52, 0x5c, 0x81, 0xe8, 0x81, 0x74, 0x57, + 0x41, 0x6f, 0x12, 0xc6, 0x18, 0xf3, 0x32, 0x6d, + 0xc6, 0x6b, 0x08, 0x25, 0x91, 0x7a, 0x72, 0xaa, + 0x0e, 0x70, 0xc6, 0xf9, 0x26, 0x51, 0xff, 0x39, + 0x65, 0xc6, 0xe3, 0x51, 0x0a, 0x29, 0x0e, 0xc8, + 0xd0, 0x4a, 0x52, 0x00, 0x48, 0x3a, 0xeb, 0xd6, + 0x2c, 0x52, 0xc3, 0xc8, 0x52, 0x48, 0x37, 0xf6, + 0x1c, 0xd0, 0x20, 0xd4, 0xdd, 0x10, 0x40, 0x43, + 0xca, 0x1d, 0x92, 0x2d, 0x97, 0x5b, 0x74, 0xf0, + 0x4b, 0x76, 0x66, 0x24, 0x5e, 0x24, 0x9b, 0xca, + 0xd1, 0x05, 0xd8, 0x03, 0x92, 0x20, 0x0d, 0xc4, + 0xc1, 0x30, 0xd6, 0xf5, 0x1d, 0x38, 0x0a, 0x33, + 0xda, 0x1b, 0xf6, 0xba, 0xa8, 0xb1, 0xae, 0xdf, + 0x8a, 0x87, 0x37, 0xa6, 0xb9, 0x42, 0x00, 0x75, + 0x9b, 0x13, 0x36, 0x77, 0xf6, 0x5c, 0xb9, 0xdc, + 0x88, 0x18, 0x44, 0x3b, 0x78, 0xdc, 0xba, 0xb5, + 0x5c, 0x25, 0xda, 0x33, 0x1e, 0x79, 0xd5, 0x4d, + 0x21, 0x5f, 0xed, 0x6a, 0x27, 0x78, 0x12, 0x7e, + 0xe5, 0xc0, 0x5e, 0xb0, 0x1b, 0x23, 0x27, 0x1e, + 0x75, 0x40, 0x46, 0xbd, 0x8a, 0xf2, 0x67, 0xc0, + 0x5b, 0x00, 0xbd, 0xf8, 0x07, 0x6a, 0xb9, 0x1e, + 0x64, 0x99, 0x1e, 0x1f, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, + 0x82}; diff --git a/samples/image/image.bkl b/samples/image/image.bkl index 3c6268b079..3f441f74c3 100644 --- a/samples/image/image.bkl +++ b/samples/image/image.bkl @@ -3,6 +3,12 @@ + + $(SRCDIR)/cursor.png + @@ -10,6 +16,7 @@ canvas.h core base + image.rc diff --git a/samples/image/image.dsp b/samples/image/image.dsp index b4cd993edf..6a6a69439d 100644 --- a/samples/image/image.dsp +++ b/samples/image/image.dsp @@ -260,7 +260,7 @@ SOURCE=.\image.cpp # End Source File # Begin Source File -SOURCE=.\..\..\samples\sample.rc +SOURCE=.\image.rc # End Source File # End Group # Begin Group "Header Files" diff --git a/samples/image/image.rc b/samples/image/image.rc new file mode 100644 index 0000000000..03d674384e --- /dev/null +++ b/samples/image/image.rc @@ -0,0 +1,5 @@ +#include "../sample.rc" + +// The exact PNG file used here doesn't really matter but it's the same one we +// embed into the sample code too. +cursor RCDATA "cursor.png" diff --git a/samples/image/image_vc7.vcproj b/samples/image/image_vc7.vcproj index 1864c07f03..1d43e03a5a 100644 --- a/samples/image/image_vc7.vcproj +++ b/samples/image/image_vc7.vcproj @@ -561,7 +561,7 @@ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + RelativePath=".\image.rc"> diff --git a/samples/image/image_vc8.vcproj b/samples/image/image_vc8.vcproj index 483573cef5..90faef6412 100644 --- a/samples/image/image_vc8.vcproj +++ b/samples/image/image_vc8.vcproj @@ -828,7 +828,7 @@ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" > diff --git a/samples/image/image_vc9.vcproj b/samples/image/image_vc9.vcproj index de1db6bf48..b286705a3d 100644 --- a/samples/image/image_vc9.vcproj +++ b/samples/image/image_vc9.vcproj @@ -800,7 +800,7 @@ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" > diff --git a/samples/image/makefile.bcc b/samples/image/makefile.bcc index 482014f884..cfa5af9df6 100644 --- a/samples/image/makefile.bcc +++ b/samples/image/makefile.bcc @@ -234,21 +234,20 @@ clean: -if exist $(OBJS)\image.ilf del $(OBJS)\image.ilf -if exist $(OBJS)\image.ils del $(OBJS)\image.ils -$(OBJS)\image.exe: $(IMAGE_OBJECTS) $(OBJS)\image_sample.res +$(OBJS)\image.exe: $(IMAGE_OBJECTS) $(OBJS)\image_image.res ilink32 -Tpe -q -L$(BCCDIR)\lib -L$(BCCDIR)\lib\psdk $(__DEBUGINFO) -L$(LIBDIRNAME) -aa $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) @&&| - c0w32.obj $(IMAGE_OBJECTS),$@,, $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__UNICOWS_LIB_p) $(__CAIRO_LIB_p) ole2w32.lib oleacc.lib import32.lib cw32$(__THREADSFLAG_5)$(__RUNTIME_LIBS_8).lib,, $(OBJS)\image_sample.res + c0w32.obj $(IMAGE_OBJECTS),$@,, $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__UNICOWS_LIB_p) $(__CAIRO_LIB_p) ole2w32.lib oleacc.lib import32.lib cw32$(__THREADSFLAG_5)$(__RUNTIME_LIBS_8).lib,, $(OBJS)\image_image.res | data: if not exist $(OBJS) mkdir $(OBJS) for %f in (horse.png horse.jpg horse.bmp horse.gif horse.pcx horse.pnm horse_ag.pnm horse_rg.pnm horse.tif horse.tga horse.xpm horse.cur horse.ico horse3.ani smile.xbm toucan.png cmyk.jpg cursor.png) do if not exist $(OBJS)\%f copy .\%f $(OBJS) -$(OBJS)\image_sample.res: .\..\..\samples\sample.rc - brcc32 -32 -r -fo$@ -i$(BCCDIR)\include -d__WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) -i$(SETUPHDIR) -i.\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_1_p) -i. $(__DLLFLAG_p_1) -i.\..\..\samples -dNOPCH .\..\..\samples\sample.rc - $(OBJS)\image_image.obj: .\image.cpp $(CXX) -q -c -P -o$@ $(IMAGE_CXXFLAGS) .\image.cpp $(OBJS)\image_canvas.obj: .\canvas.cpp $(CXX) -q -c -P -o$@ $(IMAGE_CXXFLAGS) .\canvas.cpp +$(OBJS)\image_image.res: .\image.rc + brcc32 -32 -r -fo$@ -i$(BCCDIR)\include -d__WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) -i$(SETUPHDIR) -i.\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_1_p) -i. $(__DLLFLAG_p_1) -i.\..\..\samples -dNOPCH .\image.rc diff --git a/samples/image/makefile.gcc b/samples/image/makefile.gcc index 1a61a4e61b..e5e00a9dd0 100644 --- a/samples/image/makefile.gcc +++ b/samples/image/makefile.gcc @@ -30,9 +30,9 @@ IMAGE_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG) \ -I.\..\..\samples -DNOPCH $(__RTTIFLAG_5) $(__EXCEPTIONSFLAG_6) \ -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) IMAGE_OBJECTS = \ - $(OBJS)\image_sample_rc.o \ $(OBJS)\image_image.o \ - $(OBJS)\image_canvas.o + $(OBJS)\image_canvas.o \ + $(OBJS)\image_image_rc.o ### Conditionally set variables: ### @@ -223,22 +223,22 @@ clean: -if exist $(OBJS)\*.d del $(OBJS)\*.d -if exist $(OBJS)\image.exe del $(OBJS)\image.exe -$(OBJS)\image.exe: $(IMAGE_OBJECTS) $(OBJS)\image_sample_rc.o +$(OBJS)\image.exe: $(IMAGE_OBJECTS) $(OBJS)\image_image_rc.o $(CXX) -o $@ $(IMAGE_OBJECTS) $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__UNICOWS_LIB_p) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lwsock32 -lwininet data: if not exist $(OBJS) mkdir $(OBJS) for %%f in (horse.png horse.jpg horse.bmp horse.gif horse.pcx horse.pnm horse_ag.pnm horse_rg.pnm horse.tif horse.tga horse.xpm horse.cur horse.ico horse3.ani smile.xbm toucan.png cmyk.jpg cursor.png) do if not exist $(OBJS)\%%f copy .\%%f $(OBJS) -$(OBJS)\image_sample_rc.o: ./../../samples/sample.rc - windres --use-temp-file -i$< -o$@ --define __WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) --include-dir $(SETUPHDIR) --include-dir ./../../include $(__CAIRO_INCLUDEDIR_p) --include-dir . $(__DLLFLAG_p_1) --include-dir ./../../samples --define NOPCH - $(OBJS)\image_image.o: ./image.cpp $(CXX) -c -o $@ $(IMAGE_CXXFLAGS) $(CPPDEPS) $< $(OBJS)\image_canvas.o: ./canvas.cpp $(CXX) -c -o $@ $(IMAGE_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\image_image_rc.o: ./image.rc + windres --use-temp-file -i$< -o$@ --define __WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) --include-dir $(SETUPHDIR) --include-dir ./../../include $(__CAIRO_INCLUDEDIR_p) --include-dir . $(__DLLFLAG_p_1) --include-dir ./../../samples --define NOPCH + .PHONY: all clean data diff --git a/samples/image/makefile.vc b/samples/image/makefile.vc index a9ae53836f..6a62ab620f 100644 --- a/samples/image/makefile.vc +++ b/samples/image/makefile.vc @@ -34,7 +34,7 @@ IMAGE_OBJECTS = \ $(OBJS)\image_image.obj \ $(OBJS)\image_canvas.obj IMAGE_RESOURCES = \ - $(OBJS)\image_sample.res + $(OBJS)\image_image.res ### Conditionally set variables: ### @@ -356,7 +356,7 @@ clean: -if exist $(OBJS)\image.ilk del $(OBJS)\image.ilk -if exist $(OBJS)\image.pdb del $(OBJS)\image.pdb -$(OBJS)\image.exe: $(IMAGE_OBJECTS) $(OBJS)\image_sample.res +$(OBJS)\image.exe: $(IMAGE_OBJECTS) $(OBJS)\image_image.res link /NOLOGO /OUT:$@ $(__DEBUGINFO_1) /pdb:"$(OBJS)\image.pdb" $(__DEBUGINFO_2) $(LINK_TARGET_CPU) /LIBPATH:$(LIBDIRNAME) /SUBSYSTEM:WINDOWS $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) @<< $(IMAGE_OBJECTS) $(IMAGE_RESOURCES) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__UNICOWS_LIB_p) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib wininet.lib << @@ -365,12 +365,11 @@ data: if not exist $(OBJS) mkdir $(OBJS) for %f in (horse.png horse.jpg horse.bmp horse.gif horse.pcx horse.pnm horse_ag.pnm horse_rg.pnm horse.tif horse.tga horse.xpm horse.cur horse.ico horse3.ani smile.xbm toucan.png cmyk.jpg cursor.png) do if not exist $(OBJS)\%f copy .\%f $(OBJS) -$(OBJS)\image_sample.res: .\..\..\samples\sample.rc - rc /fo$@ /d WIN32 $(____DEBUGRUNTIME_3_p_1) /d _CRT_SECURE_NO_DEPRECATE=1 /d _CRT_NON_CONFORMING_SWPRINTFS=1 /d _SCL_SECURE_NO_WARNINGS=1 $(__NO_VC_CRTDBG_p_1) /d __WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) /i $(SETUPHDIR) /i .\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_1_p) /i . $(__DLLFLAG_p_1) /d _WINDOWS /i .\..\..\samples /d NOPCH .\..\..\samples\sample.rc - $(OBJS)\image_image.obj: .\image.cpp $(CXX) /c /nologo /TP /Fo$@ $(IMAGE_CXXFLAGS) .\image.cpp $(OBJS)\image_canvas.obj: .\canvas.cpp $(CXX) /c /nologo /TP /Fo$@ $(IMAGE_CXXFLAGS) .\canvas.cpp +$(OBJS)\image_image.res: .\image.rc + rc /fo$@ /d WIN32 $(____DEBUGRUNTIME_3_p_1) /d _CRT_SECURE_NO_DEPRECATE=1 /d _CRT_NON_CONFORMING_SWPRINTFS=1 /d _SCL_SECURE_NO_WARNINGS=1 $(__NO_VC_CRTDBG_p_1) /d __WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) /i $(SETUPHDIR) /i .\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_1_p) /i . $(__DLLFLAG_p_1) /d _WINDOWS /i .\..\..\samples /d NOPCH .\image.rc diff --git a/samples/image/makefile.wat b/samples/image/makefile.wat index c501e32c15..c03d3f6dcb 100644 --- a/samples/image/makefile.wat +++ b/samples/image/makefile.wat @@ -254,7 +254,7 @@ clean : .SYMBOLIC -if exist $(OBJS)\*.pch del $(OBJS)\*.pch -if exist $(OBJS)\image.exe del $(OBJS)\image.exe -$(OBJS)\image.exe : $(IMAGE_OBJECTS) $(OBJS)\image_sample.res +$(OBJS)\image.exe : $(IMAGE_OBJECTS) $(OBJS)\image_image.res @%create $(OBJS)\image.lbc @%append $(OBJS)\image.lbc option quiet @%append $(OBJS)\image.lbc name $^@ @@ -262,7 +262,7 @@ $(OBJS)\image.exe : $(IMAGE_OBJECTS) $(OBJS)\image_sample.res @%append $(OBJS)\image.lbc $(__DEBUGINFO_1) libpath $(LIBDIRNAME) system nt_win ref '_WinMain@16' $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) @for %i in ($(IMAGE_OBJECTS)) do @%append $(OBJS)\image.lbc file %i @for %i in ( $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib wininet.lib) do @%append $(OBJS)\image.lbc library %i - @%append $(OBJS)\image.lbc option resource=$(OBJS)\image_sample.res + @%append $(OBJS)\image.lbc option resource=$(OBJS)\image_image.res @for %i in () do @%append $(OBJS)\image.lbc option stack=%i wlink @$(OBJS)\image.lbc @@ -270,12 +270,11 @@ data : .SYMBOLIC if not exist $(OBJS) mkdir $(OBJS) for %f in (horse.png horse.jpg horse.bmp horse.gif horse.pcx horse.pnm horse_ag.pnm horse_rg.pnm horse.tif horse.tga horse.xpm horse.cur horse.ico horse3.ani smile.xbm toucan.png cmyk.jpg cursor.png) do if not exist $(OBJS)\%f copy .\%f $(OBJS) -$(OBJS)\image_sample.res : .AUTODEPEND .\..\..\samples\sample.rc - wrc -q -ad -bt=nt -r -fo=$^@ -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) -i=$(SETUPHDIR) -i=.\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES) -i=. $(__DLLFLAG_p) -i=.\..\..\samples -dNOPCH $< - $(OBJS)\image_image.obj : .AUTODEPEND .\image.cpp $(CXX) -bt=nt -zq -fo=$^@ $(IMAGE_CXXFLAGS) $< $(OBJS)\image_canvas.obj : .AUTODEPEND .\canvas.cpp $(CXX) -bt=nt -zq -fo=$^@ $(IMAGE_CXXFLAGS) $< +$(OBJS)\image_image.res : .AUTODEPEND .\image.rc + wrc -q -ad -bt=nt -r -fo=$^@ -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) -i=$(SETUPHDIR) -i=.\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES) -i=. $(__DLLFLAG_p) -i=.\..\..\samples -dNOPCH $< diff --git a/src/msw/gdiimage.cpp b/src/msw/gdiimage.cpp index 1c4e5755ed..845cbb3d69 100644 --- a/src/msw/gdiimage.cpp +++ b/src/msw/gdiimage.cpp @@ -39,6 +39,18 @@ #include "wx/msw/dib.h" #endif +// By default, use PNG resource handler if we can, i.e. have support for +// loading PNG images in the library. This symbol could be predefined as 0 to +// avoid doing this if anybody ever needs to do it for some reason. +#if !defined(wxUSE_PNG_RESOURCE_HANDLER) && wxUSE_LIBPNG && wxUSE_IMAGE + #define wxUSE_PNG_RESOURCE_HANDLER 1 +#endif + +#if wxUSE_PNG_RESOURCE_HANDLER + #include "wx/image.h" + #include "wx/utils.h" // For wxLoadUserResource() +#endif + #ifdef __WXWINCE__ #include #include @@ -173,6 +185,27 @@ private: DECLARE_DYNAMIC_CLASS(wxICOResourceHandler) }; +#if wxUSE_PNG_RESOURCE_HANDLER + +class WXDLLEXPORT wxPNGResourceHandler : public wxBitmapHandler +{ +public: + wxPNGResourceHandler() : wxBitmapHandler(wxS("Windows PNG resource"), + wxString(), + wxBITMAP_TYPE_PNG_RESOURCE) + { + } + + virtual bool LoadFile(wxBitmap *bitmap, + const wxString& name, wxBitmapType flags, + int desiredWidth, int desiredHeight); + +private: + wxDECLARE_DYNAMIC_CLASS(wxPNGResourceHandler); +}; + +#endif // wxUSE_PNG_RESOURCE_HANDLER + // ---------------------------------------------------------------------------- // wxWin macros // ---------------------------------------------------------------------------- @@ -181,6 +214,9 @@ IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler) IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler) IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxObject) IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxObject) +#if wxUSE_PNG_RESOURCE_HANDLER +IMPLEMENT_DYNAMIC_CLASS(wxPNGResourceHandler, wxBitmapHandler) +#endif // wxUSE_PNG_RESOURCE_HANDLER // ---------------------------------------------------------------------------- // private functions @@ -306,8 +342,11 @@ void wxGDIImage::InitStandardHandlers() #ifndef __WXMICROWIN__ AddHandler(new wxBMPResourceHandler); AddHandler(new wxBMPFileHandler); - AddHandler(new wxICOResourceHandler); AddHandler(new wxICOFileHandler); + AddHandler(new wxICOResourceHandler); +#if wxUSE_PNG_RESOURCE_HANDLER + AddHandler(new wxPNGResourceHandler); +#endif // wxUSE_PNG_RESOURCE_HANDLER #endif } @@ -562,6 +601,55 @@ bool wxICOResourceHandler::LoadIcon(wxIcon *icon, return icon->IsOk(); } +#if wxUSE_PNG_RESOURCE_HANDLER + +// ---------------------------------------------------------------------------- +// PNG handler +// ---------------------------------------------------------------------------- + +bool wxPNGResourceHandler::LoadFile(wxBitmap *bitmap, + const wxString& name, + wxBitmapType WXUNUSED(flags), + int WXUNUSED(desiredWidth), + int WXUNUSED(desiredHeight)) +{ + const void* pngData = NULL; + size_t pngSize = 0; + + // Currently we hardcode RCDATA resource type as this is what is usually + // used for the embedded images. We could allow specifying the type as part + // of the name in the future (e.g. "type:name" or something like this) if + // really needed. + if ( !wxLoadUserResource(&pngData, &pngSize, + name, + RT_RCDATA, + wxGetInstance()) ) + { + // Notice that this message is not translated because only the + // programmer (and not the end user) can make any use of it. + wxLogError(wxS("Bitmap in PNG format \"%s\" not found, check ") + wxS("that the resource file contains \"RCDATA\" ") + wxS("resource with this name."), + name); + + return false; + } + + *bitmap = wxBitmap::NewFromPNGData(pngData, pngSize); + if ( !bitmap->IsOk() ) + { + wxLogError(wxS("Couldn't load resource bitmap \"%s\" as a PNG. "), + wxS("Have you registered PNG image handler?"), + name); + + return false; + } + + return true; +} + +#endif // wxUSE_PNG_RESOURCE_HANDLER + // ---------------------------------------------------------------------------- // private functions // ----------------------------------------------------------------------------