1 #include <lib/gdi/gpixmap.h>
8 gLookup::gLookup(int size, const gPalette &pal, const gRGB &start, const gRGB &end)
11 build(size, pal, start, end);
14 void gLookup::build(int _size, const gPalette &pal, const gRGB &start, const gRGB &end)
25 lookup=new gColor[size];
27 for (int i=0; i<size; i++)
32 int rdiff=-start.r+end.r;
33 int gdiff=-start.g+end.g;
34 int bdiff=-start.b+end.b;
35 int adiff=-start.a+end.a;
36 rdiff*=i; rdiff/=(size-1);
37 gdiff*=i; gdiff/=(size-1);
38 bdiff*=i; bdiff/=(size-1);
39 adiff*=i; adiff/=(size-1);
46 lookup[i]=pal.findColor(col);
54 gSurfaceSystem::gSurfaceSystem(eSize size, int _bpp)
68 case 24: // never use 24bit mode
79 clut.data=new gRGB[clut.colors];
85 data=malloc(x*y*bypp);
88 gSurfaceSystem::~gSurfaceSystem()
94 gPixmap *gPixmap::lock()
100 void gPixmap::unlock()
102 contentlock.unlock(1);
105 void gPixmap::fill(const eRect &area, const gColor &color)
107 if ((area.height()<=0) || (area.width()<=0))
109 if (surface->bpp == 8)
110 for (int y=area.top(); y<area.bottom(); y++)
111 memset(((__u8*)surface->data)+y*surface->stride+area.left(), color.color, area.width());
112 else if (surface->bpp == 32)
113 for (int y=area.top(); y<area.bottom(); y++)
115 __u32 *dst=(__u32*)(((__u8*)surface->data)+y*surface->stride+area.left()*surface->bypp);
119 if (surface->clut.data && color < surface->clut.colors)
120 col=(surface->clut.data[color].a<<24)|(surface->clut.data[color].r<<16)|(surface->clut.data[color].g<<8)|(surface->clut.data[color].b);
128 eWarning("couldn't fill %d bpp", surface->bpp);
131 void gPixmap::blit(const gPixmap &src, ePoint pos, const eRect &clip, int flag)
133 eRect area=eRect(pos, src.getSize());
135 area&=eRect(ePoint(0, 0), getSize());
136 if ((area.width()<0) || (area.height()<0))
140 srcarea.moveBy(-pos.x(), -pos.y());
142 if ((surface->bpp == 8) && (src.surface->bpp==8))
144 __u8 *srcptr=(__u8*)src.surface->data;
145 __u8 *dstptr=(__u8*)surface->data;
147 srcptr+=srcarea.left()*surface->bypp+srcarea.top()*src.surface->stride;
148 dstptr+=area.left()*surface->bypp+area.top()*surface->stride;
149 for (int y=0; y<area.height(); y++)
151 if (flag & blitAlphaTest)
153 // no real alphatest yet
154 int width=area.width();
155 unsigned char *src=(unsigned char*)srcptr;
156 unsigned char *dst=(unsigned char*)dstptr;
157 // use duff's device here!
168 memcpy(dstptr, srcptr, area.width()*surface->bypp);
169 srcptr+=src.surface->stride;
170 dstptr+=surface->stride;
172 } else if ((surface->bpp == 32) && (src.surface->bpp==8))
174 __u8 *srcptr=(__u8*)src.surface->data;
175 __u8 *dstptr=(__u8*)surface->data; // !!
178 for (int i=0; i<256; ++i)
180 if (src.surface->clut.data && (i<src.surface->clut.colors))
181 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);
187 srcptr+=srcarea.left()*surface->bypp+srcarea.top()*src.surface->stride;
188 dstptr+=area.left()*surface->bypp+area.top()*surface->stride;
189 for (int y=0; y<area.height(); y++)
191 if (flag & blitAlphaTest)
193 // no real alphatest yet
194 int width=area.width();
195 unsigned char *src=(unsigned char*)srcptr;
196 __u32 *dst=(__u32*)dstptr;
197 // use duff's device here!
209 int width=area.width();
210 unsigned char *src=(unsigned char*)srcptr;
211 __u32 *dst=(__u32*)dstptr;
215 srcptr+=src.surface->stride;
216 dstptr+=surface->stride;
219 eFatal("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp);
222 void gPixmap::mergePalette(const gPixmap &target)
224 if ((!surface->clut.colors) || (!target.surface->clut.colors))
226 gColor *lookup=new gColor[surface->clut.colors];
228 for (int i=0; i<surface->clut.colors; i++)
229 lookup[i].color=target.surface->clut.findColor(surface->clut.data[i]);
231 delete [] surface->clut.data;
232 surface->clut.colors=target.surface->clut.colors;
233 surface->clut.data=new gRGB[surface->clut.colors];
234 memcpy(surface->clut.data, target.surface->clut.data, sizeof(gRGB)*surface->clut.colors);
236 __u8 *dstptr=(__u8*)surface->data;
238 for (int ay=0; ay<surface->y; ay++)
240 for (int ax=0; ax<surface->x; ax++)
241 dstptr[ax]=lookup[dstptr[ax]];
242 dstptr+=surface->stride;
248 void gPixmap::line(ePoint start, ePoint dst, gColor color)
251 Ay=start.y(), Bx=dst.x(),
252 By=dst.y(); int dX, dY, fbXincr,
253 fbYincr, fbXYincr, dPr, dPru, P; __u8
254 *AfbAddr = &((__u8*)surface->data)[Ay*surface->stride+Ax*surface->bypp]; __u8
255 *BfbAddr = &((__u8*)surface->data)[By*surface->stride+Bx*surface->bypp]; fbXincr=
256 surface->bypp; if ( (dX=Bx-Ax) >= 0) goto AFTERNEGX; dX=-dX;
257 fbXincr=-1; AFTERNEGX: fbYincr=surface->stride; if ( (dY=By
258 -Ay) >= 0) goto AFTERNEGY; fbYincr=-surface->stride; dY=-dY;AFTERNEGY:
259 fbXYincr = fbXincr+fbYincr; if (dY > dX) goto YisIndependent; dPr = dY+
260 dY; P = -dX; dPru = P+P; dY = dX>>1; XLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0)
261 goto RightAndUp; AfbAddr+=fbXincr; BfbAddr-=fbXincr; if ((dY=dY-1) > 0) goto XLOOP; *AfbAddr=color; if ((dX & 1)
262 == 0) return; *BfbAddr=color; return; RightAndUp: AfbAddr+=fbXYincr; BfbAddr-=fbXYincr; P+=dPru; if ((dY=dY-1) >
263 0) goto XLOOP; *AfbAddr=color; if ((dX & 1) == 0) return; *BfbAddr=color; return; YisIndependent: dPr = dX+dX; P
264 = -dY; dPru = P+P; dX = dY>>1; YLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0) goto RightAndUp2; AfbAddr
265 +=fbYincr; BfbAddr-=fbYincr; if ((dX=dX-1) > 0) goto YLOOP; *AfbAddr=color; if ((dY & 1) == 0) return; *BfbAddr=
266 color;return; RightAndUp2: AfbAddr+=fbXYincr; BfbAddr-=fbXYincr; P+=dPru; if ((dX=dX-1) > 0) goto YLOOP; *AfbAddr
267 =color; if((dY & 1) == 0) return; *BfbAddr=color; return;
270 gColor gPalette::findColor(const gRGB &rgb) const
272 int difference=1<<30, best_choice=0;
273 for (int t=0; t<colors; t++)
276 int td=(signed)(rgb.r-data[t].r); td*=td; td*=(255-data[t].a);
280 td=(signed)(rgb.g-data[t].g); td*=td; td*=(255-data[t].a);
284 td=(signed)(rgb.b-data[t].b); td*=td; td*=(255-data[t].a);
288 td=(signed)(rgb.a-data[t].a); td*=td; td*=255;
304 gPixmap::gPixmap(gSurface *surface): surface(surface)
308 gPixmap::gPixmap(eSize size, int bpp)
310 surface = new gSurfaceSystem(size, bpp);