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

#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 */
}
