X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fgdi%2Fgpixmap.cpp;h=ee304cf2cfe791c94744ed4ab31c13146c427fde;hp=8fc263999b42df517a96fccd0157e8ee60d9e131;hb=4a5f4afeff93bb2c577c135835853ebaf2c7868b;hpb=5980156ba939d2d15adfad6abdad935b8276673c diff --git a/lib/gdi/gpixmap.cpp b/lib/gdi/gpixmap.cpp old mode 100644 new mode 100755 index 8fc2639..ee304cf --- a/lib/gdi/gpixmap.cpp +++ b/lib/gdi/gpixmap.cpp @@ -1,6 +1,13 @@ +#include +#include #include #include #include +#include + +#ifndef BYTE_ORDER +#error "no BYTE_ORDER defined!" +#endif gLookup::gLookup() :size(0), lookup(0) @@ -96,8 +103,12 @@ gSurface::gSurface(eSize size, int _bpp, int accel) stride += 63; stride &=~63; + int pal_size = 0; + if (bpp == 8) + pal_size = 256 * 4; + if (gAccel::getInstance()) - eDebug("accel memory: %d", gAccel::getInstance()->accelAlloc(data, data_phys, y * stride)); + eDebug("accel memory: %d", gAccel::getInstance()->accelAlloc(data, data_phys, y * stride + pal_size)); else eDebug("no accel available"); } @@ -106,7 +117,7 @@ gSurface::gSurface(eSize size, int _bpp, int accel) clut.data = 0; if (!data) - data = malloc(y * stride); + data = new unsigned char [y * stride]; type = 1; } @@ -118,9 +129,9 @@ gSurface::~gSurface() if (data_phys) gAccel::getInstance()->accelFree(data_phys); else - free(data); + delete [] (unsigned char*)data; - delete[] clut.data; + delete [] clut.data; } } @@ -141,13 +152,33 @@ void gPixmap::fill(const gRegion ®ion, const gColor &color) for (i=0; ibpp == 8) { for (int y=area.top(); ydata)+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; +#if BYTE_ORDER == LITTLE_ENDIAN + __u16 col = bswap_16(((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19); +#else + __u16 col = ((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19; +#endif + for (int y=area.top(); ydata)+y*surface->stride+area.left()*surface->bypp); + int x=area.width(); + while (x--) + *dst++=col; + } } else if (surface->bpp == 32) { __u32 col; @@ -157,8 +188,8 @@ void gPixmap::fill(const gRegion ®ion, const gColor &color) else col=0x10101*color; - col^=0xFF000000; - + col^=0xFF000000; + if (surface->data_phys && gAccel::getInstance()) if (!gAccel::getInstance()->fill(surface, area, col)) continue; @@ -175,34 +206,281 @@ void gPixmap::fill(const gRegion ®ion, const gColor &color) } } -void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag) +void gPixmap::fill(const gRegion ®ion, const gRGB &color) { + unsigned int i; + for (i=0; ibpp == 32) + { + __u32 col; + + col = color.argb(); + col^=0xFF000000; + + if (surface->data_phys && gAccel::getInstance()) + if (!gAccel::getInstance()->fill(surface, area, col)) + continue; + + for (int y=area.top(); ydata)+y*surface->stride+area.left()*surface->bypp); + int x=area.width(); + while (x--) + *dst++=col; + } + } else if (surface->bpp == 16) + { + __u32 icol = color.argb(); +#if BYTE_ORDER == LITTLE_ENDIAN + __u16 col = bswap_16(((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19); +#else + __u16 col = ((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19; +#endif + for (int y=area.top(); ydata)+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 inline void blit_8i_to_32(__u32 *dst, __u8 *src, __u32 *pal, int width) +{ + while (width--) + *dst++=pal[*src++]; +} + +static inline void blit_8i_to_32_at(__u32 *dst, __u8 *src, __u32 *pal, int width) +{ + while (width--) + { + if (!(pal[*src]&0x80000000)) + { + src++; + dst++; + } else + *dst++=pal[*src++]; + } +} + +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) +{ + while (width--) + { +#define BLEND(x, y, a) (y + (((x-y) * a)>>8)) + __u32 srccol = pal[*src++]; + __u32 dstcol = *dst; + unsigned char sb = srccol & 0xFF; + unsigned char sg = (srccol >> 8) & 0xFF; + unsigned char sr = (srccol >> 16) & 0xFF; + unsigned char sa = (srccol >> 24) & 0xFF; + + unsigned char db = dstcol & 0xFF; + unsigned char dg = (dstcol >> 8) & 0xFF; + unsigned char dr = (dstcol >> 16) & 0xFF; + unsigned char da = (dstcol >> 24) & 0xFF; + + da = BLEND(0xFF, da, sa) & 0xFF; + dr = BLEND(sr, dr, sa) & 0xFF; + dg = BLEND(sg, dg, sa) & 0xFF; + db = BLEND(sb, db, sa) & 0xFF; + +#undef BLEND + *dst++ = db | (dg << 8) | (dr << 16) | (da << 24); + } +} + +#define FIX 0x10000 + + +void gPixmap::blit(const gPixmap &src, const eRect &_pos, const gRegion &clip, int flag) +{ +// eDebug("blit: -> %d.%d %d:%d -> %d.%d %d:%d, flags=%d", +// _pos.x(), _pos.y(), _pos.width(), _pos.height(), +// clip.extends.x(), clip.extends.y(), clip.extends.width(), clip.extends.height(), +// flag); + eRect pos = _pos; + +// eDebug("source size: %d %d", src.size().width(), src.size().height()); + + if (!(flag & blitScale)) /* pos' size is valid only when scaling */ + pos = eRect(pos.topLeft(), src.size()); + else if (pos.size() == src.size()) /* no scaling required */ + flag &= ~blitScale; + + int scale_x = FIX, scale_y = FIX; + + if (flag & blitScale) + { + ASSERT(src.size().width()); + ASSERT(src.size().height()); + scale_x = pos.size().width() * FIX / src.size().width(); + scale_y = pos.size().height() * FIX / src.size().height(); + } + +// eDebug("SCALE %x %x", scale_x, scale_y); + for (unsigned int i=0; idata_phys && src.surface->data_phys) && (gAccel::getInstance())) - if (!gAccel::getInstance()->blit(surface, src.surface, area.topLeft(), srcarea, flag)) + if (!gAccel::getInstance()->blit(surface, src.surface, area, srcarea, flag)) continue; - flag &= ~ blitAlphaBlend; - + + if (flag & blitScale) + { + eWarning("unimplemented: scale on non-accel surfaces"); + continue; + } + +#ifdef SET_RIGHT_HALF_VFD_SKIN if ((surface->bpp == 8) && (src.surface->bpp==8)) { __u8 *srcptr=(__u8*)src.surface->data; __u8 *dstptr=(__u8*)surface->data; - + __u8 *nomptr = new __u8[area.width()]; + unsigned char gray_max = 0; + unsigned char gray_min = 255; + unsigned char index = 0; + unsigned char gray_value = 0; + gRGB pixdata; +// printf("[bilt]srcarea.left:%d, src.surface->bypp : %d,srcarea.top() :%d,src.surface->stride : %d\n",srcarea.left(),src.surface->bypp,srcarea.top(),src.surface->stride); srcptr+=srcarea.left()*src.surface->bypp+srcarea.top()*src.surface->stride; +// nomptr+=srcarea.left()*src.surface->bypp+srcarea.top()*src.surface->stride; dstptr+=area.left()*surface->bypp+area.top()*surface->stride; + if(src.surface->clut.colors != 0) + { + for (int y=0; ystride)); + pixdata = src.surface->clut.data[index]; + gray_value = ((pixdata.r+pixdata.g +pixdata.b)/3); + // printf("%3d ",gray_value); + if(gray_value > gray_max) + gray_max = gray_value; + if(gray_value < gray_min) + gray_min = gray_value; + } + // printf("\n"); + } + } +// printf("\n[bilt] ### gray_min : %d, gray_max : %d\n\n",gray_min,gray_max); for (int y=0; yclut.colors != 0) + { + for(int x=0;xclut.data[*(srcptr+x)]; + gray_value = ((pixdata.r+pixdata.g +pixdata.b)/3); + if(gray_max==gray_min) + *(nomptr+x)=gray_value; +/* else if(y == 0 || y == area.height()-1 || x == 0 || x == area.width()-1) + *(nomptr+x) = 255;*/ + else + *(nomptr+x)=( ((gray_value - gray_min)*255)/(gray_max-gray_min) ); + // printf("%3d ",*(nomptr+x)); + } + // printf("\n"); + } + else + { + for(int x=0;xbypp); + memcpy(dstptr, nomptr, area.width()*surface->bypp); + srcptr+=src.surface->stride; + dstptr+=surface->stride; + } + delete [] nomptr; +#else + if ((surface->bpp == 8) && (src.surface->bpp==8)) + { + __u8 *srcptr=(__u8*)src.surface->data; + __u8 *dstptr=(__u8*)surface->data; + + srcptr+=srcarea.left()*src.surface->bypp+srcarea.top()*src.surface->stride; + dstptr+=area.left()*surface->bypp+area.top()*surface->stride; + for (int y=0; ystride; dstptr+=surface->stride; } +#endif } else if ((surface->bpp == 32) && (src.surface->bpp==32)) { __u32 *srcptr=(__u32*)src.surface->data; __u32 *dstptr=(__u32*)surface->data; - + srcptr+=srcarea.left()+srcarea.top()*src.surface->stride/4; dstptr+=area.left()+area.top()*surface->stride/4; for (int y=0; ybypp+srcarea.top()*src.surface->stride; + dstptr+=area.left()*surface->bypp+area.top()*surface->stride; + for (int y=0; ystride; + 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 && (iclut.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; +#if BYTE_ORDER == LITTLE_ENDIAN + pal[i] = bswap_16(((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19); +#else + pal[i] = ((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19; +#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; ystride; + 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> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19); +#else + *dstp++ = ((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19; +#endif + } } } else { - int width=area.width(); - unsigned char *src=(unsigned char*)srcptr; - __u32 *dst=(__u32*)dstptr; while (width--) - *dst++=pal[*src++]; + { + __u32 icol = *srcp++; +#if BYTE_ORDER == LITTLE_ENDIAN + *dstp++ = bswap_16(((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19); +#else + *dstp++ = ((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19; +#endif + } } srcptr+=src.surface->stride; dstptr+=surface->stride; } } else - eFatal("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp); + eWarning("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp); } } +#undef FIX + void gPixmap::mergePalette(const gPixmap &target) { if ((!surface->clut.colors) || (!target.surface->clut.colors)) @@ -372,27 +728,34 @@ 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; - - __u32 col; + + __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) +#if BYTE_ORDER == LITTLE_ENDIAN + col16=bswap_16(((col & 0xFF) >> 3) << 11 | ((col & 0xFF00) >> 10) << 5 | (col & 0xFF0000) >> 19); +#else + col16=((col & 0xFF) >> 3) << 11 | ((col & 0xFF00) >> 10) << 5 | (col & 0xFF0000) >> 19; +#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); @@ -410,7 +773,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++) { @@ -437,7 +800,7 @@ void gPixmap::line(const gRegion &clip, ePoint start, ePoint dst, gColor color) do { ++a; - if (a == clip.rects.size()) + if ((unsigned int)a == clip.rects.size()) a = 0; if (a == lasthit) { @@ -447,20 +810,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; @@ -505,13 +873,17 @@ DEFINE_REF(gPixmap); gPixmap::~gPixmap() { + if (must_delete_surface) + delete surface; } -gPixmap::gPixmap(gSurface *surface): surface(surface) +gPixmap::gPixmap(gSurface *surface) + :surface(surface), must_delete_surface(false) { } gPixmap::gPixmap(eSize size, int bpp, int accel) + :must_delete_surface(true) { surface = new gSurface(size, bpp, accel); }