diff options
author | rodri <rgl@antares-labs.eu> | 2024-08-17 12:17:46 +0000 |
---|---|---|
committer | rodri <rgl@antares-labs.eu> | 2024-08-17 12:17:46 +0000 |
commit | 56e8e3de24e7fea36f165b653a8efc8c38145d4c (patch) | |
tree | c1558a4ef810d82a11d31ab085dd849c7b5bba7f /fb.c | |
parent | d0a7561dd20847504b2449e17fd791f6c2800c84 (diff) | |
download | libgraphics-56e8e3de24e7fea36f165b653a8efc8c38145d4c.tar.gz libgraphics-56e8e3de24e7fea36f165b653a8efc8c38145d4c.tar.bz2 libgraphics-56e8e3de24e7fea36f165b653a8efc8c38145d4c.zip |
unify drawing routines and add clipped fb drawing support.
now changing the viewport offset will correctly show the
portion of the framebuffer that's visible, including
support for upscaled views.
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; |