/* * Class: sun_java2d_cmm_lcms_LCMS * Method: createNativeTransform * Signature: ([JI)J */ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform (JNIEnv *env, jclass cls, jlongArray profileIDs, jint renderType, jobject disposerRef) { LPLCMSICCPROFILE _iccArray[DF_ICC_BUF_SIZE]; LPLCMSICCPROFILE *iccArray = &_iccArray[0]; cmsHTRANSFORM transform; storeID_t sTrans; int i, j, size; jlong* ids; size = (*env)->GetArrayLength (env, profileIDs); ids = (*env)->GetPrimitiveArrayCritical(env, profileIDs, 0); if (DF_ICC_BUF_SIZE < size*2) { iccArray = (LPLCMSICCPROFILE*) malloc( size*2*sizeof(LPLCMSICCPROFILE)); if (iccArray == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL"); return NULL; } } j = 0; for (i = 0; i < size; i++) { LPLCMSICCPROFILE icc; sTrans.j = ids[i]; icc = sTrans.pf; iccArray[j++] = icc; /* Middle non-abstract profiles should be doubled before passing to * the cmsCreateMultiprofileTransform function */ if (size > 2 && i != 0 && i != size - 1 && icc->ColorSpace != icSigXYZData && icc->ColorSpace != icSigLabData) { iccArray[j++] = icc; } } sTrans.xf = cmsCreateMultiprofileTransform(iccArray, j, 0, 0, renderType, 0); (*env)->ReleasePrimitiveArrayCritical(env, profileIDs, ids, 0); if (sTrans.xf == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: " "sTrans.xf == NULL"); JNU_ThrowByName(env, "java/awt/color/CMMException", "Cannot get color transform"); } else { Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j); } if (iccArray != &_iccArray[0]) { free(iccArray); } return sTrans.j; }
/* * Class: sun_dc_pr_PathStroker * Method: cInitialize * Signature: (Lsun/dc/path/PathConsumer;)V */ JNIEXPORT void JNICALL Java_sun_dc_pr_PathStroker_cInitialize (JNIEnv *env, jobject obj, jobject out) { jclass cls; jfieldID fid; jmethodID mid; PathStroker cdata; doeE cenv = doeE_make(); doeE_setPCtxt(cenv, env); cdata = (PathStroker)doeMem_malloc(cenv, sizeof(PathStrokerData)); if (doeError_occurred(cenv)) { CJError_throw(cenv); return; } (*env)->SetLongField(env, obj, fidCData, ptr_to_jlong(cdata)); /* __________________________ * the c environment variable */ cdata->env = cenv; /* Register the data for disposal */ Disposer_AddRecord(env, obj, PathStroker_DisposeOps, ptr_to_jlong(cdata)); /* __________________________________ * the corresponding CJ path consumer * (always created so as to be able to deal with any type of * incoming out path consumers) */ cdata->cjout = CJPathConsumer_create(cenv, out); if (doeError_occurred(cenv)) { CJError_throw(cenv); return; } /* ________________________________________________ * determines if "out" has a native implementation. */ cls = (*env)->GetObjectClass(env, out); mid = (*env)->GetMethodID(env, cls, "getCPathConsumer", "()J"); cdata->cout = (dcPathConsumer) jlong_to_ptr((*env)->CallLongMethod(env, out, mid)); /* ________________________ * the actual c PathStroker */ if (cdata->cout) { cdata->stroker = dcPathStroker_create(cenv, cdata->cout); } else { cdata->stroker = dcPathStroker_create(cenv, (dcPathConsumer)cdata->cjout); } if (doeError_occurred(cenv)) { CJError_throw(cenv); return; } }
JNIEXPORT void JNICALL SurfaceData_SetOps(JNIEnv *env, jobject sData, SurfaceDataOps *ops) { if (JNU_GetLongFieldAsPtr(env, sData, pDataID) == NULL) { JNU_SetLongFieldFromPtr(env, sData, pDataID, ops); /* Register the data for disposal */ Disposer_AddRecord(env, sData, SurfaceData_DisposeOps, ptr_to_jlong(ops)); } else { JNU_ThrowInternalError(env, "Attempting to set SurfaceData ops twice"); } }
/** * Initializes a new OGLContext, which includes the native WGL context handle * and some other important information such as the associated pixel format. * If sharedctx is non-null, its texture objects will be shared with the newly * created HGLRC. If useDisposer is JNI_TRUE, a new DisposerTarget * (with the current Java-level thread object as the referent) will be * created and enqueued in the Disposer, so that this OGLContext will be * disposed of properly when its associated thread exits. Contexts that are * intended to remain for the lifetime of the app (such as the sharedContext) * should specify JNI_FALSE for useDisposer. */ OGLContext * WGLGC_InitOGLContext(JNIEnv *env, WGLGraphicsConfigInfo *wglinfo, jboolean useDisposer) { OGLContext *oglc; WGLCtxInfo *ctxinfo; HGLRC context; static jboolean firstTime = JNI_TRUE; J2dTraceLn(J2D_TRACE_INFO, "in WGLGC_InitOGLContext"); oglc = (OGLContext *)malloc(sizeof(OGLContext)); if (oglc == NULL) { J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for oglc"); return NULL; } memset(oglc, 0, sizeof(OGLContext)); ctxinfo = (WGLCtxInfo *)malloc(sizeof(WGLCtxInfo)); if (ctxinfo == NULL) { J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for ctxinfo"); free(oglc); return NULL; } context = WGLGC_CreateContext(wglinfo->screen, wglinfo->pixfmt); if (context == 0) { J2dTraceLn(J2D_TRACE_ERROR, "could not create new WGL context"); free(oglc); free(ctxinfo); return NULL; } // REMIND: when using wglShareLists, the two contexts must use an // identical pixel format... if (sharedContext != NULL) { WGLCtxInfo *sharedCtxInfo = (WGLCtxInfo *)sharedContext->ctxInfo; if (!j2d_wglShareLists(sharedCtxInfo->context, context)) { J2dTraceLn(J2D_TRACE_WARNING, "unable to share lists"); } } ctxinfo->context = context; ctxinfo->configInfo = wglinfo; oglc->ctxInfo = ctxinfo; oglc->extInfo = &wglinfo->extInfo; // initialize this value to 1.0f as it is sometimes used when uploading // textures (see OGLBlitLoops_Blit()), and in the case of the shared // context, we skip the InitComposite() step that would otherwise // initialize the oglc->extraAlpha value... oglc->extraAlpha = 1.0f; /** * REMIND: The following is a total hack. The first time we enter * this method, we must be on the main thread attempting to initialize * the default GraphicsConfig. Each time we enter this method, we would * like to upcall to the static EventQueue.isDispatchThread() method. * But the first time we call that static method, we may end up implicitly * loading WToolkit, which will also attempt to call getDefaultConfig(). * But since we still haven't fully initialized the default config, we * re-enter the getDefaultConfig() method (in the same thread), and then * come down through this same method. JNI doesn't seem to like this * situation, and we end up with a seg fault. This may be a JNI bug, * but for now we'll work around it, by avoiding the upcall the first * time around. After that, we should be able to make this upcall without * the nasty side effects. */ if (firstTime) { oglc->onJED = JNI_FALSE; firstTime = JNI_FALSE; } else { oglc->onJED = JNU_CallStaticMethodByName(env, NULL, "java/awt/EventQueue", "isDispatchThread", "()Z").z; } if (useDisposer) { // initialize a new Disposer target (when the Java-level thread object // is about to go away, Disposer will invoke our native dispose // method, which destroys this OGLContext and its associated entries) jobject thread = JNU_CallStaticMethodByName(env, NULL, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;").l; if (thread == NULL) { J2dTraceLn(J2D_TRACE_ERROR, "could not fetch current thread"); j2d_wglDeleteContext(context); free(oglc); free(ctxinfo); return NULL; } Disposer_AddRecord(env, thread, WGLGC_DisposeOGLContext, ptr_to_jlong(oglc)); } return oglc; }
/** * Initializes a new OGLContext, which includes the native GLXContext handle * and some other important information such as the associated GLXFBConfig. * If sharedctx is non-null, its texture objects will be shared with the newly * created GLXContext. If useDisposer is JNI_TRUE, a new DisposerTarget * (with the current Java-level thread object as the referent) will be * created and enqueued in the Disposer, so that this OGLContext will be * disposed of properly when its associated thread exits. Contexts that are * intended to remain for the lifetime of the app (such as the sharedContext) * should specify JNI_FALSE for useDisposer. */ OGLContext * GLXGC_InitOGLContext(JNIEnv *env, GLXGraphicsConfigInfo *glxinfo, GLXContext sharedctx, jboolean useDisposer) { OGLContext *oglc; GLXCtxInfo *ctxinfo; GLXFBConfig fbconfig; GLXContext context; static jboolean firstTime = JNI_TRUE; J2dTraceLn(J2D_TRACE_INFO, "in GLXGC_InitOGLContext"); oglc = (OGLContext *)malloc(sizeof(OGLContext)); if (oglc == NULL) { J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for oglc"); return NULL; } memset(oglc, 0, sizeof(OGLContext)); ctxinfo = (GLXCtxInfo *)malloc(sizeof(GLXCtxInfo)); if (ctxinfo == NULL) { J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for ctxinfo"); free(oglc); return NULL; } fbconfig = GLXGC_InitFBConfig(env, glxinfo->screen, glxinfo->visual); if (fbconfig == 0) { J2dTraceLn(J2D_TRACE_ERROR, "could not create new GLX fbconfig"); free(oglc); free(ctxinfo); return NULL; } // REMIND: we cannot rely on direct contexts when rendering to pixmaps context = j2d_glXCreateNewContext(awt_display, fbconfig, GLX_RGBA_TYPE, sharedctx, GL_TRUE); if (context == 0) { J2dTraceLn(J2D_TRACE_ERROR, "could not create new GLX context"); free(oglc); free(ctxinfo); return NULL; } ctxinfo->fbconfig = fbconfig; ctxinfo->context = context; oglc->ctxInfo = ctxinfo; oglc->extInfo = &glxinfo->extInfo; // initialize this value to 1.0f as it is sometimes used when uploading // textures (see OGLBlitLoops_Blit()), and in the case of the shared // context, we skip the InitComposite() step that would otherwise // initialize the oglc->extraAlpha value... oglc->extraAlpha = 1.0f; /** * REMIND: The following is a total hack. The first time we enter * this method, we must be on the main thread attempting to initialize * the default GraphicsConfig. Each time we enter this method, we would * like to upcall to the static EventQueue.isDispatchThread() method. * But the first time we call that static method, we may end up implicitly * loading MToolkit, which will also attempt to call getDefaultConfig(). * But since we still haven't fully initialized the default config, we * re-enter the getDefaultConfig() method (in the same thread), and then * come down through this same method. JNI doesn't seem to like this * situation, and we end up with a seg fault. This may be a JNI bug, * but for now we'll work around it, by avoiding the upcall the first * time around. After that, we should be able to make this upcall without * the nasty side effects. */ if (firstTime) { oglc->onJED = JNI_FALSE; firstTime = JNI_FALSE; } else { oglc->onJED = JNU_CallStaticMethodByName(env, NULL, "java/awt/EventQueue", "isDispatchThread", "()Z").z; } if (useDisposer) { // initialize a new Disposer target (when the Java-level thread object // is about to go away, Disposer will invoke our native dispose // method, which destroys this OGLContext and its associated entries) jobject thread = awtJNI_GetCurrentThread(env); if (thread == NULL) { J2dTraceLn(J2D_TRACE_ERROR, "could not fetch current thread"); free(oglc); free(ctxinfo); return NULL; } Disposer_AddRecord(env, thread, GLXGC_DisposeOGLContext, ptr_to_jlong(oglc)); } return oglc; }
struct FontData * awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg) { /* We are going to create at most 4 outstanding local refs in this * function. */ if ((*env)->EnsureLocalCapacity(env, 4) < 0) { return NULL; } if (!JNU_IsNull(env, font) && awtJNI_IsMultiFont(env, font)) { struct FontData *fdata = NULL; int32_t i, size; char *fontsetname = NULL; char *nativename = NULL; jobjectArray componentFonts = NULL; jobject peer = NULL; jobject fontDescriptor = NULL; jstring fontDescriptorName = NULL; jstring charsetName = NULL; fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font, fontIDs.pData); if (fdata != NULL && fdata->flist != NULL) { return fdata; } size = (*env)->GetIntField(env, font, fontIDs.size); fdata = (struct FontData *) malloc(sizeof(struct FontData)); peer = (*env)->CallObjectMethod(env, font, fontIDs.getPeer); componentFonts = (*env)->GetObjectField(env, peer, platformFontIDs.componentFonts); /* We no longer need peer */ (*env)->DeleteLocalRef(env, peer); fdata->charset_num = (*env)->GetArrayLength(env, componentFonts); fdata->flist = (awtFontList *) malloc(sizeof(awtFontList) * fdata->charset_num); fdata->xfont = NULL; for (i = 0; i < fdata->charset_num; i++) { /* * set xlfd name */ fontDescriptor = (*env)->GetObjectArrayElement(env, componentFonts, i); fontDescriptorName = (*env)->GetObjectField(env, fontDescriptor, fontDescriptorIDs.nativeName); if (!JNU_IsNull(env, fontDescriptorName)) { nativename = (char *) JNU_GetStringPlatformChars(env, fontDescriptorName, NULL); } else { nativename = ""; } fdata->flist[i].xlfd = malloc(strlen(nativename) + strlen(defaultXLFD)); jio_snprintf(fdata->flist[i].xlfd, strlen(nativename) + 10, nativename, size * 10); if (nativename != NULL && nativename != "") JNU_ReleaseStringPlatformChars(env, fontDescriptorName, (const char *) nativename); /* * set charset_name */ charsetName = (*env)->GetObjectField(env, fontDescriptor, fontDescriptorIDs.charsetName); fdata->flist[i].charset_name = (char *) JNU_GetStringPlatformChars(env, charsetName, NULL); /* We are done with the objects. */ (*env)->DeleteLocalRef(env, fontDescriptor); (*env)->DeleteLocalRef(env, fontDescriptorName); (*env)->DeleteLocalRef(env, charsetName); /* * set load & XFontStruct */ fdata->flist[i].load = 0; /* * This appears to be a bogus check. The actual intent appears * to be to find out whether this is the "base" font in a set, * rather than iso8859_1 explicitly. Note that iso8859_15 will * and must also pass this test. */ if (fdata->xfont == NULL && strstr(fdata->flist[i].charset_name, "8859_1")) { fdata->flist[i].xfont = loadFont(awt_display, fdata->flist[i].xlfd, size * 10); if (fdata->flist[i].xfont != NULL) { fdata->flist[i].load = 1; fdata->xfont = fdata->flist[i].xfont; fdata->flist[i].index_length = 1; } else { if (errmsg != NULL) { *errmsg = "java/lang" "NullPointerException"; } (*env)->DeleteLocalRef(env, componentFonts); return NULL; } } } (*env)->DeleteLocalRef(env, componentFonts); /* * XFontSet will create if the peer of TextField/TextArea * are used. */ fdata->xfs = NULL; JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata); Disposer_AddRecord(env, font, pDataDisposeMethod, ptr_to_jlong(fdata)); return fdata; } else { Display *display = NULL; struct FontData *fdata = NULL; char fontSpec[1024]; int32_t height; int32_t oheight; int32_t above = 0; /* tries above height */ int32_t below = 0; /* tries below height */ char *foundry = NULL; char *name = NULL; char *encoding = NULL; char *style = NULL; XFontStruct *xfont = NULL; jstring family = NULL; if (JNU_IsNull(env, font)) { if (errmsg != NULL) { *errmsg = "java/lang" "NullPointerException"; } return (struct FontData *) NULL; } display = XDISPLAY; fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font,fontIDs.pData); if (fdata != NULL && fdata->xfont != NULL) { return fdata; } family = (*env)->CallObjectMethod(env, font, fontIDs.getFamily); if (!awtJNI_FontName(env, family, &foundry, &name, &encoding)) { if (errmsg != NULL) { *errmsg = "java/lang" "NullPointerException"; } (*env)->DeleteLocalRef(env, family); return (struct FontData *) NULL; } style = Style((*env)->GetIntField(env, font, fontIDs.style)); oheight = height = (*env)->GetIntField(env, font, fontIDs.size); while (1) { jio_snprintf(fontSpec, sizeof(fontSpec), "-%s-%s-%s-*-*-%d-*-*-*-*-*-%s", foundry, name, style, height, encoding); /*fprintf(stderr,"LoadFont: %s\n", fontSpec); */ xfont = XLoadQueryFont(display, fontSpec); /* XXX: sometimes XLoadQueryFont returns a bogus font structure */ /* with negative ascent. */ if (xfont == (Font) NULL || xfont->ascent < 0) { if (xfont != NULL) { XFreeFont(display, xfont); } if (foundry != anyfoundry) { /* Use ptr comparison here, not strcmp */ /* Try any other foundry before messing with the sizes */ foundry = anyfoundry; continue; } /* We couldn't find the font. We'll try to find an */ /* alternate by searching for heights above and below our */ /* preferred height. We try for 4 heights above and below. */ /* If we still can't find a font we repeat the algorithm */ /* using misc-fixed as the font. If we then fail, then we */ /* give up and signal an error. */ if (above == below) { above++; height = oheight + above; } else { below++; if (below > 4) { if (name != defaultfontname || style != anystyle) { name = defaultfontname; foundry = defaultfoundry; height = oheight; style = anystyle; encoding = isolatin1; above = below = 0; continue; } else { if (errmsg != NULL) { *errmsg = "java/io/" "FileNotFoundException"; } (*env)->DeleteLocalRef(env, family); return (struct FontData *) NULL; } } height = oheight - below; } continue; } else { fdata = ZALLOC(FontData); if (fdata == NULL) { if (errmsg != NULL) { *errmsg = "java/lang" "OutOfMemoryError"; } } else { fdata->xfont = xfont; JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata); Disposer_AddRecord(env, font, pDataDisposeMethod, ptr_to_jlong(fdata)); } (*env)->DeleteLocalRef(env, family); return fdata; } } /* not reached */ } }