FileDocCategorySizeDatePackage
PathSupport.javaAPI DocphoneME MR2 API (J2ME)18092Wed May 02 18:00:34 BST 2007com.sun.perseus.j2d

PathSupport

public class PathSupport extends Object
version
$Id: PathSupport.java,v 1.12 2006/04/21 06:35:29 st125089 Exp $

Fields Summary
private static final com.sun.pisces.Transform4
identity
Identity Transform4
private static final com.sun.pisces.Transform6
identity6
Identity Transform6
private static final com.sun.pisces.Transform6
txf
A transform used in the implementation of computeStrokedPathTile
private static TileSink
tileSink
Used to compute a stroked path's outline.
private static com.sun.pisces.Transformer
transformerSink
Used to transform the coordinates of stroked path.
private static long
acv
private static final double
CtrlVal
private static long
pcv_
private static long
ncv_
Constructors Summary
Methods Summary
static intcomputeStrokeDashOffset(float strokeDashOffset, float[] strokeDashArray)
Implemnetation: Handles negative strokeDashOffset

param
strokeDashOffset the possibly negative dash offset value.
param
strokeDashArray the applicable dash array.
return
a positive strokeDashOffset.

        if (strokeDashArray == null) {
            // The stroke dash offset does not matter, simply return 0
            return 0;
        }

        if (strokeDashOffset >= 0) {
            return (int) (strokeDashOffset * 65536);
        }

        int length = 0;
        for (int i = 0; i < strokeDashArray.length; i++) {
            length += strokeDashArray[i];
        }

        if (length <= 0) {
            return 0;
        }

        float sdo = strokeDashOffset;
        while (sdo < 0) {
            sdo += length;
        }

        return (int) (sdo * 65536);
    
public static voidcomputeStrokedPathTile(Tile tile, java.lang.Object strokedPath, Transform t)

param
strokedPath the object returned from a previous getStrokedPath call. Should not be null.
param
t the transform from the strokedPath space to the requested tile space.
param
tile the bounds of the given stroked outline.

        // Reuse the same TileSink over and over again.
        PathStore sp = (PathStore) strokedPath;

        // We use out own TileSink, chained with a Transformer to compute the 
        // stroked shape bounds.

        // Start from initial values
        tileSink.reset();

        // Transfer the input Transform value to the working transform txf.
        RenderGraphics.setTransform(t, txf);

        // Compute now. This call starts pulling data.
        transformerSink.setTransform(txf);
        sp.produce(transformerSink);

        // Compute the tile from the data that was just computed.
        tileSink.setTile(tile);
    
private static com.sun.pisces.PathSinkcreateStroker(com.sun.pisces.PathSink output, GraphicsProperties gp)
Returns a PathSink that will accept path commands and feed them into a stroking pipeline based on the stroke parameters of a given GraphicsProperties. The stroked output will be fed into the given output PathSink.

param
output a PathSink that will receive the stroked outline
param
gp a GraphicsProperties containing stroking parameters
return
a new PathSink that can accept the path to be stroked

        Stroker stroker = new Stroker();
        stroker.setParameters((int) (gp.getStrokeWidth() * 65536),
                              gp.getStrokeLineCap(), 
                              gp.getStrokeLineJoin(),
                              (int) (gp.getStrokeMiterLimit() * 65536),
                              identity);
        stroker.setOutput(output);           
        Flattener flattener = new Flattener();
        flattener.setFlatness(1 << 16);
        
        float[] strokeDashArray = gp.getStrokeDashArray();
        if (strokeDashArray != null) {            
            int[] intStrokeDashArray = new int[strokeDashArray.length];
            for (int i = 0; i < strokeDashArray.length; i++) {
                intStrokeDashArray[i] = (int) (strokeDashArray[i] * 65536);
            }
            
            // flattener -> dasher -> stroker -> output
            Dasher dasher = new Dasher();
            dasher.setParameters(intStrokeDashArray,
                                 computeStrokeDashOffset(gp.getStrokeDashOffset(),
                                                         gp.getStrokeDashArray()),
                                 identity);
            dasher.setOutput(stroker);
            flattener.setOutput(dasher);
        } else {
            // flattener -> stroker -> output
            flattener.setOutput(stroker);
        }
        
       return flattener;
    
private static voidemitPath(Path path, com.sun.pisces.PathSink output)

        int numSegments = path.getNumberOfSegments();
        byte[] pathCommands = path.getCommands();
        float[] pathData = path.getData();

        int x1 = -1, y1 = -1, x2, y2, x3, y3;
        float[] pt = null;

        int offset = 0;

        for (int seg = 0; seg < numSegments; seg++) {
            if (pathCommands[seg] != Path.CLOSE_IMPL) {
                x1 = toFixed(pathData[offset]);
                y1 = toFixed(pathData[offset + 1]);
            }

            switch (pathCommands[seg]) {
            case Path.MOVE_TO_IMPL:
                output.moveTo(x1, y1);
                offset += 2;
                break;
            case Path.LINE_TO_IMPL:
                output.lineTo(x1, y1);
                offset += 2;
                break;
            case Path.QUAD_TO_IMPL:
                x2 = toFixed(pathData[offset + 2]);
                y2 = toFixed(pathData[offset + 3]);
                output.quadTo(x1, y1, x2, y2);
                offset += 4;
                break;
            case Path.CURVE_TO_IMPL:
                x2 = toFixed(pathData[offset + 2]);
                y2 = toFixed(pathData[offset + 3]);
                x3 = toFixed(pathData[offset + 4]);
                y3 = toFixed(pathData[offset + 5]);
                output.cubicTo(x1, y1, x2, y2, x3, y3);
                offset += 6;
                break;
            case Path.CLOSE_IMPL:
                output.close();
                break;
            }
        }

        output.end();
    
public static java.lang.ObjectgetStrokedEllipse(float x, float y, float width, float height, GraphicsProperties gp)

param
x the ellipse's x-axis origin
param
y the ellipse's y-axis origin
param
width the ellipse's x-axis length
param
height the ellipse's y-axis length.
param
gp the GraphicsProperties defining rendering conditions.
return
the stroked outline.


                                            
         
                                             
                                             
                                             
                                              

        PathStore strokedPath = new PathStore();
        PathSink stroker = createStroker(strokedPath, gp);

        int x_ = toFixed(x);
        int y_ = toFixed(y);
        int width_ = toFixed(width);
        int height_ = toFixed(height);

        int xw_ = x_ + width_;
        int xw2_ = x_ + (width_ >> 1);
        int yh_ = y_ + height_;
        int yh2_ = y_ + (height_ >> 1);
        int xpcvw_ = x_ + (int)(pcv_*width_ >> 16);
        int ypcvh_ = y_ + (int)(pcv_*height_ >> 16);
        int xncvw_ = x_ + (int)(ncv_*width_ >> 16);
        int yncvh_ = y_ + (int)(ncv_*height_ >> 16);
        
        stroker.moveTo(xw_, yh2_);
        stroker.cubicTo(xw_, ypcvh_, xpcvw_, yh_, xw2_, yh_);
        stroker.cubicTo(xncvw_, yh_, x_, ypcvh_, x_, yh2_);
        stroker.cubicTo(x_, yncvh_, xncvw_, y_, xw2_, y_);
        stroker.cubicTo(xpcvw_, y_, xw_, yncvh_, xw_, yh2_);
        stroker.close();
        stroker.end();

        return strokedPath;
   
public static java.lang.ObjectgetStrokedLine(float x1, float y1, float x2, float y2, GraphicsProperties gp)

param
x1 the line's x-axis starting position.
param
y1 the line's y-axis starting position.
param
x2 the line's x-axis end position.
param
y2 the line's y-axis end position.
param
gp the GraphicsProperties defining rendering conditions.
return
the stroked outline.

        PathStore strokedPath = new PathStore();
        PathSink stroker = createStroker(strokedPath, gp);

        stroker.moveTo(toFixed(x1), toFixed(y1));
        stroker.lineTo(toFixed(x2), toFixed(y2));
        stroker.end();

        return strokedPath;
    
public static java.lang.ObjectgetStrokedPath(Path path, GraphicsProperties gp)

param
path the Path to stroke.
param
gp the GraphicsProperties defining the rendering conditions.
return
the stroked outline.

        PathStore strokedPath = new PathStore();
        PathSink stroker = createStroker(strokedPath, gp);

        emitPath(path, stroker);
        
        return strokedPath;
    
public static java.lang.ObjectgetStrokedRect(float fx, float fy, float fw, float fh, float rx, float ry, GraphicsProperties gp)

param
fx the rectangle's x-axis origin
param
fy the rectangle's y-axis origin
param
fw the rectangle's length along the x-axis
param
fh the rectangle's length along the y-axis
param
rx the rectangle's rounded corner diameter along the x-axis
param
ry the rectangle's rounded corner diameter along the y-axis.
param
gp the GraphicsProperties defining rendering conditions.
return
the stroked outline.


                                                                    
          
                                          
                                          
                                          
                                          
                                          
                                           
        int x = toFixed(fx);
        int y = toFixed(fy);
        int w = toFixed(fw);
        int h = toFixed(fh);
        int aw = toFixed(rx);
        int ah = toFixed(ry);

        int xw = x + w;
        int yh = y + h;
        int aw2 = aw >> 1;
        int ah2 = ah >> 1;
        int acvaw = (int)(acv*aw >> 16);
        int acvah = (int)(acv*ah >> 16);
        int xacvaw = x + acvaw;
        int xw_acvaw = xw - acvaw;
        int yacvah = y + acvah;
        int yh_acvah = yh - acvah;
        int xaw2 = x + aw2;
        int xw_aw2 = xw - aw2;
        int yah2 = y + ah2;
        int yh_ah2 = yh - ah2;
        
        PathStore strokedPath = new PathStore();
        PathSink stroker = createStroker(strokedPath, gp);

        stroker.moveTo(x, yah2);
        stroker.lineTo(x, yh_ah2);
        stroker.cubicTo(x, yh_acvah, xacvaw, yh, xaw2, yh);
        stroker.lineTo(xw_aw2, yh);
        stroker.cubicTo(xw_acvaw, yh, xw, yh_acvah, xw, yh_ah2);
        stroker.lineTo(xw, yah2);
        stroker.cubicTo(xw, yacvah, xw_acvaw, y, xw_aw2, y);
        stroker.lineTo(xaw2, y);
        stroker.cubicTo(xacvaw, y, x, yacvah, x, yah2);
        stroker.close();
        stroker.end();

        return strokedPath;
    
public static java.lang.ObjectgetStrokedRect(float x, float y, float w, float h, GraphicsProperties gp)

param
x the rectangle's x-axis origin
param
y the rectangle's y-axis origin
param
w the rectangle's length along the x-axis
param
h the rectangle's length along the y-axis
param
gp the GraphicsProperties defining rendering conditions.
return
the stroked outline.

        PathStore strokedPath = new PathStore();
        PathSink stroker = createStroker(strokedPath, gp);

        stroker.moveTo(toFixed(x), toFixed(y));
        stroker.lineTo(toFixed(x + w), toFixed(y));
        stroker.lineTo(toFixed(x + w), toFixed(y + h));
        stroker.lineTo(toFixed(x), toFixed(y + h));
        stroker.close();
        stroker.end();

        return strokedPath;
    
public static booleanisHit(Path path, int windingRule, float hx, float hy)
Returns true if the shape is hit by the given point.

param
path the shape on which we do hit testing. Should not be null.
param
windingRule the winding rule fo the path.
param
hx the hit point x-axis coordinate.
param
hy the hit point y-axis coordinate.
return
true if the input shape is hit. false otherwise.

        HitTester hitTester = new HitTester(windingRule,
                                            toFixed(hx), toFixed(hy));
        emitPath(path, hitTester);
        boolean hit = hitTester.containsPoint();
        return hit;
    
public static booleanisStrokedPathHit(java.lang.Object strokedPath, int windingRule, float hx, float hy)
Returns true if the input object is hit by the given point.

param
strokedPath the shape on which we do hit testing. Should not be null.
param
windingRule the winding rule fo the path.
param
hx the hit point x-axis coordinate.
param
hy the hit point y-axis coordinate.
return
true if the input shape is hit. false otherwise.

        HitTester hitTester = new HitTester(Path.WIND_NON_ZERO,
                                            toFixed(hx), toFixed(hy));
        PathStore path = (PathStore) strokedPath;
        path.produce(hitTester);
        boolean hit = hitTester.containsPoint();
        return hit;
    
private static inttoFixed(float f)


         
        return (int) (f*65536.0f);