00001
00002
00003
00004 #ifndef _GCOLOUR_H_
00005 #define _GCOLOUR_H_
00006
00007 #ifdef WIN32
00008 #pragma pack(push, before_pack)
00009 #pragma pack(1)
00010 #endif
00011
00013 class LgiClass GdcRGB
00014 {
00015 public:
00016 uchar R, G, B;
00017 #ifndef MAC
00018 uchar Flags;
00019 #endif
00020
00021 void Set(uchar r, uchar g, uchar b, uchar f = 0)
00022 {
00023 R = r;
00024 G = g;
00025 B = b;
00026 #ifndef MAC
00027 Flags = f;
00028 #endif
00029 }
00030 };
00031
00032 #ifdef WIN32
00033 #pragma pack(pop, before_pack)
00034 #endif
00035
00037 class LgiClass GPalette
00038 {
00039 protected:
00040 #if WIN32NATIVE
00041 HPALETTE hPal;
00042 LOGPALETTE *Data;
00043 #else
00044 int Size;
00045 GdcRGB *Data;
00046 #endif
00047 uchar *Lut;
00048
00049 public:
00050 GPalette();
00051 virtual ~GPalette();
00052
00053 #if WIN32NATIVE
00054 HPALETTE Handle() { return hPal; }
00055 #endif
00056
00057 GPalette(GPalette *pPal);
00058 GPalette(uchar *pPal, int s = 256);
00059 void Set(GPalette *pPal);
00060 void Set(uchar *pPal, int s = 256);
00061
00062 int GetSize();
00063 GdcRGB *operator [](int i);
00064 bool Update();
00065 bool SetSize(int s = 256);
00066 void SwapRAndB();
00067 int MatchRgb(COLOUR Rgb);
00068 void CreateCube();
00069 void CreateGreyScale();
00070 bool Load(GFile &F);
00071 bool Save(GFile &F, int Format);
00072 uchar *MakeLut(int Bits = 16);
00073
00074 bool operator ==(GPalette &p);
00075 bool operator !=(GPalette &p);
00076 };
00077
00079 class LgiClass GColour
00080 {
00081 public:
00082 enum Space
00083 {
00084 Col8,
00085 Col32,
00086 };
00087
00088 protected:
00089 class GPalette *pal;
00090 union {
00091 uint8 p8;
00092 uint32 p32;
00093 };
00094 Space space;
00095
00096 public:
00098 GColour()
00099 {
00100 c32(0);
00101 }
00102
00104 GColour(uint8 idx8, GPalette *palette)
00105 {
00106 c8(idx8, palette);
00107 }
00108
00110 GColour(int r, int g, int b, int a = 255)
00111 {
00112 c32(Rgba32(r, g, b, a));
00113 }
00114
00116 GColour(COLOUR c, int bits)
00117 {
00118 Set(c, bits);
00119 }
00120
00121 bool Transparent()
00122 {
00123 if (space == Col32)
00124 return A32(p32) == 0;
00125 else if (space == Col8)
00126 return !pal || p8 < pal->GetSize();
00127 return true;
00128 }
00129
00131 void Rgb(int r, int g, int b, int a = 255)
00132 {
00133 c32(Rgba32(r, g, b, a));
00134 }
00135
00137 void Set(COLOUR c, int bits)
00138 {
00139 pal = 0;
00140 switch (bits)
00141 {
00142 case 8:
00143 {
00144 p8 = c;
00145 space = Col8;
00146 break;
00147 }
00148 case 15:
00149 {
00150 space = Col32;
00151 p32 = Rgb15To32(c);
00152 break;
00153 }
00154 case 16:
00155 {
00156 space = Col32;
00157 p32 = Rgb16To32(c);
00158 break;
00159 }
00160 case 24:
00161 {
00162 space = Col32;
00163 p32 = Rgb24To32(c);
00164 break;
00165 }
00166 case 32:
00167 {
00168 space = Col32;
00169 p32 = c;
00170 break;
00171 }
00172 default:
00173 {
00174 space = Col32;
00175 p32 = 0;
00176 LgiAssert(!"Not a known colour depth.");
00177 }
00178 }
00179 }
00180
00181 COLOUR Get(int bits)
00182 {
00183 switch (bits)
00184 {
00185 case 8:
00186 if (space == Col8)
00187 return p8;
00188 LgiAssert(!"Not supported.");
00189 break;
00190 case 24:
00191 return c24();
00192 case 32:
00193 return c32();
00194 }
00195
00196 return 0;
00197 }
00198
00200 uint8 r()
00201 {
00202 return R32(c32());
00203 }
00204
00206 uint8 g()
00207 {
00208 return G32(c32());
00209 }
00210
00212 uint8 b()
00213 {
00214 return B32(c32());
00215 }
00216
00218 uint8 a()
00219 {
00220 return A32(c32());
00221 }
00222
00223
00224 uint8 c8()
00225 {
00226 return p8;
00227 }
00228
00229
00230 void c8(uint8 c, GPalette *p)
00231 {
00232 space = Col8;
00233 pal = p;
00234 p8 = c;
00235 }
00236
00237
00238 uint32 c24()
00239 {
00240 if (space == Col32)
00241 {
00242 return Rgb32To24(p32);
00243 }
00244 else if (space == Col8)
00245 {
00246 if (pal)
00247 {
00248
00249 if (p8 < pal->GetSize())
00250 {
00251 GdcRGB *c = (*pal)[p8];
00252 if (c)
00253 {
00254 return Rgb24(c->R, c->G, c->B);
00255 }
00256 }
00257
00258 return 0;
00259 }
00260
00261 return Rgb24(p8, p8, p8);
00262 }
00263
00264
00265 return 0;
00266 }
00267
00269 void c24(COLOUR c)
00270 {
00271 space = Col32;
00272 p32 = Rgb24To32(c);
00273 pal = 0;
00274 }
00275
00277 COLOUR c32()
00278 {
00279 if (space == Col32)
00280 {
00281 return p32;
00282 }
00283 else if (space == Col8)
00284 {
00285 if (pal)
00286 {
00287
00288 if (p8 < pal->GetSize())
00289 {
00290 GdcRGB *c = (*pal)[p8];
00291 if (c)
00292 {
00293 return Rgb32(c->R, c->G, c->B);
00294 }
00295 }
00296
00297 return 0;
00298 }
00299
00300 return Rgb32(p8, p8, p8);
00301 }
00302
00303
00304 return 0;
00305 }
00306
00308 void c32(COLOUR c)
00309 {
00310 space = Col32;
00311 pal = 0;
00312 p32 = c;
00313 }
00314
00316 GColour &Mix(GColour Tint, float RatioOfTint = 0.5)
00317 {
00318 COLOUR c1 = c32();
00319 COLOUR c2 = Tint.c32();
00320 float RatioThis = 1.0 - RatioOfTint;
00321 int r = (R32(c1) * RatioThis) + (R32(c2) * RatioOfTint);
00322 int g = (G32(c1) * RatioThis) + (G32(c2) * RatioOfTint);
00323 int b = (B32(c1) * RatioThis) + (B32(c2) * RatioOfTint);
00324 int a = (A32(c1) * RatioThis) + (A32(c2) * RatioOfTint);
00325 c32( Rgba32(r, g, b, a) );
00326 return *this;
00327 }
00328 };
00329
00330 #endif