Rboolean newJavaGD_Open(NewDevDesc *dd, newJavaGDDesc *xd, const char *dsp, double w, double h) { if (initJavaGD(xd)) return FALSE; xd->fill = 0xffffffff; /* transparent, was R_RGB(255, 255, 255); */ xd->col = R_RGB(0, 0, 0); xd->canvas = R_RGB(255, 255, 255); xd->windowWidth = w; xd->windowHeight = h; xd->holdlevel = 0; { JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) { gdWarning("gdOpen: env, xd or talk is null"); return FALSE; } /* we're not using dsp atm! */ mid = (*env)->GetMethodID(env, xd->talkClass, "gdOpen", "(DD)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, w, h); else { gdWarning("gdOpen: can't get mid"); chkX(env); return FALSE; } chkX(env); } return TRUE; }
static Rboolean newJavaGD_Locator(double *x, double *y, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) return FALSE; mid = (*env)->GetMethodID(env, xd->talkClass, "gdLocator", "()[D"); if (mid) { jobject o=(*env)->CallObjectMethod(env, xd->talk, mid); if (o) { jdouble *ac=(jdouble*)(*env)->GetDoubleArrayElements(env, o, 0); if (!ac) { (*env)->DeleteLocalRef(env, o); return FALSE; } *x=ac[0]; *y=ac[1]; (*env)->ReleaseDoubleArrayElements(env, o, ac, 0); (*env)->DeleteLocalRef(env, o); chkX(env); return TRUE; } } chkX(env); return FALSE; }
/** check changes in GC and issue corresponding commands if necessary */ static void sendGC(JNIEnv *env, newJavaGDDesc *xd, R_GE_gcontext *gc, int sendAll) { jmethodID mid; if (sendAll || gc->col != lastGC.col) { mid = (*env)->GetMethodID(env, xd->talkClass, "gdcSetColor", "(I)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, CONVERT_COLOR(gc->col)); else gdWarning("checkGC.gdcSetColor: can't get mid"); chkX(env); } if (sendAll || gc->fill != lastGC.fill) { mid = (*env)->GetMethodID(env, xd->talkClass, "gdcSetFill", "(I)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, CONVERT_COLOR(gc->fill)); else gdWarning("checkGC.gdcSetFill: can't get mid"); chkX(env); } if (sendAll || gc->lwd != lastGC.lwd || gc->lty != lastGC.lty) { mid = (*env)->GetMethodID(env, xd->talkClass, "gdcSetLine", "(DI)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, gc->lwd, gc->lty); else gdWarning("checkGC.gdcSetLine: can't get mid"); chkX(env); } if (sendAll || gc->cex!=lastGC.cex || gc->ps!=lastGC.ps || gc->lineheight!=lastGC.lineheight || gc->fontface!=lastGC.fontface || strcmp(gc->fontfamily, lastGC.fontfamily)) { jstring s = (*env)->NewStringUTF(env, gc->fontfamily); mid = (*env)->GetMethodID(env, xd->talkClass, "gdcSetFont", "(DDDILjava/lang/String;)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, gc->cex, gc->ps, gc->lineheight, gc->fontface, s); else gdWarning("checkGC.gdcSetFont: can't get mid"); chkX(env); } memcpy(&lastGC, gc, sizeof(lastGC)); }
static int newJavaGD_HoldFlush(NewDevDesc *dd, int level) { int ol; newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if (!xd) return 0; ol = xd->holdlevel; xd->holdlevel += level; if (xd->holdlevel < 0) xd->holdlevel = 0; if(!env || !xd->talk) return xd->holdlevel; mid = (*env)->GetMethodID(env, xd->talkClass, "gdFlush", "(Z)V"); if (mid) { if (xd->holdlevel == 0) /* flush */ (*env)->CallVoidMethod(env, xd->talk, mid, 1); else if (ol == 0) /* first hold */ (*env)->CallVoidMethod(env, xd->talk, mid, 0); chkX(env); } return xd->holdlevel; }
static void newJavaGD_MetricInfo(int c, R_GE_gcontext *gc, double* ascent, double* descent, double* width, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) return; checkGC(env,xd, gc); if(c <0) c = -c; mid = (*env)->GetMethodID(env, xd->talkClass, "gdMetricInfo", "(I)[D"); if (mid) { jobject o=(*env)->CallObjectMethod(env, xd->talk, mid, c); if (o) { jdouble *ac=(jdouble*)(*env)->GetDoubleArrayElements(env, o, 0); if (!ac) { (*env)->DeleteLocalRef(env, o); return; } *ascent=ac[0]; *descent=ac[1]; *width=ac[2]; (*env)->ReleaseDoubleArrayElements(env, o, ac, 0); (*env)->DeleteLocalRef(env, o); } } chkX(env); }
void getJavaGDPPI(NewDevDesc *dd, double *xpi, double *ypi) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jobject jo; if (!env || !xd || !xd->talk) return; *xpi = 96.0; *ypi = 96.0; jo = (*env)->CallObjectMethod(env, xd->talk, jmGDInterfaceGetPPI); if (jo) { jdouble *ac = (jdouble*)(*env)->GetDoubleArrayElements(env, jo, 0); if (!ac) { (*env)->DeleteLocalRef(env, jo); gdWarning("getPPI: cant's get double*, using default"); return; } if (ac[0] > 0.0 && ac[1] > 0.0) { *xpi = ac[0]; *ypi = ac[1]; } (*env)->ReleaseDoubleArrayElements(env, jo, ac, 0); (*env)->DeleteLocalRef(env, jo); } else { gdWarning("getPPI: method returned null, using default"); } chkX(env); }
static void newJavaGD_Path(double *x, double *y, int npoly, int *nper, Rboolean winding, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; jarray na, xa, ya; int n; if (!env || !xd || !xd->talk) return; checkGC(env, xd, gc); na = (*env)->NewIntArray(env, npoly); if (!na) return; (*env)->SetIntArrayRegion(env, na, 0, npoly, (jint *) nper); n = 0; for (int i = 0; i < npoly; ++i) n += nper[i]; xa = newDoubleArray(env, n, x); if (!xa) return; ya = newDoubleArray(env, n, y); if (!ya) return; mid = (*env)->GetMethodID(env, xd->talkClass, "gdPath", "(I[I[D[DZ)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, (jint) npoly, na, xa, ya, winding); (*env)->DeleteLocalRef(env, na); (*env)->DeleteLocalRef(env, xa); (*env)->DeleteLocalRef(env, ya); chkX(env); }
void initJavaGD(newJavaGDDesc *xd, double *width, double *height, int *unit, double *xpi, double *ypi) { JNIEnv *env = getJNIEnv(); jobject jo; if(!env || !xd || !xd->talk) return; jo = (*env)->CallObjectMethod(env, xd->talk, jmGDInterfaceInit, (jdouble) *width, (jdouble) *height, (jint) *unit, (jdouble) *xpi, (jdouble) *ypi); if (jo) { jdouble *ac = (jdouble*)(*env)->GetDoubleArrayElements(env, jo, 0); if (!ac) { (*env)->DeleteLocalRef(env, jo); gdWarning("gdInit: cant's get double*"); if (*unit != 1) { *width = 672.0; *height = 672.0; } return; } *width = ac[0]; *height = ac[1]; (*env)->ReleaseDoubleArrayElements(env, jo, ac, 0); (*env)->DeleteLocalRef(env, jo); } else { gdWarning("gdInit: method returned null"); if (*unit != 1) { *width = 672.0; *height = 672.0; } } chkX(env); }
static void newJavaGD_Size(double *left, double *right, double *bottom, double *top, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) return; mid = (*env)->GetMethodID(env, xd->talkClass, "gdSize", "()[D"); if (mid) { jobject o=(*env)->CallObjectMethod(env, xd->talk, mid); if (o) { jdouble *ac=(jdouble*)(*env)->GetDoubleArrayElements(env, o, 0); if (!ac) { (*env)->DeleteLocalRef(env, o); gdWarning("gdSize: cant's get double*"); return; } *left=ac[0]; *right=ac[1]; *bottom=ac[2]; *top=ac[3]; (*env)->ReleaseDoubleArrayElements(env, o, ac, 0); (*env)->DeleteLocalRef(env, o); } else gdWarning("gdSize: gdSize returned null"); } else gdWarning("gdSize: can't get mid "); chkX(env); }
static void newJavaGD_Mode(int mode, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); if(!env || !xd || !xd->talk) return; (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceMode, mode); chkX(env); }
static jarray newDoubleArray(JNIEnv *env, int n, double *ct) { jdoubleArray da=(*env)->NewDoubleArray(env,n); if (!da) return 0; if (n>0) { jdouble *dae; dae=(*env)->GetDoubleArrayElements(env, da, 0); if (!dae) { (*env)->DeleteLocalRef(env,da); chkX(env); return 0; } memcpy(dae,ct,sizeof(double)*n); (*env)->ReleaseDoubleArrayElements(env, da, dae, 0); } chkX(env); return da; }
static void newJavaGD_Clip(double x0, double x1, double y0, double y1, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); if(!env || !xd || !xd->talk) return; (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceClip, x0, x1, y0, y1); chkX(env); }
static void newJavaGD_Mode(int mode, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) return; mid = (*env)->GetMethodID(env, xd->talkClass, "gdMode", "(I)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, mode); chkX(env); }
void openJavaGD(NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; int devNr = ndevNumber(dd); JNIEnv *env = getJNIEnv(); if (!env || !xd || !xd->talk || !jmGDInterfaceOpen) return; (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceOpen, (jint) devNr); chkX(env); }
static void newJavaGD_Circle(double x, double y, double r, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); if(!env || !xd || !xd->talk) return; checkGC(env,xd, gc); (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceCircle, x, y, r); chkX(env); }
static void newJavaGD_Rect(double x0, double y0, double x1, double y1, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); if(!env || !xd || !xd->talk) return; checkGC(env,xd, gc); (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceRect, x0, y0, x1, y1); chkX(env); }
static void newJavaGD_Clip(double x0, double x1, double y0, double y1, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) return; mid = (*env)->GetMethodID(env, xd->talkClass, "gdClip", "(DDDD)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, x0, x1, y0, y1); chkX(env); }
static void newJavaGD_NewPage(R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); if(!env || !xd || !xd->talk) return; (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceNewPage); chkX(env); /* this is an exception - we send all GC attributes just after the NewPage command */ sendAllGC(env, xd, gc); }
/** check changes in GC and issue corresponding commands if necessary */ static void sendGC(JNIEnv *env, newJavaGDDesc *xd, R_GE_gcontext *gc, int sendAll) { if (sendAll || gc->col != lastGC.col) { (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceSetColor, gc->col); chkX(env); } if (sendAll || gc->fill != lastGC.fill) { (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceSetFill, gc->fill); chkX(env); } if (sendAll || gc->lwd != lastGC.lwd || gc->lty != lastGC.lty) { (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceSetLine, gc->lwd, gc->lty); chkX(env); } if (sendAll || gc->cex!=lastGC.cex || gc->ps!=lastGC.ps || gc->lineheight!=lastGC.lineheight || gc->fontface!=lastGC.fontface || strcmp(gc->fontfamily, lastGC.fontfamily)) { jstring s = (*env)->NewStringUTF(env, gc->fontfamily); (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceSetFont, gc->cex, gc->ps, gc->lineheight, gc->fontface, s); chkX(env); } memcpy(&lastGC, gc, sizeof(lastGC)); }
static void newJavaGD_Line(double x1, double y1, double x2, double y2, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) return; checkGC(env,xd, gc); mid = (*env)->GetMethodID(env, xd->talkClass, "gdLine", "(DDDD)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, x1, y1, x2, y2); chkX(env); }
static void newJavaGD_TextUTF8(double x, double y, constxt char *str, double rot, double hadj, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jstring s; if(!env || !xd || !xd->talk) return; checkGC(env,xd, gc); s = (*env)->NewStringUTF(env, str); (*env)->CallVoidMethod(env, xd->talk, jmGDInterfaceText, x, y, s, rot, hadj); (*env)->DeleteLocalRef(env, s); chkX(env); }
static void newJavaGD_Rect(double x0, double y0, double x1, double y1, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) return; checkGC(env,xd, gc); mid = (*env)->GetMethodID(env, xd->talkClass, "gdRect", "(DDDD)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, x0, y0, x1, y1); else gdWarning("gdRect: can't get mid "); chkX(env); }
static double newJavaGD_StrWidthUTF8(constxt char *str, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jstring s; double width; if(!env || !xd || !xd->talk) return 0.0; checkGC(env,xd, gc); s = (*env)->NewStringUTF(env, str); width = (*env)->CallDoubleMethod(env, xd->talk, jmGDInterfaceStrWidth, s); /* s not released! */ chkX(env); return width; }
static void newJavaGD_TextUTF8(double x, double y, constxt char *str, double rot, double hadj, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; jstring s; if(!env || !xd || !xd->talk) return; checkGC(env, xd, gc); s = (*env)->NewStringUTF(env, str); mid = (*env)->GetMethodID(env, xd->talkClass, "gdText", "(DDLjava/lang/String;DD)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, x, y, s, rot, hadj); (*env)->DeleteLocalRef(env, s); chkX(env); }
static void newJavaGD_NewPage(R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; int devNr; if(!env || !xd || !xd->talk) return; devNr = ndevNumber(dd); mid = (*env)->GetMethodID(env, xd->talkClass, "gdNewPage", "(I)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, devNr); chkX(env); /* this is an exception - we send all GC attributes just after the NewPage command */ sendAllGC(env, xd, gc); }
static double newJavaGD_StrWidthUTF8(constxt char *str, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; jstring s; double res = 0.0; if(!env || !xd || !xd->talk) return 0.0; checkGC(env, xd, gc); s = (*env)->NewStringUTF(env, str); mid = (*env)->GetMethodID(env, xd->talkClass, "gdStrWidth", "(Ljava/lang/String;)D"); if (mid) res = (*env)->CallDoubleMethod(env, xd->talk, mid, s); (*env)->DeleteLocalRef(env, s); chkX(env); return res; }
static void newJavaGD_Polyline(int n, double *x, double *y, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jarray xa, ya; if(!env || !xd || !xd->talk) return; checkGC(env,xd, gc); xa=newDoubleArray(env, n, x); if (!xa) return; ya=newDoubleArray(env, n, y); if (!ya) return; (*env)->CallVoidMethod(env, xd->talk, jmGDInterfacePolyline, n, xa, ya); (*env)->DeleteLocalRef(env, xa); (*env)->DeleteLocalRef(env, ya); chkX(env); }
static void newJavaGD_Raster(unsigned int *raster, int w, int h, double x, double y, double width, double height, double rot, Rboolean interpolate, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; if(!env || !xd || !xd->talk) return; checkGC(env, xd, gc); mid = (*env)->GetMethodID(env, xd->talkClass, "gdRaster", "([BIIDDDDDZ)V"); if (mid) { jbyteArray img = (*env)->NewByteArray(env, w * h * 4); (*env)->SetByteArrayRegion(env, img, 0, w * h * 4, (jbyte*) raster); (*env)->CallVoidMethod(env, xd->talk, mid, img, w, h, x, y, width, height, rot, interpolate); (*env)->DeleteLocalRef(env, img); } chkX(env); }
static void newJavaGD_Polygon(int n, double *x, double *y, R_GE_gcontext *gc, NewDevDesc *dd) { newJavaGDDesc *xd = (newJavaGDDesc *) dd->deviceSpecific; JNIEnv *env = getJNIEnv(); jmethodID mid; jarray xa, ya; if(!env || !xd || !xd->talk) return; checkGC(env, xd, gc); xa = newDoubleArray(env, n, x); if (!xa) return; ya = newDoubleArray(env, n, y); if (!ya) return; mid = (*env)->GetMethodID(env, xd->talkClass, "gdPolygon", "(I[D[D)V"); if (mid) (*env)->CallVoidMethod(env, xd->talk, mid, n, xa, ya); (*env)->DeleteLocalRef(env, xa); (*env)->DeleteLocalRef(env, ya); chkX(env); }
Rboolean createJavaGD(newJavaGDDesc *xd) { jclass jc = 0; jobject jo = 0; JNIEnv *env=getJNIEnv(); if (!jvm) { initJVM(jarClassPath); env=getJNIEnv(); } if (!env) return FALSE; char *customClass = getenv("RJGD_CLASS_NAME"); if (!customClass) { //customClass = "org.rosuda.javaGD.JavaGD"; customClass = "de.walware.rj.server.gd.JavaGD"; } if (!jcGDInterface) { jclass jc = getJClass(env, "org.rosuda.javaGD.GDInterface", (RJ_ERROR_RERROR | RJ_GLOBAL_REF)); jmGDInterfaceActivate = getJMethod(env, jc, "gdActivate", "()V", RJ_ERROR_RERROR); jmGDInterfaceCircle = getJMethod(env, jc, "gdCircle", "(DDD)V", RJ_ERROR_RERROR); jmGDInterfaceClip = getJMethod(env, jc, "gdClip", "(DDDD)V", RJ_ERROR_RERROR); jmGDInterfaceClose = getJMethod(env, jc, "gdClose", "()V", RJ_ERROR_RERROR); jmGDInterfaceDeactivate = getJMethod(env, jc, "gdDeactivate", "()V", RJ_ERROR_RERROR); jmGDInterfaceGetPPI = getJMethod(env, jc, "gdPPI", "()[D", RJ_ERROR_RERROR); jmGDInterfaceInit = getJMethod(env, jc, "gdInit", "(DDIDD)[D", RJ_ERROR_RERROR); jmGDInterfaceLocator = getJMethod(env, jc, "gdLocator", "()[D", RJ_ERROR_RERROR); jmGDInterfaceLine = getJMethod(env, jc, "gdLine", "(DDDD)V", RJ_ERROR_RERROR); jmGDInterfaceMetricInfo = getJMethod(env, jc, "gdMetricInfo", "(I)[D", RJ_ERROR_RERROR); jmGDInterfaceMode = getJMethod(env, jc, "gdMode", "(I)V", RJ_ERROR_RERROR); jmGDInterfaceNewPage = getJMethod(env, jc, "gdNewPage", "()V", RJ_ERROR_RERROR); jmGDInterfaceNewPageConfirm = getJMethod(env, jc, "gdNewPageConfirm", "()Z", RJ_ERROR_RERROR); jmGDInterfaceOpen = getJMethod(env, jc, "gdOpen", "(I)V", RJ_ERROR_RERROR); jmGDInterfacePolygon = getJMethod(env, jc, "gdPolygon", "(I[D[D)V", RJ_ERROR_RERROR); jmGDInterfacePolyline = getJMethod(env, jc, "gdPolyline", "(I[D[D)V", RJ_ERROR_RERROR); jmGDInterfaceRect = getJMethod(env, jc, "gdRect", "(DDDD)V", RJ_ERROR_RERROR); jmGDInterfaceSize = getJMethod(env, jc, "gdSize", "()[D", RJ_ERROR_RERROR); jmGDInterfaceStrWidth = getJMethod(env, jc, "gdStrWidth", "(Ljava/lang/String;)D", RJ_ERROR_RERROR); jmGDInterfaceText = getJMethod(env, jc, "gdText", "(DDLjava/lang/String;DD)V", RJ_ERROR_RERROR); jmGDInterfaceSetColor = getJMethod(env, jc, "gdcSetColor", "(I)V", RJ_ERROR_RERROR); jmGDInterfaceSetFill = getJMethod(env, jc, "gdcSetFill", "(I)V", RJ_ERROR_RERROR); jmGDInterfaceSetLine = getJMethod(env, jc, "gdcSetLine", "(DI)V", RJ_ERROR_RERROR); jmGDInterfaceSetFont = getJMethod(env, jc, "gdcSetFont", "(DDDILjava/lang/String;)V", RJ_ERROR_RERROR); jcGDInterface = jc; } jc = getJClass(env, customClass, (RJ_ERROR_RERROR | RJ_GLOBAL_REF)); { jmethodID jm = (*env)->GetMethodID(env, jc, "<init>", "()V"); if (!jm) { (*env)->DeleteLocalRef(env, jc); handleJError(env, RJ_ERROR_RERROR, "Cannot find default constructor for GD class '%s'.", customClass); } jo = (*env)->NewObject(env, jc, jm); if (!jo) { (*env)->DeleteLocalRef(env, jc); handleJError(env, RJ_ERROR_RERROR, "Cannot instantiate object of GD class '%s'.", customClass); } } xd->talk = (*env)->NewGlobalRef(env, jo); (*env)->DeleteLocalRef(env, jo); xd->talkClass = jc; if (!xd->talk) { chkX(env); gdWarning("Rjgd_NewDevice: talk is null"); return FALSE; } return TRUE; }