diff options
| author | ghost <andreas.monzner@multimedia-labs.de> | 2010-06-01 16:08:32 +0200 |
|---|---|---|
| committer | ghost <andreas.monzner@multimedia-labs.de> | 2010-06-01 16:08:32 +0200 |
| commit | c8724d0d7b016371309f189636b0992ea413bd96 (patch) | |
| tree | dc04f7a62a0c263b1e298441db700d4738ec75a4 /lib/gdi/gpixmap.cpp | |
| parent | db96b0766a1923d1fd4ba028c345c15b6a57dab5 (diff) | |
| download | enigma2-c8724d0d7b016371309f189636b0992ea413bd96.tar.gz enigma2-c8724d0d7b016371309f189636b0992ea413bd96.zip | |
add support for rbg565 color oled
Diffstat (limited to 'lib/gdi/gpixmap.cpp')
| -rw-r--r-- | lib/gdi/gpixmap.cpp | 193 |
1 files changed, 176 insertions, 17 deletions
diff --git a/lib/gdi/gpixmap.cpp b/lib/gdi/gpixmap.cpp index 3e643108..6f93d560 100644 --- a/lib/gdi/gpixmap.cpp +++ b/lib/gdi/gpixmap.cpp @@ -4,6 +4,8 @@ #include <lib/gdi/region.h> #include <lib/gdi/accel.h> +#define RBG565 + gLookup::gLookup() :size(0), lookup(0) { @@ -154,6 +156,26 @@ void gPixmap::fill(const gRegion ®ion, const gColor &color) { for (int y=area.top(); y<area.bottom(); y++) memset(((__u8*)surface->data)+y*surface->stride+area.left(), color.color, area.width()); + } else if (surface->bpp == 16) + { + __u32 icol; + + if (surface->clut.data && color < surface->clut.colors) + icol=(surface->clut.data[color].a<<24)|(surface->clut.data[color].r<<16)|(surface->clut.data[color].g<<8)|(surface->clut.data[color].b); + else + icol=0x10101*color; +#ifdef RBG565 + __u16 col = ((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF) >> 2) << 5 | (icol & 0xFF00) >> 11; +#else + __u16 col = ((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF) >> 3; +#endif + for (int y=area.top(); y<area.bottom(); y++) + { + __u16 *dst=(__u16*)(((__u8*)surface->data)+y*surface->stride+area.left()*surface->bypp); + int x=area.width(); + while (x--) + *dst++=col; + } } else if (surface->bpp == 32) { __u32 col; @@ -208,18 +230,33 @@ void gPixmap::fill(const gRegion ®ion, const gRGB &color) while (x--) *dst++=col; } + } else if (surface->bpp == 16) + { + __u32 icol = color.argb(); +#ifdef RBG565 + __u16 col = ((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF) >> 2) << 5 | (icol & 0xFF00) >> 11; +#else + __u16 col = ((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF) >> 3; +#endif + for (int y=area.top(); y<area.bottom(); y++) + { + __u16 *dst=(__u16*)(((__u8*)surface->data)+y*surface->stride+area.left()*surface->bypp); + int x=area.width(); + while (x--) + *dst++=col; + } } else eWarning("couldn't rgbfill %d bpp", surface->bpp); } } -static void blit_8i_to_32(__u32 *dst, __u8 *src, __u32 *pal, int width) +static inline void blit_8i_to_32(__u32 *dst, __u8 *src, __u32 *pal, int width) { while (width--) *dst++=pal[*src++]; } -static void blit_8i_to_32_at(__u32 *dst, __u8 *src, __u32 *pal, int width) +static inline void blit_8i_to_32_at(__u32 *dst, __u8 *src, __u32 *pal, int width) { while (width--) { @@ -232,6 +269,25 @@ static void blit_8i_to_32_at(__u32 *dst, __u8 *src, __u32 *pal, int width) } } +static inline void blit_8i_to_16(__u16 *dst, __u8 *src, __u32 *pal, int width) +{ + while (width--) + *dst++=pal[*src++] & 0xFFFF; +} + +static inline void blit_8i_to_16_at(__u16 *dst, __u8 *src, __u32 *pal, int width) +{ + while (width--) + { + if (!(pal[*src]&0x80000000)) + { + src++; + dst++; + } else + *dst++=pal[*src++] & 0xFFFF; + } +} + /* WARNING, this function is not endian safe! */ static void blit_8i_to_32_ab(__u32 *dst, __u8 *src, __u32 *pal, int width) { @@ -441,6 +497,95 @@ void gPixmap::blit(const gPixmap &src, const eRect &_pos, const gRegion &clip, i srcptr+=src.surface->stride; dstptr+=surface->stride; } + } else if ((surface->bpp == 16) && (src.surface->bpp==8)) + { + __u8 *srcptr=(__u8*)src.surface->data; + __u8 *dstptr=(__u8*)surface->data; // !! + __u32 pal[256]; + + for (int i=0; i<256; ++i) + { + __u32 icol; + if (src.surface->clut.data && (i<src.surface->clut.colors)) + icol=(src.surface->clut.data[i].a<<24)|(src.surface->clut.data[i].r<<16)|(src.surface->clut.data[i].g<<8)|(src.surface->clut.data[i].b); + else + icol=0x010101*i; +#ifdef RBG565 + pal[i]=icol&0xFF000000 | ((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF) >> 2) << 5 | (icol & 0xFF00) >> 11; +#else + pal[i]=icol&0xFF000000 | ((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF) >> 3; +#endif + pal[i]^=0xFF000000; + } + + srcptr+=srcarea.left()*src.surface->bypp+srcarea.top()*src.surface->stride; + dstptr+=area.left()*surface->bypp+area.top()*surface->stride; + + if (flag & blitAlphaBlend) + eWarning("ignore unsupported 8bpp -> 16bpp alphablend!"); + + for (int y=0; y<area.height(); y++) + { + int width=area.width(); + unsigned char *psrc=(unsigned char*)srcptr; + __u16 *dst=(__u16*)dstptr; + if (flag & blitAlphaTest) + blit_8i_to_16_at(dst, psrc, pal, width); + else + blit_8i_to_16(dst, psrc, pal, width); + srcptr+=src.surface->stride; + dstptr+=surface->stride; + } + } else if ((surface->bpp == 16) && (src.surface->bpp==32)) + { + __u8 *srcptr=(__u8*)src.surface->data; + __u8 *dstptr=(__u8*)surface->data; + + srcptr+=srcarea.left()+srcarea.top()*src.surface->stride; + dstptr+=area.left()+area.top()*surface->stride; + + if (flag & blitAlphaBlend) + eWarning("ignore unsupported 32bpp -> 16bpp alphablend!"); + + for (int y=0; y<area.height(); y++) + { + int width=area.width(); + __u32 *srcp=(__u32*)srcptr; + __u16 *dstp=(__u16*)dstptr; + + if (flag & blitAlphaTest) + { + while (width--) + { + if (!((*srcp)&0xFF000000)) + { + srcp++; + dstp++; + } else + { + __u32 icol = *srcp++; +#ifdef RBG565 + *dstp++=((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF) >> 2) << 5 | (icol & 0xFF00) >> 11; +#else + *dstp++=((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF) >> 3; +#endif + } + } + } else + { + while (width--) + { + __u32 icol = *srcp++; +#ifdef RBG565 + *dstp++=((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF) >> 2) << 5 | (icol & 0xFF00) >> 11; +#else + *dstp++=((icol & 0xFF0000) >> 19) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF) >> 3; +#endif + } + } + srcptr+=src.surface->stride; + dstptr+=surface->stride; + } } else eWarning("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp); } @@ -488,27 +633,36 @@ static inline int sgn(int a) void gPixmap::line(const gRegion &clip, ePoint start, ePoint dst, gColor color) { __u8 *srf8 = 0; - __u32 *srf32 = 0; + __u16 *srf16 = 0; + __u32 *srf32 = 0; int stride = surface->stride; - + if (clip.rects.empty()) return; - + + __u16 col16; __u32 col = 0; if (surface->bpp == 8) - { srf8 = (__u8*)surface->data; - } else if (surface->bpp == 32) + else { srf32 = (__u32*)surface->data; - if (surface->clut.data && color < surface->clut.colors) col=(surface->clut.data[color].a<<24)|(surface->clut.data[color].r<<16)|(surface->clut.data[color].g<<8)|(surface->clut.data[color].b); else col=0x10101*color; - col^=0xFF000000; + col^=0xFF000000; } - + + if (surface->bpp == 16) + { +#ifdef RBG565 + col16=((col & 0xFF0000) >> 19) << 11 | ((col & 0xFF) >> 2) << 5 | (col & 0xFF00) >> 11; +#else + col16=((col & 0xFF0000) >> 19) << 11 | ((col & 0xFF00) >> 10) << 5 | (col & 0xFF) >> 3; +#endif + } + int xa = start.x(), ya = start.y(), xb = dst.x(), yb = dst.y(); int dx, dy, x, y, s1, s2, e, temp, swap, i; dy=abs(yb-ya); @@ -526,7 +680,7 @@ void gPixmap::line(const gRegion &clip, ePoint start, ePoint dst, gColor color) } else swap=0; e = 2*dy-dx; - + int lasthit = 0; for(i=1; i<=dx; i++) { @@ -563,20 +717,25 @@ void gPixmap::line(const gRegion &clip, ePoint start, ePoint dst, gColor color) } while (!clip.rects[a].contains(x, y)); lasthit = a; } - + if (srf8) srf8[y * stride + x] = color; - if (srf32) + else if (srf16) + srf16[y * stride/2 + x] = col16; + else srf32[y * stride/4 + x] = col; fail: while (e>=0) { - if (swap==1) x+=s1; - else y+=s2; + if (swap==1) + x+=s1; + else + y+=s2; e-=2*dx; } - if (swap==1) - y+=s2; + + if (swap==1) + y+=s2; else x+=s1; e+=2*dy; |
