1 #include <lib/gdi/gpixmap.h>
9 gLookup::gLookup(int size, const gPalette &pal, const gRGB &start, const gRGB &end)
13 build(size, pal, start, end);
16 void gLookup::build(int _size, const gPalette &pal, const gRGB &start, const gRGB &end)
27 lookup=new gColor[size];
29 for (int i=0; i<size; i++)
34 int rdiff=-start.r+end.r;
35 int gdiff=-start.g+end.g;
36 int bdiff=-start.b+end.b;
37 int adiff=-start.a+end.a;
38 rdiff*=i; rdiff/=(size-1);
39 gdiff*=i; gdiff/=(size-1);
40 bdiff*=i; bdiff/=(size-1);
41 adiff*=i; adiff/=(size-1);
48 lookup[i]=pal.findColor(col);
54 void gPixmap::fill(const eRect &area, const gColor &color)
56 if ((area.height()<=0) || (area.width()<=0))
59 for (int y=area.top(); y<area.bottom(); y++)
60 memset(((__u8*)data)+y*stride+area.left(), color.color, area.width());
62 for (int y=area.top(); y<area.bottom(); y++)
64 __u32 *dst=(__u32*)(((__u8*)data)+y*stride+area.left()*bypp);
68 if (clut.data && color < clut.colors)
69 col=(clut.data[color].a<<24)|(clut.data[color].r<<16)|(clut.data[color].g<<8)|(clut.data[color].b);
77 eWarning("couldn't fill %d bpp", bpp);
80 void gPixmap::blit(const gPixmap &src, ePoint pos, const eRect &clip, int flag)
83 eRect area=eRect(pos, src.getSize());
86 area&=eRect(ePoint(0, 0), getSize());
87 if ((area.width()<0) || (area.height()<0))
91 srcarea.moveBy(-pos.x(), -pos.y());
93 if ((bpp == 8) && (src.bpp==8))
95 __u8 *srcptr=(__u8*)src.data;
96 __u8 *dstptr=(__u8*)data;
98 srcptr+=srcarea.left()*bypp+srcarea.top()*src.stride;
99 dstptr+=area.left()*bypp+area.top()*stride;
100 for (int y=0; y<area.height(); y++)
102 if (flag & blitAlphaTest)
104 // no real alphatest yet
105 int width=area.width();
106 unsigned char *src=(unsigned char*)srcptr;
107 unsigned char *dst=(unsigned char*)dstptr;
108 // use duff's device here!
119 memcpy(dstptr, srcptr, area.width()*bypp);
123 } else if ((bpp == 32) && (src.bpp==8))
125 __u8 *srcptr=(__u8*)src.data;
126 __u8 *dstptr=(__u8*)data; // !!
129 for (int i=0; i<256; ++i)
131 if (src.clut.data && (i<src.clut.colors))
132 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);
138 srcptr+=srcarea.left()*bypp+srcarea.top()*src.stride;
139 dstptr+=area.left()*bypp+area.top()*stride;
140 for (int y=0; y<area.height(); y++)
142 if (flag & blitAlphaTest)
144 // no real alphatest yet
145 int width=area.width();
146 unsigned char *src=(unsigned char*)srcptr;
147 __u32 *dst=(__u32*)dstptr;
148 // use duff's device here!
160 int width=area.width();
161 unsigned char *src=(unsigned char*)srcptr;
162 __u32 *dst=(__u32*)dstptr;
170 eFatal("cannot blit %dbpp from %dbpp", bpp, src.bpp);
173 void gPixmap::mergePalette(const gPixmap &target)
175 if ((!clut.colors) || (!target.clut.colors))
177 gColor *lookup=new gColor[clut.colors];
179 for (int i=0; i<clut.colors; i++)
180 lookup[i].color=target.clut.findColor(clut.data[i]);
183 clut.colors=target.clut.colors;
184 clut.data=new gRGB[clut.colors];
185 memcpy(clut.data, target.clut.data, sizeof(gRGB)*clut.colors);
187 __u8 *dstptr=(__u8*)data;
189 for (int ay=0; ay<y; ay++)
191 for (int ax=0; ax<x; ax++)
192 dstptr[ax]=lookup[dstptr[ax]];
199 void gPixmap::line(ePoint start, ePoint dst, gColor color)
201 int Ax=start.x(), // dieser code rult ganz ganz doll weil er ganz ganz fast ist und auch sehr gut dokumentiert is
202 Ay=start.y(), Bx=dst.x(), // t. es handelt sich immerhin um den weltbekannten bresenham algorithmus der nicht nur
203 By=dst.y(); int dX, dY, fbXincr, // sehr schnell ist sondern auch sehr gut dokumentiert und getestet wurde. nicht
204 fbYincr, fbXYincr, dPr, dPru, P; __u8 // nur auf dem LCD der dbox, sondern auch ueberall anders. und auch auf der
205 *AfbAddr = &((__u8*)data)[Ay*stride+Ax*bypp]; __u8 // dbox mit LCD soll das teil nun tun, und ich denke das tut es. ausse
206 *BfbAddr = &((__u8*)data)[By*stride+Bx*bypp]; fbXincr= // rdem hat dieser algo den vorteil dass man fehler sehr leicht fi
207 bypp; if ( (dX=Bx-Ax) >= 0) goto AFTERNEGX; dX=-dX; // ndet und beheben kann. das liegt nicht zuletzt an den komment
208 fbXincr=-1; AFTERNEGX: fbYincr=stride; if ( (dY=By // aren. und ausserdem, je kuerzer der code, desto weniger k
209 -Ay) >= 0) goto AFTERNEGY; fbYincr=-stride; dY=-dY;AFTERNEGY: // ann daran falsch sein. erwaehnte ich schon, da
210 fbXYincr = fbXincr+fbYincr; if (dY > dX) goto YisIndependent; dPr = dY+ // s dieser tolle code wahnsinnig schnell
211 dY; P = -dX; dPru = P+P; dY = dX>>1; XLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0) // ist? bye, tmbinc
212 goto RightAndUp; AfbAddr+=fbXincr; BfbAddr-=fbXincr; if ((dY=dY-1) > 0) goto XLOOP; *AfbAddr=color; if ((dX & 1)
213 == 0) return; *BfbAddr=color; return; RightAndUp: AfbAddr+=fbXYincr; BfbAddr-=fbXYincr; P+=dPru; if ((dY=dY-1) >
214 0) goto XLOOP; *AfbAddr=color; if ((dX & 1) == 0) return; *BfbAddr=color; return; YisIndependent: dPr = dX+dX; P
215 = -dY; dPru = P+P; dX = dY>>1; YLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0) goto RightAndUp2; AfbAddr
216 +=fbYincr; BfbAddr-=fbYincr; if ((dX=dX-1) > 0) goto YLOOP; *AfbAddr=color; if ((dY & 1) == 0) return; *BfbAddr=
217 color;return; RightAndUp2: AfbAddr+=fbXYincr; BfbAddr-=fbXYincr; P+=dPru; if ((dX=dX-1) > 0) goto YLOOP; *AfbAddr
218 =color; if((dY & 1) == 0) return; *BfbAddr=color; return; // nun ist der tolle code leider zu ende. tut mir leid.
221 gColor gPalette::findColor(const gRGB &rgb) const
223 int difference=1<<30, best_choice=0;
224 for (int t=0; t<colors; t++)
227 int td=(signed)(rgb.r-data[t].r); td*=td; td*=(255-data[t].a);
231 td=(signed)(rgb.g-data[t].g); td*=td; td*=(255-data[t].a);
235 td=(signed)(rgb.b-data[t].b); td*=td; td*=(255-data[t].a);
239 td=(signed)(rgb.a-data[t].a); td*=td; td*=255;
249 gPixmap::gPixmap(): ref(0)
257 gImage::gImage(eSize size, int _bpp)
271 case 24: // never use 24bit mode
282 clut.data=new gRGB[clut.colors];
288 data=new char[x*y*bypp];
294 delete[] (char*)data;