X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/1c242c0a654a5c4048ba4219a0982f8ba8a85246..3a044bea307a02147e2d01ad29f07b7348bd7203:/lib/gdi/gpixmap.cpp?ds=sidebyside diff --git a/lib/gdi/gpixmap.cpp b/lib/gdi/gpixmap.cpp index 855cb8b2..3e643108 100644 --- a/lib/gdi/gpixmap.cpp +++ b/lib/gdi/gpixmap.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -96,8 +98,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"); } @@ -141,7 +147,7 @@ void gPixmap::fill(const gRegion ®ion, const gColor &color) for (i=0; ibpp == 8) @@ -157,8 +163,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; @@ -181,7 +187,7 @@ void gPixmap::fill(const gRegion ®ion, const gRGB &color) for (i=0; ibpp == 32) @@ -207,24 +213,114 @@ void gPixmap::fill(const gRegion ®ion, const gRGB &color) } } -void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag) +static 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) +{ + while (width--) + { + if (!(pal[*src]&0x80000000)) + { + src++; + dst++; + } else + *dst++=pal[*src++]; + } +} + + /* 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; + if (flag & blitScale) + { + eWarning("unimplemented: scale on non-accel surfaces"); + continue; + } + if ((surface->bpp == 8) && (src.surface->bpp==8)) { __u8 *srcptr=(__u8*)src.surface->data; @@ -234,7 +330,7 @@ void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag dstptr+=area.left()*surface->bypp+area.top()*surface->stride; for (int y=0; ybypp+area.top()*surface->stride; for (int y=0; ystride; dstptr+=surface->stride; } @@ -364,6 +446,8 @@ void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag } } +#undef FIX + void gPixmap::mergePalette(const gPixmap &target) { if ((!surface->clut.colors) || (!target.surface->clut.colors))