]> git.saurik.com Git - wxWidgets.git/blob - src/msw/xpmhand.cpp
trying to fix memory leak in wxListCtrl (attributes not deleted)
[wxWidgets.git] / src / msw / xpmhand.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: xpmhand.cpp
3 // Purpose: wxBitmap: XPM handler and constructors
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "xpmhand.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/list.h"
25 #include "wx/utils.h"
26 #include "wx/app.h"
27 #include "wx/palette.h"
28 #include "wx/dcmemory.h"
29 #include "wx/bitmap.h"
30 #include "wx/icon.h"
31 #endif
32
33 #include "wx/msw/private.h"
34 #include "wx/log.h"
35
36 #if wxUSE_XPM_IN_MSW
37 #define FOR_MSW 1
38 #include "../xpm/xpm.h"
39 #endif
40
41 #include "wx/xpmhand.h"
42 #include "wx/msw/dib.h"
43
44 #if wxUSE_XPM_IN_MSW
45
46 static void XpmToBitmap(wxBitmap *bitmap,
47 const XImage *ximage,
48 const XImage *xmask,
49 const XpmAttributes& xpmAttr)
50 {
51 wxBitmapRefData *refData = bitmap->GetBitmapData();
52 refData->m_hBitmap = (WXHBITMAP)ximage->bitmap;
53
54 // first set the bitmap width, height, depth...
55 BITMAP bm;
56 if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(bm), (LPSTR) & bm) )
57 {
58 wxLogLastError("GetObject(bitmap)");
59 }
60
61 refData->m_width = bm.bmWidth;
62 refData->m_height = bm.bmHeight;
63 refData->m_depth = bm.bmPlanes * bm.bmBitsPixel;
64 refData->m_numColors = xpmAttr.npixels;
65
66 // GRG Jan/2000, mask support
67 if (xmask)
68 {
69 wxMask *mask = new wxMask();
70 mask->SetMaskBitmap((WXHBITMAP) wxInvertMask(xmask->bitmap));
71 bitmap->SetMask(mask);
72 }
73 }
74
75 #endif // wxUSE_XPM_IN_MSW
76
77 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
78
79 bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap,
80 const wxString& name,
81 long flags,
82 int desiredWidth, int desiredHeight)
83 {
84 #if wxUSE_XPM_IN_MSW
85 XImage *ximage = NULL;
86 XImage *xmask = NULL;
87 XpmAttributes xpmAttr;
88 HDC dc;
89
90 dc = CreateCompatibleDC(NULL);
91 if (dc)
92 {
93 xpmAttr.valuemask = XpmReturnPixels | XpmColorTable;
94 int errorStatus = XpmReadFileToImage(&dc,
95 wxMBSTRINGCAST name.fn_str(),
96 &ximage,
97 &xmask,
98 &xpmAttr);
99 DeleteDC(dc);
100 if (errorStatus == XpmSuccess)
101 {
102 XpmToBitmap(bitmap, ximage, xmask, xpmAttr);
103
104 XpmFree(xpmAttr.pixels);
105 XpmFreeAttributes(&xpmAttr);
106 XImageFree(ximage);
107 if (xmask)
108 XDestroyImage(xmask);
109 }
110
111 #if WXWIN_COMPATIBILITY_2
112 bitmap->SetOk(errorStatus == XpmSuccess);
113 #endif // WXWIN_COMPATIBILITY_2
114
115 return bitmap->Ok();
116 }
117 #endif // wxUSE_XPM_IN_MSW
118
119 return FALSE;
120 }
121
122 bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap,
123 const wxString& name,
124 int type,
125 const wxPalette *palette)
126 {
127 #if wxUSE_XPM_IN_MSW
128 XImage ximage;
129 XImage xmask;
130 bool hasmask = FALSE;
131
132 HDC dc = CreateCompatibleDC(NULL);
133 if (dc)
134 {
135 /* fill the XImage struct 'by hand' */
136 wxBitmapRefData *refData = bitmap->GetBitmapData();
137 ximage.width = refData->m_width;
138 ximage.height = refData->m_height;
139 ximage.depth = refData->m_depth;
140 ximage.bitmap = (HBITMAP)refData->m_hBitmap;
141
142 // GRG Jan/2000, mask support
143 hasmask = (refData->m_bitmapMask != NULL);
144 if (hasmask)
145 {
146 /* Strangely enough, the MSW version of xpmlib is not
147 * coherent with itself regarding masks; we have to invert
148 * the mask we get when loading, but we still must pass it
149 * 'as is' when saving...
150 */
151 xmask.bitmap = (HBITMAP) refData->m_bitmapMask->GetMaskBitmap();
152 xmask.width = refData->m_width;
153 xmask.height = refData->m_height;
154 xmask.depth = 1;
155 }
156
157 int errorStatus = XpmWriteFileFromImage(
158 &dc,
159 wxMBSTRINGCAST name.fn_str(),
160 &ximage,
161 (hasmask? &xmask : (XImage *)NULL),
162 (XpmAttributes *) NULL);
163
164 DeleteDC(dc);
165
166 return (errorStatus == XpmSuccess);
167 }
168 #endif // !wxUSE_XPM_IN_MSW
169
170 return FALSE;
171 }
172
173 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
174
175 bool wxXPMDataHandler::Create(wxBitmap *bitmap,
176 void *data,
177 long flags,
178 int width,
179 int height,
180 int depth)
181 {
182 #if wxUSE_XPM_IN_MSW
183 XImage *ximage = NULL;
184 XImage *xmask = NULL;
185 XpmAttributes xpmAttr;
186
187 HDC dc = CreateCompatibleDC(NULL); /* memory DC */
188
189 if (dc)
190 {
191 xpmAttr.valuemask = XpmReturnInfos | XpmColorTable;
192 int errorStatus = XpmCreateImageFromData(&dc, (char **)data,
193 &ximage,
194 &xmask,
195 &xpmAttr);
196 DeleteDC(dc);
197
198 if ( errorStatus == XpmSuccess )
199 {
200 XpmToBitmap(bitmap, ximage, xmask, xpmAttr);
201
202 XpmFree(xpmAttr.pixels);
203 XpmFreeAttributes(&xpmAttr);
204 XImageFree(ximage); // releases the malloc, but does not destroy bitmap
205 if (xmask)
206 XDestroyImage(xmask);
207 }
208
209 #if WXWIN_COMPATIBILITY_2
210 bitmap->SetOk(errorStatus == XpmSuccess);
211 #endif // WXWIN_COMPATIBILITY_2
212
213 return bitmap->Ok();
214 }
215 #endif // wxUSE_XPM_IN_MSW
216
217 return FALSE;
218 }
219