/*---------------------------------------------------------------------------*
 |              PDFlib - A library for generating PDF on the fly             |
 +---------------------------------------------------------------------------+
 | Copyright (c) 1997-2002 PDFlib GmbH and Thomas Merz. All rights reserved. |
 +---------------------------------------------------------------------------+
 |    This software is NOT in the public domain.  It can be used under two   |
 |    substantially different licensing terms:                               |
 |                                                                           |
 |    The commercial license is available for a fee, and allows you to       |
 |    - ship a commercial product based on PDFlib                            |
 |    - implement commercial Web services with PDFlib                        |
 |    - distribute (free or commercial) software when the source code is     |
 |      not made available                                                   |
 |    Details can be found in the file PDFlib-license.pdf.                   |
 |                                                                           |
 |    The "Aladdin Free Public License" doesn't require any license fee,     |
 |    and allows you to                                                      |
 |    - develop and distribute PDFlib-based software for which the complete  |
 |      source code is made available                                        |
 |    - redistribute PDFlib non-commercially under certain conditions        |
 |    - redistribute PDFlib on digital media for a fee if the complete       |
 |      contents of the media are freely redistributable                     |
 |    Details can be found in the file aladdin-license.pdf.                  |
 |                                                                           |
 |    These conditions extend to ports to other programming languages.       |
 |    PDFlib is distributed with no warranty of any kind. Commercial users,  |
 |    however, will receive warranty and support statements in writing.      |
 *---------------------------------------------------------------------------*/

/* $Id: pdflib_java.c,v 1.15.10.10 2002/01/07 18:26:29 tm Exp $
 *
 * JNI wrapper code for the PDFlib Java binding
 *
 */

#include <stdlib.h>
#include <string.h>
#include <setjmp.h>

#ifdef OS390
#define IBM_MVS
#define NEEDSIEEE754
#define NEEDSLONGLONG
#endif

#include <jni.h>

#ifdef OS390
#include <jni_convert.h>
#endif

#if	defined __ILEC400__ && !defined AS400
#define	AS400
#endif

#include "pdflib.h"

/* figure out whether or not we're running on an EBCDIC-based machine */
#define	ASCII_A			0x41
#define PLATFORM_A		'A'
#define EBCDIC_A		0xC1

#if (ASCII_A != PLATFORM_A && EBCDIC_A == PLATFORM_A)
#define PDFLIB_EBCDIC
#endif

#ifndef OS390

#ifndef int2ll
#define int2ll(a)	((jlong) (a))
#endif

#ifndef ll2int
#define ll2int(a)	((int) (a))
#endif

#ifndef tofloat
#define tofloat(a)	((jfloat) (a))
#endif

#ifndef flt2nat
#define	flt2nat(a)	((float) (a))
#endif

#endif /* OS390 */


#define NULL_INT		NULL
#define PDF_ENV			jlong
#define PDF_ENV2PTR(env)	*((PDF **) &(env))



/* Compilers which are not strictly ANSI conforming can set PDF_VOLATILE
 * to an empty value.
 */
#ifndef PDF_VOLATILE
#define PDF_VOLATILE    volatile
#endif

/* thread-specific data */
typedef struct {
    jmp_buf	env;
    int		type;
    char	buffer[256];
    int		nativeunicode;
    jint	jdkversion;
    jmethodID	MID_String_getBytes;	/* cached method identifier */
} pdf_wrapper_data;

/* This is used in the wrapper functions for thread-safe exception handling */
#define EXC_STUFF pdf_wrapper_data * PDF_VOLATILE ex
#define ASCII_STUFF char wstring[255], wstring2[255]

/* Exception handling */

/* Map PDFlib errors to Java exceptions */
static const char *pdf_java_exceptions[] = {
NULL,
"java/lang/OutOfMemoryError",		/* PDF_MemoryError    1 */
"java/io/IOException",			/* PDF_IOError        2 */
"java/lang/IllegalArgumentException",	/* PDF_RuntimeError   3 */
"java/lang/IndexOutOfBoundsException",	/* PDF_IndexError     4 */
"java/lang/ClassCastException",		/* PDF_TypeError      5 */
"java/lang/ArithmeticException",	/* PDF_DivisionByZero 6 */
"java/lang/ArithmeticException",	/* PDF_OverflowError  7 */
"java/lang/RuntimeException",		/* PDF_SyntaxError    8 */
"java/lang/IllegalArgumentException",	/* PDF_ValueError     9 */
"java/lang/InternalError",		/* PDF_SystemError   10 */
"java/lang/UnknownError",		/* PDF_NonfatalError 11 */
"java/lang/UnknownError",		/* PDF_UnknownError  12 */
};

#define try	ex = (pdf_wrapper_data *) (PDF_get_opaque(p));	\
		if (setjmp(ex->env) == 0)

#ifndef PDFLIB_EBCDIC

#define jthrow(jenv, type, msg) (*jenv)->ThrowNew(jenv, 		\
	    (*jenv)->FindClass(jenv, pdf_java_exceptions[type]), msg)
#else

static void
jthrow(JNIEnv *jenv, int type, char *msg)
{
    ASCII_STUFF;

    strcpy(wstring, pdf_java_exceptions[type]);
    __etoa(wstring);
    strcpy(wstring2, msg);
    __etoa(wstring2);

    (*jenv)->ThrowNew(jenv, (*jenv)->FindClass(jenv, wstring), wstring2);
}

#endif /* PDFLIB_EBCDIC */

#define catch	else { 					\
		    jthrow(jenv, ex->type, ex->buffer);	\
		}

static void
pdf_errorhandler(PDF *p, int type, const char* shortmsg)
{
    EXC_STUFF;

    if (!p)
	return;

    /* retrieve opaque pointer, clean up PDFlib internals */
    ex = (pdf_wrapper_data *) (PDF_get_opaque(p));

    /* Note: we must not call PDF_delete() here because it will be called in
     * the finalizer of the pdflib class!
     */

    /* ...and throw an exception */
    strcpy(ex->buffer, shortmsg);
    ex->type = type;
    longjmp(ex->env, 1);
}

/*
 * Single-byte sequence (PDFDocEncoding): pick only low bytes from Unicode
 * and end with null byte.
 */

static char *
GetStringPDFChars(PDF *p, JNIEnv *jenv, jstring string)
{
    const jchar *unistring;
    char *result;
    size_t i, len;

    if (!string)
	return NULL;

    len = (size_t) (*jenv)->GetStringLength(jenv, string);

    if (len == (size_t) 0)
	return NULL;

    unistring = (*jenv)->GetStringChars(jenv, string, NULL);

    if (!unistring) {
	pdf_errorhandler(p,
	    PDF_MemoryError, "JNI internal string allocation failed");
    }

    result = (char *) malloc(len + 1);

    if (!result) {
	pdf_errorhandler(p,
	    PDF_MemoryError, "JNI internal string allocation failed");
    }

    /* pick the low-order bytes only */
    for (i = 0; i < len; i++) {
	result[i] = (char) unistring[i];
    }

    result[i] = '\0';	/* NULL-terminate */

    (*jenv)->ReleaseStringChars(jenv, string, unistring);

#ifdef PDFLIB_EBCDIC
    __atoe(result);  /* convert to EBCDIC */
#endif

    return result;
}

/*
 * Utility function for converting JNI's UTF-8 chars to native C strings;
 * Based on S. Liang "The Java Native Interface" (Addison-Wesley).
 */

static char *
JNU_GetString_NativeChars(JNIEnv *jenv, pdf_wrapper_data *ex, jstring jstr)
{
    jbyteArray bytes = 0;
    jthrowable exc;
    char *result = NULL;

#ifdef JNI_VERSION_1_2	/* compile-time version test... */

    /* ...and run-time version test */
    if (ex->jdkversion == JNI_VERSION_1_2 &&
	(*jenv)->EnsureLocalCapacity(jenv, 2) < 0) {
	    return NULL;		/* out of memory error */
    }
#endif

    bytes = (*jenv)->CallObjectMethod(jenv, jstr, ex->MID_String_getBytes);
    exc = (*jenv)->ExceptionOccurred(jenv);

    if (!exc) {
	jint len = (*jenv)->GetArrayLength(jenv, bytes);
	result = (char *) malloc(len + 1);

	if (result == NULL) {
	    jthrow(jenv, PDF_MemoryError,
		"JNI internal string allocation failed");
	    (*jenv)->DeleteLocalRef(jenv, bytes);
	    return NULL;
	}

	(*jenv)->GetByteArrayRegion(jenv, bytes, 0, len, (jbyte *) result);
	result[len] = 0;		/* NULL-terminate */

    } else {
	(*jenv)->DeleteLocalRef(jenv, exc);
    }

    (*jenv)->DeleteLocalRef(jenv, bytes);

    return result;
}

#define ReleaseStringPDFChars(jenv, string, chars) if (chars) free(chars);

/*
 * Unicode strings - wrap with BOM and double-null
 */

/* The Unicode byte order mark (BOM) signals Unicode strings */
#define PDF_BOM0		0376		/* '\xFE' */
#define PDF_BOM1		0377		/* '\xFF' */

static char *
GetStringUnicodePDFChars(PDF *p, JNIEnv *jenv, jstring string, int *lenP)
{
    const jchar *unistring;
    unsigned char *result, have_unicode = 0;
    size_t i, len;
    EXC_STUFF;

    if (!string) {
	if (lenP)
	    *lenP = 0;
	return NULL;
    }

    len = (size_t) (*jenv)->GetStringLength(jenv, string);

    if (len == (size_t) 0) {
	if (lenP)
	    *lenP = 0;
	return NULL;
    }

    ex = (pdf_wrapper_data *) (PDF_get_opaque(p));

    unistring = (*jenv)->GetStringChars(jenv, string, NULL);

    if (!unistring) {
	pdf_errorhandler(p,
	    PDF_MemoryError, "JNI internal string allocation failed");
    }

    for (i = 0; i < len; i++) {
	/* check the high bytes */
	if (unistring[i] > 0xFF) {
	    have_unicode = 1;
	    break;
	}
    }

    /*
     * Unicode:
     * BOM plus two byte per character plus two null bytes, if the caller
     * requested so by supplying lenP = NULL. If lenP is supplied, it
     * points to the number of Unicode characters in the string.
     *
     * not Unicode: one byte per character plus null byte.
     */

    result = (unsigned char *)
	malloc(have_unicode ? (lenP ? 2*len : 2*len + 4) : len + 1);

    if (!result) {
	if (lenP)
	    *lenP = 0;
	pdf_errorhandler(p,
	    PDF_MemoryError, "JNI internal string allocation failed");
    }

    if (ex->nativeunicode && have_unicode) {
	if (!lenP) {
	    /* copy Unicode and wrap with BOM and double-null */
	    result[0] = PDF_BOM0;
	    result[1] = PDF_BOM1;

	    /* PDF requires the high-order byte first */
	    for (i = 0; i < len; i++) {
		result[2*i+2] = (unsigned char) (unistring[i] >> 8);
		result[2*i+3] = (unsigned char) unistring[i];
	    }
	    result[2*len + 2] = result[2*len + 3] = '\0';

	} else {
	    *lenP = (int) (2 * len);

            /* pure Unicode string */
            for (i = 0; i < len; i++) {
                result[2*i] = (unsigned char) (unistring[i] >> 8);
                result[2*i+1] = (unsigned char) unistring[i];
	    }
	}

    } else {
	if (lenP)
	    *lenP = (int) len;

	if (!have_unicode) {
	    /* pick the low-order bytes only */
	    for (i = 0; i < len; i++) {
		result[i] = (unsigned char) unistring[i];
	    }
	    result[i] = '\0';	/* NULL-terminate */
	} else {
	    /* kludge: JNU_GetString_NativeChars mallocs itself */
	    ReleaseStringPDFChars(jenv, NULL, result);

	    /* not in Unicode mode, but Unicode supplied:
	     * produce ANSI (native) output
	     */
	    result =
		(unsigned char *) JNU_GetString_NativeChars(jenv, ex, string);
	    *lenP=strlen((const char *) result);
	}
    }

    (*jenv)->ReleaseStringChars(jenv, string, unistring);

#ifdef PDFLIB_EBCDIC
    __atoe(result);  /* convert to EBCDIC */
#endif

    return (char *) result;
}

/* export the PDFlib routines to the shared library */
#ifdef __MWERKS__
#pragma export on
#endif

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1boot(JNIEnv *jenv, jclass jcls)
{
    /* throws nothing from within the library */
    PDF_boot();
}


JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1shutdown(JNIEnv *jenv, jclass jcls)
{
    /* throws nothing */
    PDF_shutdown();
}

JNIEXPORT jlong JNICALL
Java_com_pdflib_pdflib_PDF_1new(JNIEnv *jenv, jclass jcls)
{
    jlong _jresult;
    PDF * PDF_VOLATILE p = (PDF *) 0;
    EXC_STUFF;
    char jdkname[64];
    jclass stringClass;

#ifdef AS400
    int aux = 0;
    JavaI2L(aux, _jresult);
#else
    _jresult = int2ll(0);
#endif


    if ((ex = malloc(sizeof(pdf_wrapper_data))) == NULL) {
	jthrow(jenv, PDF_MemoryError, "Couldn't initialize PDFlib (malloc)");
	return _jresult;
    }

    ex->nativeunicode = 0;

    /* Can't use try() yet since the PDFlib core isn't initialized yet,
     * and PDF_get_opaque() wouldn't work. Do a manual setjmp() instead.
     */
    if (setjmp(ex->env) == 0) {

	p = (PDF *)PDF_new2(pdf_errorhandler, NULL, NULL, NULL, (void *) ex);

	ex->jdkversion = (*jenv)->GetVersion(jenv);

	if (((*jenv)->ExceptionOccurred(jenv)) != NULL_INT) {
	    (*jenv)->ExceptionDescribe(jenv);
	    return _jresult;
	}

	sprintf(jdkname, "JDK %d.%d",
		(int) ((ex->jdkversion & 0xFF0000) >> 16),
		(int) (ex->jdkversion & 0xFF));
	PDF_set_parameter(p, "binding", jdkname);

/* "java/lang/String */
#define PDF_java_lang_String \
	"\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67"
#define PDF_getBytes	"\x67\x65\x74\x42\x79\x74\x65\x73"	/* "getBytes" */
#define PDF_sig		"\x28\x29\x5B\x42"			/* "()[B" */

	stringClass = (*jenv)->FindClass(jenv, PDF_java_lang_String);

	if (stringClass == NULL_INT) {
	    (*jenv)->ExceptionDescribe(jenv);
	    jthrow(jenv, PDF_SystemError,
		"Couldn't initialize PDFlib (FindClass)");
#ifdef AS400
	    JavaI2L(0, _jresult);
#else
	    _jresult = int2ll(0);
#endif
	    return _jresult;
	}

	ex->MID_String_getBytes =
	    (*jenv)->GetMethodID(jenv, stringClass, PDF_getBytes, PDF_sig);

	if (ex->MID_String_getBytes == NULL_INT) {
	    (*jenv)->ExceptionDescribe(jenv);
	    jthrow(jenv, PDF_SystemError,
		"Couldn't initialize PDFlib (GetMethodID)");
	    return _jresult;
	}

    } catch;


#ifdef AS400
    JavaI2L(aux, _jresult);
#else
    *(PDF **)&_jresult = p;
#endif

    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1delete(JNIEnv *jenv, jclass jcls, PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);


    try {     PDF_delete(p);
    } catch;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1open_1file(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1)
{
    jint _jresult;
    int PDF_VOLATILE _result = -1;
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_result = (int )PDF_open_file(p,_arg1);
    } catch;

    _jresult = (jint) _result;
    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1close(JNIEnv *jenv, jclass jcls, PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_close(p);
    } catch;
}

JNIEXPORT jbyteArray JNICALL
Java_com_pdflib_pdflib_PDF_1get_1buffer(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    jbyteArray PDF_VOLATILE jbuffer;
    const unsigned char *buffer;
    PDF *p;
    EXC_STUFF;
    long size;

    p = *(PDF**) &jarg0;

    try {
	buffer = (const unsigned char *) PDF_get_buffer(p, &size);
	jbuffer = (*jenv)->NewByteArray(jenv, (jsize) size);

	if (jbuffer == (jbyteArray) NULL) {
	    pdf_errorhandler(p, PDF_MemoryError,
		"Couldn't allocate PDF output buffer");
	} else {

	    (*jenv)->SetByteArrayRegion(jenv, jbuffer,
			0, (jsize) size, (jbyte *) buffer);
	}
    } catch;

    return jbuffer;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1begin_1page(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {
	PDF_begin_page(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1end_1page(JNIEnv *jenv, jclass jcls, PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_end_page(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1set_1parameter(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jstring jarg2)
{
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    char * PDF_VOLATILE _arg2;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = (char *)GetStringPDFChars(p, jenv, jarg2);
	ex = (pdf_wrapper_data *) (PDF_get_opaque(p));

	if (!strcmp(_arg1, "nativeunicode")) {
	    if (!strcmp(_arg2, "true"))
		ex->nativeunicode = 1;
	    else if (!strcmp(_arg2, "false"))
		ex->nativeunicode = 0;
	    else
		PDF_set_parameter(p, _arg1, _arg2);
	} else
	    PDF_set_parameter(p, _arg1, _arg2);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    ReleaseStringPDFChars(jenv, jarg1, _arg2);
}

JNIEXPORT jstring JNICALL
Java_com_pdflib_pdflib_PDF_1get_1parameter(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jkey, jfloat jmod)
{
    jstring PDF_VOLATILE _jresult = 0;
    char * PDF_VOLATILE _result = NULL;
    char *key;
    float mod;
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);
    key = (char *) GetStringPDFChars(p, jenv, jkey);
    mod = flt2nat(jmod);

    try {     _result = (char *)PDF_get_parameter(p, key, mod);
    } catch;

    if(_result)
        _jresult = (jstring)(*jenv)->NewStringUTF(jenv, _result);
    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1set_1value(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    char * _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (char *) GetStringPDFChars(p, jenv, jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_set_value(p, _arg1, _arg2);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
}

JNIEXPORT jfloat JNICALL
Java_com_pdflib_pdflib_PDF_1get_1value(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jfloat jarg2)
{
    jfloat _jresult = tofloat(0);
    float PDF_VOLATILE _result;
    PDF *p;
    EXC_STUFF;
    char * _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (char *) GetStringPDFChars(p, jenv, jarg1);
    _arg2 = flt2nat(jarg2);

    try {     _result = (float )PDF_get_value(p, _arg1, _arg2);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
#ifndef OS390
    _jresult = (jfloat) _result;
#else
    _jresult = tofloat(_result);
#endif
    return _jresult;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1findfont(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jstring jarg2, jint jarg3)
{
    jint _jresult;
    int PDF_VOLATILE _result = -1;
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    char * PDF_VOLATILE _arg2;
    int _arg3;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = (char *)GetStringPDFChars(p, jenv, jarg2);
	_arg3 = (int )jarg3;

	_result = (int )PDF_findfont(p,_arg1,_arg2,_arg3);
    } catch;

    _jresult = (jint) _result;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    ReleaseStringPDFChars(jenv, jarg2, _arg2);
    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setfont(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;
    _arg2 = flt2nat(jarg2);

    try {     PDF_setfont(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1show(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1)
{
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    int len;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringUnicodePDFChars(p, jenv, jarg1, &len);

	PDF_show2(p, _arg1, len);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1show_1xy(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jfloat jarg2, jfloat jarg3)
{
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    float _arg2;
    float _arg3;
    int len;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringUnicodePDFChars(p, jenv, jarg1, &len);
	_arg2 = flt2nat(jarg2);
	_arg3 = flt2nat(jarg3);

	PDF_show_xy2(p,_arg1, len, _arg2,_arg3);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1continue_1text(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1)
{
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    int len;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringUnicodePDFChars(p, jenv, jarg1, &len);

	PDF_continue_text2(p,_arg1, len);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1show_1boxed(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jfloat jarg5, jstring jarg6, jstring jarg7)
{
    int PDF_VOLATILE _result;
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    float _arg5;
    char * PDF_VOLATILE _arg6;
    char * PDF_VOLATILE _arg7;
    int len;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringUnicodePDFChars(p, jenv, jarg1, &len);
	_arg2 = flt2nat(jarg2);
	_arg3 = flt2nat(jarg3);
	_arg4 = flt2nat(jarg4);
	_arg5 = flt2nat(jarg5);
	_arg6 = (char *)GetStringPDFChars(p, jenv, jarg6);
	_arg7 = (char *)GetStringPDFChars(p, jenv, jarg7);

	_result = PDF_show_boxed(p,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    ReleaseStringPDFChars(jenv, jarg6, _arg6);
    ReleaseStringPDFChars(jenv, jarg7, _arg7);

    return (jint) _result;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1set_1text_1pos(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_set_text_pos(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT jfloat JNICALL
Java_com_pdflib_pdflib_PDF_1stringwidth(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jint jarg2, jfloat jarg3)
{
    jfloat _jresult = tofloat(0);
    float PDF_VOLATILE _result;
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    int _arg2;
    float _arg3;
    int len;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringUnicodePDFChars(p, jenv, jarg1, &len);
	_arg2 = (int )jarg2;
	_arg3 = flt2nat(jarg3);

	_result = (float )PDF_stringwidth2(p, _arg1, len, _arg2, _arg3);
    } catch;

    _jresult = tofloat(_result);
    ReleaseStringPDFChars(jenv, jarg1, _arg1);

    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setdash(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_setdash(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setpolydash(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloatArray jarg1)
{
    PDF *p;
    EXC_STUFF;
    float carray[MAX_DASH_LENGTH];
    jfloat* javaarray;
    int i;
    jsize PDF_VOLATILE length;

    p = *(PDF **) &jarg0;
    length = (*jenv)->GetArrayLength(jenv, jarg1);

    try {
	if (length > MAX_DASH_LENGTH)
	    length = MAX_DASH_LENGTH;

	javaarray = (*jenv)->GetFloatArrayElements(jenv, jarg1, 0);

	for(i=0; i < length; i++)
	    carray[i] = flt2nat(javaarray[i]);

	PDF_setpolydash(p, carray, length);
	(*jenv)->ReleaseFloatArrayElements(jenv, jarg1, javaarray, 0);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setflat(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);

    try {     PDF_setflat(p,_arg1);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setlinejoin(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;

    try {     PDF_setlinejoin(p,_arg1);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setlinecap(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;

    try {     PDF_setlinecap(p,_arg1);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setmiterlimit(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);

    try {     PDF_setmiterlimit(p,_arg1);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setlinewidth(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;

    p = PDF_ENV2PTR(jarg0);
     _arg1 = flt2nat(jarg1);

    try {     PDF_setlinewidth(p,_arg1);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1save(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_save(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1restore(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_restore(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1translate(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_translate(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1scale(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_scale(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1rotate(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);

    try {     PDF_rotate(p,_arg1);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1skew(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_skew(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1concat(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat a, jfloat b, jfloat c, jfloat d, jfloat e, jfloat f)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_concat(p, flt2nat(a), flt2nat(b), flt2nat(c), flt2nat(d),
                                flt2nat(e), flt2nat(f));
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1moveto(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_moveto(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1lineto(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_lineto(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1curveto(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jfloat jarg5, jfloat jarg6)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    float _arg5;
    float _arg6;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);
    _arg5 = flt2nat(jarg5);
    _arg6 = flt2nat(jarg6);

    try {     PDF_curveto(p,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1circle(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);

    try {     PDF_circle(p,_arg1,_arg2,_arg3);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1arc(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jfloat jarg5)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    float _arg5;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);
    _arg5 = flt2nat(jarg5);

    try {     PDF_arc(p,_arg1,_arg2,_arg3,_arg4,_arg5);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1rect(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);

    try {     PDF_rect(p,_arg1,_arg2,_arg3,_arg4);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1closepath(JNIEnv *jenv, jclass jcls, PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_closepath(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1stroke(JNIEnv *jenv, jclass jcls, PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_stroke(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1closepath_1stroke(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_closepath_stroke(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1fill(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_fill(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1fill_1stroke(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_fill_stroke(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1closepath_1fill_1stroke(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_closepath_fill_stroke(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1endpath(JNIEnv *jenv, jclass jcls, PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_endpath(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1clip(JNIEnv *jenv, jclass jcls, PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_clip(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1place_1image(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;
    float _arg2;
    float _arg3;
    float _arg4;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);

    try {     PDF_place_image(p,_arg1,_arg2,_arg3,_arg4);
    } catch;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1open_1image(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jstring jarg2, jbyteArray jarg3, jlong jarg4,
    jint jarg5, jint jarg6, jint jarg7, jint jarg8, jstring jarg9)
{
    jint _jresult = 0;
    int PDF_VOLATILE _result;
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    char * PDF_VOLATILE _arg2;
    char * PDF_VOLATILE _arg3;
#ifdef OS390
    int i_arg4;
#endif
    long _arg4;
    int _arg5;
    int _arg6;
    int _arg7;
    int _arg8;
    char * PDF_VOLATILE _arg9;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg3 = (char *)
	    (*jenv)->GetByteArrayElements(jenv, jarg3, (jboolean *) NULL);
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = (char *)GetStringPDFChars(p, jenv, jarg2);

#ifdef AS400
	/* deal with the AS/400's idea of a jlong... */
	JavaL2I(jarg4, _arg4);
#elif OS390
	i_arg4 = ll2int(jarg4);
	_arg4 = (long )i_arg4;
#else
	_arg4 = (long )jarg4;
#endif

	_arg5 = (int )jarg5;
	_arg6 = (int )jarg6;
	_arg7 = (int )jarg7;
	_arg8 = (int )jarg8;
	_arg9 = (char *)GetStringPDFChars(p, jenv, jarg9);

	_result = (int )PDF_open_image(p,_arg1,_arg2,_arg3,_arg4,
		    _arg5,_arg6,_arg7,_arg8,_arg9);
    } catch;

    _jresult = (jint) _result;
    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    ReleaseStringPDFChars(jenv, jarg2, _arg2);
    (*jenv)->ReleaseByteArrayElements(jenv, jarg3, (jbyte*) _arg3, JNI_ABORT);
    ReleaseStringPDFChars(jenv, jarg9, _arg9);

    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1close_1image(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;

    try {     PDF_close_image(p,_arg1);
    } catch;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1open_1image_1file(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jstring jarg2, jstring jarg3, jint jarg4)
{
    jint _jresult = 0;
    int PDF_VOLATILE _result;
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    char * PDF_VOLATILE _arg2;
    char * PDF_VOLATILE _arg3;
    int _arg4;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = (char *)GetStringPDFChars(p, jenv, jarg2);
	_arg3 = (char *)GetStringPDFChars(p, jenv, jarg3);
	_arg4 = (int )jarg4;

	_result = (int )PDF_open_image_file(p,_arg1,_arg2,_arg3,_arg4);
    } catch;

    _jresult = (jint) _result;
    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    ReleaseStringPDFChars(jenv, jarg2, _arg2);
    ReleaseStringPDFChars(jenv, jarg3, _arg3);
    return _jresult;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1open_1CCITT(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jint jarg2, jint jarg3, jint jarg4,
    jint jarg5, jint jarg6)
{
    jint _jresult = 0;
    int PDF_VOLATILE _result;
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    int _arg2;
    int _arg3;
    int _arg4;
    int _arg5;
    int _arg6;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = (int )jarg2;
	_arg3 = (int )jarg3;
	_arg4 = (int )jarg4;
	_arg5 = (int )jarg5;
	_arg6 = (int )jarg6;

	_result = (int )PDF_open_CCITT(p,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6);
    } catch;

    _jresult = (jint) _result;
    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    return _jresult;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1add_1bookmark(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jint jarg2, jint jarg3)
{
    jint _jresult = 0;
    int PDF_VOLATILE _result;
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    int _arg2;
    int _arg3;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringUnicodePDFChars(p, jenv, jarg1, NULL);
	_arg2 = (int )jarg2;
	_arg3 = (int )jarg3;

	_result = (int )PDF_add_bookmark(p,_arg1,_arg2,_arg3);
    } catch;

    _jresult = (jint) _result;
    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1set_1info(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jstring jarg2)
{
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    char * PDF_VOLATILE _arg2;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = (char *)GetStringUnicodePDFChars(p, jenv, jarg2, NULL);

	PDF_set_info(p,_arg1,_arg2);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    ReleaseStringPDFChars(jenv, jarg2, _arg2);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1attach_1file(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jstring jarg5, jstring jarg6, jstring jarg7, jstring jarg8, jstring jarg9)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    char * PDF_VOLATILE _arg5;
    char * PDF_VOLATILE _arg6;
    char * PDF_VOLATILE _arg7;
    char * PDF_VOLATILE _arg8;
    char * PDF_VOLATILE _arg9;

    p = PDF_ENV2PTR(jarg0);

    try {
        _arg1 = flt2nat(jarg1);
        _arg2 = flt2nat(jarg2);
        _arg3 = flt2nat(jarg3);
        _arg4 = flt2nat(jarg4);
	_arg5 = (char *)GetStringPDFChars(p, jenv, jarg5);
	_arg6 = (char *)GetStringUnicodePDFChars(p, jenv, jarg6, NULL);
	_arg7 = (char *)GetStringUnicodePDFChars(p, jenv, jarg7, NULL);
	_arg8 = (char *)GetStringPDFChars(p, jenv, jarg8);
	_arg9 = (char *)GetStringPDFChars(p, jenv, jarg9);

	PDF_attach_file(p,_arg1,_arg2,_arg3,_arg4,_arg5,
	    _arg6,_arg7,_arg8,_arg9);
    } catch;

    ReleaseStringPDFChars(jenv, jarg5, _arg5);
    ReleaseStringPDFChars(jenv, jarg6, _arg6);
    ReleaseStringPDFChars(jenv, jarg7, _arg7);
    ReleaseStringPDFChars(jenv, jarg8, _arg8);
    ReleaseStringPDFChars(jenv, jarg9, _arg9);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1add_1note(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jstring jarg5, jstring jarg6, jstring jarg7, jint jarg8)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    char * PDF_VOLATILE _arg5;
    char * PDF_VOLATILE _arg6;
    char * PDF_VOLATILE _arg7;
    int _arg8;

    p = PDF_ENV2PTR(jarg0);

    try {
        _arg1 = flt2nat(jarg1);
        _arg2 = flt2nat(jarg2);
        _arg3 = flt2nat(jarg3);
        _arg4 = flt2nat(jarg4);
	_arg5 = (char *)GetStringUnicodePDFChars(p, jenv, jarg5, NULL);
	_arg6 = (char *)GetStringUnicodePDFChars(p, jenv, jarg6, NULL);
	_arg7 = (char *)GetStringPDFChars(p, jenv, jarg7);
	_arg8 = (int )jarg8;

	PDF_add_note(p,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8);
    } catch;

    ReleaseStringPDFChars(jenv, jarg5, _arg5);
    ReleaseStringPDFChars(jenv, jarg6, _arg6);
    ReleaseStringPDFChars(jenv, jarg7, _arg7);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1add_1pdflink(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jstring jarg5, jint jarg6, jstring jarg7)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    char * PDF_VOLATILE _arg5;
    int _arg6;
    char * PDF_VOLATILE _arg7;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = flt2nat(jarg1);
	_arg2 = flt2nat(jarg2);
	_arg3 = flt2nat(jarg3);
	_arg4 = flt2nat(jarg4);
	_arg5 = (char *)GetStringPDFChars(p, jenv, jarg5);
	_arg6 = (int )jarg6;
	_arg7 = (char *)GetStringPDFChars(p, jenv, jarg7);

	PDF_add_pdflink(p,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7);
    } catch;

    ReleaseStringPDFChars(jenv, jarg5, _arg5);
    ReleaseStringPDFChars(jenv, jarg7, _arg7);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1add_1launchlink(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jstring jarg5)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    char * PDF_VOLATILE _arg5;

    p = PDF_ENV2PTR(jarg0);

    try {
        _arg1 = flt2nat(jarg1);
        _arg2 = flt2nat(jarg2);
        _arg3 = flt2nat(jarg3);
        _arg4 = flt2nat(jarg4);
	_arg5 = (char *)GetStringPDFChars(p, jenv, jarg5);

	PDF_add_launchlink(p,_arg1,_arg2,_arg3,_arg4,_arg5);
    } catch;

    ReleaseStringPDFChars(jenv, jarg5, _arg5);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1add_1locallink(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jint jarg5, jstring jarg6)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    int _arg5;
    char * PDF_VOLATILE _arg6;

    p = PDF_ENV2PTR(jarg0);

    try {
        _arg1 = flt2nat(jarg1);
        _arg2 = flt2nat(jarg2);
        _arg3 = flt2nat(jarg3);
        _arg4 = flt2nat(jarg4);
	_arg5 = (int )jarg5;
	_arg6 = (char *)GetStringPDFChars(p, jenv, jarg6);

	PDF_add_locallink(p,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6);
    } catch;

    ReleaseStringPDFChars(jenv, jarg6, _arg6);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1add_1weblink(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jstring jarg5)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    char *PDF_VOLATILE _arg5;

    p = PDF_ENV2PTR(jarg0);

    try {
        _arg1 = flt2nat(jarg1);
        _arg2 = flt2nat(jarg2);
        _arg3 = flt2nat(jarg3);
        _arg4 = flt2nat(jarg4);
	_arg5 = (char *)GetStringPDFChars(p, jenv, jarg5);

	PDF_add_weblink(p,_arg1,_arg2,_arg3,_arg4,_arg5);
    } catch;

    ReleaseStringPDFChars(jenv, jarg5, _arg5);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1set_1border_1style(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = flt2nat(jarg2);

	PDF_set_border_style(p,_arg1,_arg2);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1set_1border_1color(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);

    try {     PDF_set_border_color(p,_arg1,_arg2,_arg3);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1set_1border_1dash(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     PDF_set_border_dash(p,_arg1,_arg2);
    } catch;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1open_1pdi(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jstring jarg2, jint jarg3)
{
    PDF *p;
    EXC_STUFF;
    jint _jresult = 0;
    int PDF_VOLATILE _result = -1;
    char * PDF_VOLATILE _arg1 = NULL;
    char * PDF_VOLATILE _arg2 = NULL;
    int _arg3;

    p = PDF_ENV2PTR(jarg0);
    _arg3 = (int )jarg3;

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = (char *)GetStringPDFChars(p, jenv, jarg2);

	_result = (int )PDF_open_pdi(p,_arg1,_arg2,_arg3);

    } catch;

    _jresult = (jint) _result;
    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    ReleaseStringPDFChars(jenv, jarg2, _arg2);

    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1close_1pdi(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;

    try {     PDF_close_pdi(p,_arg1);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1place_1pdi_1page(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1, jfloat jarg2, jfloat jarg3,
    jfloat jarg4, jfloat jarg5)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    float _arg5;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);
    _arg5 = flt2nat(jarg5);

    try {     PDF_place_pdi_page(p,_arg1,_arg2,_arg3,_arg4,_arg5);
    } catch;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1open_1pdi_1page(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1, jint jarg2, jstring jarg3)
{
    PDF *p;
    EXC_STUFF;
    jint _jresult = 0;
    int PDF_VOLATILE _result = -1;
    int _arg1;
    int _arg2;
    char * PDF_VOLATILE _arg3 = NULL;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;
    _arg2 = (int )jarg2;

    try {
	_arg3 = (char *)GetStringPDFChars(p, jenv, jarg3);
	_result = (int )PDF_open_pdi_page(p,_arg1,_arg2,_arg3);
    } catch;

    _jresult = (jint) _result;
    ReleaseStringPDFChars(jenv, jarg3, _arg3);
    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1close_1pdi_1page(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;

    try {     PDF_close_pdi_page(p,_arg1);
    } catch;
}

JNIEXPORT jstring JNICALL
Java_com_pdflib_pdflib_PDF_1get_1pdi_1parameter(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jint jarg2, jint jarg3, jint jarg4)
{
    PDF *p;
    EXC_STUFF;
    jstring PDF_VOLATILE _jresult = 0;
    char * PDF_VOLATILE _result = NULL;
    char * PDF_VOLATILE _arg1 = NULL;
    int _arg2;
    int _arg3;
    int _arg4;
    int len;

    p = PDF_ENV2PTR(jarg0);
    _arg2 = (int )jarg2;
    _arg3 = (int )jarg3;
    _arg4 = (int )jarg4;

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_result = (char *)
	    PDF_get_pdi_parameter(p, _arg1, _arg2, _arg3, _arg4, &len);
    } catch;

    /* TODO: return a Unicode string based on _result and len */
    if(_result != NULL)
        _jresult = (jstring)(*jenv)->NewStringUTF(jenv, _result);

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    return _jresult;
}

JNIEXPORT jfloat JNICALL
Java_com_pdflib_pdflib_PDF_1get_1pdi_1value(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jint jarg2, jint jarg3, jint jarg4)
{
    PDF *p;
    EXC_STUFF;
    jfloat _jresult = tofloat(0);
    jfloat PDF_VOLATILE _result = tofloat(0);
    char * PDF_VOLATILE _arg1 = NULL;
    int _arg2;
    int _arg3;
    int _arg4;

    p = PDF_ENV2PTR(jarg0);
    _arg2 = (int )jarg2;
    _arg3 = (int )jarg3;
    _arg4 = (int )jarg4;

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_result = tofloat(PDF_get_pdi_value(p,_arg1,_arg2,_arg3,_arg4));
    } catch;

    _jresult = _result;
    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    return _jresult;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1makespotcolor(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1)
{
    PDF *p;
    EXC_STUFF;
    jint _jresult = 0;
    int PDF_VOLATILE _result = -1;
    char * PDF_VOLATILE _arg1 = NULL;
    int len;

    p = PDF_ENV2PTR(jarg0);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	len = (*jenv)->GetStringLength(jenv, jarg1);
	_result = (int )PDF_makespotcolor(p,_arg1,len);
    } catch;

    _jresult = (jint) _result;
    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setcolor(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jstring jarg1, jstring jarg2, jfloat jarg3, jfloat jarg4,
    jfloat jarg5, jfloat jarg6)
{
    PDF *p;
    EXC_STUFF;
    char * PDF_VOLATILE _arg1 = NULL;
    char * PDF_VOLATILE _arg2 = NULL;
    float _arg3;
    float _arg4;
    float _arg5;
    float _arg6;

    p = PDF_ENV2PTR(jarg0);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);
    _arg5 = flt2nat(jarg5);
    _arg6 = flt2nat(jarg6);

    try {
	_arg1 = (char *)GetStringPDFChars(p, jenv, jarg1);
	_arg2 = (char *)GetStringPDFChars(p, jenv, jarg2);
	PDF_setcolor(p,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6);
    } catch;

    ReleaseStringPDFChars(jenv, jarg1, _arg1);
    ReleaseStringPDFChars(jenv, jarg2, _arg2);
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1begin_1pattern(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jint jarg5)
{
    PDF *p;
    EXC_STUFF;
    jint _jresult = 0;
    int PDF_VOLATILE _result = -1;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    int _arg5;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);
    _arg5 = (int)jarg5;

    try {
	_result = (int )PDF_begin_pattern(p,_arg1,_arg2,_arg3,_arg4,_arg5);
    } catch;

    _jresult = (jint) _result;
    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1end_1pattern(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_end_pattern(p);
    } catch;
}

JNIEXPORT jint JNICALL
Java_com_pdflib_pdflib_PDF_1begin_1template(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2)
{
    PDF *p;
    EXC_STUFF;
    jint _jresult = 0;
    int PDF_VOLATILE _result = -1;
    float _arg1;
    float _arg2;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);

    try {     _result = (int )PDF_begin_template(p,_arg1,_arg2);
    } catch;

    _jresult = (jint) _result;
    return _jresult;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1end_1template(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_end_template(p);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1arcn(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jfloat jarg5)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    float _arg5;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);
    _arg5 = flt2nat(jarg5);

    try {     PDF_arcn(p,_arg1,_arg2,_arg3,_arg4,_arg5);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1add_1thumbnail(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jint jarg1)
{
    PDF *p;
    EXC_STUFF;
    int _arg1;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = (int )jarg1;

    try {     PDF_add_thumbnail(p,_arg1);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1setmatrix(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0, jfloat jarg1, jfloat jarg2, jfloat jarg3, jfloat jarg4,
    jfloat jarg5, jfloat jarg6)
{
    PDF *p;
    EXC_STUFF;
    float _arg1;
    float _arg2;
    float _arg3;
    float _arg4;
    float _arg5;
    float _arg6;

    p = PDF_ENV2PTR(jarg0);
    _arg1 = flt2nat(jarg1);
    _arg2 = flt2nat(jarg2);
    _arg3 = flt2nat(jarg3);
    _arg4 = flt2nat(jarg4);
    _arg5 = flt2nat(jarg5);
    _arg6 = flt2nat(jarg6);

    try {     PDF_setmatrix(p,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6);
    } catch;
}

JNIEXPORT void JNICALL
Java_com_pdflib_pdflib_PDF_1initgraphics(JNIEnv *jenv, jclass jcls,
    PDF_ENV jarg0)
{
    PDF *p;
    EXC_STUFF;

    p = PDF_ENV2PTR(jarg0);

    try {     PDF_initgraphics(p);
    } catch;
}
