1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/palette.cpp
3 // Purpose:     wxPalette
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     04/01/98
7 // Copyright:   (c) Julian Smart
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13 
14 #ifdef __BORLANDC__
15     #pragma hdrstop
16 #endif
17 
18 #if wxUSE_PALETTE
19 
20 #include "wx/palette.h"
21 
22 #include "wx/msw/private.h"
23 
24 // ============================================================================
25 // wxPaletteRefData
26 // ============================================================================
27 
28 class WXDLLEXPORT wxPaletteRefData: public wxGDIRefData
29 {
30 public:
wxPaletteRefData()31     wxPaletteRefData() { Init(); }
32 
wxPaletteRefData(int n,const unsigned char * red,const unsigned char * green,const unsigned char * blue)33     wxPaletteRefData(int n,
34                      const unsigned char *red,
35                      const unsigned char *green,
36                      const unsigned char *blue)
37     {
38         Init();
39 
40         LOGPALETTE *pPal = Alloc(n);
41         if ( !pPal )
42             return;
43 
44         for ( int i = 0; i < n; i++ )
45         {
46             pPal->palPalEntry[i].peRed = red[i];
47             pPal->palPalEntry[i].peGreen = green[i];
48             pPal->palPalEntry[i].peBlue = blue[i];
49             pPal->palPalEntry[i].peFlags = 0;
50         }
51 
52         m_hPalette = ::CreatePalette(pPal);
53         free(pPal);
54     }
55 
wxPaletteRefData(const wxPaletteRefData & data)56     wxPaletteRefData(const wxPaletteRefData& data)
57         : wxGDIRefData()
58     {
59         Init();
60 
61         const UINT n = data.GetEntries();
62         if ( !n )
63             return;
64 
65         LOGPALETTE *pPal = Alloc(n);
66         if ( !pPal )
67             return;
68 
69         if ( ::GetPaletteEntries(data.m_hPalette, 0, n, pPal->palPalEntry) )
70             m_hPalette = ::CreatePalette(pPal);
71 
72         free(pPal);
73     }
74 
~wxPaletteRefData()75     virtual ~wxPaletteRefData()
76     {
77         if ( m_hPalette )
78             ::DeleteObject(m_hPalette);
79     }
80 
IsOk() const81     virtual bool IsOk() const { return m_hPalette != 0; }
82 
GetEntries() const83     UINT GetEntries() const
84     {
85         return ::GetPaletteEntries(m_hPalette, 0, 0, NULL);
86     }
87 
88 private:
89     // caller must free() the pointer
Alloc(UINT numEntries)90     static LOGPALETTE *Alloc(UINT numEntries)
91     {
92         LOGPALETTE *pPal = (LOGPALETTE *)
93             malloc(sizeof(LOGPALETTE) + numEntries*sizeof(PALETTEENTRY));
94         if ( pPal )
95         {
96             pPal->palVersion = 0x300;
97             pPal->palNumEntries = numEntries;
98         }
99 
100         return pPal;
101     }
102 
Init()103     void Init() { m_hPalette = 0; }
104 
105     HPALETTE m_hPalette;
106 
107     friend class WXDLLIMPEXP_FWD_CORE wxPalette;
108 };
109 
110 // ============================================================================
111 // wxPalette
112 // ============================================================================
113 
IMPLEMENT_DYNAMIC_CLASS(wxPalette,wxGDIObject)114 IMPLEMENT_DYNAMIC_CLASS(wxPalette, wxGDIObject)
115 
116 #define M_PALETTEDATA ((wxPaletteRefData *)m_refData)
117 
118 bool wxPalette::Create(int n,
119                        const unsigned char *red,
120                        const unsigned char *green,
121                        const unsigned char *blue)
122 {
123     m_refData = new wxPaletteRefData(n, red, green, blue);
124 
125     return IsOk();
126 }
127 
CreateGDIRefData() const128 wxGDIRefData *wxPalette::CreateGDIRefData() const
129 {
130     return new wxPaletteRefData;
131 }
132 
CloneGDIRefData(const wxGDIRefData * data) const133 wxGDIRefData *wxPalette::CloneGDIRefData(const wxGDIRefData *data) const
134 {
135     return new wxPaletteRefData(*static_cast<const wxPaletteRefData *>(data));
136 }
137 
GetColoursCount() const138 int wxPalette::GetColoursCount() const
139 {
140     return IsOk() ? M_PALETTEDATA->GetEntries() : 0;
141 }
142 
GetPixel(unsigned char red,unsigned char green,unsigned char blue) const143 int wxPalette::GetPixel(unsigned char red,
144                         unsigned char green,
145                         unsigned char blue) const
146 {
147     if ( !m_refData )
148         return wxNOT_FOUND;
149 
150     return ::GetNearestPaletteIndex(M_PALETTEDATA->m_hPalette,
151                                     PALETTERGB(red, green, blue));
152 }
153 
GetRGB(int index,unsigned char * red,unsigned char * green,unsigned char * blue) const154 bool wxPalette::GetRGB(int index,
155                        unsigned char *red,
156                        unsigned char *green,
157                        unsigned char *blue) const
158 {
159     if ( !m_refData )
160         return false;
161 
162     if (index < 0 || index > 255)
163         return false;
164 
165     PALETTEENTRY entry;
166     if ( !::GetPaletteEntries(M_PALETTEDATA->m_hPalette, index, 1, &entry) )
167         return false;
168 
169     *red = entry.peRed;
170     *green = entry.peGreen;
171     *blue = entry.peBlue;
172 
173     return true;
174 }
175 
GetHPALETTE() const176 WXHPALETTE wxPalette::GetHPALETTE() const
177 {
178     return M_PALETTEDATA ? (WXHPALETTE)M_PALETTEDATA->m_hPalette : 0;
179 }
180 
SetHPALETTE(WXHPALETTE pal)181 void wxPalette::SetHPALETTE(WXHPALETTE pal)
182 {
183     AllocExclusive();
184 
185     M_PALETTEDATA->m_hPalette = (HPALETTE)pal;
186 }
187 
188 #endif // wxUSE_PALETTE
189