+ float x1e=x1-x1f, x2e=x2f-x2, y1e=y1-y1f, y2e=y2f-y2;
+ // printf("x1e %.4f x2e %.4f y1e %.4f y2e %.4f\n", x1e, x2e, y1e, y2e);
+
+ // adjust the box so it's entirely on the canvas
+ if(x1<=0) { x1=0; x1e=0; }
+ if(y1<=0) { y1=0; y1e=0; }
+ if(x2>=surface_width) { x2=surface_width; x2e=0; }
+ if(y2>=surface_height) { y2=surface_height; y2e=0; }
+
+ int w(x2-x1), h(y2-y1);
+
+ Surface::alpha_pen surface_pen(dest_surface.get_pen(x1,y1),1.0f);
+ if(w>0 && h>0)
+ dest_surface.fill(color,surface_pen,w,h);
+
+ /* the rectangle doesn't cross any vertical pixel boundaries so we don't
+ * need to draw any top or bottom edges
+ */
+ if(x2<x1)
+ {
+ // case 1 - a single pixel
+ if(y2<y1)
+ {
+ surface_pen.move_to(x2,y2);
+ surface_pen.set_alpha((x2f-x1f)*(y2f-y1f));
+ surface_pen.put_value(color);
+ }
+ // case 2 - a single vertical column of pixels
+ else
+ {
+ surface_pen.move_to(x2,y1-1);
+ if (y1e!=0) // maybe draw top pixel
+ {
+ surface_pen.set_alpha(y1e*(x2f-x1f));
+ surface_pen.put_value(color);
+ }
+ surface_pen.inc_y();
+ surface_pen.set_alpha(x2f-x1f);
+ for(int i=y1; i<y2; i++) // maybe draw pixels between
+ {
+ surface_pen.put_value(color);
+ surface_pen.inc_y();
+ }
+ if (y2e!=0) // maybe draw bottom pixel
+ {
+ surface_pen.set_alpha(y2e*(x2f-x1f));
+ surface_pen.put_value(color);
+ }
+ }
+ }
+ else
+ {
+ // case 3 - a single horizontal row of pixels
+ if(y2<y1)
+ {
+ surface_pen.move_to(x1-1,y2);
+ if (x1e!=0) // maybe draw left pixel
+ {
+ surface_pen.set_alpha(x1e*(y2f-y1f));
+ surface_pen.put_value(color);
+ }
+ surface_pen.inc_x();
+ surface_pen.set_alpha(y2f-y1f);
+ for(int i=x1; i<x2; i++) // maybe draw pixels between
+ {
+ surface_pen.put_value(color);
+ surface_pen.inc_x();
+ }
+ if (x2e!=0) // maybe draw right pixel
+ {
+ surface_pen.set_alpha(x2e*(y2f-y1f));
+ surface_pen.put_value(color);
+ }
+ }
+ // case 4 - a proper block of pixels
+ else
+ {
+ if (x1e!=0) // maybe draw left edge
+ {
+ surface_pen.move_to(x1-1,y1-1);
+ if (y1e!=0) // maybe draw top left pixel
+ {
+ surface_pen.set_alpha(x1e*y1e);
+ surface_pen.put_value(color);
+ }
+ surface_pen.inc_y();
+ surface_pen.set_alpha(x1e);
+ for(int i=y1; i<y2; i++) // maybe draw pixels along the left edge
+ {
+ surface_pen.put_value(color);
+ surface_pen.inc_y();
+ }
+ if (y2e!=0) // maybe draw bottom left pixel
+ {
+ surface_pen.set_alpha(x1e*y2e);
+ surface_pen.put_value(color);
+ }
+ surface_pen.inc_x();
+ }
+ else
+ surface_pen.move_to(x1,y2);
+
+ if (y2e!=0) // maybe draw bottom edge
+ {
+ surface_pen.set_alpha(y2e);
+ for(int i=x1; i<x2; i++) // maybe draw pixels along the bottom edge
+ {
+ surface_pen.put_value(color);
+ surface_pen.inc_x();
+ }
+ if (x2e!=0) // maybe draw bottom right pixel
+ {
+ surface_pen.set_alpha(x2e*y2e);
+ surface_pen.put_value(color);
+ }
+ surface_pen.dec_y();
+ }
+ else
+ surface_pen.move_to(x2,y2-1);
+
+ if (x2e!=0) // maybe draw right edge
+ {
+ surface_pen.set_alpha(x2e);
+ for(int i=y1; i<y2; i++) // maybe draw pixels along the right edge
+ {
+ surface_pen.put_value(color);
+ surface_pen.dec_y();
+ }
+ if (y1e!=0) // maybe draw top right pixel
+ {
+ surface_pen.set_alpha(x2e*y1e);
+ surface_pen.put_value(color);
+ }
+ surface_pen.dec_x();
+ }
+ else
+ surface_pen.move_to(x2-1,y1-1);
+
+ if (y1e!=0) // maybe draw top edge
+ {
+ surface_pen.set_alpha(y1e);
+ for(int i=x1; i<x2; i++) // maybe draw pixels along the top edge
+ {
+ surface_pen.put_value(color);
+ surface_pen.dec_x();
+ }
+ }
+ }
+ }