mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
722 lines
26 KiB
Java
722 lines
26 KiB
Java
![]() |
/*
|
||
|
* This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com>
|
||
|
* Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/)
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* @(#)Rasterizer.java 1.15 03/01/23
|
||
|
*
|
||
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||
|
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* @(#)Rasterizer.java 2.1 97/08/18
|
||
|
*
|
||
|
* ---------------------------------------------------------------------
|
||
|
* Copyright (c) 1996-1997 by Ductus, Inc. All Rights Reserved.
|
||
|
* ---------------------------------------------------------------------
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
package sun.dc.pr;
|
||
|
|
||
|
import sun.dc.path.*;
|
||
|
|
||
|
/**
|
||
|
* A Rasterizer is an object capable of turning a <b>path</b>
|
||
|
* description into rectangular arrays of alpha pixels as indicated
|
||
|
* by <b>path to alpha conversion</b> conventions (PACs).
|
||
|
* <p>
|
||
|
* A <b>rasterization cycle</b> - the sequence of method invocations
|
||
|
* used by a client to decribe path and PAC, and to retrieve the
|
||
|
* resulting alphas - must comform to the following protocol:
|
||
|
* <p>
|
||
|
* <b>Initialization and PAC Description:</b> The client declares
|
||
|
* what it intends to do with the path - e.g., fill it, stroke it -
|
||
|
* and any aditional information which affects the relation between
|
||
|
* the path and the corresponding alpha pixel - e.g., the size of the
|
||
|
* pen used to stroke the path. The Rasterizer stores this
|
||
|
* information.
|
||
|
* <p>
|
||
|
* <b>Path Description:</b> The client describes the path - in raster
|
||
|
* space - to the Rasterizer, which stores it as part of its
|
||
|
* state.
|
||
|
* <p>
|
||
|
* <b>Alpha Bounding Box Retrieval:</b> At this stage, the client may
|
||
|
* request the rasterizer to return the alpha's bounding box, a
|
||
|
* raster space rectangle outside of which alpha is uniformly
|
||
|
* zero.
|
||
|
* <p>
|
||
|
* <b>Definition of Output Area:</b> The client defines an
|
||
|
* arbitrary rectangle in raster space, the "output area" or
|
||
|
* OA. Only the alpha pixels inside OA will be computed.
|
||
|
* <p>
|
||
|
* <b>Tile Retrieval:</b> OA divided in square "tiles." The tiles
|
||
|
* are retrieved one by one, in a conventional order. After the last
|
||
|
* tile is retrieved, the path rasterizer object resets itself to an
|
||
|
* initial state and can be used for a different path/PAC
|
||
|
* combination.
|
||
|
* <p>
|
||
|
* A rasterization cycle can be interrupted at any time by invoking
|
||
|
* <b>reset</b>.
|
||
|
*
|
||
|
* @version 3.0, 11 June 1997
|
||
|
*/
|
||
|
public class Rasterizer
|
||
|
{
|
||
|
static public final int
|
||
|
// usage
|
||
|
EOFILL = 1,
|
||
|
NZFILL = 2,
|
||
|
STROKE = 3,
|
||
|
|
||
|
// caps, corners
|
||
|
ROUND = PathStroker.ROUND,
|
||
|
SQUARE = PathStroker.SQUARE,
|
||
|
BUTT = PathStroker.BUTT,
|
||
|
BEVEL = PathStroker.BEVEL,
|
||
|
MITER = PathStroker.MITER,
|
||
|
|
||
|
// tile size
|
||
|
TILE_SIZE = 1 << PathFiller.tileSizeL2S,
|
||
|
TILE_SIZE_L2S = PathFiller.tileSizeL2S,
|
||
|
|
||
|
// implementation limits
|
||
|
MAX_ALPHA = PathFiller.MAX_PATH,
|
||
|
|
||
|
MAX_MITER = 10,
|
||
|
MAX_WN = 63,
|
||
|
|
||
|
// tile states
|
||
|
TILE_IS_ALL_0 = PathFiller.TILE_IS_ALL_0,
|
||
|
TILE_IS_ALL_1 = PathFiller.TILE_IS_ALL_1,
|
||
|
TILE_IS_GENERAL = PathFiller.TILE_IS_GENERAL;
|
||
|
|
||
|
private static final int BEG = 1,
|
||
|
PAC_FILL = 2,
|
||
|
PAC_STROKE = 3,
|
||
|
PATH = 4,
|
||
|
SUBPATH = 5,
|
||
|
RAS = 6;
|
||
|
private int state;
|
||
|
|
||
|
private PathFiller filler;
|
||
|
private PathStroker stroker;
|
||
|
private PathDasher dasher;
|
||
|
private PathConsumer curPC;
|
||
|
|
||
|
public Rasterizer() {
|
||
|
state = BEG;
|
||
|
filler = new PathFiller();
|
||
|
stroker = new PathStroker(filler);
|
||
|
dasher = new PathDasher(stroker);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Determines whether the path will be EOFILLed, NZFILLed or STROKEd.
|
||
|
* Mandatory; must be the first method used in a rasterization cycle.
|
||
|
* <p>
|
||
|
* After <tt>setUsage(STROKE)</tt>, the following state variables
|
||
|
* are implicitly set as per:
|
||
|
* <pre><tt>
|
||
|
* setPenDiameter(1.0);
|
||
|
* setPenT4(null); // identity
|
||
|
* setPenDisplacement(null); // (0,0)
|
||
|
* setCaps(ROUND);
|
||
|
* setCorners(ROUND, 0);
|
||
|
* setDash(null, 0.0); // solid line
|
||
|
* </tt></pre>
|
||
|
*
|
||
|
* @param <tt>usage</tt>
|
||
|
* the usage selector
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> in a state other than between rasterization cycles (unexpected),
|
||
|
* <li> with an invalid selector (unknow usage type).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void setUsage(int usage) throws PRError {
|
||
|
if (state != BEG) {
|
||
|
throw new PRError(PRError.UNEX_setUsage);
|
||
|
}
|
||
|
if (usage == EOFILL) {
|
||
|
filler.setFillMode(PathFiller.EOFILL);
|
||
|
curPC = filler;
|
||
|
state = PAC_FILL;
|
||
|
} else if (usage == NZFILL) {
|
||
|
filler.setFillMode(PathFiller.NZFILL);
|
||
|
curPC = filler;
|
||
|
state = PAC_FILL;
|
||
|
} else if (usage == STROKE) {
|
||
|
curPC = stroker;
|
||
|
filler.setFillMode(PathFiller.NZFILL);
|
||
|
stroker.setPenDiameter((float)1.0);
|
||
|
stroker.setPenT4(null);
|
||
|
stroker.setCaps(ROUND);
|
||
|
stroker.setCorners(ROUND, 0);
|
||
|
state = PAC_STROKE;
|
||
|
} else {
|
||
|
throw new PRError(PRError.UNK_usage);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the diameter of the pen used in stroking (the actual size and
|
||
|
* shape of the raster pen depends also on the transformation set by
|
||
|
* <tt>setPen(T4)</tt>. Optional after <tt>setUsage(STROKE)</tt>;
|
||
|
* forbidden otherwise.
|
||
|
*
|
||
|
* @param <tt>d</tt>
|
||
|
* the diameter of the pen
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setUsage</tt>, after <tt>beginPath</tt>, or
|
||
|
* after <tt>setUsage(EOFILL)</tt> or <tt>setUsage(NZFILL)</tt>
|
||
|
* (unexpected);
|
||
|
* <li> with <tt>d < 0</tt> (invalid pen diameter).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void setPenDiameter(float d) throws PRError {
|
||
|
if (state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_setPenDiameter);
|
||
|
}
|
||
|
stroker.setPenDiameter(d);
|
||
|
/* state = PAC_STROKE; // in same state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the transformation which transforms the circle defined by
|
||
|
* <tt>setPenDiameter</tt> into the (elliptical) raster pen.
|
||
|
* Optional after <tt>setUsage(STROKE)</tt> (default = identity);
|
||
|
* forbidden otherwise.
|
||
|
*
|
||
|
* @param <tt>t4</tt>
|
||
|
* a 4 coefficient transformation; null stands for the identity transformation
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setUsage</tt>, after <tt>beginPath</tt>, or
|
||
|
* after <tt>setUsage(EOFILL)</tt> or <tt>setUsage(NZFILL)</tt>
|
||
|
* (unexpected),
|
||
|
* <li> with <tt>t4.length < 4</tt> (invalid pen transformation),
|
||
|
* <li> with a non-inversible <tt>t4</tt> (invalid pen transformation (singular)).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void setPenT4(float[] t4) throws PRError {
|
||
|
if (state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_setPenT4);
|
||
|
}
|
||
|
stroker.setPenT4(t4);
|
||
|
/* state = PAC_STROKE; // in same state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Changes the pen transformation to ensure that the ellipse obtained
|
||
|
* by applying the output transformation to the raster pen has vertical
|
||
|
* and horizontal projection which are (1) multiples of <tt>unit</tt>
|
||
|
* and (2) no smaller than <tt>unit*mindiameter</tt>.
|
||
|
* Optional after <tt>setUsage(STROKE)</tt> (default = no changes);
|
||
|
* forbidden otherwise.
|
||
|
*
|
||
|
* @param <tt>unit</tt>
|
||
|
* @param <tt>mindiameter</tt>
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setUsage</tt>, after <tt>beginPath</tt>, or
|
||
|
* after <tt>setUsage(EOFILL)</tt> or <tt>setUsage(NZFILL)</tt>
|
||
|
* (unexpected),
|
||
|
* <li> with <tt>unit < 0</tt> or <tt>mindiameter < 0</tt>
|
||
|
* (invalid pen fitting specification).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void setPenFitting(float unit, int mindiameter) throws PRError {
|
||
|
if (state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_setPenFitting);
|
||
|
}
|
||
|
stroker.setPenFitting(unit, mindiameter);
|
||
|
/* state = PAC_STROKE; // in same state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the displacement from the path trajectory to the center of
|
||
|
* the pen. Optional after <tt>setUsage(STROKE)</tt> (default (0,0));
|
||
|
* forbidden otherwise.
|
||
|
*
|
||
|
* @param <tt>dx</tt>
|
||
|
* the X displacement
|
||
|
* @param <tt>dy</tt>
|
||
|
* the Y displacement
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>setUsage</tt>, after <tt>beginPath</tt>, or
|
||
|
* after <tt>setUsage(EOFILL)</tt> or <tt>setUsage(NZFILL)</tt>
|
||
|
* (unexpected).
|
||
|
*/
|
||
|
public void setPenDisplacement(float dx, float dy) throws PRError {
|
||
|
if (state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_setPenDisplacement);
|
||
|
}
|
||
|
float[] t6 = {(float)1.0, (float)0.0, (float)0.0, (float)1.0, dx, dy};
|
||
|
stroker.setOutputT6(t6);
|
||
|
/* state = PAC_STROKE; // in same state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the shape of the caps to either BUTT, ROUND or SQUARE.
|
||
|
* Optional after <tt>setUsage(STROKE)</tt> (default: ROUND);
|
||
|
* forbidden otherwise.
|
||
|
*
|
||
|
* @param <tt>caps</tt>
|
||
|
* the caps shape selector
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setUsage</tt>, after <tt>beginPath</tt>, or
|
||
|
* after <tt>setUsage(EOFILL)</tt> or <tt>setUsage(NZFILL)</tt>
|
||
|
* (unexpected),
|
||
|
* <li> with an invalid selector (unknown cap type).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void setCaps(int caps) throws PRError {
|
||
|
if (state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_setCaps);
|
||
|
}
|
||
|
stroker.setCaps(caps);
|
||
|
/* state = PAC_STROKE; // in same state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the shape of the corners to either ROUND, BEVEL or MITER.
|
||
|
* Optional after <tt>setUsage(STROKE)</tt> (default: ROUND);
|
||
|
* forbidden otherwise.
|
||
|
*
|
||
|
* @param <tt>corners</tt>
|
||
|
* the corners shape selector
|
||
|
* @param <tt>miter</tt>
|
||
|
* determines how sharp a mitered corner can be; otherwise irrelevant;
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setUsage</tt>, after <tt>beginPath</tt>, or
|
||
|
* after <tt>setUsage(EOFILL)</tt> or <tt>setUsage(NZFILL)</tt>
|
||
|
* (unexpected),
|
||
|
* <li> with an invalid selector (unknown corner type).
|
||
|
* <li> with <tt>corners==MITER & miter < 0</tt> (invalid miter limit).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void setCorners(int corners, float miter) throws PRError {
|
||
|
if (state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_setCorners);
|
||
|
}
|
||
|
stroker.setCorners(corners, miter);
|
||
|
/* state = PAC_STROKE; // in same state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the dash pattern and its initial offset. Optional after
|
||
|
* <tt>setUsage(STROKE)</tt> (default: solid line); forbidden
|
||
|
* otherwise.
|
||
|
*
|
||
|
* @param <tt>dash</tt>
|
||
|
* the dash pattern; its values are lengths, alternatively
|
||
|
* interpreted as dash and interdash lengths (the actual length
|
||
|
* depends also on their direction and on the transformation set by
|
||
|
* <tt>setDashT4</tt>); null stands for a solid line.
|
||
|
* @param <tt>offset</tt>
|
||
|
* the initial offset in the dash pattern
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setUsage</tt>, after <tt>beginPath</tt>, or
|
||
|
* after <tt>setUsage(EOFILL)</tt> or <tt>setUsage(NZFILL)</tt>
|
||
|
* (unexpected),
|
||
|
* <li> with a negative offset, with negative dash or interdash lengths, or
|
||
|
* with a dash pattern consisting only of zeroes
|
||
|
* (invalid dash pattern).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void setDash(float[] dash, float offset) throws PRError {
|
||
|
if (state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_setDash);
|
||
|
}
|
||
|
dasher.setDash(dash, offset);
|
||
|
curPC = dasher; // if the previous call is successful
|
||
|
/* state = PAC_STROKE; // in same state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the transformation which transforms the dash pattern defined
|
||
|
* by <tt>setDash</tt>. Optional after <tt>setUsage(STROKE)</tt>
|
||
|
* (default = identity); forbidden otherwise.
|
||
|
*
|
||
|
* @param <tt>t4</tt>
|
||
|
* a 4 coefficient transformation; null stands for the identity transformation;
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setUsage</tt>, after <tt>beginPath</tt>, or
|
||
|
* after <tt>setUsage(EOFILL)</tt> or <tt>setUsage(NZFILL)</tt>
|
||
|
* (unexpected),
|
||
|
* <li> with <tt>t4.length < 4</tt> (invalid dash transformation),
|
||
|
* <li> with a non-inversible <tt>t4</tt> (invalid dash transformation (singular)).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void setDashT4(float[] dasht4) throws PRError {
|
||
|
if (state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_setDashT4);
|
||
|
}
|
||
|
dasher.setDashT4(dasht4);
|
||
|
/* state = PAC_STROKE; // in same state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ends the PAC description and begins the path description. It is at
|
||
|
* this point that the PAC is validated. Mandatory.
|
||
|
*
|
||
|
* @param <tt>box</tt>
|
||
|
* an optional box (box may be null) containing all the points in the path;
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setUsage</tt> or
|
||
|
* more than once in a rasterization cycle (unexpected),
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void beginPath(float[] box) throws PRError {
|
||
|
beginPath();
|
||
|
}
|
||
|
/**
|
||
|
* Equivalent to beginPath(null).
|
||
|
*/
|
||
|
public void beginPath() throws PRError {
|
||
|
if (state != PAC_FILL && state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_beginPath);
|
||
|
}
|
||
|
try {
|
||
|
curPC.beginPath();
|
||
|
state = PATH;
|
||
|
} catch (PathError e) {
|
||
|
throw new PRError(e.getMessage());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Begins a new subpath. Mandatory after <tt>beginPath</tt>; and everytime
|
||
|
* when a new subpath begins.
|
||
|
*
|
||
|
* @param <tt>x0</tt>
|
||
|
* the X coordinate of the initial point
|
||
|
* @param <tt>y0</tt>
|
||
|
* the Y coordinate of the initial point
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>beginpath</tt> or after <tt>endPath</tt>
|
||
|
* (unexpected).
|
||
|
*/
|
||
|
public void beginSubpath(float x0, float y0) throws PRError {
|
||
|
if (state != PATH && state != SUBPATH) {
|
||
|
throw new PRError(PRError.UNEX_beginSubpath);
|
||
|
}
|
||
|
try {
|
||
|
curPC.beginSubpath(x0, y0);
|
||
|
state = SUBPATH;
|
||
|
} catch (PathError e) {
|
||
|
throw new PRError(e.getMessage());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Appends a line arc to the current subpath. Optional.
|
||
|
*
|
||
|
* @param <tt>x1</tt>
|
||
|
* the X coordinate of the end point
|
||
|
* @param <tt>y1</tt>
|
||
|
* the Y coordinate of the end point
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>beginSubpath</tt> or after <tt>endPath</tt>
|
||
|
* (unexpected).
|
||
|
*/
|
||
|
public void appendLine(float x1, float y1) throws PRError {
|
||
|
if (state != SUBPATH) {
|
||
|
throw new PRError(PRError.UNEX_appendLine);
|
||
|
}
|
||
|
try {
|
||
|
curPC.appendLine(x1, y1);
|
||
|
} catch (PathError e) {
|
||
|
throw new PRError(e.getMessage());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Appends a quadratic arc to the current subpath. Optional.
|
||
|
*
|
||
|
* @param <tt>xm</tt>
|
||
|
* the X coordinate of the control point;
|
||
|
* @param <tt>ym</tt>
|
||
|
* the Y coordinate of the control point;
|
||
|
* @param <tt>x1</tt>
|
||
|
* the X coordinate of the end point;
|
||
|
* @param <tt>y1</tt>
|
||
|
* the Y coordinate of the end point;
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>beginSubpath</tt> or after <tt>endPath</tt>
|
||
|
* (unexpected).
|
||
|
*/
|
||
|
public void appendQuadratic(float xm, float ym, float x1, float y1)
|
||
|
throws PRError {
|
||
|
if (state != SUBPATH) {
|
||
|
throw new PRError(PRError.UNEX_appendQuadratic);
|
||
|
}
|
||
|
try {
|
||
|
curPC.appendQuadratic(xm, ym, x1, y1);
|
||
|
} catch (PathError e) {
|
||
|
throw new PRError(e.getMessage());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Appends a cubic arc to the current subpath. Optional.
|
||
|
*
|
||
|
* @param <tt>xm</tt>
|
||
|
* the X coordinate of the 1st control point;
|
||
|
* @param <tt>ym</tt>
|
||
|
* the Y coordinate of the 1st control point;
|
||
|
* @param <tt>xn</tt>
|
||
|
* the X coordinate of the 2nd control point;
|
||
|
* @param <tt>yn</tt>
|
||
|
* the Y coordinate of the 2nd control point;
|
||
|
* @param <tt>x1</tt>
|
||
|
* the X coordinate of the end point;
|
||
|
* @param <tt>y1</tt>
|
||
|
* the Y coordinate of the end point;
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>beginSubpath</tt> or after <tt>endPath</tt>
|
||
|
* (unexpected).
|
||
|
*/
|
||
|
public void appendCubic(float xm, float ym, float xn, float yn, float x1, float y1)
|
||
|
throws PRError {
|
||
|
if (state != SUBPATH) {
|
||
|
throw new PRError(PRError.UNEX_appendCubic);
|
||
|
}
|
||
|
try {
|
||
|
curPC.appendCubic(xm, ym, xn, yn, x1, y1);
|
||
|
} catch (PathError e) {
|
||
|
throw new PRError(e.getMessage());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Declares that the current subpath will be closed. This may require
|
||
|
* to append a line arc connecting the last point to the first.
|
||
|
* Optional.
|
||
|
*
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>beginSubpath</tt> or after <tt>endPath</tt>
|
||
|
* (unexpected).
|
||
|
*/
|
||
|
public void closedSubpath() throws PRError {
|
||
|
if (state != SUBPATH)
|
||
|
throw new PRError(PRError.UNEX_closedSubpath);
|
||
|
try {
|
||
|
curPC.closedSubpath();
|
||
|
} catch (PathError e) {
|
||
|
throw new PRError(e.getMessage());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* Ends the path description. Mandatory.
|
||
|
*
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>beginPath</tt> or more than once in a rasterization cycle
|
||
|
* (unexpected).
|
||
|
* @exception PRException
|
||
|
* when the rasterization would result in non-zero alpha values for pixel
|
||
|
* coordinates outside of [<tt>-MAX_ALPHA,MAX_ALPHA</tt>]
|
||
|
* (alpha coordinate out of bounds).
|
||
|
*/
|
||
|
public void endPath() throws PRError, PRException {
|
||
|
if (state != PATH && state != SUBPATH)
|
||
|
throw new PRError(PRError.UNEX_endPath);
|
||
|
try {
|
||
|
curPC.endPath();
|
||
|
state = RAS;
|
||
|
} catch (PathError e) {
|
||
|
throw new PRError(e.getMessage());
|
||
|
} catch (PathException e) {
|
||
|
String msg = e.getMessage();
|
||
|
if (msg == null || !msg.startsWith("endPath:"))
|
||
|
throw new PRException(msg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Describes a path <i>by proxy</i>
|
||
|
* @exception PRError
|
||
|
* when invoked at an inappropriate time (unexpected).
|
||
|
* @see dc.path.FastPathProducer
|
||
|
*/
|
||
|
public void useProxy(FastPathProducer proxy) throws PRError, PRException {
|
||
|
if (state != PAC_FILL && state != PAC_STROKE) {
|
||
|
throw new PRError(PRError.UNEX_useProxy);
|
||
|
}
|
||
|
try {
|
||
|
curPC.useProxy(proxy);
|
||
|
state = RAS;
|
||
|
} catch (PathError e) {
|
||
|
throw new PRError(e.getMessage());
|
||
|
} catch (PathException e) {
|
||
|
throw new PRException(e.getMessage());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns in its argument array a box guaranteed to contain every
|
||
|
* non-zero alpha pixel. Optional. May be invoked <ol>
|
||
|
* <li> anytime after using <tt>beginPath</tt> with a non-null path box,
|
||
|
* <li> after <tt>endPath</tt>.
|
||
|
* </ol>
|
||
|
*
|
||
|
* @param <tt>box</tt>
|
||
|
* an array of no less than 4 entries where the extreme coordinates
|
||
|
* of the alpha box are placed;
|
||
|
*
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>beginPath</tt> or
|
||
|
* after <tt>beginPath(null)</tt> but before <tt>endPath</tt>
|
||
|
* (unexpected),
|
||
|
* <li> with a statically invalid parameter
|
||
|
* (<tt>box == null || box.length < 4</tt>)
|
||
|
* (invalid box destination array).
|
||
|
* </ol>
|
||
|
*/
|
||
|
public void getAlphaBox(int[] box) throws PRError {
|
||
|
filler.getAlphaBox(box);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Declares the output area (OA), a region of raster space
|
||
|
* containing all the pixels deemed interesting by the client.
|
||
|
* The pixels will be written by succeeding invocations to
|
||
|
* <tt>writeAlpha</tt>.
|
||
|
* <p>
|
||
|
* Pixels will be retrieved in "tiles", rectangular groups of maximum
|
||
|
* dimension less than or equal to <tt>TILE_SIZE</tt>.
|
||
|
* The region is tiled with maximal square tiles organized in "rows"
|
||
|
* extending in the direction X+. If we visualize the coordinate axii
|
||
|
* X/Y respectively pointing right/up, then the first tile is placed
|
||
|
* with its lower/left corner coincident with the lower/left corner
|
||
|
* of the output area. The first row consists of the first tile and
|
||
|
* possibly others placed to its right, as needed to completely cover
|
||
|
* the width of the output area. Rows are stacked above the first row
|
||
|
* as needed to completely cover the height of the output area.
|
||
|
* Tiles do not exceed OA; because the width and height of OA are not,
|
||
|
* in general, multiples of <tt>TILE_SIZE</tt>, the rightmost tiles may
|
||
|
* have a width < <tt>TILE_SIZE</tt> and the uppermost tiles a height
|
||
|
* less than <tt>TILE_SIZE</tt>.
|
||
|
* <p>
|
||
|
* The method is mandatory. It must be used at least once, after the
|
||
|
* description of the path and before the retrival of tiles can
|
||
|
* begin.
|
||
|
*
|
||
|
* @param <tt>x0</tt>
|
||
|
* the low X boundary of the output area;
|
||
|
* @param <tt>y0</tt>
|
||
|
* the low Y boundary of the output area;
|
||
|
* @param <tt>w</tt>
|
||
|
* the (>0) X dimension of the output area;
|
||
|
* @param <tt>h</tt>
|
||
|
* the (>0) Y dimension of the output area;
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>endPath</tt> (unexpected),
|
||
|
* <li> with a statically invalid output area
|
||
|
* (<tt>w <= 0 | h <= 0</tt>)
|
||
|
* (invalid output area),
|
||
|
* </ol>
|
||
|
* @exception PRException
|
||
|
* when <tt>x0</tt>, <tt>y0</tt>, <tt>x0+w</tt> or <tt>y0+h</tt> fall outside
|
||
|
* [<tt>-MAX_ALPHA,MAX_ALPHA</tt>] (alpha coordinate out of bounds).
|
||
|
*/
|
||
|
public void setOutputArea(float x0, float y0, int w, int h)
|
||
|
throws PRError, PRException {
|
||
|
filler.setOutputArea(x0, y0, w, h);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the state of the current tile. Optional.
|
||
|
* @return either TILE_IS_ALL_0, TILE_IS_ALL_1 or TILE_IS_GENERAL
|
||
|
*
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>setOutputArea</tt> (unexpected),
|
||
|
*/
|
||
|
public int getTileState() throws PRError {
|
||
|
return filler.getTileState(); /* return current tile state */
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Writes the alpha pixels of the current tile to pixel destination
|
||
|
* declared - the rectangular array alpha; this array is organized
|
||
|
* so the index difference between two pixels is <tt>xstride</tt>
|
||
|
* for X-adjacent pixels and <tt>ystride</tt> for Y-adjacent pixels.
|
||
|
* The pixel of lowest coordinates in the tile is written to the alpha
|
||
|
* array position <tt>pix0offset</tt>, depending on the alpha values -
|
||
|
* reals between 0 and 1 - are scaled by 255 (<tt>byte[] alpha</tt>)
|
||
|
* or 65535 (<tt>char[] alpha</tt>).
|
||
|
*
|
||
|
* @param <tt>alpha</tt>
|
||
|
* the array where pixels is to be placed;
|
||
|
* @param <tt>xstride</tt>
|
||
|
* the index difference in the array of alphas (>0) between two
|
||
|
* pixels adjacent in the X direction;
|
||
|
* @param <tt>ystride</tt>
|
||
|
* the index difference in the array of alphas (>0) between two
|
||
|
* pixels adjacent in the Y direction;
|
||
|
* @param <tt>pix0ffset</tt>
|
||
|
* the offset (>=0) of the lowest coordinates pixel in the array
|
||
|
* alpha.
|
||
|
* @exception PRError
|
||
|
* when invoked <ol>
|
||
|
* <li> before <tt>setOutputArea</tt> (unexpected),
|
||
|
* <li> with <tt>alpha==null</tt>,
|
||
|
* <tt>xstride <= 0 or ystride <= 0</tt>
|
||
|
* (invalid alpha destination).
|
||
|
* </ol>
|
||
|
* @exception PRException
|
||
|
* when the combination of the pixel destination parameters
|
||
|
* (<tt>alpha.length</tt>, <tt>xstride</tt> and <tt>ystride</tt>),
|
||
|
* <tt>pix0offset</tt> and dimensions of the current tile would
|
||
|
* otherwise result in an <tt>IndexOutOfBoundsException</tt>
|
||
|
* (alpha destination array too short).
|
||
|
*/
|
||
|
public void writeAlpha(byte[] alpha, int xstride, int ystride, int pix0offset)
|
||
|
throws PRError, PRException, InterruptedException {
|
||
|
filler.writeAlpha(alpha, xstride, ystride, pix0offset);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* See writeAlpha(byte[] ...)
|
||
|
*/
|
||
|
public void writeAlpha(char[] alpha, int xstride, int ystride, int pix0offset)
|
||
|
throws PRError, PRException, InterruptedException {
|
||
|
filler.writeAlpha(alpha, xstride, ystride, pix0offset);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Advances to the next tile. Optional (but either <tt>writeAlpha</tt> or
|
||
|
* <tt>nextTile</tt> must be used in order to move to the next tile).
|
||
|
* @exception PRError
|
||
|
* when invoked before <tt>setOutputArea</tt> (unexpected).
|
||
|
*/
|
||
|
public void nextTile() throws PRError {
|
||
|
filler.nextTile();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Mandatory; must be invoked to end a rasterization cycle.
|
||
|
* Can be invoked anytime.
|
||
|
*/
|
||
|
public void reset() {
|
||
|
state = BEG;
|
||
|
filler.reset();
|
||
|
stroker.reset();
|
||
|
dasher.reset();
|
||
|
}
|
||
|
}
|