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 } |