drawterm/gui-x11/draw.c

187 lines
3.8 KiB
C

#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)
{
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)
{
if(m->X)
getXdata(m, Rect(p.x, p.y, p.x+1, p.y+1));
return _pixelbits(m, p);
}