diff options
Diffstat (limited to 'fb.c')
-rw-r--r-- | fb.c | 70 |
1 files changed, 53 insertions, 17 deletions
@@ -93,18 +93,7 @@ scale3x_filter(ulong *dst, Framebuf *fb, Point sp) //} static void -framebufctl_draw(Framebufctl *ctl, Image *dst, Point off) -{ - Framebuf *fb; - - qlock(ctl); - fb = ctl->getfb(ctl); - loadimage(dst, rectaddpt(fb->r, addpt(dst->r.min, off)), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4); - qunlock(ctl); -} - -static void -framebufctl_upscaledraw(Framebufctl *ctl, Image *dst, Point off, Point scale) +upscaledraw(Framebufctl *ctl, Image *dst, Point off, Point scale) { void (*filter)(ulong*, Framebuf*, Point); Framebuf *fb; @@ -143,18 +132,37 @@ framebufctl_upscaledraw(Framebufctl *ctl, Image *dst, Point off, Point scale) } static void -framebufctl_memdraw(Framebufctl *ctl, Memimage *dst, Point off) +framebufctl_draw(Framebufctl *ctl, Image *dst, Point off, Point scale) { Framebuf *fb; + Rectangle sr, dr; + ulong *cb; + int y; + + if(scale.x > 1 || scale.y > 1){ + upscaledraw(ctl, dst, off, scale); + return; + } qlock(ctl); fb = ctl->getfb(ctl); - loadmemimage(dst, rectaddpt(fb->r, addpt(dst->r.min, off)), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4); + sr = rectaddpt(fb->r, off); + dr = rectsubpt(dst->r, dst->r.min); + if(rectinrect(sr, dr)) + loadimage(dst, rectaddpt(sr, dst->r.min), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4); + else if(rectclip(&sr, dr)){ + cb = emalloc(Dx(sr)*Dy(sr)*4); + /* TODO there must be a cleaner way to do this */ + for(y = sr.min.y; y < sr.max.y; y++) + memmove(&cb[(y - sr.min.y)*Dx(sr)], &fb->cb[max(y - off.y,0)*Dx(fb->r) + max(-off.x,0)], Dx(sr)*4); + loadimage(dst, rectaddpt(sr, dst->r.min), (uchar*)cb, Dx(sr)*Dy(sr)*4); + free(cb); + } qunlock(ctl); } static void -framebufctl_upscalememdraw(Framebufctl *ctl, Memimage *dst, Point off, Point scale) +upscalememdraw(Framebufctl *ctl, Memimage *dst, Point off, Point scale) { void (*filter)(ulong*, Framebuf*, Point); Framebuf *fb; @@ -193,6 +201,36 @@ framebufctl_upscalememdraw(Framebufctl *ctl, Memimage *dst, Point off, Point sca } static void +framebufctl_memdraw(Framebufctl *ctl, Memimage *dst, Point off, Point scale) +{ + Framebuf *fb; + Rectangle sr, dr; + ulong *cb; + int y; + + if(scale.x > 1 || scale.y > 1){ + upscalememdraw(ctl, dst, off, scale); + return; + } + + qlock(ctl); + fb = ctl->getfb(ctl); + sr = rectaddpt(fb->r, off); + dr = rectsubpt(dst->r, dst->r.min); + if(rectinrect(sr, dr)) + loadmemimage(dst, rectaddpt(sr, dst->r.min), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4); + else if(rectclip(&sr, dr)){ + cb = emalloc(Dx(sr)*Dy(sr)*4); + /* TODO there must be a cleaner way to do this */ + for(y = sr.min.y; y < sr.max.y; y++) + memmove(&cb[(y - sr.min.y)*Dx(sr)], &fb->cb[max(y - off.y,0)*Dx(fb->r) + max(-off.x,0)], Dx(sr)*4); + loadmemimage(dst, rectaddpt(sr, dst->r.min), (uchar*)cb, Dx(sr)*Dy(sr)*4); + free(cb); + } + qunlock(ctl); +} + +static void framebufctl_drawnormals(Framebufctl *ctl, Image *dst) { Framebuf *fb; @@ -280,9 +318,7 @@ mkfbctl(Rectangle r) fc->fb[0] = mkfb(r); fc->fb[1] = mkfb(r); fc->draw = framebufctl_draw; - fc->upscaledraw = framebufctl_upscaledraw; fc->memdraw = framebufctl_memdraw; - fc->upscalememdraw = framebufctl_upscalememdraw; fc->drawnormals = framebufctl_drawnormals; fc->swap = framebufctl_swap; fc->reset = framebufctl_reset; |