? fp_supersample.diff
Index: app/core/gimpdrawable-transform.c
===================================================================
RCS file: /cvs/gnome/gimp/app/core/gimpdrawable-transform.c,v
retrieving revision 1.96.2.2
diff -u -r1.96.2.2 gimpdrawable-transform.c
--- app/core/gimpdrawable-transform.c	29 Jul 2004 11:31:16 -0000	1.96.2.2
+++ app/core/gimpdrawable-transform.c	29 Jul 2004 12:45:08 -0000
@@ -1261,6 +1261,64 @@
 }
 
 /*
+    bilinear interpolation of a double pixel
+*/
+static void
+sample_d_bi (TileManager *tm,
+           gdouble      x,
+           gdouble      y,
+           guchar      *color,
+           guchar      *bg_color,
+           gint         bpp,
+           gint         alpha)
+{
+  guchar C[4][4];
+  gint   i;
+  gdouble xscale, yscale;
+
+  xscale = x - floor(x);
+  yscale = y - floor(y);
+
+  /*  fill the color with default values, since read_pixel_data_1
+   *  does nothing, when accesses are out of bounds.
+   */
+  for (i = 0; i < 4; i++)
+    *(guint*) (&C[i]) = *(guint*) (bg_color);
+
+  read_pixel_data_1 (tm, x, y, C[0]);
+  read_pixel_data_1 (tm, x + 1, y, C[2]);
+  read_pixel_data_1 (tm, x, y + 1, C[1]);
+  read_pixel_data_1 (tm, x + 1, y + 1, C[3]);
+
+#define lerp(v1,v2,r) \
+        ((guint)(v1) * (1 - (guint)(r)) + (guint)(v2)*(guint)(r))
+
+  color[alpha]= lerp (lerp (C[0][alpha], C[1][alpha], yscale),
+                      lerp (C[2][alpha], C[3][alpha], yscale), xscale);
+
+  if (color[alpha])
+    { /* to avoid problems, calculate with premultiplied alpha */
+      for (i=0; i<alpha; i++)
+        {
+          C[0][i] = (C[0][i] * C[0][alpha] / 255);
+          C[1][i] = (C[1][i] * C[1][alpha] / 255);
+          C[2][i] = (C[2][i] * C[2][alpha] / 255);
+          C[3][i] = (C[3][i] * C[3][alpha] / 255);
+        }
+
+      for (i = 0; i < alpha; i++)
+        color[i] = lerp (lerp (C[0][i], C[1][i], yscale),
+                         lerp (C[2][i], C[3][i], yscale), xscale);
+    }
+  else
+    {
+      for (i = 0; i < alpha; i++)
+        color[i] = 0;
+    }
+#undef lerp
+}
+
+/*
  * Returns TRUE if one of the deltas of the
  * quad edge is > 1.0 (16.16 fixed values).
  */
@@ -1386,6 +1444,86 @@
     }
 }
 
+/*
+    Same function as get_sample above, but using doubles rather than 16.16
+    integer arithmetic. Slower, but should only be used in marginal cases.
+    That said, this is probably where speed is most needed.
+*/
+static void
+get_dsample (TileManager *tm,
+            gdouble      xc,  gdouble yc,
+            gdouble      x0,  gdouble y0,
+            gdouble      x1,  gdouble y1,
+            gdouble      x2,  gdouble y2,
+            gdouble      x3,  gdouble y3,
+            gint        *cc,
+            gint         level,
+            guint       *color,
+            guchar      *bg_color,
+            gint         bpp,
+            gint         alpha)
+{
+  if (!level || !supersample_dtest (x0, y0, x1, y1, x2, y2, x3, y3))
+    {
+      gint   i;
+      guchar C[4];
+
+      sample_d_bi (tm, xc, yc, C, bg_color, bpp, alpha);
+
+      for (i = 0; i < bpp; i++)
+        color[i]+= C[i];
+
+      (*cc)++;  /* increase number of samples taken */
+    }
+  else
+    {
+      gdouble tx, lx, rx, bx, tlx, trx, blx, brx;
+      gdouble ty, ly, ry, by, tly, try, bly, bry;
+
+      /* calculate subdivided corner coordinates (including centercoords
+         thus using a bilinear interpolation,. almost as good as
+         doing the perspective transform for each subpixel coordinate*/
+
+      tx  = x0 / 2 + x1 / 2;
+      tlx = x0 / 2 + xc / 2;
+      trx = x1 / 2 + xc / 2;
+      lx  = x0 / 2 + x3 / 2;
+      rx  = x1 / 2 + x2 / 2;
+      blx = x3 / 2 + xc / 2;
+      brx = x2 / 2 + xc / 2;
+      bx  = x3 / 2 + x2 / 2;
+
+      ty  = y0 / 2 + y1 / 2;
+      tly = y0 / 2 + yc / 2;
+      try = y1 / 2 + yc / 2;
+      ly  = y0 / 2 + y3 / 2;
+      ry  = y1 / 2 + y2 / 2;
+      bly = y3 / 2 + yc / 2;
+      bry = y2 / 2 + yc / 2;
+      by  = y3 / 2 + y2 / 2;
+
+      get_dsample (tm,
+                  tlx,tly,
+                  x0,y0, tx,ty, xc,yc, lx,ly,
+                  cc, level-1, color, bg_color, bpp, alpha);
+
+      get_dsample (tm,
+                  trx,try,
+                  tx,ty, x1,y1, rx,ry, xc,yc,
+                  cc, level-1, color, bg_color, bpp, alpha);
+
+      get_dsample (tm,
+                  brx,bry,
+                  xc,yc, rx,ry, x2,y2, bx,by,
+                  cc, level-1, color, bg_color, bpp, alpha);
+
+      get_dsample (tm,
+                  blx,bly,
+                  lx,ly, xc,yc, bx,by, x3,y3,
+                  cc, level-1, color, bg_color, bpp, alpha);
+    }
+}
+
 static void
 sample_adapt (TileManager *tm,
               gdouble     xc,  gdouble yc,
@@ -1405,13 +1543,34 @@
 
     C[0] = C[1] = C[2] = C[3] = 0;
 
-    get_sample (tm,
-                xc * 65535, yc * 65535,
-                x0 * 65535, y0 * 65535,
-                x1 * 65535, y1 * 65535,
-                x2 * 65535, y2 * 65535,
-                x3 * 65535, y3 * 65535,
-                &cc, level, C, bg_color, bpp, alpha);
+#define POW_2_16 65536
+#define POW_2_15 32768
+
+    if (xc < POW_2_15 &&
+        yc < POW_2_15 &&
+        x0 < POW_2_15 &&
+        y0 < POW_2_15 &&
+        x1 < POW_2_15 &&
+        y1 < POW_2_15 &&
+        x2 < POW_2_15 &&
+        y2 < POW_2_15 &&
+        x3 < POW_2_15 &&
+        y3 < POW_2_15 )
+      get_sample (tm,
+                  xc * (POW_2_16 - 1), yc * (POW_2_16 - 1),
+                  x0 * (POW_2_16 - 1), y0 * (POW_2_16 - 1),
+                  x1 * (POW_2_16 - 1), y1 * (POW_2_16 - 1),
+                  x2 * (POW_2_16 - 1), y2 * (POW_2_16 - 1),
+                  x3 * (POW_2_16 - 1), y3 * (POW_2_16 - 1),
+                  &cc, level, C, bg_color, bpp, alpha);
+    else
+      /* Handle the case where converting to int would overflow
+       * by staying in floating-point */
+      get_dsample (tm, xc, yc, x0, y0, x1, y1, x2, y2,
+                  x3, y3, &cc, level, C, bg_color, bpp, alpha);
+
+#undef POW_2_16
+#undef POW_2_15
 
     if (!cc)
       cc=1;
Index: po/Makefile.in.in
===================================================================
RCS file: /cvs/gnome/gimp/po/Makefile.in.in,v
retrieving revision 1.28
diff -u -r1.28 Makefile.in.in
--- po/Makefile.in.in	17 Oct 2003 12:21:56 -0000	1.28
+++ po/Makefile.in.in	29 Jul 2004 12:45:20 -0000
@@ -75,7 +75,7 @@
 
 .po.pox:
 	$(MAKE) $(GETTEXT_PACKAGE).pot
-	$(MSGMERGE) $< $(srcdir)/$(GETTEXT_PACKAGE).pot -o $*pox
+	$(MSGMERGE) $< $(srcdir)/$(GETTEXT_PACKAGE).pot -o $*.pox
 
 .po.mo:
 	$(MSGFMT) -o $@ $<
@@ -179,7 +179,6 @@
 mostlyclean:
 	rm -f core core.* *.pox $(GETTEXT_PACKAGE).po *.old.po cat-id-tbl.tmp
 	rm -fr *.o
-	rm -f .intltool-merge-cache
 
 clean: mostlyclean
 
@@ -208,7 +207,7 @@
 	  cat=`basename $$cat`; \
 	  lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
 	  echo "$$lang:"; \
-	  if $$tmpdir/$(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist -o $$tmpdir/$$lang.new.po $$lang; then \
+	  if $(MSGMERGE) $$lang.po $(GETTEXT_PACKAGE).pot -o $$tmpdir/$$lang.new.po; then \
 	    if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
 	      rm -f $$tmpdir/$$lang.new.po; \
             else \
@@ -225,6 +224,19 @@
 	    rm -f $$tmpdir/$$lang.new.po; \
 	  fi; \
 	done
+
+.po: Makefile
+	$(MAKE)  $(PACKAGE).pot;
+	PATH=`pwd`/../src:$$PATH; \
+	echo; printf "$*: "; \
+	if $(MSGMERGE) $*; then \
+	  rm -f $*.old.po; \
+	  else \
+	    echo "msgmerge for * failed!"; \
+	    mv $*.old.po $*.po; \
+	fi; \
+	msgfmt --statistics $*.po; echo;
+
 
 # POTFILES is created from POTFILES.in by stripping comments, empty lines
 # and Intltool tags (enclosed in square brackets), and appending a full
