< prev index next >

src/java.desktop/unix/native/common/java2d/x11/X11Renderer.c

Print this page




 208     (*env)->ReleasePrimitiveArrayCritical(env, xcoordsArray, xcoords,
 209                                           JNI_ABORT);
 210     (*env)->ReleasePrimitiveArrayCritical(env, ycoordsArray, ycoords,
 211                                           JNI_ABORT);
 212 
 213     return points;
 214 }
 215 #endif /* !HEADLESS */
 216 
 217 /*
 218  * Class:     sun_java2d_x11_X11Renderer
 219  * Method:    XDrawLine
 220  * Signature: (IJIIII)V
 221  */
 222 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawLine
 223     (JNIEnv *env, jobject xr,
 224      jlong pXSData, jlong xgc,
 225      jint x1, jint y1, jint x2, jint y2)
 226 {
 227 #ifndef HEADLESS
 228     X11SDOps *xsdo = (X11SDOps *) pXSData;
 229 
 230     if (xsdo == NULL) {
 231         return;
 232     }
 233 
 234     XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
 235               CLAMP_TO_SHORT(x1), CLAMP_TO_SHORT(y1),
 236               CLAMP_TO_SHORT(x2), CLAMP_TO_SHORT(y2));
 237     X11SD_DirectRenderNotify(env, xsdo);
 238 #endif /* !HEADLESS */
 239 }
 240 
 241 /*
 242  * Class:     sun_java2d_x11_X11Renderer
 243  * Method:    XDrawRect
 244  * Signature: (IJIIII)V
 245  */
 246 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawRect
 247     (JNIEnv *env, jobject xr,
 248      jlong pXSData, jlong xgc,
 249      jint x, jint y, jint w, jint h)
 250 {
 251 #ifndef HEADLESS
 252     X11SDOps *xsdo = (X11SDOps *) pXSData;
 253 
 254     if (xsdo == NULL || w < 0 || h < 0) {
 255         return;
 256     }
 257 
 258     if (w < 2 || h < 2) {
 259         /* REMIND: This optimization assumes thin lines. */
 260         /*
 261          * This optimization not only simplifies the processing
 262          * of a particular degenerate case, but it protects against
 263          * the anomalies of various X11 implementations that draw
 264          * nothing for degenerate Polygons and Rectangles.
 265          */
 266         XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
 267                        CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
 268                        CLAMP_TO_USHORT(w+1), CLAMP_TO_USHORT(h+1));
 269     } else {
 270         XDrawRectangle(awt_display, xsdo->drawable, (GC) xgc,
 271                        CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
 272                        CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
 273     }
 274     X11SD_DirectRenderNotify(env, xsdo);
 275 #endif /* !HEADLESS */
 276 }
 277 
 278 /*
 279  * Class:     sun_java2d_x11_X11Renderer
 280  * Method:    XDrawRoundRect
 281  * Signature: (IJIIIIII)V
 282  */
 283 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawRoundRect
 284     (JNIEnv *env, jobject xr,
 285      jlong pXSData, jlong xgc,
 286      jint x, jint y, jint w, jint h,
 287      jint arcW, jint arcH)
 288 {
 289 #ifndef HEADLESS
 290     long ty1, ty2, tx1, tx2, cx, cy, cxw, cyh,
 291          halfW, halfH, leftW, rightW, topH, bottomH;
 292     X11SDOps *xsdo = (X11SDOps *) pXSData;
 293 
 294     if (xsdo == NULL || w < 0 || h < 0) {
 295         return;
 296     }
 297 
 298     arcW = ABS(arcW);
 299     arcH = ABS(arcH);
 300     if (arcW > w) {
 301         arcW = w;
 302     }
 303     if (arcH > h) {
 304         arcH = h;
 305     }
 306 
 307     if (arcW == 0 || arcH == 0) {
 308         Java_sun_java2d_x11_X11Renderer_XDrawRect(env, xr, pXSData, xgc,
 309                                                   x, y, w, h);
 310         return;
 311     }
 312 


 317     cx = CLAMP_TO_SHORT(x);
 318     cy = CLAMP_TO_SHORT(y);
 319     cxw = CLAMP_TO_SHORT(x + w);
 320     cyh = CLAMP_TO_SHORT(y + h);
 321 
 322     /* clamp to short coordinates of lines */
 323     tx1 = CLAMP_TO_SHORT(x + halfW + 1);
 324     tx2 = CLAMP_TO_SHORT(x + w - halfW - 1);
 325     ty1 = CLAMP_TO_SHORT(y + halfH + 1);
 326     ty2 = CLAMP_TO_SHORT(y + h - halfH - 1);
 327 
 328     /*
 329      * recalculate heightes and widthes of round parts
 330      * to minimize distortions in visible area
 331      */
 332     leftW = (tx1 - cx) * 2;
 333     rightW = (cxw - tx2) * 2;
 334     topH = (ty1 - cy) * 2;
 335     bottomH = (cyh - ty2) * 2;
 336 
 337     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 338                 cx, cy, leftW, topH,
 339                 90, 90, JNI_FALSE);
 340     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 341                 cxw - rightW, cy, rightW, topH,
 342                 0, 90, JNI_FALSE);
 343     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 344                 cx, cyh - bottomH, leftW, bottomH,
 345                 180, 90, JNI_FALSE);
 346     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 347                 cxw - rightW, cyh - bottomH, rightW, bottomH,
 348                 270, 90, JNI_FALSE);
 349 
 350     if (tx1 <= tx2) {
 351         XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
 352                   tx1, cy, tx2, cy);
 353         if (h > 0) {
 354             XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
 355                       tx1, cyh, tx2, cyh);
 356         }
 357     }
 358     if (ty1 <= ty2) {
 359         XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
 360                   cx, ty1, cx, ty2);
 361         if (w > 0) {
 362             XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
 363                       cxw, ty1, cxw, ty2);
 364         }
 365     }
 366     X11SD_DirectRenderNotify(env, xsdo);
 367 #endif /* !HEADLESS */
 368 }
 369 
 370 /*
 371  * Class:     sun_java2d_x11_X11Renderer
 372  * Method:    XDrawOval
 373  * Signature: (IJIIII)V
 374  */
 375 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawOval
 376     (JNIEnv *env, jobject xr,
 377      jlong pXSData, jlong xgc,
 378      jint x, jint y, jint w, jint h)
 379 {
 380 #ifndef HEADLESS
 381     X11SDOps *xsdo = (X11SDOps *) pXSData;
 382 
 383     if (xsdo == NULL) {
 384         return;
 385     }
 386 
 387     if (w < 2 || h < 2) {
 388         /*
 389          * Fix for 4205762 - 1x1 ovals do not draw on Ultra1, Creator3d
 390          * (related to 4411814 on Windows platform)
 391          * Really small ovals degenerate to simple rectangles as they
 392          * have no curvature or enclosed area.  Use XFillRectangle
 393          * for speed and to deal better with degenerate sizes.
 394          */
 395         if (w >= 0 && h >= 0) {
 396             XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
 397                            x, y, w+1, h+1);
 398         }
 399     } else {
 400         awt_drawArc(env, xsdo->drawable, (GC) xgc,
 401                     x, y, w, h, 0, 360, JNI_FALSE);
 402     }
 403     X11SD_DirectRenderNotify(env, xsdo);
 404 #endif /* !HEADLESS */
 405 }
 406 
 407 /*
 408  * Class:     sun_java2d_x11_X11Renderer
 409  * Method:    XDrawArc
 410  * Signature: (IJIIIIII)V
 411  */
 412 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawArc
 413     (JNIEnv *env, jobject xr,
 414      jlong pXSData, jlong xgc,
 415      jint x, jint y, jint w, jint h,
 416      jint angleStart, jint angleExtent)
 417 {
 418 #ifndef HEADLESS
 419     X11SDOps *xsdo = (X11SDOps *) pXSData;
 420 
 421     if (xsdo == NULL) {
 422         return;
 423     }
 424 
 425     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 426                 x, y, w, h, angleStart, angleExtent, JNI_FALSE);
 427     X11SD_DirectRenderNotify(env, xsdo);
 428 #endif /* !HEADLESS */
 429 }
 430 
 431 /*
 432  * Class:     sun_java2d_x11_X11Renderer
 433  * Method:    XDrawPoly
 434  * Signature: (IJII[I[IIZ)V
 435  */
 436 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawPoly
 437     (JNIEnv *env, jobject xr,
 438      jlong pXSData, jlong xgc,
 439      jint transx, jint transy,
 440      jintArray xcoordsArray, jintArray ycoordsArray, jint npoints,
 441      jboolean isclosed)
 442 {
 443 #ifndef HEADLESS
 444     XPoint pTmp[POLYTEMPSIZE], *points;
 445     X11SDOps *xsdo = (X11SDOps *) pXSData;
 446 
 447     if (xsdo == NULL) {
 448         return;
 449     }
 450 
 451     if (JNU_IsNull(env, xcoordsArray) || JNU_IsNull(env, ycoordsArray)) {
 452         JNU_ThrowNullPointerException(env, "coordinate array");
 453         return;
 454     }
 455     if ((*env)->GetArrayLength(env, ycoordsArray) < npoints ||
 456         (*env)->GetArrayLength(env, xcoordsArray) < npoints)
 457     {
 458         JNU_ThrowArrayIndexOutOfBoundsException(env, "coordinate array");
 459         return;
 460     }
 461 
 462     if (npoints < 2) {
 463         return;
 464     }
 465 
 466     points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy,
 467                              pTmp, (int *)&npoints, isclosed);
 468     if (points != 0) {
 469         if (npoints == 2) {
 470             /*
 471              * Some X11 implementations fail to draw anything for
 472              * simple 2 point polygons where the vertices are the
 473              * same point even though this violates the X11
 474              * specification.  For simplicity we will dispatch all
 475              * 2 point polygons through XDrawLine even if they are
 476              * non-degenerate as this may invoke less processing
 477              * down the line than a Poly primitive anyway.
 478              */
 479             XDrawLine(awt_display, xsdo->drawable, (GC) xgc,
 480                       points[0].x, points[0].y,
 481                       points[1].x, points[1].y);
 482         } else {
 483             XDrawLines(awt_display, xsdo->drawable, (GC) xgc,
 484                        points, npoints, CoordModeOrigin);
 485         }
 486         if (points != pTmp) {
 487             free(points);
 488         }
 489         X11SD_DirectRenderNotify(env, xsdo);
 490     }
 491 #endif /* !HEADLESS */
 492 }
 493 
 494 static void storeLine(DrawHandler* hnd,
 495                       jint x0, jint y0, jint x1, jint y1)
 496 {
 497 #ifndef HEADLESS
 498     XDrawHandlerData* dhnd = (XDrawHandlerData*)(hnd->pData);
 499 
 500     XDHD_ADD_POINT(dhnd, x0, y0);
 501     XDHD_ADD_POINT(dhnd, x1, y1);
 502 #endif /* !HEADLESS */
 503 }


 552 static void drawScanline(DrawHandler* hnd, jint x0, jint x1, jint y0)
 553 {
 554 #ifndef HEADLESS
 555     XDrawHandlerData* dhnd = (XDrawHandlerData*)(hnd->pData);
 556 
 557     XDrawLine(awt_display, dhnd->drawable, dhnd->gc, x0, y0, x1, y0);
 558 #endif /* !HEADLESS */
 559 }
 560 
 561 /*
 562  * Class:     sun_java2d_x11_X11Renderer
 563  * Method:    XDoPath
 564  * Signature: (Lsun/java2d/SunGraphics2D;JJIILjava/awt/geom/Path2D/Float;Z)V
 565  */
 566 JNIEXPORT void JNICALL
 567 Java_sun_java2d_x11_X11Renderer_XDoPath
 568     (JNIEnv *env, jobject self, jobject sg2d, jlong pXSData, jlong xgc,
 569      jint transX, jint transY, jobject p2df, jboolean isFill)
 570 {
 571 #ifndef HEADLESS
 572     X11SDOps *xsdo = (X11SDOps *) pXSData;
 573     jarray typesArray;
 574     jobject pointArray;
 575     jarray coordsArray;
 576     jint numTypes;
 577     jint fillRule;
 578     jint maxCoords;
 579     jbyte *types;
 580     jfloat *coords;
 581     XDrawHandlerData dHData;
 582     DrawHandler drawHandler = {
 583         NULL, NULL, NULL,
 584         MIN_SHORT, MIN_SHORT, MAX_SHORT, MAX_SHORT,
 585         0, 0, 0, 0,
 586         NULL
 587     };
 588     PHStroke stroke;
 589     jboolean ok = JNI_TRUE;
 590 
 591     if (xsdo == NULL) {
 592         return;
 593     }
 594 
 595     if (isFill) {
 596         fillRule = (*env)->GetIntField(env, p2df, path2DWindingRuleID);
 597     }
 598 
 599     typesArray = (jarray)(*env)->GetObjectField(env, p2df, path2DTypesID);
 600     coordsArray = (jarray)(*env)->GetObjectField(env, p2df,
 601                                                  path2DFloatCoordsID);
 602     if (coordsArray == NULL) {
 603         JNU_ThrowNullPointerException(env, "coordinates array");
 604         return;
 605     }
 606     numTypes = (*env)->GetIntField(env, p2df, path2DNumTypesID);
 607     if ((*env)->GetArrayLength(env, typesArray) < numTypes) {
 608         JNU_ThrowArrayIndexOutOfBoundsException(env, "types array");
 609         return;
 610     }
 611 
 612     XDHD_INIT(&dHData, (GC)xgc, xsdo->drawable);
 613     drawHandler.pData = &dHData;
 614 
 615     stroke = (((*env)->GetIntField(env, sg2d, sg2dStrokeHintID) ==
 616                sunHints_INTVAL_STROKE_PURE)
 617               ? PH_STROKE_PURE
 618               : PH_STROKE_DEFAULT);
 619 
 620     maxCoords = (*env)->GetArrayLength(env, coordsArray);
 621     coords = (jfloat*)
 622         (*env)->GetPrimitiveArrayCritical(env, coordsArray, NULL);
 623     if (coords != NULL) {
 624         types = (jbyte*)
 625             (*env)->GetPrimitiveArrayCritical(env, typesArray, NULL);
 626         if (types != NULL) {
 627             if (isFill) {
 628                 drawHandler.pDrawScanline = &drawScanline;
 629                 ok = doFillPath(&drawHandler,
 630                                 transX, transY,
 631                                 coords, maxCoords,
 632                                 types, numTypes,


 649             JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array");
 650         }
 651     }
 652 
 653     XDHD_FREE_POINTS(&dHData);
 654     X11SD_DirectRenderNotify(env, xsdo);
 655 #endif /* !HEADLESS */
 656 }
 657 
 658 /*
 659  * Class:     sun_java2d_x11_X11Renderer
 660  * Method:    XFillRect
 661  * Signature: (IJIIII)V
 662  */
 663 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillRect
 664     (JNIEnv *env, jobject xr,
 665      jlong pXSData, jlong xgc,
 666      jint x, jint y, jint w, jint h)
 667 {
 668 #ifndef HEADLESS
 669     X11SDOps *xsdo = (X11SDOps *) pXSData;
 670 
 671     if (xsdo == NULL) {
 672         return;
 673     }
 674 
 675     XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
 676                    CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
 677                    CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
 678     X11SD_DirectRenderNotify(env, xsdo);
 679 #endif /* !HEADLESS */
 680 }
 681 
 682 /*
 683  * Class:     sun_java2d_x11_X11Renderer
 684  * Method:    XFillRoundRect
 685  * Signature: (IJIIIIII)V
 686  */
 687 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillRoundRect
 688     (JNIEnv *env, jobject xr,
 689      jlong pXSData, jlong xgc,
 690      jint x, jint y, jint w, jint h,
 691      jint arcW, jint arcH)
 692 {
 693 #ifndef HEADLESS
 694     long ty1, ty2, tx1, tx2, cx, cy, cxw, cyh,
 695          halfW, halfH, leftW, rightW, topH, bottomH;
 696     X11SDOps *xsdo = (X11SDOps *) pXSData;
 697 
 698     if (xsdo == NULL || w <= 0 || h <= 0) {
 699         return;
 700     }
 701 
 702     arcW = ABS(arcW);
 703     arcH = ABS(arcH);
 704     if (arcW > w) {
 705         arcW = w;
 706     }
 707     if (arcH > h) {
 708         arcH = h;
 709     }
 710 
 711     if (arcW == 0 || arcH == 0) {
 712         Java_sun_java2d_x11_X11Renderer_XFillRect(env, xr, pXSData, xgc,
 713                                                   x, y, w, h);
 714         return;
 715     }
 716 


 721     cx = CLAMP_TO_SHORT(x);
 722     cy = CLAMP_TO_SHORT(y);
 723     cxw = CLAMP_TO_SHORT(x + w);
 724     cyh = CLAMP_TO_SHORT(y + h);
 725 
 726     /* clamp to short coordinates of lines */
 727     tx1 = CLAMP_TO_SHORT(x + halfW + 1);
 728     tx2 = CLAMP_TO_SHORT(x + w - halfW - 1);
 729     ty1 = CLAMP_TO_SHORT(y + halfH + 1);
 730     ty2 = CLAMP_TO_SHORT(y + h - halfH - 1);
 731 
 732     /*
 733      * recalculate heightes and widthes of round parts
 734      * to minimize distortions in visible area
 735      */
 736     leftW = (tx1 - cx) * 2;
 737     rightW = (cxw - tx2) * 2;
 738     topH = (ty1 - cy) * 2;
 739     bottomH = (cyh - ty2) * 2;
 740 
 741     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 742                 cx, cy, leftW, topH,
 743                 90, 90, JNI_TRUE);
 744     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 745                 cxw - rightW, cy, rightW, topH,
 746                 0, 90, JNI_TRUE);
 747     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 748                 cx, cyh - bottomH, leftW, bottomH,
 749                 180, 90, JNI_TRUE);
 750     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 751                 cxw - rightW, cyh - bottomH, rightW, bottomH,
 752                 270, 90, JNI_TRUE);
 753 
 754     if (tx1 < tx2) {
 755         if (cy < ty1) {
 756             XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
 757                            tx1, cy, tx2 - tx1, ty1 - cy);
 758         }
 759         if (ty2 < cyh) {
 760             XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
 761                            tx1, ty2, tx2 - tx1, cyh - ty2);
 762         }
 763     }
 764     if (ty1 < ty2) {
 765         XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
 766                        cx, ty1, cxw - cx, ty2 - ty1);
 767     }
 768     X11SD_DirectRenderNotify(env, xsdo);
 769 #endif /* !HEADLESS */
 770 }
 771 
 772 /*
 773  * Class:     sun_java2d_x11_X11Renderer
 774  * Method:    XFillOval
 775  * Signature: (IJIIII)V
 776  */
 777 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillOval
 778     (JNIEnv *env, jobject xr,
 779      jlong pXSData, jlong xgc,
 780      jint x, jint y, jint w, jint h)
 781 {
 782 #ifndef HEADLESS
 783     X11SDOps *xsdo = (X11SDOps *) pXSData;
 784 
 785     if (xsdo == NULL) {
 786         return;
 787     }
 788 
 789     if (w < 3 || h < 3) {
 790         /*
 791          * Fix for 4205762 - 1x1 ovals do not draw on Ultra1, Creator3d
 792          * (related to 4411814 on Windows platform)
 793          * Most X11 servers drivers have poor rendering
 794          * for thin ellipses and the rendering is most strikingly
 795          * different from our theoretical arcs.  Ideally we should
 796          * trap all ovals less than some fairly large size and
 797          * try to draw aesthetically pleasing ellipses, but that
 798          * would require considerably more work to get the corresponding
 799          * drawArc variants to match pixel for pixel.
 800          * Thin ovals of girth 1 pixel are simple rectangles.
 801          * Thin ovals of girth 2 pixels are simple rectangles with
 802          * potentially smaller lengths.  Determine the correct length
 803          * by calculating .5*.5 + scaledlen*scaledlen == 1.0 which
 804          * means that scaledlen is the sqrt(0.75).  Scaledlen is
 805          * relative to the true length (w or h) and needs to be
 806          * adjusted by half a pixel in different ways for odd or
 807          * even lengths.
 808          */
 809 #define SQRT_3_4 0.86602540378443864676
 810         if (w > 2 && h > 1) {
 811             int adjw = (int) ((SQRT_3_4 * w - ((w&1)-1)) * 0.5);
 812             adjw = adjw * 2 + (w&1);
 813             x += (w-adjw)/2;
 814             w = adjw;
 815         } else if (h > 2 && w > 1) {
 816             int adjh = (int) ((SQRT_3_4 * h - ((h&1)-1)) * 0.5);
 817             adjh = adjh * 2 + (h&1);
 818             y += (h-adjh)/2;
 819             h = adjh;
 820         }
 821 #undef SQRT_3_4
 822         if (w > 0 && h > 0) {
 823             XFillRectangle(awt_display, xsdo->drawable, (GC) xgc, x, y, w, h);
 824         }
 825     } else {
 826         awt_drawArc(env, xsdo->drawable, (GC) xgc,
 827                     x, y, w, h, 0, 360, JNI_TRUE);
 828     }
 829     X11SD_DirectRenderNotify(env, xsdo);
 830 #endif /* !HEADLESS */
 831 }
 832 
 833 /*
 834  * Class:     sun_java2d_x11_X11Renderer
 835  * Method:    XFillArc
 836  * Signature: (IJIIIIII)V
 837  */
 838 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillArc
 839     (JNIEnv *env, jobject xr,
 840      jlong pXSData, jlong xgc,
 841      jint x, jint y, jint w, jint h,
 842      jint angleStart, jint angleExtent)
 843 {
 844 #ifndef HEADLESS
 845     X11SDOps *xsdo = (X11SDOps *) pXSData;
 846 
 847     if (xsdo == NULL) {
 848         return;
 849     }
 850 
 851     awt_drawArc(env, xsdo->drawable, (GC) xgc,
 852                 x, y, w, h, angleStart, angleExtent, JNI_TRUE);
 853     X11SD_DirectRenderNotify(env, xsdo);
 854 #endif /* !HEADLESS */
 855 }
 856 
 857 /*
 858  * Class:     sun_java2d_x11_X11Renderer
 859  * Method:    XFillPoly
 860  * Signature: (IJII[I[II)V
 861  */
 862 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillPoly
 863     (JNIEnv *env, jobject xr,
 864      jlong pXSData, jlong xgc,
 865      jint transx, jint transy,
 866      jintArray xcoordsArray, jintArray ycoordsArray, jint npoints)
 867 {
 868 #ifndef HEADLESS
 869     XPoint pTmp[POLYTEMPSIZE], *points;
 870     X11SDOps *xsdo = (X11SDOps *) pXSData;
 871 
 872     if (xsdo == NULL) {
 873         return;
 874     }
 875 
 876     if (JNU_IsNull(env, xcoordsArray) || JNU_IsNull(env, ycoordsArray)) {
 877         JNU_ThrowNullPointerException(env, "coordinate array");
 878         return;
 879     }
 880     if ((*env)->GetArrayLength(env, ycoordsArray) < npoints ||
 881         (*env)->GetArrayLength(env, xcoordsArray) < npoints)
 882     {
 883         JNU_ThrowArrayIndexOutOfBoundsException(env, "coordinate array");
 884         return;
 885     }
 886 
 887     if (npoints < 3) {
 888         return;
 889     }
 890 
 891     points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy,
 892                              pTmp, (int *)&npoints, JNI_FALSE);
 893     if (points != 0) {
 894         if (npoints > 2) {
 895             XFillPolygon(awt_display, xsdo->drawable, (GC) xgc,
 896                          points, npoints, Complex, CoordModeOrigin);
 897             X11SD_DirectRenderNotify(env, xsdo);
 898         }
 899         if (points != pTmp) {
 900             free(points);
 901         }
 902     }
 903 #endif /* !HEADLESS */
 904 }
 905 
 906 /*
 907  * Class:     sun_java2d_x11_X11Renderer
 908  * Method:    XFillSpans
 909  * Signature: (IJLsun/java2d/pipe/SpanIterator;JII)V
 910  */
 911 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillSpans
 912     (JNIEnv *env, jobject xr,
 913      jlong pXSData, jlong xgc,
 914      jobject si, jlong pIterator,
 915      jint transx, jint transy)
 916 {
 917 #ifndef HEADLESS
 918     SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *) jlong_to_ptr(pIterator);
 919     void *srData;
 920     jint x, y, w, h;
 921     jint spanbox[4];
 922     X11SDOps *xsdo = (X11SDOps *) pXSData;
 923 
 924     if (xsdo == NULL) {
 925         return;
 926     }
 927 
 928     if (JNU_IsNull(env, si)) {
 929         JNU_ThrowNullPointerException(env, "span iterator");
 930         return;
 931     }
 932     if (pFuncs == NULL) {
 933         JNU_ThrowNullPointerException(env, "native iterator not supplied");
 934         return;
 935     }
 936 
 937     srData = (*pFuncs->open)(env, si);
 938     while ((*pFuncs->nextSpan)(srData, spanbox)) {
 939         x = spanbox[0] + transx;
 940         y = spanbox[1] + transy;
 941         w = spanbox[2] - spanbox[0];
 942         h = spanbox[3] - spanbox[1];
 943         XFillRectangle(awt_display, xsdo->drawable, (GC) xgc,
 944                        CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
 945                        CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
 946     }
 947     (*pFuncs->close)(env, srData);
 948     X11SD_DirectRenderNotify(env, xsdo);
 949 #endif /* !HEADLESS */
 950 }
 951 
 952 /*
 953  * Class:     sun_java2d_x11_X11Renderer
 954  * Method:    devCopyArea
 955  * Signature: (Lsun/java2d/SurfaceData;IIIIII)V
 956  */
 957 JNIEXPORT void JNICALL
 958 Java_sun_java2d_x11_X11Renderer_devCopyArea
 959     (JNIEnv *env, jobject xr,
 960      jlong xsd, jlong gc,
 961      jint srcx, jint srcy,
 962      jint dstx, jint dsty,
 963      jint width, jint height)
 964 {
 965 #ifndef HEADLESS
 966     X11SDOps *xsdo;
 967     GC xgc;
 968 
 969     xsdo = (X11SDOps *)jlong_to_ptr(xsd);
 970     if (xsdo == NULL) {
 971         return;
 972     }
 973 
 974     xgc = (GC)gc;
 975     if (xgc == NULL) {
 976         return;
 977     }
 978 
 979     XCopyArea(awt_display, xsdo->drawable, xsdo->drawable, xgc,
 980               srcx, srcy, width, height, dstx, dsty);
 981 
 982     X11SD_DirectRenderNotify(env, xsdo);
 983 #endif /* !HEADLESS */
 984 }


 208     (*env)->ReleasePrimitiveArrayCritical(env, xcoordsArray, xcoords,
 209                                           JNI_ABORT);
 210     (*env)->ReleasePrimitiveArrayCritical(env, ycoordsArray, ycoords,
 211                                           JNI_ABORT);
 212 
 213     return points;
 214 }
 215 #endif /* !HEADLESS */
 216 
 217 /*
 218  * Class:     sun_java2d_x11_X11Renderer
 219  * Method:    XDrawLine
 220  * Signature: (IJIIII)V
 221  */
 222 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawLine
 223     (JNIEnv *env, jobject xr,
 224      jlong pXSData, jlong xgc,
 225      jint x1, jint y1, jint x2, jint y2)
 226 {
 227 #ifndef HEADLESS
 228     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 229 
 230     if (xsdo == NULL) {
 231         return;
 232     }
 233 
 234     XDrawLine(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 235               CLAMP_TO_SHORT(x1), CLAMP_TO_SHORT(y1),
 236               CLAMP_TO_SHORT(x2), CLAMP_TO_SHORT(y2));
 237     X11SD_DirectRenderNotify(env, xsdo);
 238 #endif /* !HEADLESS */
 239 }
 240 
 241 /*
 242  * Class:     sun_java2d_x11_X11Renderer
 243  * Method:    XDrawRect
 244  * Signature: (IJIIII)V
 245  */
 246 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawRect
 247     (JNIEnv *env, jobject xr,
 248      jlong pXSData, jlong xgc,
 249      jint x, jint y, jint w, jint h)
 250 {
 251 #ifndef HEADLESS
 252     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 253 
 254     if (xsdo == NULL || w < 0 || h < 0) {
 255         return;
 256     }
 257 
 258     if (w < 2 || h < 2) {
 259         /* REMIND: This optimization assumes thin lines. */
 260         /*
 261          * This optimization not only simplifies the processing
 262          * of a particular degenerate case, but it protects against
 263          * the anomalies of various X11 implementations that draw
 264          * nothing for degenerate Polygons and Rectangles.
 265          */
 266         XFillRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 267                        CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
 268                        CLAMP_TO_USHORT(w+1), CLAMP_TO_USHORT(h+1));
 269     } else {
 270         XDrawRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 271                        CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
 272                        CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
 273     }
 274     X11SD_DirectRenderNotify(env, xsdo);
 275 #endif /* !HEADLESS */
 276 }
 277 
 278 /*
 279  * Class:     sun_java2d_x11_X11Renderer
 280  * Method:    XDrawRoundRect
 281  * Signature: (IJIIIIII)V
 282  */
 283 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawRoundRect
 284     (JNIEnv *env, jobject xr,
 285      jlong pXSData, jlong xgc,
 286      jint x, jint y, jint w, jint h,
 287      jint arcW, jint arcH)
 288 {
 289 #ifndef HEADLESS
 290     long ty1, ty2, tx1, tx2, cx, cy, cxw, cyh,
 291          halfW, halfH, leftW, rightW, topH, bottomH;
 292     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 293 
 294     if (xsdo == NULL || w < 0 || h < 0) {
 295         return;
 296     }
 297 
 298     arcW = ABS(arcW);
 299     arcH = ABS(arcH);
 300     if (arcW > w) {
 301         arcW = w;
 302     }
 303     if (arcH > h) {
 304         arcH = h;
 305     }
 306 
 307     if (arcW == 0 || arcH == 0) {
 308         Java_sun_java2d_x11_X11Renderer_XDrawRect(env, xr, pXSData, xgc,
 309                                                   x, y, w, h);
 310         return;
 311     }
 312 


 317     cx = CLAMP_TO_SHORT(x);
 318     cy = CLAMP_TO_SHORT(y);
 319     cxw = CLAMP_TO_SHORT(x + w);
 320     cyh = CLAMP_TO_SHORT(y + h);
 321 
 322     /* clamp to short coordinates of lines */
 323     tx1 = CLAMP_TO_SHORT(x + halfW + 1);
 324     tx2 = CLAMP_TO_SHORT(x + w - halfW - 1);
 325     ty1 = CLAMP_TO_SHORT(y + halfH + 1);
 326     ty2 = CLAMP_TO_SHORT(y + h - halfH - 1);
 327 
 328     /*
 329      * recalculate heightes and widthes of round parts
 330      * to minimize distortions in visible area
 331      */
 332     leftW = (tx1 - cx) * 2;
 333     rightW = (cxw - tx2) * 2;
 334     topH = (ty1 - cy) * 2;
 335     bottomH = (cyh - ty2) * 2;
 336 
 337     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 338                 cx, cy, leftW, topH,
 339                 90, 90, JNI_FALSE);
 340     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 341                 cxw - rightW, cy, rightW, topH,
 342                 0, 90, JNI_FALSE);
 343     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 344                 cx, cyh - bottomH, leftW, bottomH,
 345                 180, 90, JNI_FALSE);
 346     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 347                 cxw - rightW, cyh - bottomH, rightW, bottomH,
 348                 270, 90, JNI_FALSE);
 349 
 350     if (tx1 <= tx2) {
 351         XDrawLine(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 352                   tx1, cy, tx2, cy);
 353         if (h > 0) {
 354             XDrawLine(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 355                       tx1, cyh, tx2, cyh);
 356         }
 357     }
 358     if (ty1 <= ty2) {
 359         XDrawLine(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 360                   cx, ty1, cx, ty2);
 361         if (w > 0) {
 362             XDrawLine(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 363                       cxw, ty1, cxw, ty2);
 364         }
 365     }
 366     X11SD_DirectRenderNotify(env, xsdo);
 367 #endif /* !HEADLESS */
 368 }
 369 
 370 /*
 371  * Class:     sun_java2d_x11_X11Renderer
 372  * Method:    XDrawOval
 373  * Signature: (IJIIII)V
 374  */
 375 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawOval
 376     (JNIEnv *env, jobject xr,
 377      jlong pXSData, jlong xgc,
 378      jint x, jint y, jint w, jint h)
 379 {
 380 #ifndef HEADLESS
 381     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 382 
 383     if (xsdo == NULL) {
 384         return;
 385     }
 386 
 387     if (w < 2 || h < 2) {
 388         /*
 389          * Fix for 4205762 - 1x1 ovals do not draw on Ultra1, Creator3d
 390          * (related to 4411814 on Windows platform)
 391          * Really small ovals degenerate to simple rectangles as they
 392          * have no curvature or enclosed area.  Use XFillRectangle
 393          * for speed and to deal better with degenerate sizes.
 394          */
 395         if (w >= 0 && h >= 0) {
 396             XFillRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 397                            x, y, w+1, h+1);
 398         }
 399     } else {
 400         awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 401                     x, y, w, h, 0, 360, JNI_FALSE);
 402     }
 403     X11SD_DirectRenderNotify(env, xsdo);
 404 #endif /* !HEADLESS */
 405 }
 406 
 407 /*
 408  * Class:     sun_java2d_x11_X11Renderer
 409  * Method:    XDrawArc
 410  * Signature: (IJIIIIII)V
 411  */
 412 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawArc
 413     (JNIEnv *env, jobject xr,
 414      jlong pXSData, jlong xgc,
 415      jint x, jint y, jint w, jint h,
 416      jint angleStart, jint angleExtent)
 417 {
 418 #ifndef HEADLESS
 419     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 420 
 421     if (xsdo == NULL) {
 422         return;
 423     }
 424 
 425     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 426                 x, y, w, h, angleStart, angleExtent, JNI_FALSE);
 427     X11SD_DirectRenderNotify(env, xsdo);
 428 #endif /* !HEADLESS */
 429 }
 430 
 431 /*
 432  * Class:     sun_java2d_x11_X11Renderer
 433  * Method:    XDrawPoly
 434  * Signature: (IJII[I[IIZ)V
 435  */
 436 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawPoly
 437     (JNIEnv *env, jobject xr,
 438      jlong pXSData, jlong xgc,
 439      jint transx, jint transy,
 440      jintArray xcoordsArray, jintArray ycoordsArray, jint npoints,
 441      jboolean isclosed)
 442 {
 443 #ifndef HEADLESS
 444     XPoint pTmp[POLYTEMPSIZE], *points;
 445     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 446 
 447     if (xsdo == NULL) {
 448         return;
 449     }
 450 
 451     if (JNU_IsNull(env, xcoordsArray) || JNU_IsNull(env, ycoordsArray)) {
 452         JNU_ThrowNullPointerException(env, "coordinate array");
 453         return;
 454     }
 455     if ((*env)->GetArrayLength(env, ycoordsArray) < npoints ||
 456         (*env)->GetArrayLength(env, xcoordsArray) < npoints)
 457     {
 458         JNU_ThrowArrayIndexOutOfBoundsException(env, "coordinate array");
 459         return;
 460     }
 461 
 462     if (npoints < 2) {
 463         return;
 464     }
 465 
 466     points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy,
 467                              pTmp, (int *)&npoints, isclosed);
 468     if (points != 0) {
 469         if (npoints == 2) {
 470             /*
 471              * Some X11 implementations fail to draw anything for
 472              * simple 2 point polygons where the vertices are the
 473              * same point even though this violates the X11
 474              * specification.  For simplicity we will dispatch all
 475              * 2 point polygons through XDrawLine even if they are
 476              * non-degenerate as this may invoke less processing
 477              * down the line than a Poly primitive anyway.
 478              */
 479             XDrawLine(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 480                       points[0].x, points[0].y,
 481                       points[1].x, points[1].y);
 482         } else {
 483             XDrawLines(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 484                        points, npoints, CoordModeOrigin);
 485         }
 486         if (points != pTmp) {
 487             free(points);
 488         }
 489         X11SD_DirectRenderNotify(env, xsdo);
 490     }
 491 #endif /* !HEADLESS */
 492 }
 493 
 494 static void storeLine(DrawHandler* hnd,
 495                       jint x0, jint y0, jint x1, jint y1)
 496 {
 497 #ifndef HEADLESS
 498     XDrawHandlerData* dhnd = (XDrawHandlerData*)(hnd->pData);
 499 
 500     XDHD_ADD_POINT(dhnd, x0, y0);
 501     XDHD_ADD_POINT(dhnd, x1, y1);
 502 #endif /* !HEADLESS */
 503 }


 552 static void drawScanline(DrawHandler* hnd, jint x0, jint x1, jint y0)
 553 {
 554 #ifndef HEADLESS
 555     XDrawHandlerData* dhnd = (XDrawHandlerData*)(hnd->pData);
 556 
 557     XDrawLine(awt_display, dhnd->drawable, dhnd->gc, x0, y0, x1, y0);
 558 #endif /* !HEADLESS */
 559 }
 560 
 561 /*
 562  * Class:     sun_java2d_x11_X11Renderer
 563  * Method:    XDoPath
 564  * Signature: (Lsun/java2d/SunGraphics2D;JJIILjava/awt/geom/Path2D/Float;Z)V
 565  */
 566 JNIEXPORT void JNICALL
 567 Java_sun_java2d_x11_X11Renderer_XDoPath
 568     (JNIEnv *env, jobject self, jobject sg2d, jlong pXSData, jlong xgc,
 569      jint transX, jint transY, jobject p2df, jboolean isFill)
 570 {
 571 #ifndef HEADLESS
 572     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 573     jarray typesArray;
 574     jobject pointArray;
 575     jarray coordsArray;
 576     jint numTypes;
 577     jint fillRule;
 578     jint maxCoords;
 579     jbyte *types;
 580     jfloat *coords;
 581     XDrawHandlerData dHData;
 582     DrawHandler drawHandler = {
 583         NULL, NULL, NULL,
 584         MIN_SHORT, MIN_SHORT, MAX_SHORT, MAX_SHORT,
 585         0, 0, 0, 0,
 586         NULL
 587     };
 588     PHStroke stroke;
 589     jboolean ok = JNI_TRUE;
 590 
 591     if (xsdo == NULL) {
 592         return;
 593     }
 594 
 595     if (isFill) {
 596         fillRule = (*env)->GetIntField(env, p2df, path2DWindingRuleID);
 597     }
 598 
 599     typesArray = (jarray)(*env)->GetObjectField(env, p2df, path2DTypesID);
 600     coordsArray = (jarray)(*env)->GetObjectField(env, p2df,
 601                                                  path2DFloatCoordsID);
 602     if (coordsArray == NULL) {
 603         JNU_ThrowNullPointerException(env, "coordinates array");
 604         return;
 605     }
 606     numTypes = (*env)->GetIntField(env, p2df, path2DNumTypesID);
 607     if ((*env)->GetArrayLength(env, typesArray) < numTypes) {
 608         JNU_ThrowArrayIndexOutOfBoundsException(env, "types array");
 609         return;
 610     }
 611 
 612     XDHD_INIT(&dHData, (GC) jlong_to_ptr(xgc), xsdo->drawable);
 613     drawHandler.pData = &dHData;
 614 
 615     stroke = (((*env)->GetIntField(env, sg2d, sg2dStrokeHintID) ==
 616                sunHints_INTVAL_STROKE_PURE)
 617               ? PH_STROKE_PURE
 618               : PH_STROKE_DEFAULT);
 619 
 620     maxCoords = (*env)->GetArrayLength(env, coordsArray);
 621     coords = (jfloat*)
 622         (*env)->GetPrimitiveArrayCritical(env, coordsArray, NULL);
 623     if (coords != NULL) {
 624         types = (jbyte*)
 625             (*env)->GetPrimitiveArrayCritical(env, typesArray, NULL);
 626         if (types != NULL) {
 627             if (isFill) {
 628                 drawHandler.pDrawScanline = &drawScanline;
 629                 ok = doFillPath(&drawHandler,
 630                                 transX, transY,
 631                                 coords, maxCoords,
 632                                 types, numTypes,


 649             JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array");
 650         }
 651     }
 652 
 653     XDHD_FREE_POINTS(&dHData);
 654     X11SD_DirectRenderNotify(env, xsdo);
 655 #endif /* !HEADLESS */
 656 }
 657 
 658 /*
 659  * Class:     sun_java2d_x11_X11Renderer
 660  * Method:    XFillRect
 661  * Signature: (IJIIII)V
 662  */
 663 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillRect
 664     (JNIEnv *env, jobject xr,
 665      jlong pXSData, jlong xgc,
 666      jint x, jint y, jint w, jint h)
 667 {
 668 #ifndef HEADLESS
 669     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 670 
 671     if (xsdo == NULL) {
 672         return;
 673     }
 674 
 675     XFillRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 676                    CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
 677                    CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
 678     X11SD_DirectRenderNotify(env, xsdo);
 679 #endif /* !HEADLESS */
 680 }
 681 
 682 /*
 683  * Class:     sun_java2d_x11_X11Renderer
 684  * Method:    XFillRoundRect
 685  * Signature: (IJIIIIII)V
 686  */
 687 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillRoundRect
 688     (JNIEnv *env, jobject xr,
 689      jlong pXSData, jlong xgc,
 690      jint x, jint y, jint w, jint h,
 691      jint arcW, jint arcH)
 692 {
 693 #ifndef HEADLESS
 694     long ty1, ty2, tx1, tx2, cx, cy, cxw, cyh,
 695          halfW, halfH, leftW, rightW, topH, bottomH;
 696     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 697 
 698     if (xsdo == NULL || w <= 0 || h <= 0) {
 699         return;
 700     }
 701 
 702     arcW = ABS(arcW);
 703     arcH = ABS(arcH);
 704     if (arcW > w) {
 705         arcW = w;
 706     }
 707     if (arcH > h) {
 708         arcH = h;
 709     }
 710 
 711     if (arcW == 0 || arcH == 0) {
 712         Java_sun_java2d_x11_X11Renderer_XFillRect(env, xr, pXSData, xgc,
 713                                                   x, y, w, h);
 714         return;
 715     }
 716 


 721     cx = CLAMP_TO_SHORT(x);
 722     cy = CLAMP_TO_SHORT(y);
 723     cxw = CLAMP_TO_SHORT(x + w);
 724     cyh = CLAMP_TO_SHORT(y + h);
 725 
 726     /* clamp to short coordinates of lines */
 727     tx1 = CLAMP_TO_SHORT(x + halfW + 1);
 728     tx2 = CLAMP_TO_SHORT(x + w - halfW - 1);
 729     ty1 = CLAMP_TO_SHORT(y + halfH + 1);
 730     ty2 = CLAMP_TO_SHORT(y + h - halfH - 1);
 731 
 732     /*
 733      * recalculate heightes and widthes of round parts
 734      * to minimize distortions in visible area
 735      */
 736     leftW = (tx1 - cx) * 2;
 737     rightW = (cxw - tx2) * 2;
 738     topH = (ty1 - cy) * 2;
 739     bottomH = (cyh - ty2) * 2;
 740 
 741     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 742                 cx, cy, leftW, topH,
 743                 90, 90, JNI_TRUE);
 744     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 745                 cxw - rightW, cy, rightW, topH,
 746                 0, 90, JNI_TRUE);
 747     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 748                 cx, cyh - bottomH, leftW, bottomH,
 749                 180, 90, JNI_TRUE);
 750     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 751                 cxw - rightW, cyh - bottomH, rightW, bottomH,
 752                 270, 90, JNI_TRUE);
 753 
 754     if (tx1 < tx2) {
 755         if (cy < ty1) {
 756             XFillRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 757                            tx1, cy, tx2 - tx1, ty1 - cy);
 758         }
 759         if (ty2 < cyh) {
 760             XFillRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 761                            tx1, ty2, tx2 - tx1, cyh - ty2);
 762         }
 763     }
 764     if (ty1 < ty2) {
 765         XFillRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 766                        cx, ty1, cxw - cx, ty2 - ty1);
 767     }
 768     X11SD_DirectRenderNotify(env, xsdo);
 769 #endif /* !HEADLESS */
 770 }
 771 
 772 /*
 773  * Class:     sun_java2d_x11_X11Renderer
 774  * Method:    XFillOval
 775  * Signature: (IJIIII)V
 776  */
 777 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillOval
 778     (JNIEnv *env, jobject xr,
 779      jlong pXSData, jlong xgc,
 780      jint x, jint y, jint w, jint h)
 781 {
 782 #ifndef HEADLESS
 783     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 784 
 785     if (xsdo == NULL) {
 786         return;
 787     }
 788 
 789     if (w < 3 || h < 3) {
 790         /*
 791          * Fix for 4205762 - 1x1 ovals do not draw on Ultra1, Creator3d
 792          * (related to 4411814 on Windows platform)
 793          * Most X11 servers drivers have poor rendering
 794          * for thin ellipses and the rendering is most strikingly
 795          * different from our theoretical arcs.  Ideally we should
 796          * trap all ovals less than some fairly large size and
 797          * try to draw aesthetically pleasing ellipses, but that
 798          * would require considerably more work to get the corresponding
 799          * drawArc variants to match pixel for pixel.
 800          * Thin ovals of girth 1 pixel are simple rectangles.
 801          * Thin ovals of girth 2 pixels are simple rectangles with
 802          * potentially smaller lengths.  Determine the correct length
 803          * by calculating .5*.5 + scaledlen*scaledlen == 1.0 which
 804          * means that scaledlen is the sqrt(0.75).  Scaledlen is
 805          * relative to the true length (w or h) and needs to be
 806          * adjusted by half a pixel in different ways for odd or
 807          * even lengths.
 808          */
 809 #define SQRT_3_4 0.86602540378443864676
 810         if (w > 2 && h > 1) {
 811             int adjw = (int) ((SQRT_3_4 * w - ((w&1)-1)) * 0.5);
 812             adjw = adjw * 2 + (w&1);
 813             x += (w-adjw)/2;
 814             w = adjw;
 815         } else if (h > 2 && w > 1) {
 816             int adjh = (int) ((SQRT_3_4 * h - ((h&1)-1)) * 0.5);
 817             adjh = adjh * 2 + (h&1);
 818             y += (h-adjh)/2;
 819             h = adjh;
 820         }
 821 #undef SQRT_3_4
 822         if (w > 0 && h > 0) {
 823             XFillRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc), x, y, w, h);
 824         }
 825     } else {
 826         awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 827                     x, y, w, h, 0, 360, JNI_TRUE);
 828     }
 829     X11SD_DirectRenderNotify(env, xsdo);
 830 #endif /* !HEADLESS */
 831 }
 832 
 833 /*
 834  * Class:     sun_java2d_x11_X11Renderer
 835  * Method:    XFillArc
 836  * Signature: (IJIIIIII)V
 837  */
 838 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillArc
 839     (JNIEnv *env, jobject xr,
 840      jlong pXSData, jlong xgc,
 841      jint x, jint y, jint w, jint h,
 842      jint angleStart, jint angleExtent)
 843 {
 844 #ifndef HEADLESS
 845     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 846 
 847     if (xsdo == NULL) {
 848         return;
 849     }
 850 
 851     awt_drawArc(env, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 852                 x, y, w, h, angleStart, angleExtent, JNI_TRUE);
 853     X11SD_DirectRenderNotify(env, xsdo);
 854 #endif /* !HEADLESS */
 855 }
 856 
 857 /*
 858  * Class:     sun_java2d_x11_X11Renderer
 859  * Method:    XFillPoly
 860  * Signature: (IJII[I[II)V
 861  */
 862 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillPoly
 863     (JNIEnv *env, jobject xr,
 864      jlong pXSData, jlong xgc,
 865      jint transx, jint transy,
 866      jintArray xcoordsArray, jintArray ycoordsArray, jint npoints)
 867 {
 868 #ifndef HEADLESS
 869     XPoint pTmp[POLYTEMPSIZE], *points;
 870     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 871 
 872     if (xsdo == NULL) {
 873         return;
 874     }
 875 
 876     if (JNU_IsNull(env, xcoordsArray) || JNU_IsNull(env, ycoordsArray)) {
 877         JNU_ThrowNullPointerException(env, "coordinate array");
 878         return;
 879     }
 880     if ((*env)->GetArrayLength(env, ycoordsArray) < npoints ||
 881         (*env)->GetArrayLength(env, xcoordsArray) < npoints)
 882     {
 883         JNU_ThrowArrayIndexOutOfBoundsException(env, "coordinate array");
 884         return;
 885     }
 886 
 887     if (npoints < 3) {
 888         return;
 889     }
 890 
 891     points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy,
 892                              pTmp, (int *)&npoints, JNI_FALSE);
 893     if (points != 0) {
 894         if (npoints > 2) {
 895             XFillPolygon(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 896                          points, npoints, Complex, CoordModeOrigin);
 897             X11SD_DirectRenderNotify(env, xsdo);
 898         }
 899         if (points != pTmp) {
 900             free(points);
 901         }
 902     }
 903 #endif /* !HEADLESS */
 904 }
 905 
 906 /*
 907  * Class:     sun_java2d_x11_X11Renderer
 908  * Method:    XFillSpans
 909  * Signature: (IJLsun/java2d/pipe/SpanIterator;JII)V
 910  */
 911 JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillSpans
 912     (JNIEnv *env, jobject xr,
 913      jlong pXSData, jlong xgc,
 914      jobject si, jlong pIterator,
 915      jint transx, jint transy)
 916 {
 917 #ifndef HEADLESS
 918     SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *) jlong_to_ptr(pIterator);
 919     void *srData;
 920     jint x, y, w, h;
 921     jint spanbox[4];
 922     X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
 923 
 924     if (xsdo == NULL) {
 925         return;
 926     }
 927 
 928     if (JNU_IsNull(env, si)) {
 929         JNU_ThrowNullPointerException(env, "span iterator");
 930         return;
 931     }
 932     if (pFuncs == NULL) {
 933         JNU_ThrowNullPointerException(env, "native iterator not supplied");
 934         return;
 935     }
 936 
 937     srData = (*pFuncs->open)(env, si);
 938     while ((*pFuncs->nextSpan)(srData, spanbox)) {
 939         x = spanbox[0] + transx;
 940         y = spanbox[1] + transy;
 941         w = spanbox[2] - spanbox[0];
 942         h = spanbox[3] - spanbox[1];
 943         XFillRectangle(awt_display, xsdo->drawable, (GC) jlong_to_ptr(xgc),
 944                        CLAMP_TO_SHORT(x),  CLAMP_TO_SHORT(y),
 945                        CLAMP_TO_USHORT(w), CLAMP_TO_USHORT(h));
 946     }
 947     (*pFuncs->close)(env, srData);
 948     X11SD_DirectRenderNotify(env, xsdo);
 949 #endif /* !HEADLESS */
 950 }
 951 
 952 /*
 953  * Class:     sun_java2d_x11_X11Renderer
 954  * Method:    devCopyArea
 955  * Signature: (Lsun/java2d/SurfaceData;IIIIII)V
 956  */
 957 JNIEXPORT void JNICALL
 958 Java_sun_java2d_x11_X11Renderer_devCopyArea
 959     (JNIEnv *env, jobject xr,
 960      jlong xsd, jlong gc,
 961      jint srcx, jint srcy,
 962      jint dstx, jint dsty,
 963      jint width, jint height)
 964 {
 965 #ifndef HEADLESS
 966     X11SDOps *xsdo;
 967     GC xgc;
 968 
 969     xsdo = (X11SDOps *)jlong_to_ptr(xsd);
 970     if (xsdo == NULL) {
 971         return;
 972     }
 973 
 974     xgc = (GC) jlong_to_ptr(gc);
 975     if (xgc == NULL) {
 976         return;
 977     }
 978 
 979     XCopyArea(awt_display, xsdo->drawable, xsdo->drawable, xgc,
 980               srcx, srcy, width, height, dstx, dsty);
 981 
 982     X11SD_DirectRenderNotify(env, xsdo);
 983 #endif /* !HEADLESS */
 984 }
< prev index next >