// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
package org.xwt.plat;
-import java.awt.*;
-import java.awt.image.*;
import gnu.gcj.RawData;
import java.net.*;
import java.lang.reflect.*;
import java.io.*;
import java.util.*;
-import java.awt.peer.*;
import org.xwt.util.*;
import org.xwt.*;
/** Platform implementation for Carbon UI on a POSIX-compliant OS (ie Mac OS X) */
public class Carbon extends POSIX {
+ /** hashtable of all OS X fonts; key is an XWT font name, value is WrappedRawData which stores an ATSFontRef.
+ * Initialized by natInit(). */
+ static Hashtable nativeFontCache = new Hashtable();
+
+ /** Cache of ATSUStyle objects; key is an XWT font spec, value is WrappedRawData which stores an ATSUStyle.
+ * According to an Apple technote, caching the style bjects can really increase performance. */
+ static Hashtable atsuStyleCache = new Hashtable();
+
+ /** List of all XWT font specs. Initialized by init(). */
+ static String[] fontList = null;
+
// General Methods ///////////////////////////////////////////////////////
protected String _getAltKeyName() { return "option"; }
- protected String[] _listFonts() { throw new Error("FIXME"); }
+ protected String[] _listFonts() { return fontList; }
protected Picture _createPicture(int[] data, int w, int h) { return new CarbonPicture(data, w, h); }
protected DoubleBuffer _createDoubleBuffer(int w, int h, Surface owner) { return new CarbonDoubleBuffer(w, h); }
protected Surface _createSurface(Box b, boolean framed) { return new CarbonSurface(b, framed); }
- protected boolean _needsAutoClick() { throw new Error("FIXME"); }
+ protected boolean _needsAutoClick() { return false; }
protected native int _getScreenWidth();
protected native int _getScreenHeight();
protected native String _getClipBoard();
protected native void _setClipBoard(String s);
- protected native int _stringWidth(String font, String text);
+ static String defaultFontName = "lucida_grande";
+ protected String _getDefaultFont() { return defaultFontName + "13"; }
+ protected native int _stringWidth(String fontSpec, String text);
protected native int _getMaxAscent(String font);
protected native int _getMaxDescent(String font);
- protected boolean _needsAutoDoubleClick() { throw new Error("FIXME"); }
+ protected boolean _needsAutoDoubleClick() { return false; }
+
+ /** Returns the ATSUStyle associated with the given XWT font spec.
+ * This method first checks its internal cache before creating the
+ * ATSUStyle object from scratch. */
+ protected RawData _getATSUStyle( String fontSpec ) {
+ WrappedRawData ret = null;
+ ret = (WrappedRawData) atsuStyleCache.get( fontSpec );
+ if (ret != null) return ret.wrapee;
+
+ Platform.ParsedFont pf = new Platform.ParsedFont( fontSpec );
+
+ // Find the font
+ if (pf.name.equals("serif")) pf.name = "lucida_grande";
+ else if (pf.name.equals("sansserif")) pf.name = "helvetica";
+ else if (pf.name.equals("monospace")) pf.name = "courier";
+ else if (pf.name.equals("dialog")) pf.name = "lucida_grande";
+ else if (pf.name.equals("tty")) pf.name = "courier";
+
+ // Find the ATSFontRef
+ WrappedRawData fontRef = (WrappedRawData) nativeFontCache.get( pf.name );
+ // If we couldn't find the font, use the default font
+ if ( fontRef == null ) fontRef = (WrappedRawData) nativeFontCache.get( defaultFontName );
+ if ( fontRef == null ) throw new Error( "Default font cannot be found" );
+
+ // Create the ATSUStyle object
+ ret = new WrappedRawData( _createATSUStyle( fontRef.wrapee, pf.size, pf.bold, pf.italic, pf.underline ) );
+
+ // Map this font spec to the ATSFontRef to optimize future requests
+ atsuStyleCache.put( fontSpec, ret );
+
+ return ret.wrapee;
+ }
+
+ /** Creates an ATSUStyle object with the specified attributes. */
+ protected native RawData _createATSUStyle( RawData fontRef, int fontSize, boolean isBold, boolean isItalic, boolean isUnderline );
+
+ /** Called once XWT is initialized and the application is running. On Mac OS X this calls
+ * RunApplicationEventLoop(). */
+ protected native void _running();
+
+ /** dumps a list of Mac OS X font strings. TODO: Will this be sufficient? */
+ //private native String[] listNativeFonts();
+ /** translates a font string into an ATSUFontRef? TODO: Will this be sufficient? */
+ //public static native gnu.gcj.RawData fontStringToStruct(String s);
public Carbon() { }
- public void init() { throw new Error("FIXME"); }
+ public void init() {
+ natInit();
+
+ // nativeFontCache contains font NAMES. Each font exists as an outline font
+ // which can be any size, plus can have real or simulated bold or italic
+ fontList = new String[nativeFontCache.size()*4];
+ Enumeration e = nativeFontCache.keys();
+ for(int i=0; e.hasMoreElements(); i+=4) {
+ String fontName = (String)e.nextElement() + "0";
+
+ fontList[i] = fontName;
+ fontList[i+1] = fontName + "i";
+ fontList[i+2] = fontName + "b";
+ fontList[i+3] = fontName + "bi";
+ }
+
+ // Make sure that the default font exists
+ if ( _getATSUStyle( _getDefaultFont() ) == null ) throw new Error( "Default font does not exist" );
+ }
+ private native void natInit();
+
+ /** so we can put ATSUStyles and ATSFontRefs into Hashtables */
+ private static class WrappedRawData {
+ public RawData wrapee = null;
+ public WrappedRawData(RawData r) { wrapee = r; }
+ }
// CarbonSurface /////////////////////////////////////////////////////
/** Implements a Surface as an Carbon Window */
public static class CarbonSurface extends Surface {
+
+ /** The WindowRef that implements this Surface. */
+ gnu.gcj.RawData window = null;
+ /** The CGContextRef. TODO: How do we get this??? */
+ gnu.gcj.RawData gc = null;
public native void setInvisible(boolean i);
public native void _setMaximized(boolean m);
public native void setTitleBarText(String s);
public native void setSize(int w, int h);
public native void setLocation(int x, int y);
- public native void natInit();
+ public native void natInit(boolean framed);
public native void toFront();
public native void toBack();
public native void syncCursor();
public native void _dispose();
- public native void setLimits(int minw, int minh, int maxw, int maxh);
+ //public native void setLimits(int minw, int minh, int maxw, int maxh);
public native void blit(DoubleBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
- public CarbonSurface(Box root, boolean framed) { super(root); throw new Error("FIXME"); }
+ public CarbonSurface(Box root, boolean framed) { super(root); natInit( framed ); }
}
/** Implements a Picture */
public static class CarbonPicture extends Picture {
-
int width;
int height;
int[] data = null;
+
+ /** A CGImageRef of the picture. */
+ RawData image = null;
+
public int getWidth() { return width; }
public int getHeight() { return height; }
+ public native void natInit();
+ public native void finalize();
+
public CarbonPicture(int[] data, int w, int h) {
this.data = data;
this.width = w;
this.height = h;
- throw new Error("FIXME");
+ natInit();
}
}
/** A Carbon DoubleBuffer */
public static class CarbonDoubleBuffer extends DoubleBuffer {
-
int width;
int height;
+
+ /** A pointer to the raw bitmap data. */
+ RawData bitmapData;
+ /** A CGBitmapContextRef. */
+ RawData gc;
+ /** A CGImageRef which represents the CGBitmapContext. */
+ RawData image;
+
public int getWidth() { return width; }
public int getHeight() { return height; }
- public CarbonDoubleBuffer(int w, int h) { this.width = w; this.height = h; throw new Error("FIXME"); }
- public void setClip(int x, int y, int x2, int y2) { throw new Error("FIXME"); }
- public void drawPicture(Picture source, int x, int y) { throw new Error("FIXME"); }
- public void drawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) { throw new Error("FIXME"); }
+ public CarbonDoubleBuffer(int w, int h) {
+ this.width = w;
+ this.height = h;
+ natInit();
+ }
+
+ public native void setClip(int x, int y, int x2, int y2);
+ public native void drawPicture(Picture source, int x, int y);
+ public native void drawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2);
public native void fillRect(int x, int y, int x2, int y2, int color);
public native void drawString(String font, String text, int x, int y, int color);
+ public native void natInit();
public native void finalize();
}