Hi Graydon, you wrote on Tue, 2 Sep 2003 20:25:19 -0400:
> I recently posted some new files to the java-patches list of the gcj > project, containing the beginnings of my cairo java2d > implementation. I was wondering if anyone here had comments on the > work. >From a coarse view, I'd say your code looks really good. I've just a few remarks: (1) In GdkGraphics2D.walkPath(PathIterator), the treatment of quadratic splines is almost, but not entirely correct. The page http://pfaedit.sourceforge.net/bezier.html describes how to convert quadratic splines into cubic ones (they call them "TrueType" and "PostScript", respectively). In case you find this a useful reference, you might want to include a comment in the code that points to that page. (2) Strokes that are not a BasicStroke: The drawing methods could check whether the value of the stroke field is an instance of BasicStroke. If not, they would not directly call into Cairo. For example, GdkGraphics2D.draw(Shape) could look as follows: public void draw(Shape s) { if (!(stroke instanceof BasicStroke)) { fill(stroke.createStrokedShape(s)); return; } /* here comes your current implementation */ } Methods like GdkGraphics2D.drawRect(int, int, int, int) would need adjustments: public void drawRect(int x, int y, int width, int height) { if (!(stroke instanceof BasicStroke)) { draw(new Rectangle(x, y, width, height)); return; } /* here comes your current implementation */ } When GdkGraphics2D.setStroke(Stroke) gets passed a non-BasicStroke, it would just store the stroke without calling into Cairo. (3) When GdkGraphics2D.drawImage gets passed a BufferedImage, you now copy all pixels into a freshly allocated int[]. This has the advantage that it works for all pixel formats, but it is inefficient for large images. The problem is that copying pixel data is an expensive operation, which should be avoided whenever possible. To increase performance, you could check whether the image is in a format that is directly supported by Cairo, such as TYPE_INT_ARGB with an sRGB ColorSpace. If this is the case, you could retrieve the underlying DataBufferInt (via getRaster().getDataBuffer()) and directly pass its int[] to GdkGraphics2D.drawPixels. (4) Methods like GdkGraphics2D.drawRenderedImage can be implemented by fetching a Raster from the RenderedImage and proceeding as with BufferedImage. My proposal would be to define a private drawRaster method that gets called by the various public image drawing methods. (5) It might be worth extending the native method GdkGraphics2D.drawPixels to include an offset into the int[]. This might be useful for cases where pixel (0,0) is not at index 0 of the int[] that belongs to the DataBuffer. (6) You could further avoid copying pixel data by slightly changing the native implementation of GdkGraphics2D.drawPixels. Instead of GetIntArrayElements, I'd recommend using GetPrimitiveArrayCritical and ReleasePrimitiveArrayCritical. See http://java.sun.com/j2se/1.4.2/docs/guide/jni/jni- 12.html#GetPrimitiveArrayCritical (It depends on the JVM whether or not this makes a difference). Like the above, this is not a micro-optimization. It is likely to make a noticeable difference whether several megabytes of pixel data are accessed in place, or copied several times. (7) As of how to implement Font.getFamily(java.util.Locale) etc., (you have FIXMEs in that code), I've written some Java code for parsing the 'name' table of TrueType or OpenType fonts. Of course, you'll need a means to retrieve the contents of font tables -- but this is anyway a necessity for supporting java.awt.font.OpenType. See http://www.dandelis.ch/development/fonts/doc/. (It may be confusing that private classes/methods are also listed). Only one class is relevant here, namely gnu.java.awt.font.opentype.NameDecoder with the method public static String getName(java.nio.ByteBuffer nameTable, int name, java.util.Locale locale); For the "name" parameter, you'd pass e.g. NameDecoder.NAME_FAMILY. The NameDecoder is actually quite independent from the rest of my code, so you could use just that part. You would not have to include a large code base just for the font names. We could also put the name decoding into another package. (8) Maybe you could have a look at the interface which is described at http://www.dandelis.ch/development/fonts/doc/gnu/java/awt/font/ FontDelegate.html Maybe we can use an extended version of this interface for the FontPeers that you've proposed in your recent e-mail. (The getGlyphName method is not needed for Java2D, but it would be necessary if someone wanted to write a decent PostScript or PDF provider for javax.print.) Best regards, -- Sascha Sascha Brawer, [EMAIL PROTECTED], http://www.dandelis.ch/people/brawer/ _______________________________________________ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath

