/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "jni.h"
#include "jni_util.h"
#include <jlong.h>
#include "j2d_md.h"
#include "PathConsumer2D.h"
#include "SpanIterator.h"
#include "sun_java2d_pipe_ShapeSpanIterator.h"
#include "java_awt_geom_PathIterator.h"
/*
* This structure holds all of the information needed to trace and
* manage a single line segment of the shape's outline.
*/
typedef struct {
} segmentData;
/*
* This structure holds all of the information needed to trace out
* the entire span list of a single Shape object.
*/
typedef struct {
} pathData;
#define STATE_INIT 0
};
do { \
} else { \
} \
} while (0)
/*
* _ADJUST is the internal macro used to adjust a new endpoint
* and then invoke the "additional" code from the callers below
* which will adjust the control points as needed to match.
*
* When the "additional" code is executed, newadj[xy] will
* contain the adjustment applied to the new endpoint and
* pd->adj[xy] will still contain the previous adjustment
* that was applied to the old endpoint.
*/
do { \
x = newx; \
y = newy; \
additional; \
} \
} while (0)
/*
* Adjust a single endpoint with no control points.
* "additional" code is a null statement.
*/
do { \
} while (0))
/*
* Adjust a quadratic curve. The _ADJUST macro takes care
* of the new endpoint and the "additional" code adjusts
* the single quadratic control point by the averge of
* the prior and the new adjustment amounts.
*/
do { \
} while (0))
/*
* Adjust a cubic curve. The _ADJUST macro takes care
* of the new endpoint and the "additional" code adjusts
* the first of the two cubic control points by the same
* amount that the prior endpoint was adjusted and then
* adjusts the second of the two control points by the
* same amount as the new endpoint was adjusted. This
* keeps the tangent lines from xy0 to xy1 and xy3 to xy2
* parallel before and after the adjustment.
*/
do { \
} while (0))
do { \
} while (0)
do { \
if (!subdivideLine(pd, 0, \
OOMERR; \
break; \
} \
} while (0)
do { \
if (!subdivideQuad(pd, 0, \
OOMERR; \
break; \
} \
} while (0)
do { \
if (!subdivideCubic(pd, 0, \
OOMERR; \
break; \
} \
} while (0)
do { \
if (!subdivideLine(pd, 0, \
OOMERR; \
break; \
} \
} \
} while (0)
do { \
} while (0)
static pathData *
{
}
return pd;
}
static pathData *
{
return NULL;
}
} else {
/* Initialize PathConsumer2D struct header */
/* Initialize ShapeSpanIterator fields */
}
return pd;
}
{
}
/*
* Class: sun_java2d_pipe_ShapeSpanIterator
* Method: setNormalize
* Signature: (Z)V
*/
{
return;
}
}
{
return;
}
}
{
return;
}
}
{
int numpts = 0;
return;
}
return;
}
switch (type) {
break;
break;
break;
break;
break;
default:
return;
}
if (oom) {
return;
}
}
{
return;
}
}
{
return;
}
}
{
return JNI_FALSE;
}
if (ret) {
}
return ret;
}
{
return;
}
ShapeSISkipDownTo(pd, y);
}
{
return ptr_to_jlong(&ShapeSIFuncs);
}
{
return;
}
}
}
}
do { \
else outc = 0; \
} while (0)
{
int i;
return;
}
xoff += 0.25f;
yoff += 0.25f;
}
return;
}
{
return;
}
if (nPoints > 0) {
jfloat x, y;
/* Horizontal segment - do not append */
/* Not empty segment - track change in X */
}
continue;
}
if (outc0 == 0) {
}
}
}
}
}
if (!oom) {
}
if (oom) {
}
}
{
return;
}
}
{
return;
}
}
{
return;
}
}
{
return;
}
}
{
return;
}
}
{
return;
}
}
{
return jlong_zero;
}
}
static jboolean
{
return oom;
}
static jboolean
{
return oom;
}
static jboolean
{
return oom;
}
static jboolean
{
return oom;
}
static jboolean
{
return oom;
}
static jboolean
{
return oom;
}
/*
* REMIND: CDECL needed for WIN32 "qsort"
*/
#ifdef _WIN32
#else
#define CDECL
#endif
do { \
} else { \
} \
} while(0)
do { \
} else { \
} \
} else { \
} else { \
} \
} \
} while (0)
do { \
} else { \
} \
} else { \
} else { \
} \
} \
} while(0)
static jfloat
{
/* Adjust vectors relative to x0,y0 */
/* x1,y1 becomes relative vector from x0,y0 to end of segment */
/* px,py becomes relative vector from x0,y0 to test point */
if (dotprod <= 0.0) {
/* px,py is on the side of x0,y0 away from x1,y1 */
/* distance to segment is length of px,py vector */
/* "length of its (clipped) projection" is now 0.0 */
projlenSq = 0.0;
} else {
/* switch to backwards vectors relative to x1,y1 */
/* x1,y1 are already the negative of x0,y0=>x1,y1 */
/* to get px,py to be the negative of px,py=>x1,y1 */
/* the dot product of two negated vectors is the same */
/* as the dot product of the two normal vectors */
if (dotprod <= 0.0) {
/* px,py is on the side of x1,y1 away from x0,y0 */
/* distance to segment is length of (backwards) px,py vector */
/* "length of its (clipped) projection" is now 0.0 */
projlenSq = 0.0;
} else {
/* px,py is between x0,y0 and x1,y1 */
/* dotprod is the length of the px,py vector */
/* projected on the x1,y1=>x0,y0 vector times the */
/* length of the x1,y1=>x0,y0 vector */
}
}
/* Distance to line is now the length of the relative point */
/* vector minus the length of its projection onto the line */
/* (which is zero if the projection falls outside the range */
/* of the line segment). */
}
static jboolean
{
jfloat t;
windDir = -1;
} else {
windDir = 1;
}
/* We want to iterate at every horizontal pixel center (HPC) crossing. */
/* First calculate next highest HPC we will cross at the start. */
/* Then calculate next highest HPC we would cross at the end. */
/* Ignore if we start and end outside clip, or on the same scanline. */
return JNI_TRUE;
}
/* We will need to insert this segment, check for room. */
return JNI_FALSE;
}
}
}
/*
* The Y coordinate of the first HPC was calculated as istarty. We
* now need to calculate the corresponding X coordinate (both integer
* version for span start coordinate and float version for sub-pixel
* error calculation).
*/
/* First, how far does y bump to get to next HPC? */
/* Now, bump the float x coordinate to get X sample at that HPC. */
/* Now calculate the integer coordinate that such a span starts at. */
/* NOTE: Span inclusion is based on vertical pixel centers (VPC). */
/* What is the lower bound of the per-scanline change in the X coord? */
/* What is the subpixel amount by which the bumpx is off? */
/* Finally, find out how far the x coordinate can go before next VPC. */
return JNI_TRUE;
}
/*
* Lines don't really need to be subdivided, but this function performs
* the same trivial rejections and reductions that the curve subdivision
* functions perform before it hands the coordinates off to the appendSegment
* function.
*/
static jboolean
{
return JNI_TRUE;
}
}
}
static jboolean
{
return JNI_TRUE;
}
}
if (level < SUBDIVIDE_MAX) {
/* Test if the curve is flat enough for insertion. */
level++;
}
}
}
static jboolean
{
return JNI_TRUE;
}
}
if (level < SUBDIVIDE_MAX) {
/* Test if the curve is flat enough for insertion. */
{
level++;
}
}
}
static int CDECL
{
return -1;
}
return 1;
}
return -1;
}
return 1;
}
return -1;
}
return 1;
}
return 0;
}
static void *
{
}
static void
{
}
static void
{
}
/* Adjust the clip box from the given bounds. Used to constrain
the output to a device clip
*/
static void
{
}
}
}
}
}
static jboolean
{
if (!initSegmentTable(pd)) {
/* REMIND: - throw exception? */
return JNI_FALSE;
}
}
continue;
}
}
cur += 2;
} else {
}
} else {
cur++;
while (JNI_TRUE) {
break;
}
if (wind == 0) {
break;
}
}
}
}
continue;
}
break;
}
break;
}
/* Go through active segments and toss which end "above" loy */
}
}
/* The current list of segments is empty so we need to
* jump to the beginning of the next set of segments.
* Since the segments are not clipped to the output
* area we need to make sure we don't jump "backwards"
*/
}
}
/* Go through new segments and accept any which start "above" loy */
hi++;
}
/* Update and sort the active segments by x0 */
/* First update the x0, y0 of the segment */
err &= ERRSTEP_MAX;
} else {
}
/* Then make sure the segment is sorted by x0 */
break;
}
}
}
}
return ret;
}
static void
{
if (!initSegmentTable(pd)) {
/* REMIND: - throw exception? */
return;
}
}
/* Make sure we are jumping forward */
/* Pretend like we just finished with the span line y-1... */
}
}
static jboolean
{
if (segmentTable == NULL) {
return JNI_FALSE;
}
for (i = 0; i < pd->numSegments; i++) {
}
/* Skip to the first segment that ends below the top clip edge */
cur = 0;
cur++;
}
/* Prepare for next action to increment loy and prepare new segments */
return JNI_TRUE;
}