/*
* some comments on alpha blending!
+ * ################################
*
- * ...
- *
+ * if c is the result of layer a over layer b with opacity alpha:
+ *
+ * c=alpha*a+(1-alpha)*b and if alpha is a byte (0-255)
+ * => c=alpha*a+(255-alpha)*b
+ *
*/
#include "display.h"
}
}
-void display_draw_rectangle(int x,int y,int w,int h,u8 fill,u8 alpha) {
+#define display_m2i(m,r) (((((m)[0]>>r)&1)<<1)|(((m)[1]>>r)&1))
- int c,r,rmax;
- u8 p,spage,epage;
- u8 b[2],a[2]; // c = a over b => c=alpha*a+(1-alpha)*b
+void display_draw_rectangle(u8 x,u8 y,u8 w,u8 h,u8 fill,u8 alpha) {
- a[0]=0;
- a[1]=0;
- switch(fill) {
- case DISPLAY_FILL_LG:
- a[1]=1;
- break;
- case DISPLAY_FILL_DG:
- a[0]=1;
- break;
- case DISPLAY_FILL_B:
- a[0]=1;
- a[1]=1;
- case DISPLAY_FILL_W:
- default:
- break;
- }
+ u8 page,col,row,rmax,cnt;
+ u8 d[2];
+ int ca,cb;
+ u8 a,b,c; // c = a over b
+
+ a=fill&0x03;
+ ca=0;
+ for(cnt=0;cnt<a;cnt++) // contribution of a: alpha*a
+ ca+=alpha;
- spage=y>>3; // start page = y/8
- epage=(y+h)>>3; // end page (y+h)/8
-
- for(p=spage;p<=epage;p++) {
- DISPLAY_SET_PAGE_ADDR(p);
- for(c=x;c<x+w;c++) {
- DISPLAY_SET_C_ADDR(c);
- b[0]=DISPLAY_DATA; // dummy read (p.16)
- b[0]=DISPLAY_DATA;
- b[1]=DISPLAY_DATA;
- rmax=y+8>y+h?y+h:y+8;
- for(r=y;r<rmax;r++) {
- b[0]&=~(1<<r);
- b[1]&=~(1<<r);
- b[0]|=a[0]<<r;
- b[1]|=a[1]<<r;
+ for(page=(y>>3);page<=((y+h)>>3);page++) { // page = y/8
+ DISPLAY_SET_PAGE_ADDR(page);
+ rmax=(page+1)<<3; // row max
+ if(rmax>y+h)
+ rmax=y+h;
+ for(col=x;col<x+w;col++) {
+ DISPLAY_SET_C_ADDR(col);
+ d[0]=DISPLAY_DATA; // dummy read (p.16)
+ d[0]=DISPLAY_DATA;
+ d[1]=DISPLAY_DATA;
+ for(row=y;row<rmax;row++) {
+ // contribution of b: (255-alpha)*b
+ b=display_m2i(d,row);
+ cb=0;
+ for(cnt=0;cnt<b;cnt++)
+ cb+=(255-alpha);
+ // finally there is c
+ c=(ca+cb)>>8;
+ d[0]&=~(1<<row);
+ d[1]&=~(1<<row);
+ d[0]|=((c>>1)&1)<<row;
+ d[1]|=(c&1)<<row;
}
- DISPLAY_SET_C_ADDR(c);
+ DISPLAY_SET_C_ADDR(col);
DISPLAY_DATA=b[0];
DISPLAY_DATA=b[1];
}
- y+=8;
+ y=rmax;
}
}
+void display_draw_buf(u8 x,u8 y,u8 w,u8 h,u8 *buf,u8 alpha) {
+
+}
+
void display_bl_init(void) {
IODIR0|=(1<<4);