diff options
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | libvncserver/cursor.c | 38 | ||||
-rw-r--r-- | rfb/rfb.h | 1 |
3 files changed, 39 insertions, 1 deletions
@@ -2,7 +2,6 @@ immediate: ---------- VisualNaCro testing -rfbMakeMaskFromAlphaSource test IRIX -overlay (x11vnc) java vncviewer doesn't do colour cursors? MinGW32 doesn't do fcntl on sockets; use setsockopt instead... diff --git a/libvncserver/cursor.c b/libvncserver/cursor.c index 49d7b99..2577064 100644 --- a/libvncserver/cursor.c +++ b/libvncserver/cursor.c @@ -306,6 +306,44 @@ char* rfbMakeMaskForXCursor(int width,int height,char* source) return(mask); } +/* this function dithers the alpha using Floyd-Steinberg */ + +char* rfbMakeMaskFromAlphaSource(int width,int height,unsigned char* alphaSource) +{ + int* error=(int*)calloc(sizeof(int),width); + int i,j,currentError=0,maskStride=(width+7)/8; + unsigned char* result=(unsigned char*)calloc(maskStride,height); + + for(j=0;j<height;j++) + for(i=0;i<width;i++) { + int right,middle,left; + currentError+=alphaSource[i+width*j]+error[i]; + + if(currentError<0x80) { + /* set to transparent */ + /* alpha was treated as 0 */ + } else { + /* set to solid */ + result[i/8+j*maskStride]|=(0x100>>(i&7)); + /* alpha was treated as 0xff */ + currentError-=0xff; + } + /* propagate to next row */ + right=currentError/16; + middle=currentError*5/16; + left=currentError*3/16; + currentError-=right+middle+left; + error[i]=right; + if(i>0) { + error[i-1]=middle; + if(i>1) + error[i-2]=left; + } + } + free(error); + return result; +} + void rfbFreeCursor(rfbCursorPtr cursor) { if(cursor) { @@ -639,6 +639,7 @@ extern rfbBool rfbSendCursorPos(rfbClientPtr cl); extern void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap); extern rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString); extern char* rfbMakeMaskForXCursor(int width,int height,char* cursorString); +extern char* rfbMakeMaskFromAlphaSource(int width,int height,unsigned char* alphaSource); extern void rfbMakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor); extern void rfbMakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor); extern void rfbFreeCursor(rfbCursorPtr cursor); |