/* -*- Mode: C; c-file-style: "gnu" -*-
   fontmetrics.c -- native methods for sun/awt/motif/X11FontMetrics.
   Created: Chris Toshok <toshok@hungry.com>, 9-Mar-1998.
 */
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1998, 1999 The Hungry Programmers

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "jniint.h"
#include "common.h"

#include <assert.h>

jint
Java_sun_awt_motif_X11FontMetrics_getMFCharSegmentWidth(JNIEnv *env,
							jobject metrics,
							jobject font,
							jobject fontdescriptor,
							jbyteArray chars,
							jint length)
{
  jbyte *bytes;
  int width;
  XFontStruct *fs = jfont_to_xfontstruct(env, font);

  PR_LOG (awtLm, PR_LOG_DEBUG,
	  ("in sun_awt_motif_X11FontMetrics_getMFCharSegmentWidth\n"));

  bytes = (*env)->GetByteArrayElements(env, chars, NULL);

  LOCK_AWT();
  width = XTextWidth(fs, bytes, length);
  UNLOCK_AWT();

  (*env)->ReleaseByteArrayElements(env, chars, bytes, 0);

  return width;
}

/* JDK1.2 */
jint
Java_sun_awt_motif_X11FontMetrics_getMFCharsWidth(JNIEnv *env,
						  jobject metrics,
						  jcharArray chars,
						  jint start,
						  jint length,
						  jobject font)
{
  printf ("uh oh!!)(&*#%)(*!@&%*@&%$)*@)$#(*@$\n");
  return 20; /* XXX */
}

jint
Java_sun_awt_motif_X11FontMetrics_bytesWidth(JNIEnv *env,
					     jobject metrics,
					     jbyteArray chars,
					     jint start,
					     jint length)
{
  jbyte *bytes;
  int width;
  jfieldID font_field = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, metrics),
					   "font", "Ljava/awt/Font;");
  jobject font = (*env)->GetObjectField(env, metrics, font_field);
  XFontStruct *fs = jfont_to_xfontstruct(env, font);

  PR_LOG (awtLm, PR_LOG_DEBUG,
	  ("in sun_awt_motif_X11FontMetrics_bytesWidth\n"));

  bytes = (*env)->GetByteArrayElements(env, chars, NULL);

  LOCK_AWT();
  width = XTextWidth(fs, bytes + start, length);
  UNLOCK_AWT();

  (*env)->ReleaseByteArrayElements(env, chars, bytes, 0);

  return width;
}

void
Java_sun_awt_motif_X11FontMetrics_init(JNIEnv *env,
				       jobject metrics)
{
  HungryEnv *henv = HVM_ThreadGetEnv();
  jclass metrics_class = (*env)->GetObjectClass(env, metrics);
  jfieldID font_field = (*env)->GetFieldID(env, metrics_class, "font", "Ljava/awt/Font;");
  jfieldID ascent_field = (*env)->GetFieldID(env, metrics_class, "ascent", "I");
  jfieldID descent_field = (*env)->GetFieldID(env, metrics_class, "descent", "I");
  jfieldID leading_field = (*env)->GetFieldID(env, metrics_class, "leading", "I");
  jfieldID height_field = (*env)->GetFieldID(env, metrics_class, "height", "I");
  jfieldID maxAscent_field = (*env)->GetFieldID(env, metrics_class, "maxAscent", "I");
  jfieldID maxDescent_field = (*env)->GetFieldID(env, metrics_class, "maxDescent", "I");
  jfieldID maxHeight_field = (*env)->GetFieldID(env, metrics_class, "maxHeight", "I");
  jfieldID maxAdvance_field = (*env)->GetFieldID(env, metrics_class, "maxAdvance", "I");
  jfieldID widths_field = (*env)->GetFieldID(env, metrics_class, "widths", "[I");
  jintArray widthArray;
  jint *widths;
  jobject font = (*env)->GetObjectField(env, metrics, font_field);
  int i;
  XFontStruct *fs = jfont_to_xfontstruct(env, font);

  PR_LOG (awtLm, PR_LOG_DEBUG,
	  ("in sun_awt_motif_X11FontMetrics_init\n"));

  if (NULL == fs)
    { /* XXX What should we really throw? */
      HVM_ExceptionThrow(henv, "java/lang/NullPointerException",
		      "no XFontStruct for font");
      return;
    }

  (*env)->SetIntField(env, metrics, ascent_field, fs->ascent);
  (*env)->SetIntField(env, metrics, descent_field, fs->descent);
  (*env)->SetIntField(env, metrics, leading_field, fs->max_bounds.lbearing);
  (*env)->SetIntField(env, metrics, height_field, fs->ascent + fs->descent);
  (*env)->SetIntField(env, metrics, maxAscent_field, fs->max_bounds.ascent);
  (*env)->SetIntField(env, metrics, maxDescent_field, fs->max_bounds.descent);
  (*env)->SetIntField(env, metrics, maxHeight_field, (fs->max_bounds.ascent 
						      + fs->max_bounds.descent));
  (*env)->SetIntField(env, metrics, maxAdvance_field, (fs->max_bounds.lbearing +
						       fs->max_bounds.rbearing));

  widthArray = (*env)->NewIntArray(env, fs->max_char_or_byte2);
  widths = (*env)->GetIntArrayElements(env, widthArray, NULL);
  for (i = 0; i < fs->min_char_or_byte2; i ++)
    {
      widths[i] = fs->min_bounds.width + fs->min_bounds.lbearing;
    }
  for (i = fs->min_char_or_byte2; i < fs->max_char_or_byte2; i ++)
    {
      widths[i] = fs->per_char[i].width + fs->per_char[i].lbearing;
    }

  (*env)->ReleaseIntArrayElements(env, widthArray, widths, JNI_COMMIT);

  (*env)->SetObjectField(env, metrics, widths_field, widthArray);
}

/* JDK1.2 */
void
Java_sun_awt_motif_X11FontMetrics_initIDs(JNIEnv *env,
					  jobject metrics)
{
}

/* JDK1.2 */
void
Java_java_awt_FontMetrics_initIDs(JNIEnv *env,
				  jobject metrics)
{
  /* nothing to do here. */
}
