| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
/*  | 
 | 
 * @author Charlton Innovations, Inc.  | 
 | 
 */  | 
 | 
 | 
 | 
package sun.java2d.loops;  | 
 | 
 | 
 | 
import java.awt.image.BufferedImage;  | 
 | 
import java.awt.AlphaComposite;  | 
 | 
import java.awt.Rectangle;  | 
 | 
import sun.awt.image.BufImgSurfaceData;  | 
 | 
import sun.java2d.SurfaceData;  | 
 | 
import sun.java2d.pipe.Region;  | 
 | 
import java.lang.reflect.Field;  | 
 | 
import java.util.StringTokenizer;  | 
 | 
import java.util.Iterator;  | 
 | 
import java.util.HashMap;  | 
 | 
import java.util.Map;  | 
 | 
import java.io.PrintStream;  | 
 | 
import java.io.OutputStream;  | 
 | 
import java.io.FileOutputStream;  | 
 | 
import java.io.FileNotFoundException;  | 
 | 
import java.security.AccessController;  | 
 | 
import java.security.PrivilegedAction;  | 
 | 
import sun.security.action.GetPropertyAction;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public abstract class GraphicsPrimitive { | 
 | 
 | 
 | 
    protected static interface GeneralBinaryOp { | 
 | 
          | 
 | 
 | 
 | 
 | 
 | 
         */  | 
 | 
        public void setPrimitives(Blit srcconverter,  | 
 | 
                                  Blit dstconverter,  | 
 | 
                                  GraphicsPrimitive genericop,  | 
 | 
                                  Blit resconverter);  | 
 | 
 | 
 | 
          | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
         */  | 
 | 
        public SurfaceType getSourceType();  | 
 | 
        public CompositeType getCompositeType();  | 
 | 
        public SurfaceType getDestType();  | 
 | 
        public String getSignature();  | 
 | 
        public int getPrimTypeID();  | 
 | 
    }  | 
 | 
 | 
 | 
    protected static interface GeneralUnaryOp { | 
 | 
          | 
 | 
 | 
 | 
 | 
 | 
         */  | 
 | 
        public void setPrimitives(Blit dstconverter,  | 
 | 
                                  GraphicsPrimitive genericop,  | 
 | 
                                  Blit resconverter);  | 
 | 
 | 
 | 
          | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
         */  | 
 | 
        public CompositeType getCompositeType();  | 
 | 
        public SurfaceType getDestType();  | 
 | 
        public String getSignature();  | 
 | 
        public int getPrimTypeID();  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
    *  INSTANCE DATA MEMBERS DESCRIBING CHARACTERISTICS OF THIS PRIMITIVE  | 
 | 
    **/  | 
 | 
 | 
 | 
    // Making these be instance data members (instead of virtual methods  | 
 | 
    // overridden by subclasses) is actually cheaper, since each class  | 
 | 
    // is a singleton.  As instance data members with final accessors,  | 
 | 
      | 
 | 
    private String methodSignature;  | 
 | 
    private int uniqueID;  | 
 | 
    private static int unusedPrimID = 1;  | 
 | 
 | 
 | 
    private SurfaceType sourceType;  | 
 | 
    private CompositeType compositeType;  | 
 | 
    private SurfaceType destType;  | 
 | 
 | 
 | 
    private long pNativePrim;     | 
 | 
 | 
 | 
    public synchronized static final int makePrimTypeID() { | 
 | 
        if (unusedPrimID > 255) { | 
 | 
            throw new InternalError("primitive id overflow"); | 
 | 
        }  | 
 | 
        return unusedPrimID++;  | 
 | 
    }  | 
 | 
 | 
 | 
    public synchronized static final int makeUniqueID(int primTypeID,  | 
 | 
                                                      SurfaceType src,  | 
 | 
                                                      CompositeType cmp,  | 
 | 
                                                      SurfaceType dst)  | 
 | 
    { | 
 | 
        return (primTypeID << 24) |  | 
 | 
            (dst.getUniqueID() << 16) |  | 
 | 
            (cmp.getUniqueID() << 8)  |  | 
 | 
            (src.getUniqueID());  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    protected GraphicsPrimitive(String methodSignature,  | 
 | 
                                int primTypeID,  | 
 | 
                                SurfaceType sourceType,  | 
 | 
                                CompositeType compositeType,  | 
 | 
                                SurfaceType destType)  | 
 | 
    { | 
 | 
        this.methodSignature = methodSignature;  | 
 | 
        this.sourceType = sourceType;  | 
 | 
        this.compositeType = compositeType;  | 
 | 
        this.destType = destType;  | 
 | 
 | 
 | 
        if(sourceType == null || compositeType == null || destType == null) { | 
 | 
            this.uniqueID = primTypeID << 24;  | 
 | 
        } else { | 
 | 
            this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,  | 
 | 
                                                           sourceType,  | 
 | 
                                                           compositeType,  | 
 | 
                                                           destType);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    protected GraphicsPrimitive(long pNativePrim,  | 
 | 
                                String methodSignature,  | 
 | 
                                int primTypeID,  | 
 | 
                                SurfaceType sourceType,  | 
 | 
                                CompositeType compositeType,  | 
 | 
                                SurfaceType destType)  | 
 | 
    { | 
 | 
        this.pNativePrim = pNativePrim;  | 
 | 
        this.methodSignature = methodSignature;  | 
 | 
        this.sourceType = sourceType;  | 
 | 
        this.compositeType = compositeType;  | 
 | 
        this.destType = destType;  | 
 | 
 | 
 | 
        if(sourceType == null || compositeType == null || destType == null) { | 
 | 
            this.uniqueID = primTypeID << 24;  | 
 | 
        } else { | 
 | 
            this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,  | 
 | 
                                                           sourceType,  | 
 | 
                                                           compositeType,  | 
 | 
                                                           destType);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
    *   METHODS TO DESCRIBE THE SURFACES PRIMITIVES  | 
 | 
    *   CAN OPERATE ON AND THE FUNCTIONALITY THEY IMPLEMENT  | 
 | 
    **/  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final int getUniqueID() { | 
 | 
        return uniqueID;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
     */  | 
 | 
    public final String getSignature() { | 
 | 
        return methodSignature;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final int getPrimTypeID() { | 
 | 
        return uniqueID >>> 24;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
     */  | 
 | 
    public final long getNativePrim() { | 
 | 
        return pNativePrim;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
     */  | 
 | 
    public final SurfaceType getSourceType() { | 
 | 
        return sourceType;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
     */  | 
 | 
    public final CompositeType getCompositeType() { | 
 | 
        return compositeType;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
     */  | 
 | 
    public final SurfaceType getDestType() { | 
 | 
        return destType;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean satisfies(String signature,  | 
 | 
                                   SurfaceType srctype,  | 
 | 
                                   CompositeType comptype,  | 
 | 
                                   SurfaceType dsttype)  | 
 | 
    { | 
 | 
        if (signature != methodSignature) { | 
 | 
            return false;  | 
 | 
        }  | 
 | 
        while (true) { | 
 | 
            if (srctype == null) { | 
 | 
                return false;  | 
 | 
            }  | 
 | 
            if (srctype.equals(sourceType)) { | 
 | 
                break;  | 
 | 
            }  | 
 | 
            srctype = srctype.getSuperType();  | 
 | 
        }  | 
 | 
        while (true) { | 
 | 
            if (comptype == null) { | 
 | 
                return false;  | 
 | 
            }  | 
 | 
            if (comptype.equals(compositeType)) { | 
 | 
                break;  | 
 | 
            }  | 
 | 
            comptype = comptype.getSuperType();  | 
 | 
        }  | 
 | 
        while (true) { | 
 | 
            if (dsttype == null) { | 
 | 
                return false;  | 
 | 
            }  | 
 | 
            if (dsttype.equals(destType)) { | 
 | 
                break;  | 
 | 
            }  | 
 | 
            dsttype = dsttype.getSuperType();  | 
 | 
        }  | 
 | 
        return true;  | 
 | 
    }  | 
 | 
 | 
 | 
    //  | 
 | 
    // A version of satisfies used for regression testing  | 
 | 
      | 
 | 
    final boolean satisfiesSameAs(GraphicsPrimitive other) { | 
 | 
        return (methodSignature == other.methodSignature &&  | 
 | 
                sourceType.equals(other.sourceType) &&  | 
 | 
                compositeType.equals(other.compositeType) &&  | 
 | 
                destType.equals(other.destType));  | 
 | 
    }  | 
 | 
 | 
 | 
    public abstract GraphicsPrimitive makePrimitive(SurfaceType srctype,  | 
 | 
                                                    CompositeType comptype,  | 
 | 
                                                    SurfaceType dsttype);  | 
 | 
 | 
 | 
    public abstract GraphicsPrimitive traceWrap();  | 
 | 
 | 
 | 
    static HashMap traceMap;  | 
 | 
 | 
 | 
    public static int traceflags;  | 
 | 
    public static String tracefile;  | 
 | 
    public static PrintStream traceout;  | 
 | 
 | 
 | 
    public static final int TRACELOG = 1;  | 
 | 
    public static final int TRACETIMESTAMP = 2;  | 
 | 
    public static final int TRACECOUNTS = 4;  | 
 | 
 | 
 | 
    static { | 
 | 
        GetPropertyAction gpa = new GetPropertyAction("sun.java2d.trace"); | 
 | 
        String trace = AccessController.doPrivileged(gpa);  | 
 | 
        if (trace != null) { | 
 | 
            boolean verbose = false;  | 
 | 
            int traceflags = 0;  | 
 | 
            StringTokenizer st = new StringTokenizer(trace, ",");  | 
 | 
            while (st.hasMoreTokens()) { | 
 | 
                String tok = st.nextToken();  | 
 | 
                if (tok.equalsIgnoreCase("count")) { | 
 | 
                    traceflags |= GraphicsPrimitive.TRACECOUNTS;  | 
 | 
                } else if (tok.equalsIgnoreCase("log")) { | 
 | 
                    traceflags |= GraphicsPrimitive.TRACELOG;  | 
 | 
                } else if (tok.equalsIgnoreCase("timestamp")) { | 
 | 
                    traceflags |= GraphicsPrimitive.TRACETIMESTAMP;  | 
 | 
                } else if (tok.equalsIgnoreCase("verbose")) { | 
 | 
                    verbose = true;  | 
 | 
                } else if (tok.regionMatches(true, 0, "out:", 0, 4)) { | 
 | 
                    tracefile = tok.substring(4);  | 
 | 
                } else { | 
 | 
                    if (!tok.equalsIgnoreCase("help")) { | 
 | 
                        System.err.println("unrecognized token: "+tok); | 
 | 
                    }  | 
 | 
                    System.err.println("usage: -Dsun.java2d.trace="+ | 
 | 
                                       "[log[,timestamp]],[count],"+  | 
 | 
                                       "[out:<filename>],[help],[verbose]");  | 
 | 
                }  | 
 | 
            }  | 
 | 
            if (verbose) { | 
 | 
                System.err.print("GraphicsPrimitive logging "); | 
 | 
                if ((traceflags & GraphicsPrimitive.TRACELOG) != 0) { | 
 | 
                    System.err.println("enabled"); | 
 | 
                    System.err.print("GraphicsPrimitive timetamps "); | 
 | 
                    if ((traceflags & GraphicsPrimitive.TRACETIMESTAMP) != 0) { | 
 | 
                        System.err.println("enabled"); | 
 | 
                    } else { | 
 | 
                        System.err.println("disabled"); | 
 | 
                    }  | 
 | 
                } else { | 
 | 
                    System.err.println("[and timestamps] disabled"); | 
 | 
                }  | 
 | 
                System.err.print("GraphicsPrimitive invocation counts "); | 
 | 
                if ((traceflags & GraphicsPrimitive.TRACECOUNTS) != 0) { | 
 | 
                    System.err.println("enabled"); | 
 | 
                } else { | 
 | 
                    System.err.println("disabled"); | 
 | 
                }  | 
 | 
                System.err.print("GraphicsPrimitive trace output to "); | 
 | 
                if (tracefile == null) { | 
 | 
                    System.err.println("System.err"); | 
 | 
                } else { | 
 | 
                    System.err.println("file '"+tracefile+"'"); | 
 | 
                }  | 
 | 
            }  | 
 | 
            GraphicsPrimitive.traceflags = traceflags;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public static boolean tracingEnabled() { | 
 | 
        return (traceflags != 0);  | 
 | 
    }  | 
 | 
 | 
 | 
    private static PrintStream getTraceOutputFile() { | 
 | 
        if (traceout == null) { | 
 | 
            if (tracefile != null) { | 
 | 
                FileOutputStream o = AccessController.doPrivileged(  | 
 | 
                    new PrivilegedAction<FileOutputStream>() { | 
 | 
                        public FileOutputStream run() { | 
 | 
                            try { | 
 | 
                                return new FileOutputStream(tracefile);  | 
 | 
                            } catch (FileNotFoundException e) { | 
 | 
                                return null;  | 
 | 
                            }  | 
 | 
                        }  | 
 | 
                    });  | 
 | 
                if (o != null) { | 
 | 
                    traceout = new PrintStream(o);  | 
 | 
                } else { | 
 | 
                    traceout = System.err;  | 
 | 
                }  | 
 | 
            } else { | 
 | 
                traceout = System.err;  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return traceout;  | 
 | 
    }  | 
 | 
 | 
 | 
    public static class TraceReporter extends Thread { | 
 | 
        public static void setShutdownHook() { | 
 | 
            AccessController.doPrivileged(new PrivilegedAction<Void>() { | 
 | 
                public Void run() { | 
 | 
                    TraceReporter t = new TraceReporter();  | 
 | 
                    t.setContextClassLoader(null);  | 
 | 
                    Runtime.getRuntime().addShutdownHook(t);  | 
 | 
                    return null;  | 
 | 
                }  | 
 | 
            });  | 
 | 
        }  | 
 | 
 | 
 | 
        public void run() { | 
 | 
            PrintStream ps = getTraceOutputFile();  | 
 | 
            Iterator iterator = traceMap.entrySet().iterator();  | 
 | 
            long total = 0;  | 
 | 
            int numprims = 0;  | 
 | 
            while (iterator.hasNext()) { | 
 | 
                Map.Entry me = (Map.Entry) iterator.next();  | 
 | 
                Object prim = me.getKey();  | 
 | 
                int[] count = (int[]) me.getValue();  | 
 | 
                if (count[0] == 1) { | 
 | 
                    ps.print("1 call to "); | 
 | 
                } else { | 
 | 
                    ps.print(count[0]+" calls to ");  | 
 | 
                }  | 
 | 
                ps.println(prim);  | 
 | 
                numprims++;  | 
 | 
                total += count[0];  | 
 | 
            }  | 
 | 
            if (numprims == 0) { | 
 | 
                ps.println("No graphics primitives executed"); | 
 | 
            } else if (numprims > 1) { | 
 | 
                ps.println(total+" total calls to "+  | 
 | 
                           numprims+" different primitives");  | 
 | 
            }  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public synchronized static void tracePrimitive(Object prim) { | 
 | 
        if ((traceflags & TRACECOUNTS) != 0) { | 
 | 
            if (traceMap == null) { | 
 | 
                traceMap = new HashMap();  | 
 | 
                TraceReporter.setShutdownHook();  | 
 | 
            }  | 
 | 
            Object o = traceMap.get(prim);  | 
 | 
            if (o == null) { | 
 | 
                o = new int[1];  | 
 | 
                traceMap.put(prim, o);  | 
 | 
            }  | 
 | 
            ((int[]) o)[0]++;  | 
 | 
        }  | 
 | 
        if ((traceflags & TRACELOG) != 0) { | 
 | 
            PrintStream ps = getTraceOutputFile();  | 
 | 
            if ((traceflags & TRACETIMESTAMP) != 0) { | 
 | 
                ps.print(System.currentTimeMillis()+": ");  | 
 | 
            }  | 
 | 
            ps.println(prim);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    protected void setupGeneralBinaryOp(GeneralBinaryOp gbo) { | 
 | 
        int primID = gbo.getPrimTypeID();  | 
 | 
        String methodSignature = gbo.getSignature();  | 
 | 
        SurfaceType srctype = gbo.getSourceType();  | 
 | 
        CompositeType comptype = gbo.getCompositeType();  | 
 | 
        SurfaceType dsttype = gbo.getDestType();  | 
 | 
        Blit convertsrc, convertdst, convertres;  | 
 | 
        GraphicsPrimitive performop;  | 
 | 
 | 
 | 
        convertsrc = createConverter(srctype, SurfaceType.IntArgb);  | 
 | 
        performop = GraphicsPrimitiveMgr.locatePrim(primID,  | 
 | 
                                                    SurfaceType.IntArgb,  | 
 | 
                                                    comptype, dsttype);  | 
 | 
        if (performop != null) { | 
 | 
            convertdst = null;  | 
 | 
            convertres = null;  | 
 | 
        } else { | 
 | 
            performop = getGeneralOp(primID, comptype);  | 
 | 
            if (performop == null) { | 
 | 
                throw new InternalError("Cannot construct general op for "+ | 
 | 
                                        methodSignature+" "+comptype);  | 
 | 
            }  | 
 | 
            convertdst = createConverter(dsttype, SurfaceType.IntArgb);  | 
 | 
            convertres = createConverter(SurfaceType.IntArgb, dsttype);  | 
 | 
        }  | 
 | 
 | 
 | 
        gbo.setPrimitives(convertsrc, convertdst, performop, convertres);  | 
 | 
    }  | 
 | 
 | 
 | 
    protected void setupGeneralUnaryOp(GeneralUnaryOp guo) { | 
 | 
        int primID = guo.getPrimTypeID();  | 
 | 
        String methodSignature = guo.getSignature();  | 
 | 
        CompositeType comptype = guo.getCompositeType();  | 
 | 
        SurfaceType dsttype = guo.getDestType();  | 
 | 
 | 
 | 
        Blit convertdst = createConverter(dsttype, SurfaceType.IntArgb);  | 
 | 
        GraphicsPrimitive performop = getGeneralOp(primID, comptype);  | 
 | 
        Blit convertres = createConverter(SurfaceType.IntArgb, dsttype);  | 
 | 
        if (convertdst == null || performop == null || convertres == null) { | 
 | 
            throw new InternalError("Cannot construct binary op for "+ | 
 | 
                                    comptype+" "+dsttype);  | 
 | 
        }  | 
 | 
 | 
 | 
        guo.setPrimitives(convertdst, performop, convertres);  | 
 | 
    }  | 
 | 
 | 
 | 
    protected static Blit createConverter(SurfaceType srctype,  | 
 | 
                                          SurfaceType dsttype)  | 
 | 
    { | 
 | 
        if (srctype.equals(dsttype)) { | 
 | 
            return null;  | 
 | 
        }  | 
 | 
        Blit cv = Blit.getFromCache(srctype, CompositeType.SrcNoEa, dsttype);  | 
 | 
        if (cv == null) { | 
 | 
            throw new InternalError("Cannot construct converter for "+ | 
 | 
                                    srctype+"=>"+dsttype);  | 
 | 
        }  | 
 | 
        return cv;  | 
 | 
    }  | 
 | 
 | 
 | 
    protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,  | 
 | 
                                             int srcX, int srcY, int w, int h,  | 
 | 
                                             SurfaceData dstData)  | 
 | 
    { | 
 | 
        return convertFrom(ob, srcData,  | 
 | 
                           srcX, srcY, w, h, dstData,  | 
 | 
                           BufferedImage.TYPE_INT_ARGB);  | 
 | 
    }  | 
 | 
 | 
 | 
    protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,  | 
 | 
                                             int srcX, int srcY, int w, int h,  | 
 | 
                                             SurfaceData dstData, int type)  | 
 | 
    { | 
 | 
        if (dstData != null) { | 
 | 
            Rectangle r = dstData.getBounds();  | 
 | 
            if (w > r.width || h > r.height) { | 
 | 
                dstData = null;  | 
 | 
            }  | 
 | 
        }  | 
 | 
        if (dstData == null) { | 
 | 
            BufferedImage dstBI = new BufferedImage(w, h, type);  | 
 | 
            dstData = BufImgSurfaceData.createData(dstBI);  | 
 | 
        }  | 
 | 
        ob.Blit(srcData, dstData, AlphaComposite.Src, null,  | 
 | 
                srcX, srcY, 0, 0, w, h);  | 
 | 
        return dstData;  | 
 | 
    }  | 
 | 
 | 
 | 
    protected static void convertTo(Blit ob,  | 
 | 
                                    SurfaceData srcImg, SurfaceData dstImg,  | 
 | 
                                    Region clip,  | 
 | 
                                    int dstX, int dstY, int w, int h)  | 
 | 
    { | 
 | 
        if (ob != null) { | 
 | 
            ob.Blit(srcImg, dstImg, AlphaComposite.Src, clip,  | 
 | 
                    0, 0, dstX, dstY, w, h);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    protected static GraphicsPrimitive getGeneralOp(int primID,  | 
 | 
                                                    CompositeType comptype)  | 
 | 
    { | 
 | 
        return GraphicsPrimitiveMgr.locatePrim(primID,  | 
 | 
                                               SurfaceType.IntArgb,  | 
 | 
                                               comptype,  | 
 | 
                                               SurfaceType.IntArgb);  | 
 | 
    }  | 
 | 
 | 
 | 
    public static String simplename(Field[] fields, Object o) { | 
 | 
        for (int i = 0; i < fields.length; i++) { | 
 | 
            Field f = fields[i];  | 
 | 
            try { | 
 | 
                if (o == f.get(null)) { | 
 | 
                    return f.getName();  | 
 | 
                }  | 
 | 
            } catch (Exception e) { | 
 | 
            }  | 
 | 
        }  | 
 | 
        return "\""+o.toString()+"\"";  | 
 | 
    }  | 
 | 
 | 
 | 
    public static String simplename(SurfaceType st) { | 
 | 
        return simplename(SurfaceType.class.getDeclaredFields(), st);  | 
 | 
    }  | 
 | 
 | 
 | 
    public static String simplename(CompositeType ct) { | 
 | 
        return simplename(CompositeType.class.getDeclaredFields(), ct);  | 
 | 
    }  | 
 | 
 | 
 | 
    private String cachedname;  | 
 | 
 | 
 | 
    public String toString() { | 
 | 
        if (cachedname == null) { | 
 | 
            String sig = methodSignature;  | 
 | 
            int index = sig.indexOf('('); | 
 | 
            if (index >= 0) { | 
 | 
                sig = sig.substring(0, index);  | 
 | 
            }  | 
 | 
            cachedname = (getClass().getName()+"::"+  | 
 | 
                          sig+"("+ | 
 | 
                          simplename(sourceType)+", "+  | 
 | 
                          simplename(compositeType)+", "+  | 
 | 
                          simplename(destType)+")");  | 
 | 
        }  | 
 | 
        return cachedname;  | 
 | 
    }  | 
 | 
}  |