GdkGraphics2D.translate is written in ineffective "generic" way. The AffineTransform.translate could provide more optimal way of translation. The inverse transform of the clip also need not be computed in so sophisticated way. Translate seems frequent when painting swing components. The proposed patch rewrites GdkGraphics2D.translate and also adds the translation performance test to FillRect. With the translation test on, my computer gives about 210 ms for the current version of translate and about 130 ms for the rewritten version.

2006-05-29  Audrius Meskauskas  <[EMAIL PROTECTED]>

   * gnu/java/awt/peer/gtk/GdkGraphics2D.java (translate):
   Rewritten.
   * examples/gnu/classpath/examples/swing/FillRect.java (paintComponent):
   Optionally paint with translation. (createContent): Added option
   to test painting with translation.
Index: examples/gnu/classpath/examples/swing/FillRect.java
===================================================================
RCS file: /sources/classpath/classpath/examples/gnu/classpath/examples/swing/FillRect.java,v
retrieving revision 1.1
diff -u -r1.1 FillRect.java
--- examples/gnu/classpath/examples/swing/FillRect.java	25 May 2006 20:39:41 -0000	1.1
+++ examples/gnu/classpath/examples/swing/FillRect.java	29 May 2006 06:47:17 -0000
@@ -37,6 +37,7 @@
   LCDCanvas lcd;
   Worker worker;
   JLabel label;
+  JCheckBox translate;
 
   int     nx = 64;
   int     ny = 64;
@@ -48,6 +49,11 @@
   long    lastMillis = System.currentTimeMillis();
 
   boolean enableRepaints = true;
+  
+  /**
+   * If true, test translation.
+   */
+  boolean testTranslation = false;
 
   public void actionPerformed(ActionEvent e) 
   {
@@ -71,8 +77,22 @@
     lcd   = new LCDCanvas();
     label = new JLabel();
     label.setText("paintComponent took 00 msec. (00000 fillRect calls)");
+    
+    translate = new JCheckBox("translate");
+    translate.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent event)
+      {
+        testTranslation = translate.isSelected();
+      }
+    });
+    
+    JPanel bottom = new JPanel();
+    bottom.add(label);
+    bottom.add(translate);
+    
     p.add(lcd, BorderLayout.CENTER);
-    p.add(label, BorderLayout.SOUTH);
+    p.add(bottom, BorderLayout.SOUTH);
     add(p);
   }
 
@@ -123,6 +143,9 @@
       g.fillRect(0, 0, sx, sy);
 
       Color pixelColor = null;
+      
+      int dx, dy;
+      
       for (int ix = 0; ix < nx; ix++)
         {
           for (int iy = 0; iy < ny; iy++)
@@ -131,9 +154,19 @@
                 pixelColor = activePixel;
               else
                 pixelColor = passivePixel;
-
+               
+              dx = 4 * ix;
+              dy = 4 * iy;
               g.setColor(pixelColor);
-              g.fillRect(4 * ix, 4 * iy, 3, 3);
+              
+              if (testTranslation)
+                {
+                  g.translate(dx, dy);
+                  g.fillRect(0, 0, 3, 3);
+                  g.translate(-dx, -dy);
+                }
+              else
+                g.fillRect(dx, dy, 3, 3);
             }
         }
 
Index: gnu/java/awt/peer/gtk/GdkGraphics2D.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java,v
retrieving revision 1.56
diff -u -r1.56 GdkGraphics2D.java
--- gnu/java/awt/peer/gtk/GdkGraphics2D.java	25 May 2006 15:29:36 -0000	1.56
+++ gnu/java/awt/peer/gtk/GdkGraphics2D.java	29 May 2006 06:47:25 -0000
@@ -746,10 +746,35 @@
   {
     transform(AffineTransform.getScaleInstance(sx, sy));
   }
-
+  
+  /**
+   * Translate the system of the co-ordinates. As translation is a frequent
+   * operation, it is done in an optimised way, unlike scaling and rotating.
+   */
   public void translate(double tx, double ty)
   {
-    transform(AffineTransform.getTranslateInstance(tx, ty));
+    // 200 -> 140
+    if (transform != null)
+      transform.translate(tx, ty);
+    else
+      transform = AffineTransform.getTranslateInstance(tx, ty);
+
+    if (clip != null)
+      {
+        // FIXME: this should actuall try to transform the shape
+        // rather than degrade to bounds.
+        Rectangle2D r;
+
+        if (clip instanceof Rectangle2D)
+          r = (Rectangle2D) clip;
+        else
+          r = clip.getBounds2D();
+
+        r.setRect(r.getX() - tx, r.getY() - ty, r.getWidth(), r.getHeight());
+        clip = r;
+      }
+
+    setTransform(transform);
   }
 
   public void translate(int x, int y)

Reply via email to