/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#include "sun_java2d_x11_X11Renderer.h"

#include "X11SurfaceData.h"
#include "SpanIterator.h"
#include "Trace.h"
#include "ProcessPath.h"
#include "GraphicsPrimitiveMgr.h"


#include <jlong.h>

#ifndef HEADLESS
#define POLYTEMPSIZE    (int)(256 / sizeof(XPoint))
#define ABS(n)          (((n) < 0) ? -(n) : (n))

#define MAX_SHORT 32767
#define MIN_SHORT (-32768)

#define CLAMP_TO_SHORT(x) (((x) > MAX_SHORT)                            \
                           ? MAX_SHORT                                  \
                           : ((x) < MIN_SHORT)                          \
                               ? MIN_SHORT                              \
                               : (x))

#define CLAMP_TO_USHORT(x)  (((x) > 65535) ? 65535 : ((x) < 0) ? 0 : (x))

#define DF_MAX_XPNTS 256

typedef struct {
    Drawable drawable;
    GC      gc;
    XPoint  *pPoints;
    XPoint  dfPoints[DF_MAX_XPNTS];
    jint    npoints;
    jint    maxpoints;
} XDrawHandlerData;

#define XDHD_INIT(PTR, _GC, DRAWABLE)                                       \
    do {                                                                    \
        (PTR)->pPoints = (PTR)->dfPoints;                                   \
        (PTR)->npoints = 0;                                                 \
        (PTR)->maxpoints = DF_MAX_XPNTS;                                    \
        (PTR)->gc = (_GC);                                                    \
        (PTR)->drawable = (DRAWABLE);                                         \
    } while(0)

#define XDHD_RESET(PTR)                                                     \
    do {                                                                    \
        (PTR)->npoints = 0;                                                 \
    } while(0)


#define XDHD_ADD_POINT(PTR, X, Y)                                           \
    do {                                                                    \
        XPoint* _pnts = (PTR)->pPoints;                                     \
        jint _npnts = (PTR)->npoints;                                       \
        if (_npnts >= (PTR)->maxpoints) {                                   \
            jint newMax = (PTR)->maxpoints*2;                               \
            if ((PTR)->pPoints == (PTR)->dfPoints) {                        \
                (PTR)->pPoints = (XPoint*)malloc(newMax*sizeof(XPoint));    \
                memcpy((PTR)->pPoints, _pnts, _npnts*sizeof(XPoint));       \
            } else {                                                        \
                (PTR)->pPoints = (XPoint*)realloc(                          \
                    _pnts, newMax*sizeof(XPoint));                          \
            }                                                               \
            _pnts = (PTR)->pPoints;                                         \
            (PTR)->maxpoints = newMax;                                      \
        }                                                                   \
        _pnts += _npnts;                                                    \
        _pnts->x = X;                                                       \
        _pnts->y = Y;                                                       \
        (PTR)->npoints = _npnts + 1;                                        \
    } while(0)

#define XDHD_FREE_POINTS(PTR)                                               \
    do {                                                                    \
        if ((PTR)->pPoints != (PTR)->dfPoints) {                            \
            free((PTR)->pPoints);                                           \
        }                                                                   \
    } while(0)


static void
awt_drawArc(JNIEnv * env, jint drawable, GC xgc,
            int x, int y, int w, int h,
            int startAngle, int endAngle,
            int filled)
{
    int s, e;

    if (w < 0 || h < 0) {
        return;
    }
    if (endAngle >= 360 || endAngle <= -360) {
        s = 0;
        e = 360 * 64;
    } else {
        s = (startAngle % 360) * 64;
        e = endAngle * 64;
    }
    if (filled == 0) {
        XDrawArc(awt_display, drawable, xgc, x, y, w, h, s, e);
    } else {
        XFillArc(awt_display, drawable, xgc, x, y, w, h, s, e);
    }
}

/*
 * Copy vertices from xcoordsArray and ycoordsArray to a buffer
 * of XPoint structures, translating by transx and transy and
 * collapsing empty segments out of the list as we go.
 * The number of points to be converted should be guaranteed
 * to be more than 2 by the caller and is stored at *pNpoints.
 * The resulting number of uncollapsed unique translated vertices
 * will be stored back into the location *pNpoints.
 * The points pointer is guaranteed to be pointing to an area of
 * memory large enough for POLYTEMPSIZE points and a larger
 * area of memory is allocated (and returned) if that is not enough.
 */
static XPoint *
transformPoints(JNIEnv * env,
                jintArray xcoordsArray, jintArray ycoordsArray,
                jint transx, jint transy,
                XPoint * points, int *pNpoints, int close)
{
    int npoints = *pNpoints;
    jint *xcoords, *ycoords;

    xcoords = (jint *)
        (*env)->GetPrimitiveArrayCritical(env, xcoordsArray, NULL);
    if (xcoords == NULL) {
        return 0;
    }

    ycoords = (jint *)
        (*env)->GetPrimitiveArrayCritical(env, ycoordsArray, NULL);
    if (ycoords == NULL) {
        (*env)->ReleasePrimitiveArrayCritical(env, xcoordsArray, xcoords,
                                              JNI_ABORT);
        return 0;
    }

    if (close) {
        close = (xcoords[npoints - 1] != xcoords[0] ||
                 ycoords[npoints - 1] != ycoords[0]);
        if (close) {
            npoints++;
        }
    }
    if (npoints > POLYTEMPSIZE) {
        points = (XPoint *) malloc(sizeof(XPoint) * npoints);
    }
    if (points != NULL) {
        int in, out;
        int oldx = CLAMP_TO_SHORT(xcoords[0] + transx);
        int oldy = CLAMP_TO_SHORT(ycoords[0] + transy);
        points[0].x = oldx;
        points[0].y = oldy;
        if (close) {
            npoints--;
        }
        for (in = 1, out = 1; in < npoints; in++) {
            int newx = CLAMP_TO_SHORT(xcoords[in] + transx);
            int newy = CLAMP_TO_SHORT(ycoords[in] + transy);
            if (newx != oldx || newy != oldy) {
                points[out].x = newx;
                points[out].y = newy;
                out++;
                oldx = newx;
                oldy = newy;
            }
        }
        if (out == 1) {
            points[1].x = oldx;
            points[1].y = oldy;
            out = 2;
        } else if (close) {
            points[out++] = points[0];
        }
        *pNpoints = out;
    }

    (*env)->ReleasePrimitiveArrayCritical(env, xcoordsArray, xcoords,
                                          JNI_ABORT);
    (*env)->ReleasePrimitiveArrayCritical(env, ycoordsArray, ycoords,
                                          JNI_ABORT);

    return points;
}
#endif /* !HEADLESS */

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XDrawLine
 * Signature: (IJIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawLine
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x1, jint y1, jint x2, jint y2)
{
#ifndef HEADLESS
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
              CLAMP_TO_SHORT(x1), CLAMP_TO_SHORT(y1),
              CLAMP_TO_SHORT(x2), CLAMP_TO_SHORT(y2));
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XDrawRect
 * Signature: (IJIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawRect
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x, jint y, jint w, jint h)
{
#ifndef HEADLESS
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL || w < 0 || h < 0) {
        return;
    }

    if (w < 2 || h < 2) {
        /* REMIND: This optimization assumes thin lines. */
        /*
         * This optimization not only simplifies the processing
         * of a particular degenerate case, but it protects against
         * the anomalies of various X11 implementations that draw
         * nothing for degenerate Polygons and Rectangles.
         */
        XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
                       CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
                       CLAMP_TO_USHORT(w+1), CLAMP_TO_USHORT(h+1));
    } else {
        XDrawRectangle(awt_display, xsdo->drawable, (GC) xgc,
                       CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
                       CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
    }
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XDrawRoundRect
 * Signature: (IJIIIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawRoundRect
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x, jint y, jint w, jint h,
     jint arcW, jint arcH)
{
#ifndef HEADLESS
    long ty1, ty2, tx1, tx2, cx, cy, cxw, cyh,
         halfW, halfH, leftW, rightW, topH, bottomH;
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL || w < 0 || h < 0) {
        return;
    }

    arcW = ABS(arcW);
    arcH = ABS(arcH);
    if (arcW > w) {
        arcW = w;
    }
    if (arcH > h) {
        arcH = h;
    }

    if (arcW == 0 || arcH == 0) {
        Java_sun_java2d_x11_X11Renderer_XDrawRect(env, xr, pXSData, xgc,
                                                  x, y, w, h);
        return;
    }

    halfW = (arcW / 2);
    halfH = (arcH / 2);

    /* clamp to short bounding box of round rectangle */
    cx = CLAMP_TO_SHORT(x);
    cy = CLAMP_TO_SHORT(y);
    cxw = CLAMP_TO_SHORT(x + w);
    cyh = CLAMP_TO_SHORT(y + h);

    /* clamp to short coordinates of lines */
    tx1 = CLAMP_TO_SHORT(x + halfW + 1);
    tx2 = CLAMP_TO_SHORT(x + w - halfW - 1);
    ty1 = CLAMP_TO_SHORT(y + halfH + 1);
    ty2 = CLAMP_TO_SHORT(y + h - halfH - 1);

    /*
     * recalculate heightes and widthes of round parts
     * to minimize distortions in visible area
     */
    leftW = (tx1 - cx) * 2;
    rightW = (cxw - tx2) * 2;
    topH = (ty1 - cy) * 2;
    bottomH = (cyh - ty2) * 2;

    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                cx, cy, leftW, topH,
                90, 90, JNI_FALSE);
    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                cxw - rightW, cy, rightW, topH,
                0, 90, JNI_FALSE);
    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                cx, cyh - bottomH, leftW, bottomH,
                180, 90, JNI_FALSE);
    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                cxw - rightW, cyh - bottomH, rightW, bottomH,
                270, 90, JNI_FALSE);

    if (tx1 <= tx2) {
        XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
                  tx1, cy, tx2, cy);
        if (h > 0) {
            XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
                      tx1, cyh, tx2, cyh);
        }
    }
    if (ty1 <= ty2) {
        XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
                  cx, ty1, cx, ty2);
        if (w > 0) {
            XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
                      cxw, ty1, cxw, ty2);
        }
    }
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XDrawOval
 * Signature: (IJIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawOval
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x, jint y, jint w, jint h)
{
#ifndef HEADLESS
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    if (w < 2 || h < 2) {
        /*
         * Fix for 4205762 - 1x1 ovals do not draw on Ultra1, Creator3d
         * (related to 4411814 on Windows platform)
         * Really small ovals degenerate to simple rectangles as they
         * have no curvature or enclosed area.  Use XFillRectangle
         * for speed and to deal better with degenerate sizes.
         */
        if (w >= 0 && h >= 0) {
            XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
                           x, y, w+1, h+1);
        }
    } else {
        awt_drawArc(env, xsdo->drawable, (GC) xgc,
                    x, y, w, h, 0, 360, JNI_FALSE);
    }
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XDrawArc
 * Signature: (IJIIIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawArc
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x, jint y, jint w, jint h,
     jint angleStart, jint angleExtent)
{
#ifndef HEADLESS
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                x, y, w, h, angleStart, angleExtent, JNI_FALSE);
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XDrawPoly
 * Signature: (IJII[I[IIZ)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawPoly
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint transx, jint transy,
     jintArray xcoordsArray, jintArray ycoordsArray, jint npoints,
     jboolean isclosed)
{
#ifndef HEADLESS
    XPoint pTmp[POLYTEMPSIZE], *points;
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    if (JNU_IsNull(env, xcoordsArray) || JNU_IsNull(env, ycoordsArray)) {
        JNU_ThrowNullPointerException(env, "coordinate array");
        return;
    }
    if ((*env)->GetArrayLength(env, ycoordsArray) < npoints ||
        (*env)->GetArrayLength(env, xcoordsArray) < npoints)
    {
        JNU_ThrowArrayIndexOutOfBoundsException(env, "coordinate array");
        return;
    }

    if (npoints < 2) {
        return;
    }

    points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy,
                             pTmp, (int *)&npoints, isclosed);
    if (points == 0) {
        JNU_ThrowOutOfMemoryError(env, "translated coordinate array");
    } else {
        if (npoints == 2) {
            /*
             * Some X11 implementations fail to draw anything for
             * simple 2 point polygons where the vertices are the
             * same point even though this violates the X11
             * specification.  For simplicity we will dispatch all
             * 2 point polygons through XDrawLine even if they are
             * non-degenerate as this may invoke less processing
             * down the line than a Poly primitive anyway.
             */
            XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
                      points[0].x, points[0].y,
                      points[1].x, points[1].y);
        } else {
            XDrawLines(awt_display, xsdo->drawable, (GC) xgc,
                       points, npoints, CoordModeOrigin);
        }
        if (points != pTmp) {
            free(points);
        }
        X11SD_DirectRenderNotify(env, xsdo);
    }
#endif /* !HEADLESS */
}

static void storeLine(DrawHandler* hnd,
                      jint x0, jint y0, jint x1, jint y1)
{
#ifndef HEADLESS
    XDrawHandlerData* dhnd = (XDrawHandlerData*)(hnd->pData);

    XDHD_ADD_POINT(dhnd, x0, y0);
    XDHD_ADD_POINT(dhnd, x1, y1);
#endif /* !HEADLESS */
}

static void storePoint(DrawHandler* hnd, jint x0, jint y0) {
#ifndef HEADLESS
    XDrawHandlerData* dhnd = (XDrawHandlerData*)(hnd->pData);

    XDHD_ADD_POINT(dhnd, x0, y0);
#endif /* !HEADLESS */
}

static void drawSubPath(ProcessHandler* hnd) {
#ifndef HEADLESS
    XDrawHandlerData* dhnd = (XDrawHandlerData*)(hnd->dhnd->pData);
    XPoint *points = dhnd->pPoints;

    switch (dhnd->npoints) {
    case 0:
        /* No-op */
        break;
    case 1:
        /* Draw the single pixel */
        XFillRectangle(awt_display, dhnd->drawable, dhnd->gc,
                       points[0].x, points[0].y, 1, 1);
        break;
    case 2:
        /*
         * The XDrawLines method for some X11 implementations
         * fails to draw anything for simple 2 point polygons
         * where the vertices are the same point even though
         * this violates the X11 specification.  For simplicity
         * we will dispatch all 2 point polygons through XDrawLine
         * even if they are non-degenerate as this may invoke
         * less processing down the line than a poly primitive anyway.
         */
        XDrawLine(awt_display, dhnd->drawable, dhnd->gc,
                  points[0].x, points[0].y,
                  points[1].x, points[1].y);
        break;
    default:
        /* Draw the entire polyline */
        XDrawLines(awt_display, dhnd->drawable, dhnd->gc, points,
                   dhnd->npoints, CoordModeOrigin);
        break;
    }

    XDHD_RESET(dhnd);
#endif /* !HEADLESS */
}

static void drawScanline(DrawHandler* hnd, jint x0, jint x1, jint y0)
{
#ifndef HEADLESS
    XDrawHandlerData* dhnd = (XDrawHandlerData*)(hnd->pData);

    XDrawLine(awt_display, dhnd->drawable, dhnd->gc, x0, y0, x1, y0);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XDoPath
 * Signature: (Lsun/java2d/SunGraphics2D;JJIILjava/awt/geom/Path2D/Float;Z)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_x11_X11Renderer_XDoPath
    (JNIEnv *env, jobject self, jobject sg2d, jlong pXSData, jlong xgc,
     jint transX, jint transY, jobject p2df, jboolean isFill)
{
#ifndef HEADLESS
    X11SDOps *xsdo = (X11SDOps *) pXSData;
    jarray typesArray;
    jobject pointArray;
    jarray coordsArray;
    jint numTypes;
    jint fillRule;
    jint maxCoords;
    jbyte *types;
    jfloat *coords;
    XDrawHandlerData dHData;
    DrawHandler drawHandler = {
        NULL, NULL, NULL,
        MIN_SHORT, MIN_SHORT, MAX_SHORT, MAX_SHORT,
        0, 0, 0, 0,
        NULL
    };
    PHStroke stroke;

    if (xsdo == NULL) {
        return;
    }

    if (isFill) {
        fillRule = (*env)->GetIntField(env, p2df, path2DWindingRuleID);
    }

    typesArray = (jarray)(*env)->GetObjectField(env, p2df, path2DTypesID);
    coordsArray = (jarray)(*env)->GetObjectField(env, p2df,
                                                 path2DFloatCoordsID);
    if (coordsArray == NULL) {
        JNU_ThrowNullPointerException(env, "coordinates array");
        return;
    }
    numTypes = (*env)->GetIntField(env, p2df, path2DNumTypesID);
    if ((*env)->GetArrayLength(env, typesArray) < numTypes) {
        JNU_ThrowArrayIndexOutOfBoundsException(env, "types array");
        return;
    }

    XDHD_INIT(&dHData, (GC)xgc, xsdo->drawable);
    drawHandler.pData = &dHData;

    stroke = (((*env)->GetIntField(env, sg2d, sg2dStrokeHintID) ==
               sunHints_INTVAL_STROKE_PURE)
              ? PH_STROKE_PURE
              : PH_STROKE_DEFAULT);

    maxCoords = (*env)->GetArrayLength(env, coordsArray);
    coords = (jfloat*)
        (*env)->GetPrimitiveArrayCritical(env, coordsArray, NULL);
    if (coords != NULL) {
        types = (jbyte*)
            (*env)->GetPrimitiveArrayCritical(env, typesArray, NULL);
        if (types != NULL) {
            jboolean ok;

            if (isFill) {
                drawHandler.pDrawScanline = &drawScanline;
                ok = doFillPath(&drawHandler,
                                transX, transY,
                                coords, maxCoords,
                                types, numTypes,
                                stroke, fillRule);
            } else {
                drawHandler.pDrawLine = &storeLine;
                drawHandler.pDrawPixel = &storePoint;
                ok = doDrawPath(&drawHandler, &drawSubPath,
                                transX, transY,
                                coords, maxCoords,
                                types, numTypes,
                                stroke);
            }
            if (!ok) {
                JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array");
            }
            (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
                                                  JNI_ABORT);
        }
        (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords,
                                              JNI_ABORT);
    }

    XDHD_FREE_POINTS(&dHData);
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XFillRect
 * Signature: (IJIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillRect
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x, jint y, jint w, jint h)
{
#ifndef HEADLESS
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
                   CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
                   CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XFillRoundRect
 * Signature: (IJIIIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillRoundRect
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x, jint y, jint w, jint h,
     jint arcW, jint arcH)
{
#ifndef HEADLESS
    long ty1, ty2, tx1, tx2, cx, cy, cxw, cyh,
         halfW, halfH, leftW, rightW, topH, bottomH;
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL || w <= 0 || h <= 0) {
        return;
    }

    arcW = ABS(arcW);
    arcH = ABS(arcH);
    if (arcW > w) {
        arcW = w;
    }
    if (arcH > h) {
        arcH = h;
    }

    if (arcW == 0 || arcH == 0) {
        Java_sun_java2d_x11_X11Renderer_XFillRect(env, xr, pXSData, xgc,
                                                  x, y, w, h);
        return;
    }

    halfW = (arcW / 2);
    halfH = (arcH / 2);

    /* clamp to short bounding box of round rectangle */
    cx = CLAMP_TO_SHORT(x);
    cy = CLAMP_TO_SHORT(y);
    cxw = CLAMP_TO_SHORT(x + w);
    cyh = CLAMP_TO_SHORT(y + h);

    /* clamp to short coordinates of lines */
    tx1 = CLAMP_TO_SHORT(x + halfW + 1);
    tx2 = CLAMP_TO_SHORT(x + w - halfW - 1);
    ty1 = CLAMP_TO_SHORT(y + halfH + 1);
    ty2 = CLAMP_TO_SHORT(y + h - halfH - 1);

    /*
     * recalculate heightes and widthes of round parts
     * to minimize distortions in visible area
     */
    leftW = (tx1 - cx) * 2;
    rightW = (cxw - tx2) * 2;
    topH = (ty1 - cy) * 2;
    bottomH = (cyh - ty2) * 2;

    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                cx, cy, leftW, topH,
                90, 90, JNI_TRUE);
    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                cxw - rightW, cy, rightW, topH,
                0, 90, JNI_TRUE);
    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                cx, cyh - bottomH, leftW, bottomH,
                180, 90, JNI_TRUE);
    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                cxw - rightW, cyh - bottomH, rightW, bottomH,
                270, 90, JNI_TRUE);

    if (tx1 < tx2) {
        if (cy < ty1) {
            XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
                           tx1, cy, tx2 - tx1, ty1 - cy);
        }
        if (ty2 < cyh) {
            XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
                           tx1, ty2, tx2 - tx1, cyh - ty2);
        }
    }
    if (ty1 < ty2) {
        XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
                       cx, ty1, cxw - cx, ty2 - ty1);
    }
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XFillOval
 * Signature: (IJIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillOval
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x, jint y, jint w, jint h)
{
#ifndef HEADLESS
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    if (w < 3 || h < 3) {
        /*
         * Fix for 4205762 - 1x1 ovals do not draw on Ultra1, Creator3d
         * (related to 4411814 on Windows platform)
         * Most X11 servers drivers have poor rendering
         * for thin ellipses and the rendering is most strikingly
         * different from our theoretical arcs.  Ideally we should
         * trap all ovals less than some fairly large size and
         * try to draw aesthetically pleasing ellipses, but that
         * would require considerably more work to get the corresponding
         * drawArc variants to match pixel for pixel.
         * Thin ovals of girth 1 pixel are simple rectangles.
         * Thin ovals of girth 2 pixels are simple rectangles with
         * potentially smaller lengths.  Determine the correct length
         * by calculating .5*.5 + scaledlen*scaledlen == 1.0 which
         * means that scaledlen is the sqrt(0.75).  Scaledlen is
         * relative to the true length (w or h) and needs to be
         * adjusted by half a pixel in different ways for odd or
         * even lengths.
         */
#define SQRT_3_4 0.86602540378443864676
        if (w > 2 && h > 1) {
            int adjw = (int) ((SQRT_3_4 * w - ((w&1)-1)) * 0.5);
            adjw = adjw * 2 + (w&1);
            x += (w-adjw)/2;
            w = adjw;
        } else if (h > 2 && w > 1) {
            int adjh = (int) ((SQRT_3_4 * h - ((h&1)-1)) * 0.5);
            adjh = adjh * 2 + (h&1);
            y += (h-adjh)/2;
            h = adjh;
        }
#undef SQRT_3_4
        if (w > 0 && h > 0) {
            XFillRectangle(awt_display, xsdo->drawable, (GC) xgc, x, y, w, h);
        }
    } else {
        awt_drawArc(env, xsdo->drawable, (GC) xgc,
                    x, y, w, h, 0, 360, JNI_TRUE);
    }
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XFillArc
 * Signature: (IJIIIIII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillArc
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint x, jint y, jint w, jint h,
     jint angleStart, jint angleExtent)
{
#ifndef HEADLESS
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    awt_drawArc(env, xsdo->drawable, (GC) xgc,
                x, y, w, h, angleStart, angleExtent, JNI_TRUE);
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XFillPoly
 * Signature: (IJII[I[II)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillPoly
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jint transx, jint transy,
     jintArray xcoordsArray, jintArray ycoordsArray, jint npoints)
{
#ifndef HEADLESS
    XPoint pTmp[POLYTEMPSIZE], *points;
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    if (JNU_IsNull(env, xcoordsArray) || JNU_IsNull(env, ycoordsArray)) {
        JNU_ThrowNullPointerException(env, "coordinate array");
        return;
    }
    if ((*env)->GetArrayLength(env, ycoordsArray) < npoints ||
        (*env)->GetArrayLength(env, xcoordsArray) < npoints)
    {
        JNU_ThrowArrayIndexOutOfBoundsException(env, "coordinate array");
        return;
    }

    if (npoints < 3) {
        return;
    }

    points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy,
                             pTmp, (int *)&npoints, JNI_FALSE);
    if (points == 0) {
        JNU_ThrowOutOfMemoryError(env, "translated coordinate array");
    } else {
        if (npoints > 2) {
            XFillPolygon(awt_display, xsdo->drawable, (GC) xgc,
                         points, npoints, Complex, CoordModeOrigin);
            X11SD_DirectRenderNotify(env, xsdo);
        }
        if (points != pTmp) {
            free(points);
        }
    }
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    XFillSpans
 * Signature: (IJLsun/java2d/pipe/SpanIterator;JII)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillSpans
    (JNIEnv *env, jobject xr,
     jlong pXSData, jlong xgc,
     jobject si, jlong pIterator,
     jint transx, jint transy)
{
#ifndef HEADLESS
    SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *) jlong_to_ptr(pIterator);
    void *srData;
    jint x, y, w, h;
    jint spanbox[4];
    X11SDOps *xsdo = (X11SDOps *) pXSData;

    if (xsdo == NULL) {
        return;
    }

    if (JNU_IsNull(env, si)) {
        JNU_ThrowNullPointerException(env, "span iterator");
        return;
    }
    if (pFuncs == NULL) {
        JNU_ThrowNullPointerException(env, "native iterator not supplied");
        return;
    }

    srData = (*pFuncs->open)(env, si);
    while ((*pFuncs->nextSpan)(srData, spanbox)) {
        x = spanbox[0] + transx;
        y = spanbox[1] + transy;
        w = spanbox[2] - spanbox[0];
        h = spanbox[3] - spanbox[1];
        XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
                       CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
                       CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
    }
    (*pFuncs->close)(env, srData);
    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}

/*
 * Class:     sun_java2d_x11_X11Renderer
 * Method:    devCopyArea
 * Signature: (Lsun/java2d/SurfaceData;IIIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_x11_X11Renderer_devCopyArea
    (JNIEnv *env, jobject xr,
     jlong xsd, jlong gc,
     jint srcx, jint srcy,
     jint dstx, jint dsty,
     jint width, jint height)
{
#ifndef HEADLESS
    X11SDOps *xsdo;
    GC xgc;

    xsdo = (X11SDOps *)jlong_to_ptr(xsd);
    if (xsdo == NULL) {
        return;
    }

    xgc = (GC)gc;
    if (xgc == NULL) {
        return;
    }

    XCopyArea(awt_display, xsdo->drawable, xsdo->drawable, xgc,
              srcx, srcy, width, height, dstx, dsty);

    X11SD_DirectRenderNotify(env, xsdo);
#endif /* !HEADLESS */
}
