/* * m should be a 1-bit-deep bitmap with origin (0,0) and the * same extents as r. s should have the same depth as d. * Rectangle r of s is copied to d wherever corresponding * bits of m are 1 */ void copymasked(Bitmap *d, Point p, Bitmap *s, Bitmap *m, Rectangle r) { int sx, sy, dx, dy; XGCValues gcv; GC g; if(Dx(r)<=0 || Dy(r)<=0) return; sx = r.min.x; sy = r.min.y; if(s->flag&SHIFT){ sx -= s->r.min.x; sy -= s->r.min.y; } dx = p.x; dy = p.y; if(d->flag&SHIFT){ dx -= d->r.min.x; dy -= d->r.min.y; } gcv.fill_style = FillStippled; gcv.stipple = (Pixmap)m->id; gcv.function = GXclear; gcv.ts_x_origin = dx; gcv.ts_y_origin = dy; gcv.fill_style = FillStippled; g = _getgc(d, GCFunction|GCStipple|GCTileStipXOrigin |GCTileStipYOrigin|GCFillStyle, &gcv); XFillRectangle(_dpy, (Drawable)d->id, g, dx, dy, Dx(r), Dy(r)); gcv.function = GXor; gcv.fill_style = FillSolid; g = _getgc(d, GCFunction|GCFillStyle, &gcv); XCopyArea(_dpy, (Drawable)s->id, (Drawable)d->id, g, sx, sy, Dx(r), Dy(r), dx, dy); }
GC _getcopygc2(Fcode f, Bitmap *db, Bitmap *sb, int *bltfunc, uint64_t fg, uint64_t bg) { uint64_t spix, df, sf; int xf, c; XGCValues gcv; uint64_t gcvm; spix = xf = 0; f &= F; gcvm = 0; df = db->flag; if(degengc[f]){ *bltfunc = UseFillRectangle; if(df&SCR || !(df&DP1)){ // nothing XXX }else{ /* must be DP1 and BL1 */ fg = 1; bg = 0; } switch(f){ case Zero: xf = GXcopy; spix = bg; break; case F: xf = GXcopy; spix = fg; break; case D: xf = GXnoop; spix = fg; break; case notD: xf = GXxor; spix = fg^bg; break; default: /* ignored */ break; } gcv.function = xf; gcv.foreground = spix; gcvm = GCFunction|GCForeground; }else{ /* src is involved in f */ #define code(f1,f2) ((((f1)&(DP1|BL1))<<2)|((f2)&(DP1|BL1))) sf = sb->flag; c = code(df,sf); *bltfunc = UseCopyArea; switch(code(df,sf)){ case code(DP1|BL1,DP1|BL1): case code(BL1,BL1): xf = gx[f]; break; case code(DP1|BL1,DP1): xf = d1s0gx[f]; break; case code(DP1,DP1|BL1): xf = d0s1gx[f]; break; case code(DP1,DP1): case code(0,0): xf = d0s0gx[f]; break; default: /* * One bitmap has depth 1, the other has screen depth. * We know the bitmap must have BL1. * CopyPlane must be used; it won't really work * for more than fcode==S. */ *bltfunc = UseCopyPlane; xf = GXcopy; switch(c){ case code(0,DP1|BL1): case code(BL1,DP1|BL1): // nothing XXX break; case code(DP1|BL1,0): fg = 0; bg = 1; break; case code(DP1|BL1,BL1): fg = 1; bg = 0; break; default: berror("bad combination of copy bitmaps"); } gcv.foreground = fg; gcv.background = bg; gcvm |= GCForeground|GCBackground; } gcv.function = xf; gcvm |= GCFunction; #undef code } return _getgc(db, gcvm, &gcv); }
GC _getfillgc2(Fcode f, Bitmap *b, uint64_t val, uint64_t fg, uint64_t bg) { int xf, m; uint64_t v, spix, vmax; XGCValues gcv; f &= F; vmax = _ld2dmask[b->ldepth]; v = val & vmax; spix = v; xf = GXcopy; m = b->flag; if(m & DP1){ xf = (m&BL1)? gx[f] : d0s1gx[f]; }else{ switch(f){ case Zero: labZero: spix = bg; break; case F: labF: spix = fg; break; case D: labD: xf = GXnoop; break; case notD: labnotD: xf = GXxor; spix = fg^bg; break; case S: if(val == ~0) spix = fg; else spix = v; break; case notS: if(val == ~0) spix = bg; else spix = v; break; case DxorS: xf = GXxor; if(val == ~0) spix = fg^bg; else spix = v; break; case DxnorS: xf = GXxor; if(val == 0) spix = fg^bg; else spix = v; break; default: /* hard to do anything other than v==0 or v==~0 case */ if(v < vmax-v){ /* v is closer to 0 than vmax */ switch(f&~S){ case D&~S: goto labD; case notD&~S: goto labnotD; case Zero&~S: goto labZero; case F&~S: goto labF; } }else{ /* v is closer to vmax than 0 */ switch(f&S){ case D&S: goto labD; case notD&S: goto labnotD; case Zero&S: goto labZero; case F&S: goto labF; } } } } gcv.foreground = spix; gcv.function = xf; return _getgc(b, GCForeground|GCFunction, &gcv); }