shithub: riscv

Download patch

ref: b318debfc2c1b2d16cb7ed6f4cddec04a15c81c6
parent: 18bfca7978bdaf7dc96e4b1a5b64ae9283856782
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Mon Oct 17 23:41:57 EDT 2011

page: avoid drawing background if image has no alpha channel

--- a/sys/src/cmd/page.c
+++ b/sys/src/cmd/page.c
@@ -856,8 +856,6 @@
 	Point origin;
 	Point delta;
 
-	USED(op);
-
 	if(Dx(bot)*Dy(bot) == 0)
 		return;
 
@@ -906,18 +904,23 @@
 	}
 }
 
+int
+alphachan(ulong chan)
+{
+	for(; chan; chan >>= 8)
+		if(TYPE(chan) == CAlpha)
+			return 1;
+	return 0;
+}
+
 void
-zoomdraw(Image *d, Rectangle r, Rectangle top, Image *s, Point sp, int f)
+zoomdraw(Image *d, Rectangle r, Rectangle top, Image *b, Image *s, Point sp, int f)
 {
-	int w, x, y;
+	Rectangle dr;
 	Image *t;
 	Point a;
+	int w;
 
-	if(f <= 1){
-		gendrawdiff(d, r, top, paper, sp, nil, ZP, SoverD);
-		gendrawdiff(d, r, top, s, sp, nil, ZP, SoverD);
-		return;
-	}
 	a = ZP;
 	if(r.min.x < d->r.min.x){
 		sp.x += (d->r.min.x - r.min.x)/f;
@@ -933,23 +936,34 @@
 	w = s->r.max.x - sp.x;
 	if(w > Dx(r))
 		w = Dx(r);
-	t = allocimage(display, Rect(r.min.x, r.min.y, r.min.x+w, r.max.y), s->chan, 0, 0);
-	if(t == nil)
+	dr = r;
+	dr.max.x = dr.min.x+w;
+	if(!alphachan(s->chan))
+		b = nil;
+	if(f <= 1){
+		if(b) gendrawdiff(d, dr, top, b, sp, nil, ZP, SoverD);
+		gendrawdiff(d, dr, top, s, sp, nil, ZP, SoverD);
 		return;
-	for(y=r.min.y; y<r.max.y; y++){
-		draw(t, Rect(r.min.x, y, r.min.x+w, y+1), s, nil, sp);
+	}
+	if((t = allocimage(display, dr, s->chan, 0, 0)) == nil)
+		return;
+	for(; dr.min.y < r.max.y; dr.min.y++){
+		dr.max.y = dr.min.y+1;
+		draw(t, dr, s, nil, sp);
 		if(++a.y == f){
 			a.y = 0;
 			sp.y++;
 		}
 	}
-	x=r.min.x;
-	for(sp=r.min; x<r.max.x; sp.x++){
-		gendrawdiff(d, Rect(x, r.min.y, x+1, r.max.y), top, paper, sp, nil, ZP, SoverD);
-		gendrawdiff(d, Rect(x, r.min.y, x+1, r.max.y), top, t, sp, nil, ZP, SoverD);
-		for(x++; ++a.x<f && x<r.max.x; x++)
-			gendrawdiff(d, Rect(x, r.min.y, x+1, r.max.y), top, d, 
-				Pt(x-1, r.min.y), nil, ZP, SoverD);
+	dr = r;
+	for(sp=dr.min; dr.min.x < r.max.x; sp.x++){
+		dr.max.x = dr.min.x+1;
+		if(b) gendrawdiff(d, dr, top, b, sp, nil, ZP, SoverD);
+		gendrawdiff(d, dr, top, t, sp, nil, ZP, SoverD);
+		for(dr.min.x++; ++a.x < f && dr.min.x < r.max.x; dr.min.x++){
+			dr.max.x = dr.min.x+1;
+			gendrawdiff(d, dr, top, d, Pt(dr.min.x-1, dr.min.y), nil, ZP, SoverD);
+		}
 		a.x = 0;
 	}
 	freeimage(t);
@@ -977,7 +991,7 @@
 
 	if(i = p->image){
 		r = rectaddpt(Rpt(ZP, pagesize(p)), addpt(pos, screen->r.min));
-		zoomdraw(screen, r, ZR, i, i->r.min, zoom);
+		zoomdraw(screen, r, ZR, paper, i, i->r.min, zoom);
 	} else {
 		r = Rpt(ZP, stringsize(font, p->label));
 		r = rectaddpt(r, addpt(subpt(divpt(subpt(screen->r.max, screen->r.min), 2),
@@ -1002,7 +1016,7 @@
 	nr = rectaddpt(r, d);
 	rectclip(&r, screen->r);
 	draw(screen, rectaddpt(r, d), screen, nil, r.min);
-	zoomdraw(screen, nr, rectaddpt(r, d), i, i->r.min, zoom);
+	zoomdraw(screen, nr, rectaddpt(r, d), paper, i, i->r.min, zoom);
 	drawframe(nr);
 }