1 /*
   2  * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "jni_util.h"
  27 #include "jlong.h"
  28 
  29 #include "sun_java2d_loops_GraphicsPrimitiveMgr.h"
  30 
  31 #include "Region.h"
  32 #include "GraphicsPrimitiveMgr.h"
  33 #include "AlphaMacros.h"
  34 
  35 static char *InitName = "<init>";
  36 static char *InitSig =  ("(JLsun/java2d/loops/SurfaceType;"
  37                          "Lsun/java2d/loops/CompositeType;"
  38                          "Lsun/java2d/loops/SurfaceType;)V");
  39 
  40 static char *RegisterName =     "register";
  41 static char *RegisterSig =      "([Lsun/java2d/loops/GraphicsPrimitive;)V";
  42 
  43 static jclass GraphicsPrimitiveMgr;
  44 static jclass GraphicsPrimitive;
  45 
  46 static jmethodID RegisterID;
  47 static jfieldID pNativePrimID;
  48 static jfieldID pixelID;
  49 static jfieldID eargbID;
  50 static jfieldID clipRegionID;
  51 static jfieldID compositeID;
  52 static jfieldID lcdTextContrastID;
  53 static jfieldID xorPixelID;
  54 static jfieldID xorColorID;
  55 static jfieldID alphaMaskID;
  56 static jfieldID ruleID;
  57 static jfieldID extraAlphaID;
  58 
  59 static jfieldID m00ID;
  60 static jfieldID m01ID;
  61 static jfieldID m02ID;
  62 static jfieldID m10ID;
  63 static jfieldID m11ID;
  64 static jfieldID m12ID;
  65 
  66 static jmethodID getRgbID;
  67 
  68 static jboolean InitPrimTypes(JNIEnv *env);
  69 static jboolean InitSurfaceTypes(JNIEnv *env, jclass SurfaceType);
  70 static jboolean InitCompositeTypes(JNIEnv *env, jclass CompositeType);
  71 
  72 JNIEXPORT jfieldID path2DTypesID;
  73 JNIEXPORT jfieldID path2DNumTypesID;
  74 JNIEXPORT jfieldID path2DWindingRuleID;
  75 JNIEXPORT jfieldID path2DFloatCoordsID;
  76 JNIEXPORT jfieldID sg2dStrokeHintID;
  77 JNIEXPORT jint sunHints_INTVAL_STROKE_PURE;
  78 
  79 /*
  80  * Class:     sun_java2d_loops_GraphicsPrimitiveMgr
  81  * Method:    initIDs
  82  * Signature: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;)V
  83  */
  84 JNIEXPORT void JNICALL
  85 Java_sun_java2d_loops_GraphicsPrimitiveMgr_initIDs
  86     (JNIEnv *env, jclass GPMgr,
  87      jclass GP, jclass ST, jclass CT,
  88      jclass SG2D, jclass Color, jclass AT,
  89      jclass XORComp, jclass AlphaComp,
  90      jclass Path2D, jclass Path2DFloat,
  91      jclass SHints)
  92 {
  93     jfieldID fid;
  94     initAlphaTables();
  95     GraphicsPrimitiveMgr = (*env)->NewGlobalRef(env, GPMgr);
  96     GraphicsPrimitive = (*env)->NewGlobalRef(env, GP);
  97     if (GraphicsPrimitiveMgr == NULL || GraphicsPrimitive == NULL) {
  98         JNU_ThrowOutOfMemoryError(env, "creating global refs");
  99         return;
 100     }
 101     if (!InitPrimTypes(env) ||
 102         !InitSurfaceTypes(env, ST) ||
 103         !InitCompositeTypes(env, CT))
 104     {
 105         return;
 106     }
 107     CHECK_NULL(RegisterID =
 108         (*env)->GetStaticMethodID(env, GPMgr, RegisterName, RegisterSig));
 109     CHECK_NULL(pNativePrimID = (*env)->GetFieldID(env, GP, "pNativePrim", "J"));
 110     CHECK_NULL(pixelID = (*env)->GetFieldID(env, SG2D, "pixel", "I"));
 111     CHECK_NULL(eargbID = (*env)->GetFieldID(env, SG2D, "eargb", "I"));
 112     CHECK_NULL(clipRegionID =
 113         (*env)->GetFieldID(env, SG2D, "clipRegion", "Lsun/java2d/pipe/Region;"));
 114     CHECK_NULL(compositeID =
 115         (*env)->GetFieldID(env, SG2D, "composite", "Ljava/awt/Composite;"));
 116     CHECK_NULL(lcdTextContrastID =
 117         (*env)->GetFieldID(env, SG2D, "lcdTextContrast", "I"));
 118     CHECK_NULL(getRgbID = (*env)->GetMethodID(env, Color, "getRGB", "()I"));
 119     CHECK_NULL(xorPixelID = (*env)->GetFieldID(env, XORComp, "xorPixel", "I"));
 120     CHECK_NULL(xorColorID =
 121         (*env)->GetFieldID(env, XORComp, "xorColor", "Ljava/awt/Color;"));
 122     CHECK_NULL(alphaMaskID =
 123         (*env)->GetFieldID(env, XORComp, "alphaMask", "I"));
 124     CHECK_NULL(ruleID = (*env)->GetFieldID(env, AlphaComp, "rule", "I"));
 125     CHECK_NULL(extraAlphaID =
 126         (*env)->GetFieldID(env, AlphaComp, "extraAlpha", "F"));
 127 
 128 
 129     CHECK_NULL(m00ID = (*env)->GetFieldID(env, AT, "m00", "D"));
 130     CHECK_NULL(m01ID = (*env)->GetFieldID(env, AT, "m01", "D"));
 131     CHECK_NULL(m02ID = (*env)->GetFieldID(env, AT, "m02", "D"));
 132     CHECK_NULL(m10ID = (*env)->GetFieldID(env, AT, "m10", "D"));
 133     CHECK_NULL(m11ID = (*env)->GetFieldID(env, AT, "m11", "D"));
 134     CHECK_NULL(m12ID = (*env)->GetFieldID(env, AT, "m12", "D"));
 135 
 136     CHECK_NULL(path2DTypesID =
 137         (*env)->GetFieldID(env, Path2D, "pointTypes", "[B"));
 138     CHECK_NULL(path2DNumTypesID =
 139         (*env)->GetFieldID(env, Path2D, "numTypes", "I"));
 140     CHECK_NULL(path2DWindingRuleID =
 141         (*env)->GetFieldID(env, Path2D, "windingRule", "I"));
 142     CHECK_NULL(path2DFloatCoordsID =
 143         (*env)->GetFieldID(env, Path2DFloat, "floatCoords", "[F"));
 144     CHECK_NULL(sg2dStrokeHintID =
 145         (*env)->GetFieldID(env, SG2D, "strokeHint", "I"));
 146     CHECK_NULL(fid =
 147         (*env)->GetStaticFieldID(env, SHints, "INTVAL_STROKE_PURE", "I"));
 148     sunHints_INTVAL_STROKE_PURE = (*env)->GetStaticIntField(env, SHints, fid);
 149 }
 150 
 151 void GrPrim_RefineBounds(SurfaceDataBounds *bounds, jint transX, jint transY,
 152                          jfloat *coords,  jint maxCoords)
 153 {
 154     jint xmin, ymin, xmax, ymax;
 155     if (maxCoords > 1) {
 156         xmin = xmax = transX + (jint)(*coords++ + 0.5);
 157         ymin = ymax = transY + (jint)(*coords++ + 0.5);
 158         for (;maxCoords > 1; maxCoords -= 2) {
 159             jint x = transX + (jint)(*coords++ + 0.5);
 160             jint y = transY + (jint)(*coords++ + 0.5);
 161             if (xmin > x) xmin = x;
 162             if (ymin > y) ymin = y;
 163             if (xmax < x) xmax = x;
 164             if (ymax < y) ymax = y;
 165         }
 166         if (++xmax < xmin) xmax--;
 167         if (++ymax < ymin) ymax--;
 168         if (bounds->x1 < xmin) bounds->x1 = xmin;
 169         if (bounds->y1 < ymin) bounds->y1 = ymin;
 170         if (bounds->x2 > xmax) bounds->x2 = xmax;
 171         if (bounds->y2 > ymax) bounds->y2 = ymax;
 172     } else {
 173         bounds->x2 = bounds->x1;
 174         bounds->y2 = bounds->y1;
 175     }
 176 }
 177 
 178 /*
 179  * Class:     sun_java2d_loops_GraphicsPrimitiveMgr
 180  * Method:    registerNativeLoops
 181  * Signature: ()V
 182  */
 183 JNIEXPORT void JNICALL
 184 Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops
 185     (JNIEnv *env, jclass GPMgr)
 186 {
 187     RegisterFunc RegisterAnyByte;
 188     RegisterFunc RegisterByteBinary1Bit;
 189     RegisterFunc RegisterByteBinary2Bit;
 190     RegisterFunc RegisterByteBinary4Bit;
 191     RegisterFunc RegisterByteIndexed;
 192     RegisterFunc RegisterByteGray;
 193     RegisterFunc RegisterIndex8Gray;
 194     RegisterFunc RegisterIndex12Gray;
 195     RegisterFunc RegisterAnyShort;
 196     RegisterFunc RegisterUshort555Rgb;
 197     RegisterFunc RegisterUshort565Rgb;
 198     RegisterFunc RegisterUshort4444Argb;
 199     RegisterFunc RegisterUshort555Rgbx;
 200     RegisterFunc RegisterUshortGray;
 201     RegisterFunc RegisterUshortIndexed;
 202     RegisterFunc RegisterAny3Byte;
 203     RegisterFunc RegisterThreeByteBgr;
 204     RegisterFunc RegisterAnyInt;
 205     RegisterFunc RegisterIntArgb;
 206     RegisterFunc RegisterIntArgbPre;
 207     RegisterFunc RegisterIntArgbBm;
 208     RegisterFunc RegisterIntRgb;
 209     RegisterFunc RegisterIntBgr;
 210     RegisterFunc RegisterIntRgbx;
 211     RegisterFunc RegisterAny4Byte;
 212     RegisterFunc RegisterFourByteAbgr;
 213     RegisterFunc RegisterFourByteAbgrPre;
 214 
 215     if (!RegisterAnyByte(env) ||
 216         !RegisterByteBinary1Bit(env) ||
 217         !RegisterByteBinary2Bit(env) ||
 218         !RegisterByteBinary4Bit(env) ||
 219         !RegisterByteIndexed(env) ||
 220         !RegisterByteGray(env) ||
 221         !RegisterIndex8Gray(env) ||
 222         !RegisterIndex12Gray(env) ||
 223         !RegisterAnyShort(env) ||
 224         !RegisterUshort555Rgb(env) ||
 225         !RegisterUshort565Rgb(env) ||
 226         !RegisterUshort4444Argb(env) ||
 227         !RegisterUshort555Rgbx(env) ||
 228         !RegisterUshortGray(env) ||
 229         !RegisterUshortIndexed(env) ||
 230         !RegisterAny3Byte(env) ||
 231         !RegisterThreeByteBgr(env) ||
 232         !RegisterAnyInt(env) ||
 233         !RegisterIntArgb(env) ||
 234         !RegisterIntArgbPre(env) ||
 235         !RegisterIntArgbBm(env) ||
 236         !RegisterIntRgb(env) ||
 237         !RegisterIntBgr(env) ||
 238         !RegisterIntRgbx(env) ||
 239         !RegisterAny4Byte(env) ||
 240         !RegisterFourByteAbgr(env) ||
 241         !RegisterFourByteAbgrPre(env))
 242     {
 243         return;
 244     }
 245 }
 246 
 247 #define _StartOf(T)     ((T *) (&T##s))
 248 #define _NumberOf(T)    (sizeof(T##s) / sizeof(T))
 249 #define _EndOf(T)       (_StartOf(T) + _NumberOf(T))
 250 
 251 #define PrimTypeStart   _StartOf(PrimitiveType)
 252 #define PrimTypeEnd     _EndOf(PrimitiveType)
 253 
 254 #define SurfTypeStart   _StartOf(SurfaceType)
 255 #define SurfTypeEnd     _EndOf(SurfaceType)
 256 
 257 #define CompTypeStart   _StartOf(CompositeType)
 258 #define CompTypeEnd     _EndOf(CompositeType)
 259 
 260 /*
 261  * This function initializes the global collection of PrimitiveType
 262  * structures by retrieving the necessary Java Class object and the
 263  * associated methodID of the necessary constructor.
 264  *
 265  * See PrimitiveTypes.* below.
 266  */
 267 static jboolean InitPrimTypes(JNIEnv *env)
 268 {
 269     jboolean ok = JNI_TRUE;
 270     PrimitiveType *pPrimType;
 271     jclass cl;
 272 
 273     for (pPrimType = PrimTypeStart; pPrimType < PrimTypeEnd; pPrimType++) {
 274         cl = (*env)->FindClass(env, pPrimType->ClassName);
 275         if (cl == NULL) {
 276             ok = JNI_FALSE;
 277             break;
 278         }
 279         pPrimType->ClassObject = (*env)->NewGlobalRef(env, cl);
 280         pPrimType->Constructor =
 281             (*env)->GetMethodID(env, cl, InitName, InitSig);
 282 
 283         (*env)->DeleteLocalRef(env, cl);
 284         if (pPrimType->ClassObject == NULL ||
 285             pPrimType->Constructor == NULL)
 286         {
 287             ok = JNI_FALSE;
 288             break;
 289         }
 290     }
 291 
 292     if (!ok) {
 293         for (pPrimType = PrimTypeStart; pPrimType < PrimTypeEnd; pPrimType++) {
 294             if (pPrimType->ClassObject != NULL) {
 295                 (*env)->DeleteGlobalRef(env, pPrimType->ClassObject);
 296                 pPrimType->ClassObject = NULL;
 297             }
 298             pPrimType->Constructor = NULL;
 299         }
 300     }
 301 
 302     return ok;
 303 }
 304 
 305 /*
 306  * This function initializes the global collection of SurfaceType
 307  * or CompositeType structures by retrieving the corresponding Java
 308  * object stored as a static field on the Java Class.
 309  *
 310  * See SurfaceTypes.* below.
 311  * See CompositeeTypes.* below.
 312  */
 313 static jboolean InitSimpleTypes
 314     (JNIEnv *env, jclass SimpleClass, char *SimpleSig,
 315      SurfCompHdr *pStart, SurfCompHdr *pEnd, jsize size)
 316 {
 317     jboolean ok = JNI_TRUE;
 318     SurfCompHdr *pHdr;
 319     jfieldID field;
 320     jobject obj;
 321 
 322     for (pHdr = pStart; pHdr < pEnd; pHdr = PtrAddBytes(pHdr, size)) {
 323         field = (*env)->GetStaticFieldID(env,
 324                                          SimpleClass,
 325                                          pHdr->Name,
 326                                          SimpleSig);
 327         if (field == NULL) {
 328             ok = JNI_FALSE;
 329             break;
 330         }
 331         obj = (*env)->GetStaticObjectField(env, SimpleClass, field);
 332         if (obj == NULL) {
 333             ok = JNI_FALSE;
 334             break;
 335         }
 336         pHdr->Object = (*env)->NewGlobalRef(env, obj);
 337         (*env)->DeleteLocalRef(env, obj);
 338         if (pHdr->Object == NULL) {
 339             ok = JNI_FALSE;
 340             break;
 341         }
 342     }
 343 
 344     if (!ok) {
 345         for (pHdr = pStart; pHdr < pEnd; pHdr = PtrAddBytes(pHdr, size)) {
 346             if (pHdr->Object != NULL) {
 347                 (*env)->DeleteGlobalRef(env, pHdr->Object);
 348                 pHdr->Object = NULL;
 349             }
 350         }
 351     }
 352 
 353     return ok;
 354 }
 355 
 356 static jboolean InitSurfaceTypes(JNIEnv *env, jclass ST)
 357 {
 358     return InitSimpleTypes(env, ST, "Lsun/java2d/loops/SurfaceType;",
 359                            (SurfCompHdr *) SurfTypeStart,
 360                            (SurfCompHdr *) SurfTypeEnd,
 361                            sizeof(SurfaceType));
 362 }
 363 
 364 static jboolean InitCompositeTypes(JNIEnv *env, jclass CT)
 365 {
 366     return InitSimpleTypes(env, CT, "Lsun/java2d/loops/CompositeType;",
 367                            (SurfCompHdr *) CompTypeStart,
 368                            (SurfCompHdr *) CompTypeEnd,
 369                            sizeof(CompositeType));
 370 }
 371 
 372 /*
 373  * This function registers a set of Java GraphicsPrimitive objects
 374  * based on information stored in an array of NativePrimitive structures.
 375  */
 376 jboolean RegisterPrimitives(JNIEnv *env,
 377                             NativePrimitive *pPrim,
 378                             jint NumPrimitives)
 379 {
 380     jarray primitives;
 381     int i;
 382 
 383     primitives = (*env)->NewObjectArray(env, NumPrimitives,
 384                                         GraphicsPrimitive, NULL);
 385     if (primitives == NULL) {
 386         return JNI_FALSE;
 387     }
 388 
 389     for (i = 0; i < NumPrimitives; i++, pPrim++) {
 390         jint srcflags, dstflags;
 391         jobject prim;
 392         PrimitiveType *pType = pPrim->pPrimType;
 393         SurfaceType *pSrc = pPrim->pSrcType;
 394         CompositeType *pComp = pPrim->pCompType;
 395         SurfaceType *pDst = pPrim->pDstType;
 396 
 397         pPrim->funcs.initializer = MapAccelFunction(pPrim->funcs_c.initializer);
 398 
 399         /*
 400          * Calculate the necessary SurfaceData lock flags for the
 401          * source and destination surfaces based on the information
 402          * stored in the PrimitiveType, SurfaceType, and CompositeType
 403          * structures.  The starting point is the values that are
 404          * already stored in the NativePrimitive structure.  These
 405          * flags are usually left as 0, but can be filled in by
 406          * native primitive loops that have special needs that are
 407          * not deducible from their declared attributes.
 408          */
 409         srcflags = pPrim->srcflags;
 410         dstflags = pPrim->dstflags;
 411         srcflags |= pType->srcflags;
 412         dstflags |= pType->dstflags;
 413         dstflags |= pComp->dstflags;
 414         if (srcflags & SD_LOCK_READ) srcflags |= pSrc->readflags;
 415         /* if (srcflags & SD_LOCK_WRITE) srcflags |= pSrc->writeflags; */
 416         if (dstflags & SD_LOCK_READ) dstflags |= pDst->readflags;
 417         if (dstflags & SD_LOCK_WRITE) dstflags |= pDst->writeflags;
 418         pPrim->srcflags = srcflags;
 419         pPrim->dstflags = dstflags;
 420 
 421         prim = (*env)->NewObject(env,
 422                                  pType->ClassObject,
 423                                  pType->Constructor,
 424                                  ptr_to_jlong(pPrim),
 425                                  pSrc->hdr.Object,
 426                                  pComp->hdr.Object,
 427                                  pDst->hdr.Object);
 428         if (prim == NULL) {
 429             break;
 430         }
 431         (*env)->SetObjectArrayElement(env, primitives, i, prim);
 432         (*env)->DeleteLocalRef(env, prim);
 433         if ((*env)->ExceptionCheck(env)) {
 434             break;
 435         }
 436     }
 437 
 438     if (i >= NumPrimitives) {
 439         /* No error - upcall to GraphicsPrimitiveMgr to register the
 440          * new primitives... */
 441         (*env)->CallStaticVoidMethod(env, GraphicsPrimitiveMgr, RegisterID,
 442                                      primitives);
 443     }
 444     (*env)->DeleteLocalRef(env, primitives);
 445 
 446     return !((*env)->ExceptionCheck(env));
 447 }
 448 
 449 JNIEXPORT NativePrimitive * JNICALL
 450 GetNativePrim(JNIEnv *env, jobject gp)
 451 {
 452     NativePrimitive *pPrim;
 453 
 454     pPrim = (NativePrimitive *) JNU_GetLongFieldAsPtr(env, gp, pNativePrimID);
 455     if (pPrim == NULL) {
 456         JNU_ThrowInternalError(env, "Non-native Primitive invoked natively");
 457     }
 458 
 459     return pPrim;
 460 }
 461 
 462 JNIEXPORT void JNICALL
 463 GrPrim_Sg2dGetCompInfo(JNIEnv *env, jobject sg2d,
 464                        NativePrimitive *pPrim, CompositeInfo *pCompInfo)
 465 {
 466     jobject comp;
 467 
 468     comp = (*env)->GetObjectField(env, sg2d, compositeID);
 469     (*pPrim->pCompType->getCompInfo)(env, pCompInfo, comp);
 470     (*env)->DeleteLocalRef(env, comp);
 471 }
 472 
 473 JNIEXPORT jint JNICALL
 474 GrPrim_CompGetXorColor(JNIEnv *env, jobject comp)
 475 {
 476     jobject color;
 477     jint rgb;
 478 
 479     color = (*env)->GetObjectField(env, comp, xorColorID);
 480     rgb = (*env)->CallIntMethod(env, color, getRgbID);
 481     (*env)->DeleteLocalRef(env, color);
 482 
 483     return rgb;
 484 }
 485 
 486 JNIEXPORT void JNICALL
 487 GrPrim_Sg2dGetClip(JNIEnv *env, jobject sg2d, SurfaceDataBounds *bounds)
 488 {
 489     jobject clip = (*env)->GetObjectField(env, sg2d, clipRegionID);
 490     Region_GetBounds(env, clip, bounds);
 491 }
 492 
 493 JNIEXPORT jint JNICALL
 494 GrPrim_Sg2dGetPixel(JNIEnv *env, jobject sg2d)
 495 {
 496     return (*env)->GetIntField(env, sg2d, pixelID);
 497 }
 498 
 499 JNIEXPORT jint JNICALL
 500 GrPrim_Sg2dGetEaRGB(JNIEnv *env, jobject sg2d)
 501 {
 502     return (*env)->GetIntField(env, sg2d, eargbID);
 503 }
 504 
 505 JNIEXPORT jint JNICALL
 506 GrPrim_Sg2dGetLCDTextContrast(JNIEnv *env, jobject sg2d)
 507 {
 508     return (*env)->GetIntField(env, sg2d, lcdTextContrastID);
 509 }
 510 
 511 /*
 512  * Helper function for CompositeTypes.Xor
 513  */
 514 JNIEXPORT void JNICALL
 515 GrPrim_CompGetXorInfo(JNIEnv *env, CompositeInfo *pCompInfo, jobject comp)
 516 {
 517     pCompInfo->rule = RULE_Xor;
 518     pCompInfo->details.xorPixel = (*env)->GetIntField(env, comp, xorPixelID);
 519     pCompInfo->alphaMask = (*env)->GetIntField(env, comp, alphaMaskID);
 520 }
 521 
 522 /*
 523  * Helper function for CompositeTypes.AnyAlpha
 524  */
 525 JNIEXPORT void JNICALL
 526 GrPrim_CompGetAlphaInfo(JNIEnv *env, CompositeInfo *pCompInfo, jobject comp)
 527 {
 528     pCompInfo->rule =
 529         (*env)->GetIntField(env, comp, ruleID);
 530     pCompInfo->details.extraAlpha =
 531         (*env)->GetFloatField(env, comp, extraAlphaID);
 532 }
 533 
 534 JNIEXPORT void JNICALL
 535 Transform_GetInfo(JNIEnv *env, jobject txform, TransformInfo *pTxInfo)
 536 {
 537     pTxInfo->dxdx = (*env)->GetDoubleField(env, txform, m00ID);
 538     pTxInfo->dxdy = (*env)->GetDoubleField(env, txform, m01ID);
 539     pTxInfo->tx   = (*env)->GetDoubleField(env, txform, m02ID);
 540     pTxInfo->dydx = (*env)->GetDoubleField(env, txform, m10ID);
 541     pTxInfo->dydy = (*env)->GetDoubleField(env, txform, m11ID);
 542     pTxInfo->ty   = (*env)->GetDoubleField(env, txform, m12ID);
 543 }
 544 
 545 JNIEXPORT void JNICALL
 546 Transform_transform(TransformInfo *pTxInfo, jdouble *pX, jdouble *pY)
 547 {
 548     jdouble x = *pX;
 549     jdouble y = *pY;
 550 
 551     *pX = pTxInfo->dxdx * x + pTxInfo->dxdy * y + pTxInfo->tx;
 552     *pY = pTxInfo->dydx * x + pTxInfo->dydy * y + pTxInfo->ty;
 553 }
 554 
 555 /*
 556  * External declarations for the pixelFor helper methods for the various
 557  * named surface types.  These functions are defined in the various
 558  * files that contain the loop functions for their type.
 559  */
 560 extern PixelForFunc PixelForByteBinary;
 561 extern PixelForFunc PixelForByteIndexed;
 562 extern PixelForFunc PixelForByteGray;
 563 extern PixelForFunc PixelForIndex8Gray;
 564 extern PixelForFunc PixelForIndex12Gray;
 565 extern PixelForFunc PixelForUshort555Rgb;
 566 extern PixelForFunc PixelForUshort555Rgbx;
 567 extern PixelForFunc PixelForUshort565Rgb;
 568 extern PixelForFunc PixelForUshort4444Argb;
 569 extern PixelForFunc PixelForUshortGray;
 570 extern PixelForFunc PixelForUshortIndexed;
 571 extern PixelForFunc PixelForIntArgbPre;
 572 extern PixelForFunc PixelForIntArgbBm;
 573 extern PixelForFunc PixelForIntBgr;
 574 extern PixelForFunc PixelForIntRgbx;
 575 extern PixelForFunc PixelForFourByteAbgr;
 576 extern PixelForFunc PixelForFourByteAbgrPre;
 577 
 578 /*
 579  * Definition and initialization of the globally accessible PrimitiveTypes.
 580  */
 581 struct _PrimitiveTypes PrimitiveTypes = {
 582     { "sun/java2d/loops/Blit", SD_LOCK_READ, SD_LOCK_WRITE, NULL, NULL},
 583     { "sun/java2d/loops/BlitBg", SD_LOCK_READ, SD_LOCK_WRITE, NULL, NULL},
 584     { "sun/java2d/loops/ScaledBlit", SD_LOCK_READ, SD_LOCK_WRITE, NULL, NULL},
 585     { "sun/java2d/loops/FillRect", 0, SD_LOCK_WRITE, NULL, NULL},
 586     { "sun/java2d/loops/FillSpans", 0, SD_LOCK_PARTIAL_WRITE, NULL, NULL},
 587     { "sun/java2d/loops/FillParallelogram", 0, SD_LOCK_PARTIAL_WRITE, NULL, NULL},
 588     { "sun/java2d/loops/DrawParallelogram", 0, SD_LOCK_PARTIAL_WRITE, NULL, NULL},
 589     { "sun/java2d/loops/DrawLine", 0, SD_LOCK_PARTIAL_WRITE, NULL, NULL},
 590     { "sun/java2d/loops/DrawRect", 0, SD_LOCK_PARTIAL_WRITE, NULL, NULL},
 591     { "sun/java2d/loops/DrawPolygons", 0, SD_LOCK_PARTIAL_WRITE, NULL, NULL},
 592     { "sun/java2d/loops/DrawPath", 0, SD_LOCK_PARTIAL_WRITE, NULL, NULL},
 593     { "sun/java2d/loops/FillPath", 0, SD_LOCK_PARTIAL_WRITE, NULL, NULL},
 594     { "sun/java2d/loops/MaskBlit", SD_LOCK_READ, SD_LOCK_RD_WR, NULL, NULL},
 595     { "sun/java2d/loops/MaskFill", 0, SD_LOCK_RD_WR, NULL, NULL},
 596     { "sun/java2d/loops/DrawGlyphList", 0, SD_LOCK_PARTIAL_WRITE |
 597                                            SD_LOCK_FASTEST, NULL, NULL},
 598     { "sun/java2d/loops/DrawGlyphListAA", 0, SD_LOCK_RD_WR | SD_LOCK_FASTEST, NULL, NULL},
 599     { "sun/java2d/loops/DrawGlyphListLCD", 0, SD_LOCK_RD_WR | SD_LOCK_FASTEST, NULL, NULL},
 600     { "sun/java2d/loops/TransformHelper", SD_LOCK_READ, 0, NULL, NULL}
 601 };
 602 
 603 /*
 604  * Definition and initialization of the globally accessible SurfaceTypes.
 605  */
 606 struct _SurfaceTypes SurfaceTypes = {
 607     { { "OpaqueColor", NULL}, NULL, 0, 0 },
 608     { { "AnyColor", NULL}, NULL, 0, 0 },
 609     { { "AnyByte", NULL}, NULL, 0, 0 },
 610     { { "ByteBinary1Bit", NULL},
 611       PixelForByteBinary, SD_LOCK_LUT, SD_LOCK_INVCOLOR },
 612     { { "ByteBinary2Bit", NULL},
 613       PixelForByteBinary, SD_LOCK_LUT, SD_LOCK_INVCOLOR },
 614     { { "ByteBinary4Bit", NULL},
 615       PixelForByteBinary, SD_LOCK_LUT, SD_LOCK_INVCOLOR },
 616     { { "ByteIndexed", NULL},
 617       PixelForByteIndexed, SD_LOCK_LUT, SD_LOCK_INVCOLOR },
 618     { { "ByteIndexedBm", NULL},
 619       PixelForByteIndexed, SD_LOCK_LUT, SD_LOCK_INVCOLOR },
 620     { { "ByteGray", NULL}, PixelForByteGray, 0, 0},
 621     { { "Index8Gray", NULL},
 622       PixelForIndex8Gray, SD_LOCK_LUT, SD_LOCK_INVGRAY },
 623     { { "Index12Gray", NULL},
 624       PixelForIndex12Gray, SD_LOCK_LUT, SD_LOCK_INVGRAY },
 625     { { "AnyShort", NULL}, NULL, 0, 0 },
 626     { { "Ushort555Rgb", NULL}, PixelForUshort555Rgb, 0, 0},
 627     { { "Ushort555Rgbx", NULL}, PixelForUshort555Rgbx, 0, 0},
 628     { { "Ushort565Rgb", NULL}, PixelForUshort565Rgb, 0, 0 },
 629     { { "Ushort4444Argb", NULL}, PixelForUshort4444Argb, 0, 0 },
 630     { { "UshortGray", NULL}, PixelForUshortGray, 0, 0},
 631     { { "UshortIndexed", NULL},
 632       PixelForUshortIndexed, SD_LOCK_LUT, SD_LOCK_INVCOLOR },
 633     { { "Any3Byte", NULL},  NULL, 0, 0 },
 634     { { "ThreeByteBgr", NULL},  NULL, 0, 0 },
 635     { { "AnyInt", NULL}, NULL, 0, 0 },
 636     { { "IntArgb", NULL},  NULL, 0, 0 },
 637     { { "IntArgbPre", NULL}, PixelForIntArgbPre, 0, 0},
 638     { { "IntArgbBm", NULL}, PixelForIntArgbBm, 0, 0},
 639     { { "IntRgb", NULL},  NULL, 0, 0 },
 640     { { "IntBgr", NULL}, PixelForIntBgr, 0, 0},
 641     { { "IntRgbx", NULL}, PixelForIntRgbx, 0, 0},
 642     { { "Any4Byte", NULL},  NULL, 0, 0 },
 643     { { "FourByteAbgr", NULL}, PixelForFourByteAbgr, 0, 0},
 644     { { "FourByteAbgrPre", NULL}, PixelForFourByteAbgrPre, 0, 0},
 645 };
 646 
 647 /*
 648  * Definition and initialization of the globally accessible CompositeTypes.
 649  */
 650 struct _CompositeTypes CompositeTypes = {
 651     { { "SrcNoEa", NULL}, NULL, 0},
 652     { { "SrcOverNoEa", NULL}, NULL, SD_LOCK_RD_WR },
 653     { { "SrcOverNoEa", NULL}, NULL, SD_LOCK_PARTIAL_WRITE }, /* SrcOverBmNoEa */
 654     { { "Src", NULL}, GrPrim_CompGetAlphaInfo, 0},
 655     { { "SrcOver", NULL}, GrPrim_CompGetAlphaInfo, SD_LOCK_RD_WR },
 656     { { "Xor", NULL}, GrPrim_CompGetXorInfo, SD_LOCK_RD_WR },
 657     { { "AnyAlpha", NULL}, GrPrim_CompGetAlphaInfo, SD_LOCK_RD_WR },
 658 };