330 lines · 12.3 KB · Java
RawDownload
/* * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @author Charlton Innovations, Inc. */ package sun.java2d.loops; import java.util.Comparator;import java.util.Arrays;import sun.java2d.SunGraphics2D; /** *   GraphicsComponentMgr provides services to *   1. register primitives for later use *   2. locate an instance of a primitve based on characteristics */public final class GraphicsPrimitiveMgr {     private static final boolean debugTrace = false;    private static GraphicsPrimitive primitives[];    private static GraphicsPrimitive generalPrimitives[];    private static boolean needssort = true;     private static native void initIDs(Class GP, Class ST, Class CT,                                       Class SG2D, Class Color, Class AT,                                       Class XORComp, Class AlphaComp,                                       Class Path2D, Class Path2DFloat,                                       Class SHints);    private static native void registerNativeLoops();     static {        initIDs(GraphicsPrimitive.class,                SurfaceType.class,                CompositeType.class,                SunGraphics2D.class,                java.awt.Color.class,                java.awt.geom.AffineTransform.class,                XORComposite.class,                java.awt.AlphaComposite.class,                java.awt.geom.Path2D.class,                java.awt.geom.Path2D.Float.class,                sun.awt.SunHints.class);        CustomComponent.register();        GeneralRenderer.register();        registerNativeLoops();    }     private static class PrimitiveSpec {        public int uniqueID;    }     private static Comparator primSorter = new Comparator() {        public int compare(Object o1, Object o2) {            int id1 = ((GraphicsPrimitive) o1).getUniqueID();            int id2 = ((GraphicsPrimitive) o2).getUniqueID();             return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1));        }    };     private static Comparator primFinder = new Comparator() {        public int compare(Object o1, Object o2) {            int id1 = ((GraphicsPrimitive) o1).getUniqueID();            int id2 = ((PrimitiveSpec) o2).uniqueID;             return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1));        }    };     /**     * Ensure that noone can instantiate this class.     */    private GraphicsPrimitiveMgr() {    }     public synchronized static void register(GraphicsPrimitive[] newPrimitives)    {        GraphicsPrimitive[] devCollection = primitives;        int oldSize = 0;        int newSize = newPrimitives.length;        if (debugTrace) {            writeLog("Registering " + newSize + " primitives");            for (int i = 0; i < newSize; i++) {                writeLog(newPrimitives[i].toString());            }        }        if (devCollection != null) {            oldSize = devCollection.length;        }        GraphicsPrimitive[] temp = new GraphicsPrimitive[oldSize + newSize];        if (devCollection != null) {            System.arraycopy(devCollection, 0, temp, 0, oldSize);        }        System.arraycopy(newPrimitives, 0, temp, oldSize, newSize);        needssort = true;        primitives = temp;    }     public synchronized static void registerGeneral(GraphicsPrimitive gen) {        if (generalPrimitives == null) {            generalPrimitives = new GraphicsPrimitive[] {gen};            return;        }        int len = generalPrimitives.length;        GraphicsPrimitive[] newGen = new GraphicsPrimitive[len + 1];        System.arraycopy(generalPrimitives, 0, newGen, 0, len);        newGen[len] = gen;        generalPrimitives = newGen;    }     public synchronized static GraphicsPrimitive locate(int primTypeID,                                                        SurfaceType dsttype)    {        return locate(primTypeID,                      SurfaceType.OpaqueColor,                      CompositeType.Src,                      dsttype);    }     public synchronized static GraphicsPrimitive locate(int primTypeID,                                                        SurfaceType srctype,                                                        CompositeType comptype,                                                        SurfaceType dsttype)    {        /*          System.out.println("Looking for:");          System.out.println("    method: "+signature);          System.out.println("    from:   "+srctype);          System.out.println("    by:     "+comptype);          System.out.println("    to:     "+dsttype);        */        GraphicsPrimitive prim = locatePrim(primTypeID,                                            srctype, comptype, dsttype);         if (prim == null) {            //System.out.println("Trying general loop");            prim = locateGeneral(primTypeID);            if (prim != null) {                prim = prim.makePrimitive(srctype, comptype, dsttype);                if (prim != null && GraphicsPrimitive.traceflags != 0) {                    prim = prim.traceWrap();                }            }        }        return prim;    }     public synchronized static GraphicsPrimitive        locatePrim(int primTypeID,                   SurfaceType srctype,                   CompositeType comptype,                   SurfaceType dsttype)    {        /*          System.out.println("Looking for:");          System.out.println("    method: "+signature);          System.out.println("    from:   "+srctype);          System.out.println("    by:     "+comptype);          System.out.println("    to:     "+dsttype);        */        SurfaceType src, dst;        CompositeType cmp;        GraphicsPrimitive prim;        PrimitiveSpec spec = new PrimitiveSpec();         for (dst = dsttype; dst != null; dst = dst.getSuperType()) {            for (src = srctype; src != null; src = src.getSuperType()) {                for (cmp = comptype; cmp != null; cmp = cmp.getSuperType()) {                    /*                      System.out.println("Trying:");                      System.out.println("    method: "+spec.methodSignature);                      System.out.println("    from:   "+spec.sourceType);                      System.out.println("    by:     "+spec.compType);                      System.out.println("    to:     "+spec.destType);                    */                     spec.uniqueID =                        GraphicsPrimitive.makeUniqueID(primTypeID, src, cmp, dst);                    prim = locate(spec);                    if (prim != null) {                        //System.out.println("<GPMgr> Found: " + prim + " in " + i + " steps");                        return prim;                    }                }            }        }        return null;    }     private static GraphicsPrimitive locateGeneral(int primTypeID) {        if (generalPrimitives == null) {            return null;        }        for (int i = 0; i < generalPrimitives.length; i++) {            GraphicsPrimitive prim = generalPrimitives[i];            if (prim.getPrimTypeID() == primTypeID) {                return prim;            }        }        return null;        //throw new InternalError("No general handler registered for"+signature);    }     private static GraphicsPrimitive locate(PrimitiveSpec spec) {        if (needssort) {            if (GraphicsPrimitive.traceflags != 0) {                for (int i = 0; i < primitives.length; i++) {                    primitives[i] = primitives[i].traceWrap();                }            }            Arrays.sort(primitives, primSorter);            needssort = false;        }        GraphicsPrimitive[] devCollection = primitives;        if (devCollection == null) {            return null;        }        int index = Arrays.binarySearch(devCollection, spec, primFinder);        if (index >= 0) {            GraphicsPrimitive prim = devCollection[index];            if (prim instanceof GraphicsPrimitiveProxy) {                prim = ((GraphicsPrimitiveProxy) prim).instantiate();                devCollection[index] = prim;                if (debugTrace) {                    writeLog("Instantiated graphics primitive " + prim);                }            }            if (debugTrace) {                writeLog("Lookup found[" + index + "]["+ prim + "]");            }            return prim;        }        if (debugTrace) {            writeLog("Lookup found nothing for:");            writeLog(" " + spec.uniqueID);        }        return null;    }     private static void writeLog(String str) {        if (debugTrace) {            System.err.println(str);        }    }     /**     * Test that all of the GraphicsPrimitiveProxy objects actually     * resolve to something.  Throws a RuntimeException if anything     * is wrong, an has no effect if all is well.     */    // This is only really meant to be called from GraphicsPrimitiveProxyTest    // in the regression tests directory, but it has to be here because    // it needs access to a private data structure.  It is not very    // big, though.    public static void testPrimitiveInstantiation() {        testPrimitiveInstantiation(false);    }     public static void testPrimitiveInstantiation(boolean verbose) {        int resolved = 0;        int unresolved = 0;        GraphicsPrimitive[] prims = primitives;        for (int j = 0; j < prims.length; j++) {            GraphicsPrimitive p = prims[j];            if (p instanceof GraphicsPrimitiveProxy) {                GraphicsPrimitive r = ((GraphicsPrimitiveProxy) p).instantiate();                if (!r.getSignature().equals(p.getSignature()) ||                    r.getUniqueID() != p.getUniqueID()) {                    System.out.println("r.getSignature == "+r.getSignature());                    System.out.println("r.getUniqueID == " + r.getUniqueID());                    System.out.println("p.getSignature == "+p.getSignature());                    System.out.println("p.getUniqueID == " + p.getUniqueID());                    throw new RuntimeException("Primitive " + p                                               + " returns wrong signature for "                                               + r.getClass());                }                // instantiate checks that p.satisfiesSameAs(r)                unresolved++;                p = r;                if (verbose) {                    System.out.println(p);                }            } else {                if (verbose) {                    System.out.println(p + " (not proxied).");                }                resolved++;            }        }        System.out.println(resolved+                           " graphics primitives were not proxied.");        System.out.println(unresolved+                           " proxied graphics primitives resolved correctly.");        System.out.println(resolved+unresolved+                           " total graphics primitives");    }     public static void main(String argv[]) {        // REMIND: Should trigger loading of platform primitives somehow...        if (needssort) {            Arrays.sort(primitives, primSorter);            needssort = false;        }        testPrimitiveInstantiation(argv.length > 0);    }}