mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
368 lines
7.2 KiB
C++
368 lines
7.2 KiB
C++
#include "Draw.h"
|
|
|
|
NAMESPACE_UPP
|
|
|
|
static int sMaskPos16(dword mask)
|
|
{
|
|
if(mask > 0xffff)
|
|
return 0;
|
|
int pos = 0;
|
|
while(((mask << pos) & 0x18000) != 0x8000)
|
|
pos++;
|
|
return pos;
|
|
}
|
|
|
|
void RasterFormat::Set16le(dword _rmask, dword _gmask, dword _bmask)
|
|
{
|
|
rpos = sMaskPos16(rmask = _rmask);
|
|
gpos = sMaskPos16(gmask = _gmask);
|
|
bpos = sMaskPos16(bmask = _bmask);
|
|
type = RASTER_16;
|
|
}
|
|
|
|
void RasterFormat::Set16be(dword _rmask, dword _gmask, dword _bmask)
|
|
{
|
|
Set16le(_rmask, _gmask, _bmask);
|
|
type = RASTER_16|RASTER_MSBFIRST;
|
|
}
|
|
|
|
void RasterFormat::Set24le(dword rmask, dword gmask, dword bmask)
|
|
{
|
|
rpos = GetChMaskPos32(rmask);
|
|
gpos = GetChMaskPos32(gmask);
|
|
bpos = GetChMaskPos32(bmask);
|
|
apos = 0;
|
|
type = RASTER_24;
|
|
}
|
|
|
|
void RasterFormat::Set32le(dword rmask, dword gmask, dword bmask, dword amask)
|
|
{
|
|
Set24le(rmask, gmask, bmask);
|
|
if(amask) {
|
|
apos = GetChMaskPos32(amask);
|
|
type = RASTER_32ALPHA;
|
|
}
|
|
else
|
|
type = RASTER_32;
|
|
}
|
|
|
|
void RasterFormat::Set24be(dword rmask, dword gmask, dword bmask)
|
|
{
|
|
rpos = 2 - GetChMaskPos32(rmask);
|
|
gpos = 2 - GetChMaskPos32(gmask);
|
|
bpos = 2 - GetChMaskPos32(bmask);
|
|
apos = 0;
|
|
type = RASTER_24;
|
|
}
|
|
|
|
void RasterFormat::Set32be(dword rmask, dword gmask, dword bmask, dword amask)
|
|
{
|
|
rpos = 3 - GetChMaskPos32(rmask);
|
|
gpos = 3 - GetChMaskPos32(gmask);
|
|
bpos = 3 - GetChMaskPos32(bmask);
|
|
if(amask) {
|
|
apos = 3 - GetChMaskPos32(amask);
|
|
type = RASTER_32PREMULTIPLIED;
|
|
}
|
|
else
|
|
type = RASTER_32;
|
|
}
|
|
|
|
void RasterFormat::Set32leStraight(dword rmask, dword gmask, dword bmask, dword amask)
|
|
{
|
|
Set32le(rmask, gmask, bmask, amask);
|
|
type = RASTER_32ALPHA;
|
|
}
|
|
|
|
void RasterFormat::Set32beStraight(dword rmask, dword gmask, dword bmask, dword amask)
|
|
{
|
|
Set32be(rmask, gmask, bmask, amask);
|
|
type = RASTER_32ALPHA;
|
|
}
|
|
|
|
void RasterFormat::SetRGBA()
|
|
{
|
|
type = RASTER_32PREMULTIPLIED;
|
|
bpos = 0;
|
|
gpos = 1;
|
|
rpos = 2;
|
|
apos = 3;
|
|
}
|
|
|
|
void RasterFormat::SetRGBAStraight()
|
|
{
|
|
type = RASTER_32ALPHA;
|
|
bpos = 0;
|
|
gpos = 1;
|
|
rpos = 2;
|
|
apos = 3;
|
|
}
|
|
|
|
int RasterFormat::IsRGBA() const
|
|
{
|
|
return (type & 31) == RASTER_32PREMULTIPLIED && bpos == 0 && gpos == 1 && rpos == 2 && apos == 3;
|
|
}
|
|
|
|
static byte bits[16] = { 1, 2, 4, 8, 16, 16, 24, 32, 32, 32 };
|
|
|
|
int RasterFormat::GetByteCount(int cx) const
|
|
{
|
|
int b = bits[type & 15];
|
|
return (cx * b + 7) >> 3;
|
|
}
|
|
|
|
int RasterFormat::GetBpp() const
|
|
{
|
|
return bits[type & 15];
|
|
}
|
|
|
|
bool RasterFormat::HasAlpha() const
|
|
{
|
|
return (type & 15) == RASTER_32ALPHA;
|
|
}
|
|
|
|
int RasterFormat::GetColorCount() const
|
|
{
|
|
static int colors[16] = { 2, 4, 16, 256, 256, 65536, 256 * 256 * 256, 256 * 256 * 256, 256 * 256 * 256 };
|
|
return colors[type & 15];
|
|
}
|
|
|
|
int RasterFormat::GetPaletteCount() const
|
|
{
|
|
static int colors[16] = { 2, 4, 16, 256 };
|
|
return (type & 15) < 4 ? colors[type & 15] : 0;
|
|
}
|
|
|
|
void RasterFormat::TailBits(RGBA *t, const byte *src, int cx, byte andm, byte shift, const RGBA *palette)
|
|
{
|
|
if(cx) {
|
|
byte c = *src;
|
|
while(cx > 0) {
|
|
*t++ = palette[c & andm]; c >>= shift;
|
|
cx--;
|
|
}
|
|
}
|
|
}
|
|
|
|
void RasterFormat::TailBitsMSB1st(RGBA *t, const byte *src, int cx, byte shift1, byte andm, byte shift, const RGBA *palette)
|
|
{
|
|
if(cx) {
|
|
byte c = *src;
|
|
while(cx > 0) {
|
|
*t++ = palette[(c >> shift1) & andm]; c <<= shift;
|
|
cx--;
|
|
}
|
|
}
|
|
}
|
|
|
|
void RasterFormat::Read(RGBA *t, const byte *s, int cx, const RGBA *palette) const
|
|
{
|
|
switch(type) {
|
|
case RASTER_1:
|
|
{
|
|
const byte *e = s + (cx >> 3);
|
|
while(s < e) {
|
|
byte c = *s++;
|
|
t[0] = palette[(c >> 0) & 1];
|
|
t[1] = palette[(c >> 1) & 1];
|
|
t[2] = palette[(c >> 2) & 1];
|
|
t[3] = palette[(c >> 3) & 1];
|
|
t[4] = palette[(c >> 4) & 1];
|
|
t[5] = palette[(c >> 5) & 1];
|
|
t[6] = palette[(c >> 6) & 1];
|
|
t[7] = palette[(c >> 7) & 1];
|
|
t += 8;
|
|
}
|
|
TailBits(t, s, cx & 7, 1, 1, palette);
|
|
}
|
|
break;
|
|
case RASTER_1|RASTER_MSBFIRST:
|
|
{
|
|
const byte *e = s + (cx >> 3);
|
|
while(s < e) {
|
|
byte c = *s++;
|
|
t[7] = palette[(c >> 0) & 1];
|
|
t[6] = palette[(c >> 1) & 1];
|
|
t[5] = palette[(c >> 2) & 1];
|
|
t[4] = palette[(c >> 3) & 1];
|
|
t[3] = palette[(c >> 4) & 1];
|
|
t[2] = palette[(c >> 5) & 1];
|
|
t[1] = palette[(c >> 6) & 1];
|
|
t[0] = palette[(c >> 7) & 1];
|
|
t += 8;
|
|
}
|
|
TailBitsMSB1st(t, s, cx & 7, 7, 1, 1, palette);
|
|
}
|
|
break;
|
|
case RASTER_2:
|
|
{
|
|
const byte *e = s + (cx >> 2);
|
|
while(s < e) {
|
|
byte c = *s++;
|
|
t[0] = palette[(c >> 0) & 3];
|
|
t[1] = palette[(c >> 2) & 3];
|
|
t[2] = palette[(c >> 4) & 3];
|
|
t[3] = palette[(c >> 6) & 3];
|
|
t += 4;
|
|
}
|
|
TailBits(t, s, cx & 3, 3, 2, palette);
|
|
}
|
|
break;
|
|
case RASTER_2|RASTER_MSBFIRST:
|
|
{
|
|
const byte *e = s + (cx >> 2);
|
|
while(s < e) {
|
|
byte c = *s++;
|
|
t[3] = palette[(c >> 0) & 3];
|
|
t[2] = palette[(c >> 2) & 3];
|
|
t[1] = palette[(c >> 4) & 3];
|
|
t[0] = palette[(c >> 6) & 3];
|
|
t += 4;
|
|
}
|
|
TailBitsMSB1st(t, s, cx & 3, 6, 3, 2, palette);
|
|
}
|
|
break;
|
|
case RASTER_4:
|
|
{
|
|
const byte *e = s + (cx >> 1);
|
|
while(s < e) {
|
|
byte c = *s++;
|
|
t[0] = palette[(c >> 0) & 15];
|
|
t[1] = palette[(c >> 4) & 15];
|
|
t += 2;
|
|
}
|
|
TailBits(t, s, cx & 1, 15, 4, palette);
|
|
}
|
|
break;
|
|
case RASTER_4|RASTER_MSBFIRST:
|
|
{
|
|
const byte *e = s + (cx >> 1);
|
|
while(s < e) {
|
|
byte c = *s++;
|
|
t[1] = palette[(c >> 0) & 15];
|
|
t[0] = palette[(c >> 4) & 15];
|
|
t += 2;
|
|
}
|
|
TailBitsMSB1st(t, s, cx & 1, 4, 15, 4, palette);
|
|
}
|
|
break;
|
|
case RASTER_8:
|
|
case RASTER_8|RASTER_MSBFIRST:
|
|
{
|
|
RGBA *e = t + cx;
|
|
while(t < e)
|
|
*t++ = palette[*s++];
|
|
}
|
|
break;
|
|
case RASTER_8ALPHA:
|
|
case RASTER_8ALPHA|RASTER_MSBFIRST:
|
|
{
|
|
RGBA *e = t + cx;
|
|
while(t < e) {
|
|
RGBA pal = palette[*s];
|
|
pal.a = s[1];
|
|
*t++ = pal;
|
|
s += 2;
|
|
}
|
|
break;
|
|
}
|
|
case RASTER_16:
|
|
{
|
|
RGBA *e = t + cx;
|
|
while(t < e) {
|
|
word w = Peek16le(s);
|
|
t->a = 255;
|
|
t->r = byte((w & rmask) << rpos >> 8);
|
|
t->g = byte((w & gmask) << gpos >> 8);
|
|
t->b = byte((w & bmask) << bpos >> 8);
|
|
s += 2;
|
|
t++;
|
|
}
|
|
}
|
|
break;
|
|
case RASTER_16|RASTER_MSBFIRST:
|
|
{
|
|
RGBA *e = t + cx;
|
|
while(t < e) {
|
|
word w = Peek16be(s);
|
|
t->a = 255;
|
|
t->r = byte((w & rmask) << rpos >> 8);
|
|
t->g = byte((w & gmask) << gpos >> 8);
|
|
t->b = byte((w & bmask) << bpos >> 8);
|
|
s += 2;
|
|
t++;
|
|
}
|
|
}
|
|
break;
|
|
case RASTER_24:
|
|
case RASTER_24|RASTER_MSBFIRST:
|
|
{
|
|
RGBA *e = t + cx;
|
|
while(t < e) {
|
|
t->a = 255;
|
|
t->r = s[rpos];
|
|
t->g = s[gpos];
|
|
t->b = s[bpos];
|
|
s += 3;
|
|
t++;
|
|
}
|
|
}
|
|
break;
|
|
case RASTER_32:
|
|
case RASTER_32|RASTER_MSBFIRST:
|
|
if(bpos == 0 && gpos == 1 && rpos == 2) {
|
|
RGBA *e = t + cx;
|
|
while(t < e) {
|
|
*t = *(RGBA *)s;
|
|
t->a = 255;
|
|
s += 4;
|
|
t++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RGBA *e = t + cx;
|
|
while(t < e) {
|
|
t->a = 255;
|
|
t->r = s[rpos];
|
|
t->g = s[gpos];
|
|
t->b = s[bpos];
|
|
s += 4;
|
|
t++;
|
|
}
|
|
}
|
|
break;
|
|
case RASTER_32ALPHA:
|
|
case RASTER_32ALPHA|RASTER_MSBFIRST: {
|
|
RGBA *e = t + cx;
|
|
while(t < e) {
|
|
t->a = s[apos];
|
|
int alpha = t->a + (t->a >> 7);
|
|
t->r = (alpha * s[rpos]) >> 8;
|
|
t->g = (alpha * s[gpos]) >> 8;
|
|
t->b = (alpha * s[bpos]) >> 8;
|
|
s += 4;
|
|
t++;
|
|
}
|
|
}
|
|
break;
|
|
case RASTER_32PREMULTIPLIED:
|
|
case RASTER_32PREMULTIPLIED|RASTER_MSBFIRST:
|
|
if(bpos == 0 && gpos == 1 && rpos == 2 && apos == 3)
|
|
memcpy(t, s, cx * sizeof(RGBA));
|
|
else {
|
|
RGBA *e = t + cx;
|
|
while(t < e) {
|
|
t->a = s[apos];
|
|
t->r = s[rpos];
|
|
t->g = s[gpos];
|
|
t->b = s[bpos];
|
|
s += 4;
|
|
t++;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
END_UPP_NAMESPACE
|