ref: 69cd42bb94c4454c8478eae8a61c5fec9e16ebb7
parent: a222ad25f1656a5d098028c11283cc7f8c67f0e4
author: rodri <rgl@antares-labs.eu>
date: Fri Aug 15 11:07:22 EDT 2025
libmemdraw: follow draw(2)'s behavior for clipr and repl
--- a/sys/src/libmemdraw/warp.c
+++ b/sys/src/libmemdraw/warp.c
@@ -24,6 +24,7 @@
{
Memimage *i;
uchar *a;
+ Rectangle r;
int bpp;
int bpl;
int cmask;
@@ -40,23 +41,22 @@
}
static ulong
-edgehandler(Sampler*, Point*)
-{
- return 0; /* constant */
-}
-
-static ulong
sample(Sampler *s, Point p)
{
ulong c;
- if(p.x >= s->i->r.min.x && p.x < s->i->r.max.x
- && p.y >= s->i->r.min.y && p.y < s->i->r.max.y){
+ if(p.x >= s->r.min.x && p.x < s->r.max.x
+ && p.y >= s->r.min.y && p.y < s->r.max.y){
+inside:
c = *(ulong*)(s->a + p.y*s->bpl + p.x*s->bpp);
c &= s->cmask;
- }else
- c = edgehandler(s, &p);
- return c;
+ return c;
+ }else if(s->i->flags & Frepl){
+ p = drawrepl(s->r, p);
+ goto inside;
+ }
+ /* edge handler: constant */
+ return 0;
}
int
@@ -65,15 +65,17 @@
Sampler samp;
Point sp, dp;
Foint p2;
+ Rectangle dr;
long Δx, Δy;
ulong c00, c01, c10, c11;
- uchar c0, c1, c, *a;
- int bpp, bploff;
+ uchar c0, c1, c, *a0, *a;
+ int bpp, bpl;
- if(s->depth < 8 || (s->depth & 3) != 0){
- werrstr("unsupported image format");
- return -1;
- }
+ for(c00 = s->chan; c00; c00 >>= 8)
+ if(NBITS(c00) != 8){
+ werrstr("unsupported image format");
+ return -1;
+ }
if(d->chan != s->chan){
werrstr("image formats differ");
@@ -80,24 +82,29 @@
return -1;
}
- if(rectclip(&r, d->r) == 0)
+ dr = d->clipr;
+ rectclip(&dr, d->r);
+ if(rectclip(&r, dr) == 0)
return 0;
+ samp.r = s->clipr;
+ if(rectclip(&samp.r, s->r) == 0)
+ return 0;
+
samp.i = s;
samp.a = s->data->bdata + s->zero;
samp.bpp = s->depth >> 3;
samp.bpl = sizeof(ulong)*s->width;
samp.cmask = (1ULL << s->depth) - 1;
- a = d->data->bdata + d->zero;
+ a0 = d->data->bdata + d->zero;
bpp = d->depth >> 3;
- bploff = sizeof(ulong)*d->width - Dx(d->r)*bpp;
+ bpl = sizeof(ulong)*d->width;
- r = rectsubpt(r, r.min);
+ for(dp.y = r.min.y; dp.y < r.max.y; dp.y++)
+ for(dp.x = r.min.x; dp.x < r.max.x; dp.x++){
+ a = a0 + dp.y*bpl + dp.x*bpp;
+ p2 = fix_xform((Foint){int2fix(dp.x - dr.min.x), int2fix(dp.y - dr.min.y), 1<<7}, m);
- for(dp.y = 0; dp.y < r.max.y; dp.y++, a += bploff)
- for(dp.x = 0; dp.x < r.max.x; dp.x++, a += bpp){
- p2 = fix_xform((Foint){int2fix(dp.x), int2fix(dp.y), 1<<7}, m);
-
Δx = fixfrac(p2.x);
Δy = fixfrac(p2.y);
@@ -118,22 +125,22 @@
c0 = c00 >> 8*3 & 0xFF; c0 = lerp(c0, c01 >> 8*3 & 0xFF, Δx);
c1 = c10 >> 8*3 & 0xFF; c1 = lerp(c1, c11 >> 8*3 & 0xFF, Δx);
c = lerp(c0, c1, Δy);
- *(a + 3) = c;
+ a[3] = c;
case 3:
c0 = c00 >> 8*2 & 0xFF; c0 = lerp(c0, c01 >> 8*2 & 0xFF, Δx);
c1 = c10 >> 8*2 & 0xFF; c1 = lerp(c1, c11 >> 8*2 & 0xFF, Δx);
c = lerp(c0, c1, Δy);
- *(a + 2) = c;
+ a[2] = c;
case 2:
c0 = c00 >> 8*1 & 0xFF; c0 = lerp(c0, c01 >> 8*1 & 0xFF, Δx);
c1 = c10 >> 8*1 & 0xFF; c1 = lerp(c1, c11 >> 8*1 & 0xFF, Δx);
c = lerp(c0, c1, Δy);
- *(a + 1) = c;
+ a[1] = c;
case 1:
c0 = c00 >> 8*0 & 0xFF; c0 = lerp(c0, c01 >> 8*0 & 0xFF, Δx);
c1 = c10 >> 8*0 & 0xFF; c1 = lerp(c1, c11 >> 8*0 & 0xFF, Δx);
c = lerp(c0, c1, Δy);
- *(a + 0) = c;
+ a[0] = c;
}
}
--- a/sys/src/libmemdraw/warptest.c
+++ b/sys/src/libmemdraw/warptest.c
@@ -130,11 +130,25 @@
// dr = getbbox(&src->r, T);
dr = src->r;
dst = allocmemimage(dr, src->chan);
+ memfillcolor(dst, DTransparent);
mkwarp(w, T);
profbegin();
- if(memaffinewarp(dst, dst->r, src, src->r.min, w) < 0)
+ dr = rectaddpt(Rect(0,0,Dx(dst->r)/2,Dy(dst->r)/2), dst->r.min);
+ dst->clipr = dr;
+ if(memaffinewarp(dst, dr, src, src->r.min, w) < 0)
+ sysfatal("memaffinewarp: %r");
+ dr = rectaddpt(Rect(Dx(dst->r)/2+1,0,Dx(dst->r),Dy(dst->r)/2), dst->r.min);
+ dst->clipr = dst->r;
+ if(memaffinewarp(dst, dr, src, src->r.min, w) < 0)
+ sysfatal("memaffinewarp: %r");
+ dr = rectaddpt(Rect(0,Dy(dst->r)/2+1,Dx(dst->r)/2,Dy(dst->r)), dst->r.min);
+ if(memaffinewarp(dst, dr, src, src->r.min, w) < 0)
+ sysfatal("memaffinewarp: %r");
+ dr = rectaddpt(Rect(Dx(dst->r)/2+1,Dy(dst->r)/2+1,Dx(dst->r),Dy(dst->r)), dst->r.min);
+ dst->clipr = dr;
+ if(memaffinewarp(dst, dr, src, src->r.min, w) < 0)
sysfatal("memaffinewarp: %r");
profend();
writememimage(1, dst);
--
⑨