a
This commit is contained in:
189
gui-x11/draw.c
Normal file
189
gui-x11/draw.c
Normal file
@ -0,0 +1,189 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
#include "xmem.h"
|
||||
|
||||
void xfillcolor(Memimage*, Rectangle, ulong);
|
||||
static int xdraw(Memdrawparam*);
|
||||
|
||||
int xgcfillcolor = 0;
|
||||
int xgcfillcolor0 = 0;
|
||||
int xgczeropm = 0;
|
||||
int xgczeropm0 = 0;
|
||||
int xgcsimplecolor = 0;
|
||||
int xgcsimplecolor0 = 0;
|
||||
int xgcsimplepm = 0;
|
||||
int xgcsimplepm0 = 0;
|
||||
int xgcreplsrctile = 0;
|
||||
int xgcreplsrctile0 = 0;
|
||||
|
||||
void
|
||||
memimageinit(void)
|
||||
{
|
||||
static int didinit = 0;
|
||||
|
||||
if(didinit)
|
||||
return;
|
||||
|
||||
didinit = 1;
|
||||
_memimageinit();
|
||||
|
||||
xfillcolor(memblack, memblack->r, 0);
|
||||
xfillcolor(memwhite, memwhite->r, 1);
|
||||
}
|
||||
|
||||
void
|
||||
memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp, Memimage *mask, Point mp, int op)
|
||||
{
|
||||
int didx;
|
||||
Rectangle dr, mr, sr;
|
||||
Memdrawparam *par;
|
||||
|
||||
if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil)
|
||||
return;
|
||||
_memimagedraw(par);
|
||||
if(!xdraw(par))
|
||||
putXdata(dst, par->r);
|
||||
}
|
||||
|
||||
void
|
||||
xfillcolor(Memimage *m, Rectangle r, ulong v)
|
||||
{
|
||||
GC gc;
|
||||
Xmem *dxm;
|
||||
|
||||
dxm = m->X;
|
||||
assert(dxm != nil);
|
||||
r = rectsubpt(r, m->r.min);
|
||||
|
||||
if(m->chan == GREY1){
|
||||
gc = xgcfill0;
|
||||
if(xgcfillcolor0 != v){
|
||||
XSetForeground(xdisplay, gc, v);
|
||||
xgcfillcolor0 = v;
|
||||
}
|
||||
}else{
|
||||
if(m->chan == CMAP8 && xtblbit)
|
||||
v = plan9tox11[v];
|
||||
|
||||
gc = xgcfill;
|
||||
if(xgcfillcolor != v){
|
||||
XSetForeground(xdisplay, gc, v);
|
||||
xgcfillcolor = v;
|
||||
}
|
||||
}
|
||||
XFillRectangle(xdisplay, dxm->pmid, gc, r.min.x, r.min.y, Dx(r), Dy(r));
|
||||
}
|
||||
|
||||
static int
|
||||
xdraw(Memdrawparam *par)
|
||||
{
|
||||
int dy, dx;
|
||||
unsigned m;
|
||||
Memimage *src, *dst, *mask;
|
||||
Xmem *dxm, *sxm, *mxm;
|
||||
GC gc;
|
||||
Rectangle r, sr, mr;
|
||||
ulong sdval;
|
||||
|
||||
dx = Dx(par->r);
|
||||
dy = Dy(par->r);
|
||||
src = par->src;
|
||||
dst = par->dst;
|
||||
mask = par->mask;
|
||||
r = par->r;
|
||||
sr = par->sr;
|
||||
mr = par->mr;
|
||||
sdval = par->sdval;
|
||||
|
||||
return 0;
|
||||
if((dxm = dst->X) == nil)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If we have an opaque mask and source is one opaque pixel we can convert to the
|
||||
* destination format and just XFillRectangle.
|
||||
*/
|
||||
m = Simplesrc|Simplemask|Fullmask;
|
||||
if((par->state&m)==m){
|
||||
xfillcolor(dst, r, sdval);
|
||||
dirtyXdata(dst, par->r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no source alpha, an opaque mask, we can just copy the
|
||||
* source onto the destination. If the channels are the same and
|
||||
* the source is not replicated, XCopyArea suffices.
|
||||
*/
|
||||
m = Simplemask|Fullmask;
|
||||
if((par->state&(m|Replsrc))==m && src->chan == dst->chan && src->X){
|
||||
sxm = src->X;
|
||||
r = rectsubpt(r, dst->r.min);
|
||||
sr = rectsubpt(sr, src->r.min);
|
||||
if(dst->chan == GREY1)
|
||||
gc = xgccopy0;
|
||||
else
|
||||
gc = xgccopy;
|
||||
XCopyArea(xdisplay, sxm->pmid, dxm->pmid, gc,
|
||||
sr.min.x, sr.min.y, dx, dy, r.min.x, r.min.y);
|
||||
dirtyXdata(dst, par->r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no source alpha, a 1-bit mask, and a simple source
|
||||
* we can just copy through the mask onto the destination.
|
||||
*/
|
||||
if(dst->X && mask->X && !(mask->flags&Frepl)
|
||||
&& mask->chan == GREY1 && (par->state&Simplesrc)){
|
||||
Point p;
|
||||
|
||||
mxm = mask->X;
|
||||
r = rectsubpt(r, dst->r.min);
|
||||
mr = rectsubpt(mr, mask->r.min);
|
||||
p = subpt(r.min, mr.min);
|
||||
if(dst->chan == GREY1){
|
||||
gc = xgcsimplesrc0;
|
||||
if(xgcsimplecolor0 != sdval){
|
||||
XSetForeground(xdisplay, gc, sdval);
|
||||
xgcsimplecolor0 = sdval;
|
||||
}
|
||||
if(xgcsimplepm0 != mxm->pmid){
|
||||
XSetStipple(xdisplay, gc, mxm->pmid);
|
||||
xgcsimplepm0 = mxm->pmid;
|
||||
}
|
||||
}else{
|
||||
/* somehow this doesn't work on rob's mac
|
||||
gc = xgcsimplesrc;
|
||||
if(dst->chan == CMAP8 && xtblbit)
|
||||
sdval = plan9tox11[sdval];
|
||||
|
||||
if(xgcsimplecolor != sdval){
|
||||
XSetForeground(xdisplay, gc, sdval);
|
||||
xgcsimplecolor = sdval;
|
||||
}
|
||||
if(xgcsimplepm != mxm->pmid){
|
||||
XSetStipple(xdisplay, gc, mxm->pmid);
|
||||
xgcsimplepm = mxm->pmid;
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
XSetTSOrigin(xdisplay, gc, p.x, p.y);
|
||||
XFillRectangle(xdisplay, dxm->pmid, gc, r.min.x, r.min.y, dx, dy);
|
||||
dirtyXdata(dst, par->r);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong
|
||||
pixelbits(Memimage *m, Point p)
|
||||
{
|
||||
Xmem *xm;
|
||||
if(m->X)
|
||||
getXdata(m, Rect(p.x, p.y, p.x+1, p.y+1));
|
||||
return _pixelbits(m, p);
|
||||
}
|
Reference in New Issue
Block a user