mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			402 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			402 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
/* qtimage.cpp --
 | 
						|
   Copyright (C)  2005  Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath 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
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
#include <assert.h>
 | 
						|
#include <QImage>
 | 
						|
#include <QColor>
 | 
						|
#include <QMatrix>
 | 
						|
#include <QPainter>
 | 
						|
#include <gnu_java_awt_peer_qt_QtImage.h>
 | 
						|
#include "qtimage.h"
 | 
						|
#include "qtstrings.h"
 | 
						|
#include "qtgraphics.h"
 | 
						|
#include "nativewrapper.h"
 | 
						|
 | 
						|
/* The constant fields in java.awt.Image */   
 | 
						|
#define SCALE_DEFAULT      1
 | 
						|
#define SCALE_FAST         2
 | 
						|
#define SCALE_SMOOTH       4
 | 
						|
#define SCALE_REPLICATE    8 
 | 
						|
#define SCALE_AREA_AVERAGING  16
 | 
						|
 | 
						|
QImage *getQtImage( JNIEnv *env, jobject obj )
 | 
						|
{
 | 
						|
  jclass cls = env->GetObjectClass( obj );
 | 
						|
  jfieldID field = env->GetFieldID( cls, "nativeObject", "J" );
 | 
						|
  return (QImage *)env->GetLongField( obj, field );
 | 
						|
}
 | 
						|
 | 
						|
static void setNativePtr( JNIEnv *env, jobject obj, void *value )
 | 
						|
{
 | 
						|
  jlong longValue = (jlong) value; 
 | 
						|
  jclass cls = env->GetObjectClass( obj );
 | 
						|
  jfieldID field = env->GetFieldID( cls, "nativeObject", "J" );
 | 
						|
  env->SetLongField( obj, field, longValue );
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Creates a QImage.
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_createImage
 | 
						|
(JNIEnv *env, jobject obj)
 | 
						|
{
 | 
						|
  int width, height;
 | 
						|
  jclass cls;
 | 
						|
  jfieldID field;
 | 
						|
 | 
						|
  cls = env->GetObjectClass( obj );
 | 
						|
  field = env->GetFieldID (cls, "width", "I");
 | 
						|
  assert (field != 0);
 | 
						|
  width = env->GetIntField(obj, field);
 | 
						|
 | 
						|
  field = env->GetFieldID(cls, "height", "I");
 | 
						|
  assert (field != 0);
 | 
						|
  height = env->GetIntField(obj, field);
 | 
						|
  
 | 
						|
  QImage *image = new QImage ( width, height, 
 | 
						|
			       QImage::Format_ARGB32_Premultiplied );
 | 
						|
  setNativePtr(env, obj, image);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Frees the image data.
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_freeImage
 | 
						|
(JNIEnv *env, jobject obj)
 | 
						|
{
 | 
						|
   QImage *image = getQtImage(env, obj);
 | 
						|
   setNativePtr(env, obj, NULL);
 | 
						|
   if ( image )
 | 
						|
     delete image;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Clears the image to zero.
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_clear
 | 
						|
(JNIEnv *env, jobject obj)
 | 
						|
{
 | 
						|
  QImage *image = getQtImage(env, obj);
 | 
						|
  assert( image );
 | 
						|
  image->fill(0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Returns the pixel data in an int array.
 | 
						|
 */
 | 
						|
JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_qt_QtImage_getPixels
 | 
						|
(JNIEnv *env, jobject obj)
 | 
						|
{
 | 
						|
  QImage *image = getQtImage(env, obj);
 | 
						|
  jintArray result_array;
 | 
						|
  jint *result_array_ptr, *dst;
 | 
						|
  int x, y;
 | 
						|
  jint pixel;
 | 
						|
  QRgb current;
 | 
						|
 | 
						|
  assert( image );
 | 
						|
 | 
						|
  result_array = env->NewIntArray (image->width() * image->height());
 | 
						|
  dst = result_array_ptr = 
 | 
						|
    env->GetIntArrayElements(result_array, NULL);
 | 
						|
 | 
						|
  // A bit inefficient.
 | 
						|
  for ( y = 0; y < image->height(); y++)
 | 
						|
      for ( x = 0; x < image->width(); x++)
 | 
						|
	{
 | 
						|
	  current = image->pixel(x, y);
 | 
						|
	  pixel = 0;
 | 
						|
	  pixel = (qAlpha(current) & 0xFF) << 24 | 
 | 
						|
	    (qRed(current) & 0xFF) << 16 |
 | 
						|
	    (qGreen(current) & 0xFF) << 8 |
 | 
						|
	    (qBlue(current) & 0xFF);
 | 
						|
	  *dst = pixel;
 | 
						|
	  dst++;
 | 
						|
	}
 | 
						|
 | 
						|
  env->ReleaseIntArrayElements (result_array, result_array_ptr, 0);
 | 
						|
  return result_array;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Sets the pixel data.
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_setPixels
 | 
						|
(JNIEnv *env, jobject obj, jintArray pixels)
 | 
						|
{
 | 
						|
  QImage *image = getQtImage(env, obj);
 | 
						|
  assert( image );
 | 
						|
 | 
						|
  int width, height;
 | 
						|
  jint *src_array, *src;
 | 
						|
 | 
						|
  width =  image->width();
 | 
						|
  height = image->height();
 | 
						|
 | 
						|
  src = src_array = 
 | 
						|
    env->GetIntArrayElements(pixels, NULL);
 | 
						|
 | 
						|
  for(int i = 0 ; i < height; i++)
 | 
						|
    {
 | 
						|
      uchar *scanline = image->scanLine( i );
 | 
						|
      memcpy((void *)scanline, (void *)src, width * 4);
 | 
						|
      src += width;
 | 
						|
    }
 | 
						|
 | 
						|
  env->ReleaseIntArrayElements(pixels, src_array, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Loads an image from a file, 
 | 
						|
 * returns true on success, false on failure.
 | 
						|
 */
 | 
						|
JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_qt_QtImage_loadImage
 | 
						|
(JNIEnv *env, jobject obj, jstring fn)
 | 
						|
{
 | 
						|
  QString *filename = getQString(env, fn);
 | 
						|
 | 
						|
  QImage *image = new QImage();
 | 
						|
  bool retVal = image->load( *filename );
 | 
						|
  delete filename;
 | 
						|
 | 
						|
  if(image->isNull() && !retVal)
 | 
						|
    {
 | 
						|
      setNativePtr(env, obj, NULL);
 | 
						|
      return JNI_FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  setNativePtr(env, obj, image);
 | 
						|
  
 | 
						|
  jclass cls = env->GetObjectClass( obj );
 | 
						|
  jfieldID field = env->GetFieldID( cls, "width", "I" );
 | 
						|
  env->SetIntField( obj, field, image->width() );
 | 
						|
  field = env->GetFieldID( cls, "height", "I" );
 | 
						|
  env->SetIntField( obj, field, image->height() );
 | 
						|
  
 | 
						|
  return JNI_TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Creates the image from an array of java bytes.
 | 
						|
 */
 | 
						|
JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_qt_QtImage_loadImageFromData
 | 
						|
(JNIEnv *env, jobject obj, jbyteArray data)
 | 
						|
{
 | 
						|
  jbyte *src_array, *src;
 | 
						|
  bool retVal;
 | 
						|
 | 
						|
  src = env->GetByteArrayElements(data, NULL);
 | 
						|
  int len = env->GetArrayLength( data );
 | 
						|
 | 
						|
  QImage *image = new QImage();
 | 
						|
  retVal = image->loadFromData( (uchar *) src, len);
 | 
						|
  env->ReleaseByteArrayElements(data, src, 0);
 | 
						|
 | 
						|
  if(image->isNull() || retVal == false)
 | 
						|
    {
 | 
						|
      setNativePtr(env, obj, NULL);
 | 
						|
      return JNI_FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  setNativePtr(env, obj, image);
 | 
						|
  
 | 
						|
  jclass cls = env->GetObjectClass( obj );
 | 
						|
  jfieldID field = env->GetFieldID( cls, "width", "I" );
 | 
						|
  env->SetIntField( obj, field, image->width() );
 | 
						|
  field = env->GetFieldID( cls, "height", "I" );
 | 
						|
  env->SetIntField( obj, field, image->height() );
 | 
						|
  
 | 
						|
  return JNI_TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_createScaledImage
 | 
						|
(JNIEnv *env, jobject obj, jobject src, jint hints)
 | 
						|
{
 | 
						|
  int w,h;
 | 
						|
  jclass cls;
 | 
						|
  jfieldID field;
 | 
						|
 | 
						|
  cls = env->GetObjectClass( obj );
 | 
						|
  field = env->GetFieldID(cls, "width", "I");
 | 
						|
  assert (field != 0);
 | 
						|
  w = env->GetIntField(obj, field);
 | 
						|
 | 
						|
  field = env->GetFieldID(cls, "height", "I");
 | 
						|
  assert (field != 0);
 | 
						|
  h = env->GetIntField(obj, field);
 | 
						|
 | 
						|
  QImage *image = getQtImage(env, src);
 | 
						|
  assert( image );
 | 
						|
  QImage imageScaled;
 | 
						|
 | 
						|
  if (hints == SCALE_SMOOTH || hints == SCALE_AREA_AVERAGING)
 | 
						|
    imageScaled = image->scaled(w, h, 
 | 
						|
				Qt::IgnoreAspectRatio, 
 | 
						|
				Qt::SmoothTransformation);
 | 
						|
  else
 | 
						|
    imageScaled = image->scaled(w, h, 
 | 
						|
				Qt::IgnoreAspectRatio, 
 | 
						|
				Qt::FastTransformation);
 | 
						|
  QImage *scaledPtr = new QImage( imageScaled );
 | 
						|
  
 | 
						|
  // create new QtImage object
 | 
						|
  setNativePtr( env, obj, scaledPtr );
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Simple draw without scaling.
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_drawPixels
 | 
						|
(JNIEnv *env, jobject obj, jobject graphics, jint bg_red, jint bg_green, 
 | 
						|
 jint bg_blue, jint x, jint y, jboolean composite)
 | 
						|
{
 | 
						|
  QImage *image = getQtImage(env, obj);
 | 
						|
  assert( image );
 | 
						|
  QPainter *painter = getPainter( env, graphics );
 | 
						|
  assert( painter );
 | 
						|
  if(composite == JNI_TRUE)
 | 
						|
    painter->fillRect ( x, y, image->width(), image->height(), 
 | 
						|
 			QColor(bg_red, bg_green, bg_blue ) );
 | 
						|
  painter->drawImage ( QPoint(x, y), *image );
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Draw the image with scaling.
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_drawPixelsScaled
 | 
						|
(JNIEnv *env, jobject obj, jobject graphics, 
 | 
						|
 jint bg_red, jint bg_green, jint bg_blue, 
 | 
						|
 jint x, jint y, jint w, jint h, jboolean composite)
 | 
						|
{
 | 
						|
  QImage *image = getQtImage(env, obj);
 | 
						|
  assert( image );
 | 
						|
  QPainter *painter = getPainter( env, graphics );
 | 
						|
  assert( painter );
 | 
						|
 | 
						|
  if(composite == JNI_TRUE)
 | 
						|
    painter->fillRect ( x, y, w, h, QColor(bg_red, bg_green, bg_blue ) );
 | 
						|
  
 | 
						|
  QRectF *srcRect = new QRectF((qreal)0, (qreal)0,
 | 
						|
			       (qreal)image->width(), (qreal)image->height());
 | 
						|
  QRectF *dstRect = new QRectF((qreal)x, (qreal)y,
 | 
						|
			       (qreal)w, (qreal)h);
 | 
						|
  
 | 
						|
  if(composite == JNI_TRUE)
 | 
						|
    painter->fillRect( *dstRect, QColor(bg_red, bg_green, bg_blue ) );
 | 
						|
 | 
						|
  painter->drawImage( *dstRect, *image, *srcRect);
 | 
						|
 | 
						|
  delete srcRect;
 | 
						|
  delete dstRect;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Draws a transformed image.
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_drawPixelsTransformed
 | 
						|
(JNIEnv *env, jobject obj, jobject graphics, jobject transform)
 | 
						|
{
 | 
						|
  QImage *originalImage = getQtImage(env, obj);
 | 
						|
  assert( originalImage );
 | 
						|
  QPainter *painter = getPainter( env, graphics );
 | 
						|
  assert( painter );
 | 
						|
  QMatrix *matrix = (QMatrix *)getNativeObject(env, transform);
 | 
						|
  assert( matrix );
 | 
						|
 | 
						|
  // FIXME : Add rendering hint support here.
 | 
						|
  QPoint p = matrix->map( QPoint(0,0) );
 | 
						|
  QImage image = originalImage->transformed ( *matrix, Qt::FastTransformation );
 | 
						|
  painter->drawImage(p, image);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Draws the pixbuf at x, y, scaled to width and height and 
 | 
						|
 * optionally composited and/or flipped with a given background color.
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL 
 | 
						|
Java_gnu_java_awt_peer_qt_QtImage_drawPixelsScaledFlipped 
 | 
						|
(JNIEnv *env, jobject obj, jobject graphics,
 | 
						|
 jint bg_red, jint bg_green, jint bg_blue, 
 | 
						|
 jboolean flipx, jboolean flipy,
 | 
						|
 jint srcx, jint srcy, jint srcwidth, jint srcheight, 
 | 
						|
 jint dstx, jint dsty, jint dstwidth, jint dstheight, 
 | 
						|
 jboolean composite)
 | 
						|
{
 | 
						|
  QImage *originalImage = getQtImage(env, obj);
 | 
						|
  assert( originalImage );
 | 
						|
  QPainter *painter = getPainter( env, graphics );
 | 
						|
  assert( painter );
 | 
						|
 | 
						|
  QRectF *srcRect = new QRectF((qreal)srcx, (qreal)srcy,
 | 
						|
			       (qreal)srcwidth, (qreal)srcheight);
 | 
						|
  QRectF *dstRect = new QRectF((qreal)dstx, (qreal)dsty,
 | 
						|
			       (qreal)dstwidth, (qreal)dstheight);
 | 
						|
  
 | 
						|
  QImage image;
 | 
						|
  if( flipx == JNI_TRUE || flipy == JNI_TRUE)
 | 
						|
    image = originalImage->mirrored ( (flipx == JNI_TRUE), 
 | 
						|
				      (flipy == JNI_TRUE) );
 | 
						|
  else
 | 
						|
    image = *originalImage;
 | 
						|
 | 
						|
  if(composite == JNI_TRUE)
 | 
						|
    painter->fillRect( *dstRect, QColor(bg_red, bg_green, bg_blue ) );
 | 
						|
 | 
						|
  painter->drawImage( *dstRect, image, *srcRect);
 | 
						|
 | 
						|
  delete srcRect;
 | 
						|
  delete dstRect;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Copies an area of the image (used by Graphics)
 | 
						|
 */
 | 
						|
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtImage_copyArea
 | 
						|
(JNIEnv *env, jobject obj , jint x, jint y, jint w, jint h, jint dx, jint dy)
 | 
						|
{
 | 
						|
  QImage *image = getQtImage(env, obj);
 | 
						|
  assert( image );
 | 
						|
  QImage area = image->copy(x, y, w, h);
 | 
						|
  QPainter *p = new QPainter( image );
 | 
						|
  p->drawImage( x + dx, y + dy, area );
 | 
						|
  delete p;
 | 
						|
}
 |