#include <lib/gdi/gpixmap.h>
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);
}
{
if (lookup)
{
- delete lookup;
+ delete [] lookup;
lookup=0;
size=0;
}
}
}
-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(); y<area.bottom(); y++)
- memset(((__u8*)data)+y*stride+area.left(), color.color, area.width());
- else if (bpp == 32)
+ memset(((__u8*)surface->data)+y*surface->stride+area.left(), color.color, area.width());
+ else if (surface->bpp == 32)
for (int y=area.top(); y<area.bottom(); y++)
{
- __u32 *dst=(__u32*)(((__u8*)data)+y*stride+area.left()*bypp);
+ __u32 *dst=(__u32*)(((__u8*)surface->data)+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;
*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; y<area.height(); y++)
{
if (flag & blitAlphaTest)
*dst++=*src++;
}
} else
- memcpy(dstptr, srcptr, area.width()*bypp);
- srcptr+=src.stride;
- dstptr+=stride;
+ memcpy(dstptr, srcptr, area.width()*surface->bypp);
+ 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 && (i<src.clut.colors))
- pal[i]=(src.clut.data[i].a<<24)|(src.clut.data[i].r<<16)|(src.clut.data[i].g<<8)|(src.clut.data[i].b);
+ if (src.surface->clut.data && (i<src.surface->clut.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; y<area.height(); y++)
{
if (flag & blitAlphaTest)
while (width--)
*dst++=pal[*src++];
}
- srcptr+=src.stride;
- dstptr+=stride;
+ srcptr+=src.surface->stride;
+ 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; i<clut.colors; i++)
- lookup[i].color=target.clut.findColor(clut.data[i]);
+ for (int i=0; i<surface->clut.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; ay<y; ay++)
+ for (int ay=0; ay<surface->y; ay++)
{
- for (int ax=0; ax<x; ax++)
+ for (int ax=0; ax<surface->x; 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
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);
}
+