X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/0667332d1c91d29459f5fbdab667f54e47912da9..d6f6602d7cea3a7899990fe79216af7d98d05917:/lib/gdi/gpixmap.cpp diff --git a/lib/gdi/gpixmap.cpp b/lib/gdi/gpixmap.cpp index e8ddcf73..b6711fcb 100644 --- a/lib/gdi/gpixmap.cpp +++ b/lib/gdi/gpixmap.cpp @@ -1,15 +1,13 @@ #include gLookup::gLookup() + :size(0), lookup(0) { - size=0; - lookup=0; } gLookup::gLookup(int size, const gPalette &pal, const gRGB &start, const gRGB &end) + :size(0), lookup(0) { - size=0; - lookup=0; build(size, pal, start, end); } @@ -17,7 +15,7 @@ void gLookup::build(int _size, const gPalette &pal, const gRGB &start, const gRG { if (lookup) { - delete lookup; + delete [] lookup; lookup=0; size=0; } @@ -49,24 +47,77 @@ void gLookup::build(int _size, const gPalette &pal, const gRGB &start, const gRG } } -DEFINE_REF(gPixmap); +gSurface::~gSurface() +{ +} + +gSurfaceSystem::gSurfaceSystem(eSize size, int _bpp) +{ + x=size.width(); + y=size.height(); + bpp=_bpp; + switch (bpp) + { + case 8: + bypp=1; + break; + case 15: + case 16: + bypp=2; + break; + case 24: // never use 24bit mode + case 32: + bypp=4; + break; + default: + bypp=(bpp+7)/8; + } + stride=x*bypp; + if (bpp==8) + { + clut.colors=256; + clut.data=new gRGB[clut.colors]; + } else + { + clut.colors=0; + clut.data=0; + } + data=malloc(x*y*bypp); +} + +gSurfaceSystem::~gSurfaceSystem() +{ + free(data); + delete[] clut.data; +} + +gPixmap *gPixmap::lock() +{ + contentlock.lock(1); + return this; +} + +void gPixmap::unlock() +{ + contentlock.unlock(1); +} void gPixmap::fill(const eRect &area, const gColor &color) { if ((area.height()<=0) || (area.width()<=0)) return; - if (bpp == 8) + if (surface->bpp == 8) for (int y=area.top(); ydata)+y*surface->stride+area.left(), color.color, area.width()); + else if (surface->bpp == 32) for (int y=area.top(); ydata)+y*surface->stride+area.left()*surface->bypp); int x=area.width(); __u32 col; - if (clut.data && color < clut.colors) - col=(clut.data[color].a<<24)|(clut.data[color].r<<16)|(clut.data[color].g<<8)|(clut.data[color].b); + 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; @@ -74,29 +125,27 @@ void gPixmap::fill(const eRect &area, const gColor &color) *dst++=col; } else - eWarning("couldn't fill %d bpp", bpp); + eWarning("couldn't fill %d bpp", surface->bpp); } void gPixmap::blit(const gPixmap &src, ePoint pos, const eRect &clip, int flag) { - eRect area=eRect(pos, src.getSize()); - if (!clip.isNull()) - area&=clip; + area&=clip; area&=eRect(ePoint(0, 0), getSize()); if ((area.width()<0) || (area.height()<0)) return; - + eRect srcarea=area; srcarea.moveBy(-pos.x(), -pos.y()); - if ((bpp == 8) && (src.bpp==8)) + if ((surface->bpp == 8) && (src.surface->bpp==8)) { - __u8 *srcptr=(__u8*)src.data; - __u8 *dstptr=(__u8*)data; + __u8 *srcptr=(__u8*)src.surface->data; + __u8 *dstptr=(__u8*)surface->data; - srcptr+=srcarea.left()*bypp+srcarea.top()*src.stride; - dstptr+=area.left()*bypp+area.top()*stride; + srcptr+=srcarea.left()*surface->bypp+srcarea.top()*src.surface->stride; + dstptr+=area.left()*surface->bypp+area.top()*surface->stride; for (int y=0; ybypp); + srcptr+=src.surface->stride; + dstptr+=surface->stride; } - } else if ((bpp == 32) && (src.bpp==8)) + } else if ((surface->bpp == 32) && (src.surface->bpp==8)) { - __u8 *srcptr=(__u8*)src.data; - __u8 *dstptr=(__u8*)data; // !! + __u8 *srcptr=(__u8*)src.surface->data; + __u8 *dstptr=(__u8*)surface->data; // !! __u32 pal[256]; for (int i=0; i<256; ++i) { - if (src.clut.data && (iclut.data && (iclut.colors)) + pal[i]=(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 pal[i]=0x010101*i; pal[i]^=0xFF000000; } - srcptr+=srcarea.left()*bypp+srcarea.top()*src.stride; - dstptr+=area.left()*bypp+area.top()*stride; + srcptr+=srcarea.left()*surface->bypp+srcarea.top()*src.surface->stride; + dstptr+=area.left()*surface->bypp+area.top()*surface->stride; for (int y=0; ystride; + dstptr+=surface->stride; } } else - eFatal("cannot blit %dbpp from %dbpp", bpp, src.bpp); + eFatal("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp); } void gPixmap::mergePalette(const gPixmap &target) { - if ((!clut.colors) || (!target.clut.colors)) + if ((!surface->clut.colors) || (!target.surface->clut.colors)) return; - gColor *lookup=new gColor[clut.colors]; + gColor *lookup=new gColor[surface->clut.colors]; - for (int i=0; iclut.colors; i++) + lookup[i].color=target.surface->clut.findColor(surface->clut.data[i]); - delete clut.data; - clut.colors=target.clut.colors; - clut.data=new gRGB[clut.colors]; - memcpy(clut.data, target.clut.data, sizeof(gRGB)*clut.colors); + delete [] surface->clut.data; + surface->clut.colors=target.surface->clut.colors; + surface->clut.data=new gRGB[surface->clut.colors]; + memcpy(surface->clut.data, target.surface->clut.data, sizeof(gRGB)*surface->clut.colors); - __u8 *dstptr=(__u8*)data; + __u8 *dstptr=(__u8*)surface->data; - for (int ay=0; ayy; ay++) { - for (int ax=0; axx; ax++) dstptr[ax]=lookup[dstptr[ax]]; - dstptr+=stride; + dstptr+=surface->stride; } - delete lookup; + delete [] lookup; } void gPixmap::line(ePoint start, ePoint dst, gColor color) { -int Ax=start.x(), // dieser code rult ganz ganz doll weil er ganz ganz fast ist und auch sehr gut dokumentiert is -Ay=start.y(), Bx=dst.x(), // t. es handelt sich immerhin um den weltbekannten bresenham algorithmus der nicht nur -By=dst.y(); int dX, dY, fbXincr, // sehr schnell ist sondern auch sehr gut dokumentiert und getestet wurde. nicht -fbYincr, fbXYincr, dPr, dPru, P; __u8 // nur auf dem LCD der dbox, sondern auch ueberall anders. und auch auf der -*AfbAddr = &((__u8*)data)[Ay*stride+Ax*bypp]; __u8 // dbox mit LCD soll das teil nun tun, und ich denke das tut es. ausse -*BfbAddr = &((__u8*)data)[By*stride+Bx*bypp]; fbXincr= // rdem hat dieser algo den vorteil dass man fehler sehr leicht fi -bypp; if ( (dX=Bx-Ax) >= 0) goto AFTERNEGX; dX=-dX; // ndet und beheben kann. das liegt nicht zuletzt an den komment -fbXincr=-1; AFTERNEGX: fbYincr=stride; if ( (dY=By // aren. und ausserdem, je kuerzer der code, desto weniger k --Ay) >= 0) goto AFTERNEGY; fbYincr=-stride; dY=-dY;AFTERNEGY: // ann daran falsch sein. erwaehnte ich schon, da -fbXYincr = fbXincr+fbYincr; if (dY > dX) goto YisIndependent; dPr = dY+ // s dieser tolle code wahnsinnig schnell -dY; P = -dX; dPru = P+P; dY = dX>>1; XLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0) // ist? bye, tmbinc +int Ax=start.x(), +Ay=start.y(), Bx=dst.x(), +By=dst.y(); int dX, dY, fbXincr, +fbYincr, fbXYincr, dPr, dPru, P; __u8 +*AfbAddr = &((__u8*)surface->data)[Ay*surface->stride+Ax*surface->bypp]; __u8 +*BfbAddr = &((__u8*)surface->data)[By*surface->stride+Bx*surface->bypp]; fbXincr= +surface->bypp; if ( (dX=Bx-Ax) >= 0) goto AFTERNEGX; dX=-dX; +fbXincr=-1; AFTERNEGX: fbYincr=surface->stride; if ( (dY=By +-Ay) >= 0) goto AFTERNEGY; fbYincr=-surface->stride; dY=-dY;AFTERNEGY: +fbXYincr = fbXincr+fbYincr; if (dY > dX) goto YisIndependent; dPr = dY+ +dY; P = -dX; dPru = P+P; dY = dX>>1; XLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0) goto RightAndUp; AfbAddr+=fbXincr; BfbAddr-=fbXincr; if ((dY=dY-1) > 0) goto XLOOP; *AfbAddr=color; if ((dX & 1) == 0) return; *BfbAddr=color; return; RightAndUp: AfbAddr+=fbXYincr; BfbAddr-=fbXYincr; P+=dPru; if ((dY=dY-1) > 0) goto XLOOP; *AfbAddr=color; if ((dX & 1) == 0) return; *BfbAddr=color; return; YisIndependent: dPr = dX+dX; P = -dY; dPru = P+P; dX = dY>>1; YLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0) goto RightAndUp2; AfbAddr +=fbYincr; BfbAddr-=fbYincr; if ((dX=dX-1) > 0) goto YLOOP; *AfbAddr=color; if ((dY & 1) == 0) return; *BfbAddr= color;return; RightAndUp2: AfbAddr+=fbXYincr; BfbAddr-=fbXYincr; P+=dPru; if ((dX=dX-1) > 0) goto YLOOP; *AfbAddr -=color; if((dY & 1) == 0) return; *BfbAddr=color; return; // nun ist der tolle code leider zu ende. tut mir leid. +=color; if((dY & 1) == 0) return; *BfbAddr=color; return; } gColor gPalette::findColor(const gRGB &rgb) const @@ -246,50 +295,18 @@ gColor gPalette::findColor(const gRGB &rgb) const return best_choice; } -gPixmap::gPixmap(): ref(0) -{ -} +DEFINE_REF(gPixmap); gPixmap::~gPixmap() { } -gImage::gImage(eSize size, int _bpp) +gPixmap::gPixmap(gSurface *surface): surface(surface) { - x=size.width(); - y=size.height(); - bpp=_bpp; - switch (bpp) - { - case 8: - bypp=1; - break; - case 15: - case 16: - bypp=2; - break; - case 24: // never use 24bit mode - case 32: - bypp=4; - break; - default: - bypp=(bpp+7)/8; - } - stride=x*bypp; - if (bpp==8) - { - clut.colors=256; - clut.data=new gRGB[clut.colors]; - } else - { - clut.colors=0; - clut.data=0; - } - data=new char[x*y*bypp]; } -gImage::~gImage() +gPixmap::gPixmap(eSize size, int bpp) { - delete[] clut.data; - delete[] (char*)data; + surface = new gSurfaceSystem(size, bpp); } +