alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (RenderingEngine.java)

This example Java source code file (RenderingEngine.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

aatilegenerator, affinetransform, awt, basicstroke, geometry, getpropertyaction, internalerror, pathconsumer2d, privilegedaction, reflectiveoperationexception, region, renderingengine, security, shape, string, tracer, util

The RenderingEngine.java Java example source code

/*
 * Copyright (c) 2007, 2013, 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.
 */

package sun.java2d.pipe;

import java.awt.Shape;
import java.awt.BasicStroke;
import java.awt.geom.PathIterator;
import java.awt.geom.AffineTransform;

import java.security.PrivilegedAction;
import java.security.AccessController;
import java.util.ServiceLoader;
import sun.security.action.GetPropertyAction;

import sun.awt.geom.PathConsumer2D;

/**
 * This class abstracts a number of features for which the Java 2D
 * implementation relies on proprietary licensed software libraries.
 * Access to those features is now achieved by retrieving the singleton
 * instance of this class and calling the appropriate methods on it.
 * The 3 primary features abstracted here include:
 * <dl>
 * <dt>Shape createStrokedShape(Shape, [BasicStroke attributes]);
 * <dd>This method implements the functionality of the method of the
 * same name on the {@link BasicStroke} class.
 * <dt>void strokeTo(Shape, [rendering parameters], PathConsumer2D);
 * <dd>This method performs widening of the source path on the fly
 * and sends the results to the given {@link PathConsumer2D} object.
 * This procedure avoids having to create an intermediate Shape
 * object to hold the results of the {@code createStrokedShape} method.
 * The main user of this method is the Java 2D non-antialiasing renderer.
 * <dt>AATileGenerator getAATileGenerator(Shape, [rendering parameters]);
 * <dd>This method returns an object which can iterate over the
 * specified bounding box and produce tiles of coverage values for
 * antialiased rendering.  The details of the operation of the
 * {@link AATileGenerator} object are explained in its class comments.
 * </dl>
 * Additionally, the following informational method supplies important
 * data about the implementation.
 * <dl>
 * <dt>float getMinimumAAPenSize()
 * <dd>This method provides information on how small the BasicStroke
 * line width can get before dropouts occur.  Rendering with a BasicStroke
 * is defined to never allow the line to have breaks, gaps, or dropouts
 * even if the width is set to 0.0f, so this information allows the
 * {@link SunGraphics2D} class to detect the "thin line" case and set
 * the rendering attributes accordingly.
 * </dl>
 * At startup the runtime will load a single instance of this class.
 * It searches the classpath for a registered provider of this API
 * and returns either the last one it finds, or the instance whose
 * class name matches the value supplied in the System property
 * {@code sun.java2d.renderer}.
 * Additionally, a runtime System property flag can be set to trace
 * all calls to methods on the {@code RenderingEngine} in use by
 * setting the sun.java2d.renderer.trace property to any non-null value.
 * <p>
 * Parts of the system that need to use any of the above features should
 * call {@code RenderingEngine.getInstance()} to obtain the properly
 * registered (and possibly trace-enabled) version of the RenderingEngine.
 */
public abstract class RenderingEngine {
    private static RenderingEngine reImpl;

    /**
     * Returns an instance of {@code RenderingEngine} as determined
     * by the installation environment and runtime flags.
     * <p>
     * A specific instance of the {@code RenderingEngine} can be
     * chosen by specifying the runtime flag:
     * <pre>
     *     java -Dsun.java2d.renderer=<classname>
     * </pre>
     *
     * If no specific {@code RenderingEngine} is specified on the command
     * or Ductus renderer is specified, it will attempt loading the
     * sun.dc.DuctusRenderingEngine class using Class.forName as a fastpath;
     * if not found, use the ServiceLoader.
     * If no specific {@code RenderingEngine} is specified on the command
     * line then the last one returned by enumerating all subclasses of
     * {@code RenderingEngine} known to the ServiceLoader is used.
     * <p>
     * Runtime tracing of the actions of the {@code RenderingEngine}
     * can be enabled by specifying the runtime flag:
     * <pre>
     *     java -Dsun.java2d.renderer.trace=<any string>
     * </pre>
     * @return an instance of {@code RenderingEngine}
     * @since 1.7
     */
    public static synchronized RenderingEngine getInstance() {
        if (reImpl != null) {
            return reImpl;
        }

        reImpl =
            AccessController.doPrivileged(new PrivilegedAction<RenderingEngine>() {
                public RenderingEngine run() {
                    final String ductusREClass = "sun.dc.DuctusRenderingEngine";
                    String reClass =
                        System.getProperty("sun.java2d.renderer", ductusREClass);
                    if (reClass.equals(ductusREClass)) {
                        try {
                            Class<?> cls = Class.forName(ductusREClass);
                            return (RenderingEngine) cls.newInstance();
                        } catch (ReflectiveOperationException ignored) {
                            // not found
                        }
                    }

                    ServiceLoader<RenderingEngine> reLoader =
                        ServiceLoader.loadInstalled(RenderingEngine.class);

                    RenderingEngine service = null;

                    for (RenderingEngine re : reLoader) {
                        service = re;
                        if (re.getClass().getName().equals(reClass)) {
                            break;
                        }
                    }
                    return service;
                }
            });

        if (reImpl == null) {
            throw new InternalError("No RenderingEngine module found");
        }

        GetPropertyAction gpa =
            new GetPropertyAction("sun.java2d.renderer.trace");
        String reTrace = AccessController.doPrivileged(gpa);
        if (reTrace != null) {
            reImpl = new Tracer(reImpl);
        }

        return reImpl;
    }

    /**
     * Create a widened path as specified by the parameters.
     * <p>
     * The specified {@code src} {@link Shape} is widened according
     * to the specified attribute parameters as per the
     * {@link BasicStroke} specification.
     *
     * @param src the source path to be widened
     * @param width the width of the widened path as per {@code BasicStroke}
     * @param caps the end cap decorations as per {@code BasicStroke}
     * @param join the segment join decorations as per {@code BasicStroke}
     * @param miterlimit the miter limit as per {@code BasicStroke}
     * @param dashes the dash length array as per {@code BasicStroke}
     * @param dashphase the initial dash phase as per {@code BasicStroke}
     * @return the widened path stored in a new {@code Shape} object
     * @since 1.7
     */
    public abstract Shape createStrokedShape(Shape src,
                                             float width,
                                             int caps,
                                             int join,
                                             float miterlimit,
                                             float dashes[],
                                             float dashphase);

    /**
     * Sends the geometry for a widened path as specified by the parameters
     * to the specified consumer.
     * <p>
     * The specified {@code src} {@link Shape} is widened according
     * to the parameters specified by the {@link BasicStroke} object.
     * Adjustments are made to the path as appropriate for the
     * {@link VALUE_STROKE_NORMALIZE} hint if the {@code normalize}
     * boolean parameter is true.
     * Adjustments are made to the path as appropriate for the
     * {@link VALUE_ANTIALIAS_ON} hint if the {@code antialias}
     * boolean parameter is true.
     * <p>
     * The geometry of the widened path is forwarded to the indicated
     * {@link PathConsumer2D} object as it is calculated.
     *
     * @param src the source path to be widened
     * @param bs the {@code BasicSroke} object specifying the
     *           decorations to be applied to the widened path
     * @param normalize indicates whether stroke normalization should
     *                  be applied
     * @param antialias indicates whether or not adjustments appropriate
     *                  to antialiased rendering should be applied
     * @param consumer the {@code PathConsumer2D} instance to forward
     *                 the widened geometry to
     * @since 1.7
     */
    public abstract void strokeTo(Shape src,
                                  AffineTransform at,
                                  BasicStroke bs,
                                  boolean thin,
                                  boolean normalize,
                                  boolean antialias,
                                  PathConsumer2D consumer);

    /**
     * Construct an antialiased tile generator for the given shape with
     * the given rendering attributes and store the bounds of the tile
     * iteration in the bbox parameter.
     * The {@code at} parameter specifies a transform that should affect
     * both the shape and the {@code BasicStroke} attributes.
     * The {@code clip} parameter specifies the current clip in effect
     * in device coordinates and can be used to prune the data for the
     * operation, but the renderer is not required to perform any
     * clipping.
     * If the {@code BasicStroke} parameter is null then the shape
     * should be filled as is, otherwise the attributes of the
     * {@code BasicStroke} should be used to specify a draw operation.
     * The {@code thin} parameter indicates whether or not the
     * transformed {@code BasicStroke} represents coordinates smaller
     * than the minimum resolution of the antialiasing rasterizer as
     * specified by the {@code getMinimumAAPenWidth()} method.
     * <p>
     * Upon returning, this method will fill the {@code bbox} parameter
     * with 4 values indicating the bounds of the iteration of the
     * tile generator.
     * The iteration order of the tiles will be as specified by the
     * pseudo-code:
     * <pre>
     *     for (y = bbox[1]; y < bbox[3]; y += tileheight) {
     *         for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
     *         }
     *     }
     * </pre>
     * If there is no output to be rendered, this method may return
     * null.
     *
     * @param s the shape to be rendered (fill or draw)
     * @param at the transform to be applied to the shape and the
     *           stroke attributes
     * @param clip the current clip in effect in device coordinates
     * @param bs if non-null, a {@code BasicStroke} whose attributes
     *           should be applied to this operation
     * @param thin true if the transformed stroke attributes are smaller
     *             than the minimum dropout pen width
     * @param normalize true if the {@code VALUE_STROKE_NORMALIZE}
     *                  {@code RenderingHint} is in effect
     * @param bbox returns the bounds of the iteration
     * @return the {@code AATileGenerator} instance to be consulted
     *         for tile coverages, or null if there is no output to render
     * @since 1.7
     */
    public abstract AATileGenerator getAATileGenerator(Shape s,
                                                       AffineTransform at,
                                                       Region clip,
                                                       BasicStroke bs,
                                                       boolean thin,
                                                       boolean normalize,
                                                       int bbox[]);

    /**
     * Construct an antialiased tile generator for the given parallelogram
     * store the bounds of the tile iteration in the bbox parameter.
     * The parallelogram is specified as a starting point and 2 delta
     * vectors that indicate the slopes of the 2 pairs of sides of the
     * parallelogram.
     * The 4 corners of the parallelogram are defined by the 4 points:
     * <ul>
     * <li> {@code x}, {@code y}
     * <li> {@code x+dx1}, {@code y+dy1}
     * <li> {@code x+dx1+dx2}, {@code y+dy1+dy2}
     * <li> {@code x+dx2}, {@code y+dy2}
     * </ul>
     * The {@code lw1} and {@code lw2} parameters provide a specification
     * for an optionally stroked parallelogram if they are positive numbers.
     * The {@code lw1} parameter is the ratio of the length of the {@code dx1},
     * {@code dx2} delta vector to half of the line width in that same
     * direction.
     * The {@code lw2} parameter provides the same ratio for the other delta
     * vector.
     * If {@code lw1} and {@code lw2} are both greater than zero, then
     * the parallelogram figure is doubled by both expanding and contracting
     * each delta vector by its corresponding {@code lw} value.
     * If either (@code lw1) or {@code lw2} are also greater than 1, then
     * the inner (contracted) parallelogram disappears and the figure is
     * simply a single expanded parallelogram.
     * The {@code clip} parameter specifies the current clip in effect
     * in device coordinates and can be used to prune the data for the
     * operation, but the renderer is not required to perform any
     * clipping.
     * <p>
     * Upon returning, this method will fill the {@code bbox} parameter
     * with 4 values indicating the bounds of the iteration of the
     * tile generator.
     * The iteration order of the tiles will be as specified by the
     * pseudo-code:
     * <pre>
     *     for (y = bbox[1]; y < bbox[3]; y += tileheight) {
     *         for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
     *         }
     *     }
     * </pre>
     * If there is no output to be rendered, this method may return
     * null.
     *
     * @param x the X coordinate of the first corner of the parallelogram
     * @param y the Y coordinate of the first corner of the parallelogram
     * @param dx1 the X coordinate delta of the first leg of the parallelogram
     * @param dy1 the Y coordinate delta of the first leg of the parallelogram
     * @param dx2 the X coordinate delta of the second leg of the parallelogram
     * @param dy2 the Y coordinate delta of the second leg of the parallelogram
     * @param lw1 the line width ratio for the first leg of the parallelogram
     * @param lw2 the line width ratio for the second leg of the parallelogram
     * @param clip the current clip in effect in device coordinates
     * @param bbox returns the bounds of the iteration
     * @return the {@code AATileGenerator} instance to be consulted
     *         for tile coverages, or null if there is no output to render
     * @since 1.7
     */
    public abstract AATileGenerator getAATileGenerator(double x, double y,
                                                       double dx1, double dy1,
                                                       double dx2, double dy2,
                                                       double lw1, double lw2,
                                                       Region clip,
                                                       int bbox[]);

    /**
     * Returns the minimum pen width that the antialiasing rasterizer
     * can represent without dropouts occurring.
     * @since 1.7
     */
    public abstract float getMinimumAAPenSize();

    /**
     * Utility method to feed a {@link PathConsumer2D} object from a
     * given {@link PathIterator}.
     * This method deals with the details of running the iterator and
     * feeding the consumer a segment at a time.
     */
    public static void feedConsumer(PathIterator pi, PathConsumer2D consumer) {
        float coords[] = new float[6];
        while (!pi.isDone()) {
            switch (pi.currentSegment(coords)) {
            case PathIterator.SEG_MOVETO:
                consumer.moveTo(coords[0], coords[1]);
                break;
            case PathIterator.SEG_LINETO:
                consumer.lineTo(coords[0], coords[1]);
                break;
            case PathIterator.SEG_QUADTO:
                consumer.quadTo(coords[0], coords[1],
                                coords[2], coords[3]);
                break;
            case PathIterator.SEG_CUBICTO:
                consumer.curveTo(coords[0], coords[1],
                                 coords[2], coords[3],
                                 coords[4], coords[5]);
                break;
            case PathIterator.SEG_CLOSE:
                consumer.closePath();
                break;
            }
            pi.next();
        }
    }

    static class Tracer extends RenderingEngine {
        RenderingEngine target;
        String name;

        public Tracer(RenderingEngine target) {
            this.target = target;
            name = target.getClass().getName();
        }

        public Shape createStrokedShape(Shape src,
                                        float width,
                                        int caps,
                                        int join,
                                        float miterlimit,
                                        float dashes[],
                                        float dashphase)
        {
            System.out.println(name+".createStrokedShape("+
                               src.getClass().getName()+", "+
                               "width = "+width+", "+
                               "caps = "+caps+", "+
                               "join = "+join+", "+
                               "miter = "+miterlimit+", "+
                               "dashes = "+dashes+", "+
                               "dashphase = "+dashphase+")");
            return target.createStrokedShape(src,
                                             width, caps, join, miterlimit,
                                             dashes, dashphase);
        }

        public void strokeTo(Shape src,
                             AffineTransform at,
                             BasicStroke bs,
                             boolean thin,
                             boolean normalize,
                             boolean antialias,
                             PathConsumer2D consumer)
        {
            System.out.println(name+".strokeTo("+
                               src.getClass().getName()+", "+
                               at+", "+
                               bs+", "+
                               (thin ? "thin" : "wide")+", "+
                               (normalize ? "normalized" : "pure")+", "+
                               (antialias ? "AA" : "non-AA")+", "+
                               consumer.getClass().getName()+")");
            target.strokeTo(src, at, bs, thin, normalize, antialias, consumer);
        }

        public float getMinimumAAPenSize() {
            System.out.println(name+".getMinimumAAPenSize()");
            return target.getMinimumAAPenSize();
        }

        public AATileGenerator getAATileGenerator(Shape s,
                                                  AffineTransform at,
                                                  Region clip,
                                                  BasicStroke bs,
                                                  boolean thin,
                                                  boolean normalize,
                                                  int bbox[])
        {
            System.out.println(name+".getAATileGenerator("+
                               s.getClass().getName()+", "+
                               at+", "+
                               clip+", "+
                               bs+", "+
                               (thin ? "thin" : "wide")+", "+
                               (normalize ? "normalized" : "pure")+")");
            return target.getAATileGenerator(s, at, clip,
                                             bs, thin, normalize,
                                             bbox);
        }
        public AATileGenerator getAATileGenerator(double x, double y,
                                                  double dx1, double dy1,
                                                  double dx2, double dy2,
                                                  double lw1, double lw2,
                                                  Region clip,
                                                  int bbox[])
        {
            System.out.println(name+".getAATileGenerator("+
                               x+", "+y+", "+
                               dx1+", "+dy1+", "+
                               dx2+", "+dy2+", "+
                               lw1+", "+lw2+", "+
                               clip+")");
            return target.getAATileGenerator(x, y,
                                             dx1, dy1,
                                             dx2, dy2,
                                             lw1, lw2,
                                             clip, bbox);
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java RenderingEngine.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.