summaryrefslogtreecommitdiff
path: root/fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fb.c')
-rw-r--r--fb.c70
1 files changed, 53 insertions, 17 deletions
diff --git a/fb.c b/fb.c
index 4b1f82e..2c1d494 100644
--- a/fb.c
+++ b/fb.c
@@ -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;