ref: f48eac8988cf8ce8b18f49a97b26695c7b44ee52
parent: 672d39e9b1697da4b955f7a8b692994dfe916be7
author: jmq <jmq@jmq.sh>
date: Fri Aug 22 22:35:39 EDT 2025
fixing pill resize
--- a/main.c
+++ b/main.c
@@ -24,7 +24,7 @@
int CanvasMoved = 1;
Rectangle CanvasSize;
Rectangle ZoomedSize;
-Point CanvasAt = {0};+Point CanvasAt = {0}; // Position of the canvas relative to wuindow positionLayer * RootLayer = nil;
Layer * CurrentLayer = nil;
Image * Background = nil;
@@ -172,20 +172,45 @@
if (Background == nil)
setbackground(BACKGROUNDCOLOR);
-
+
+ // vr (Viewable Rectangle) is just a rectangle with the dimensions
+ // of the zoomed canvas that starts at the position of the canvas
+ // relative to the window
vr = rectaddpt(ZoomedSize, CanvasAt);
+
+ // Get the intersect rectangle between vr and the window.
+ // Remember, vr's position is relative to the window, meaning
+ // the window's position, as far as vr is concerned, is the origin.
+ // After this, vr is just a rectangle that shows the viewable part
+ // of the zoomed in canvas, relative to the window's position
i = rectclip(&vr,Rect(0, 0, Dx(screen->r), Dy(screen->r)));
+
+ // If we are clipping (i == true) and, either we Should Redraw (sr) or,
+ // the canvas moved since we last drew it and the area of vr is still the same
+ // as the zoomed size we want. The reason we do the last check, is because
+ // there's no need to redraw the Zoomed Image if vr hasn't changed in size,
+ // since it's position doesn't affect it's contents.
if (i && ((CanvasMoved && Ar(vr) != Ar(ZoomedSize)) || sr)) {- p = CanvasAt;
- if (p.x < 0) {- vr.max.x += -p.x;
- p.x = 0;
- }
- if (p.y < 0) {- vr.max.y += -p.y;
- p.y = 0;
- }
- vr = rectsubpt(vr, p);
+ // Now this might look a little confusing, and that's because this is actually a workaround
+ // to a problem with resizeimage (and that function still gives me nightmares)
+ //
+ // The issue is that we want Zoomed Image to have only the visible part of the
+ // zoomed canvas (which is the whole point of vr). Now, this is fine for positive
+ // coordinates, but when the canvas starts on negative coordinates, resize image gets
+ // a little fucky. To fix that, I found that increasing the max coordinates of vr
+ // by the same amount their respecting origin origin is on the negative makes this work
+ // fine for some reson. Don't ask me why.
+ p = CanvasAt;
+ if (p.x < 0) {+ vr.max.x += -p.x;
+ p.x = 0;
+ }
+ if (p.y < 0) {+ vr.max.y += -p.y;
+ p.y = 0;
+ }
+ vr = rectsubpt(vr, p);
+
if (resizeimage(ZoomedImage, vr, Zoom, ViewImage, ZP) < 0)
sysfatal("resizeimage: %r");}
--- a/pill/pill.c
+++ b/pill/pill.c
@@ -59,7 +59,7 @@
tr.max.y = tr.min.y + Dy(sr);
}
- if ((t = allocimage(display, tr, s->chan, 1, DNofill)) == nil) {+ if ((t = allocimage(display, tr, s->chan, 1, DTransparent)) == nil) { werrstr("allocimage: %r");return -1;
}
@@ -71,23 +71,19 @@
return -1;
}
- if (Dx(tr) > Dx(sr)) {- scale = ((float)Dx(tr))/((float)Dx(sr));
- } else {- scale = ((float)Dx(sr))/((float)Dx(tr));
- }
- p = dr.min;
+ scale = ((float)Dx(sr))/((float)Dx(tr));
+ p = ZP;
r.min = tr.min;
- r.max.y = tr.max.y;
+ r.max.y = s->r.max.y;
i = 0;
- while (r.min.x < tr.max.x) {- draw(c, c->r, s, nil, p);
- p.x += 1;
+ while (i < Dx(tr)) {+ drawop(c, c->r, s, nil, p, S);
+ p.x = s->r.min.x + (int)(((float)i)*scale);
- r.min.x = (int)(((float)(i))*scale) + tr.min.x;
- r.max.x = (int)(((float)(i+1))*scale) + tr.min.x;
- draw(t, r, c, nil, ZP);
+ r.min.x = i + tr.min.x;
+ r.max.x = r.min.x + 1;
+ draw(screen, r, c, nil, ZP);
i+=1;
}
@@ -100,30 +96,29 @@
return -1;
}
- if (Dy(tr) > Dy(sr)) {- scale = ((float)Dy(tr))/((float)Dy(sr));
- } else {- scale = ((float)Dy(sr))/((float)Dy(tr));
- }
+ scale = ((float)Dy(sr))/((float)Dy(tr));
p = dr.min;
r.min = tr.min;
r.max.x = tr.max.x;
- r.max.y = r.min.y + MAX(1.0, scale);
- i = 0;
- while (r.min.y < dr.max.y) {- draw(c, c->r, t, nil, p);
- p.y += 1;
-
- // Move the draw rectangle for the temporary image scale
- // rectangles to the right
- r.min.y = (int)(((float)(i))*scale) + dr.min.x;
- r.max.y = (int)(((float)(i+1))*scale) + dr.min.x;
- draw(d, r, c, nil, ZP);
- i+=1;
- }
+// i = 0;
+// while (r.min.y < dr.max.y) {+// draw(c, c->r, t, nil, p);
+// p.y = (int)(((float)i)*scale);
+//
+// // Move the draw rectangle for the temporary image scale
+// // rectangles to the right
+// r.min.y = i + tr.min.x;
+// r.max.y =i + tr.min.x + 1;
+// Rectangle fr = rectaddpt(r, d->r.min);
+// draw(d, fr, c, nil, ZP);
+// i+=1;
+// }
+ draw(d, d->r, t, nil, d->r.min);
+
+
freeimage(t);
freeimage(c);
@@ -304,10 +299,14 @@
static void
drawcanvas(void)
{- print("VirtualWindow: %R\n", VirtualWindow->r);- print("screen: %R\n", screen->r);- draw(screen, screen->r, Background, nil, ZP);
- draw(screen, screen->r, VirtualWindow, nil, ZP);
+ Rectangle vwr = VirtualWindow->r;
+ //print("VirtualWindow: %R\n", VirtualWindow->r);+ //print("screen: %R\n", screen->r);+ VirtualWindow->r.min = screen->r.min;
+ VirtualWindow->r.max.x = VirtualWindow->r.min.x + Dx(vwr);
+ VirtualWindow->r.max.y = VirtualWindow->r.min.y + Dy(vwr);
+ //draw(screen, screen->r, Background, nil, ZP);
+ //draw(screen, screen->r, VirtualWindow, nil, ZP);
}
void
@@ -330,11 +329,12 @@
freeimage(VirtualWindow);
}
- VirtualWindow = allocimage(display, screen->r, RGBA32, 1, DTransparent);
+ VirtualWindow = allocimage(display, screen->r, RGBA32, 0, DTransparent);
if (VirtualWindow == nil) { sysfatal("initcanvas: %r");}
+ draw(screen, screen->r, Background, nil, ZP);
rc = resizeimage(VirtualWindow, HuePicker);
if (rc < 0) { sysfatal("resizeimage: %r");--- a/resize.c
+++ b/resize.c
@@ -11,7 +11,6 @@
int
resizeimage(Image * di, Rectangle dr, float scale, Image * si, Point sp)
{- float d, f;
Point p;
Rectangle r, tr;
int i;
@@ -68,7 +67,7 @@
// image, for every line on the target image will we will skip over multiple
// lines on the source image.
- // Move the ci one 1/scale space to the righ
+ // Move the ci one 1 space to the righ
draw(ci, ci->r, si, nil, p);
p.x += 1;
@@ -108,8 +107,6 @@
r.max.y = r.min.y + MAX(1.0, scale);
i = 0;
- d = p.y;
- f = r.min.y;
while (r.min.y < dr.max.y) {// If we are expanding an image, one scan on the source image will result on
// multiple draws on the target image. Conversively, if we are shrinking an
@@ -116,7 +113,7 @@
// image, for every line on the target image will we will skip over multiple
// lines on the source image.
- // Move the ci one 1/scale space to the right
+ // Move the ci one 1 space down
draw(ci, ci->r, t, nil, p);
p.y += 1;
--
⑨