1 /* qtvolatileimage.cpp --
2    Copyright (C)  2005  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 #include <assert.h>
39 #include <QPixmap>
40 #include <QImage>
41 #include <QColor>
42 #include <QMatrix>
43 #include <QPainter>
44 #include <gnu_java_awt_peer_qt_QtVolatileImage.h>
45 #include "qtimage.h"
46 #include "qtstrings.h"
47 #include "qtgraphics.h"
48 #include "nativewrapper.h"
49 
50 /* The constant fields in java.awt.Image */
51 #define SCALE_DEFAULT      1
52 #define SCALE_FAST         2
53 #define SCALE_SMOOTH       4
54 #define SCALE_REPLICATE    8
55 #define SCALE_AREA_AVERAGING  16
56 
getQtVolatileImage(JNIEnv * env,jobject obj)57 QPixmap *getQtVolatileImage( JNIEnv *env, jobject obj )
58 {
59   jclass cls = env->GetObjectClass( obj );
60   jfieldID field = env->GetFieldID( cls, "nativeObject", "J" );
61   return (QPixmap *)env->GetLongField( obj, field );
62 }
63 
setNativePtr(JNIEnv * env,jobject obj,void * value)64 static void setNativePtr( JNIEnv *env, jobject obj, void *value )
65 {
66   jlong longValue = (jlong) value;
67   jclass cls = env->GetObjectClass( obj );
68   jfieldID field = env->GetFieldID( cls, "nativeObject", "J" );
69   env->SetLongField( obj, field, longValue );
70 }
71 
72 /*
73  * Clears the image to zero.
74  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_clear(JNIEnv * env,jobject obj)75 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_clear
76 (JNIEnv *env, jobject obj)
77 {
78   QPixmap *image = getQtVolatileImage(env, obj);
79   assert( image );
80   image->fill();
81 }
82 
83 /*
84  * Returns the pixel data in an int array.
85  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_getPixels(JNIEnv * env,jobject obj)86 JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_getPixels
87 (JNIEnv *env, jobject obj)
88 {
89   QPixmap *image = getQtVolatileImage(env, obj);
90   jintArray result_array;
91   jint *result_array_ptr, *dst;
92   int x, y;
93   jint pixel;
94   QRgb current;
95 
96   assert( image );
97   QImage im = image->toImage();
98 
99   result_array = env->NewIntArray (image->width() * image->height());
100   dst = result_array_ptr =
101     env->GetIntArrayElements(result_array, NULL);
102 
103   // A bit inefficient.
104   for ( y = 0; y < image->height(); y++)
105     for ( x = 0; x < image->width(); x++)
106       {
107 	current = im.pixel(x, y);
108 	pixel = 0;
109 	pixel = (qAlpha(current) & 0xFF) << 24 |
110 	  (qRed(current) & 0xFF) << 16 |
111 	  (qGreen(current) & 0xFF) << 8 |
112 	  (qBlue(current) & 0xFF);
113 	*dst = pixel;
114 	dst++;
115       }
116 
117   env->ReleaseIntArrayElements (result_array, result_array_ptr, 0);
118   return result_array;
119 }
120 
121 /*
122  * Creates a QImage.
123  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_createImage(JNIEnv * env,jobject obj)124 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_createImage
125 (JNIEnv *env, jobject obj)
126 {
127   int width, height;
128   jclass cls;
129   jfieldID field;
130 
131   cls = env->GetObjectClass( obj );
132   field = env->GetFieldID (cls, "width", "I");
133   assert (field != 0);
134   width = env->GetIntField(obj, field);
135 
136   field = env->GetFieldID(cls, "height", "I");
137   assert (field != 0);
138   height = env->GetIntField(obj, field);
139 
140   QPixmap *image = new QPixmap ( width, height );
141   setNativePtr(env, obj, image);
142 }
143 
144 /*
145  * Frees the image data.
146  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_freeImage(JNIEnv * env,jobject obj)147 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_freeImage
148 (JNIEnv *env, jobject obj)
149 {
150   QPixmap *image = getQtVolatileImage(env, obj);
151   if ( image )
152     delete image;
153   setNativePtr(env, obj, NULL);
154 }
155 
156 /*
157  * Blits a QImage
158  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_blit__Lgnu_java_awt_peer_qt_QtImage_2(JNIEnv * env,jobject obj,jobject i2)159 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_blit__Lgnu_java_awt_peer_qt_QtImage_2
160 (JNIEnv *env, jobject obj, jobject i2)
161 {
162   QPixmap *image = getQtVolatileImage(env, obj);
163   assert( image );
164 
165   QImage *blit = getQtImage(env, i2);
166   assert( blit );
167 
168   QPainter *p = new QPainter( image );
169   assert( p );
170   p->drawImage( 0, 0, *blit );
171 
172   delete p;
173 }
174 
175 /*
176  * Blits a QImage
177  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_blit__Lgnu_java_awt_peer_qt_QtImage_2IIII(JNIEnv * env,jobject obj,jobject i2,jint x,jint y,jint w,jint h)178 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_blit__Lgnu_java_awt_peer_qt_QtImage_2IIII
179 (JNIEnv *env, jobject obj, jobject i2, jint x, jint y, jint w, jint h)
180 {
181   QPixmap *image = getQtVolatileImage(env, obj);
182   assert( image );
183 
184   QImage *blit = getQtImage(env, i2);
185   assert( blit );
186 
187   QPainter *p = new QPainter( image );
188   assert( p );
189   p->drawImage( x, y, *blit, x, y, w, h);
190 
191   delete p;
192 }
193 
194 /*
195  * Creates a scaled version.
196  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_createScaledImage(JNIEnv * env,jobject obj,jobject src,jint hints)197 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_createScaledImage
198 (JNIEnv *env, jobject obj, jobject src, jint hints)
199 {
200   int w,h;
201   jclass cls;
202   jfieldID field;
203 
204   cls = env->GetObjectClass( obj );
205   field = env->GetFieldID(cls, "width", "I");
206   assert (field != 0);
207   w = env->GetIntField(obj, field);
208 
209   field = env->GetFieldID(cls, "height", "I");
210   assert (field != 0);
211   h = env->GetIntField(obj, field);
212 
213   QPixmap *ip = getQtVolatileImage(env, src);
214   assert( ip );
215   QImage image = ip->toImage();
216   QImage imageScaled;
217 
218   if (hints == SCALE_SMOOTH || hints == SCALE_AREA_AVERAGING)
219     imageScaled = image.scaled(w, h,
220 			       Qt::IgnoreAspectRatio,
221 			       Qt::SmoothTransformation);
222   else
223     imageScaled = image.scaled(w, h,
224 			       Qt::IgnoreAspectRatio,
225 			       Qt::FastTransformation);
226   QImage *scaledPtr = new QImage( imageScaled );
227 
228   // create new QtImage object
229   setNativePtr( env, obj, scaledPtr );
230 }
231 
232 /*
233  * DrawPixels.
234  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_drawPixels(JNIEnv * env,jobject obj,jobject graphics,jint bg_red,jint bg_green,jint bg_blue,jint x,jint y,jboolean composite)235 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_drawPixels
236 (JNIEnv *env, jobject obj, jobject graphics, jint bg_red, jint bg_green,
237  jint bg_blue, jint x, jint y, jboolean composite)
238 {
239   QPixmap *image = getQtVolatileImage(env, obj);
240   assert( image );
241   QPainter *painter = getPainter( env, graphics );
242   assert( painter );
243 
244   if(composite == JNI_TRUE)
245     painter->fillRect ( x, y, image->width(), image->height(),
246 			QColor(bg_red, bg_green, bg_blue ) );
247   painter->drawPixmap ( QPoint(x, y), *image );
248 }
249 
250 /*
251  * DrawPixels scaled.
252  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_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)253 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_drawPixelsScaled
254 (JNIEnv *env, jobject obj, jobject graphics,
255  jint bg_red, jint bg_green, jint bg_blue,
256  jint x, jint y, jint w, jint h, jboolean composite)
257 {
258   QPixmap *image = getQtVolatileImage(env, obj);
259   assert( image );
260   QPainter *painter = getPainter( env, graphics );
261   assert( painter );
262 
263   if(composite == JNI_TRUE)
264     painter->fillRect ( x, y, w, h, QColor(bg_red, bg_green, bg_blue ) );
265 
266   QRectF *srcRect = new QRectF((qreal)0, (qreal)0,
267 			       (qreal)image->width(), (qreal)image->height());
268   QRectF *dstRect = new QRectF((qreal)x, (qreal)y,
269 			       (qreal)w, (qreal)h);
270 
271   if(composite == JNI_TRUE)
272     painter->fillRect( *dstRect, QColor(bg_red, bg_green, bg_blue ) );
273 
274   painter->drawPixmap( *dstRect, *image, *srcRect);
275 
276   delete srcRect;
277   delete dstRect;
278 }
279 
280 /*
281  * Draw pixels transformed.
282  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_drawPixelsTransformed(JNIEnv * env,jobject obj,jobject graphics,jobject transform)283 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_drawPixelsTransformed
284 (JNIEnv *env, jobject obj, jobject graphics, jobject transform)
285 {
286   QPixmap *originalImage = getQtVolatileImage(env, obj);
287   assert( originalImage );
288   QPainter *painter = getPainter( env, graphics );
289   assert( painter );
290   QMatrix *matrix = (QMatrix *)getNativeObject(env, transform);
291   assert( matrix );
292 
293   // FIXME : Add rendering hint support here.
294   QPoint p = matrix->map( QPoint(0,0) );
295   QImage image = originalImage->toImage().transformed ( *matrix, Qt::FastTransformation );
296   painter->drawImage(p, image);
297 }
298 
299 
300 /**
301  * Draw pixels scaled and flipped
302  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_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)303 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_drawPixelsScaledFlipped
304 (JNIEnv *env, jobject obj, jobject graphics,
305  jint bg_red, jint bg_green, jint bg_blue,
306  jboolean flipx, jboolean flipy,
307  jint srcx, jint srcy, jint srcwidth, jint srcheight,
308  jint dstx, jint dsty, jint dstwidth, jint dstheight,
309  jboolean composite)
310 {
311   QPixmap *originalImage = getQtVolatileImage(env, obj);
312   assert( originalImage );
313   QPainter *painter = getPainter( env, graphics );
314   assert( painter );
315 
316   QRectF *srcRect = new QRectF((qreal)srcx, (qreal)srcy,
317 			       (qreal)srcwidth, (qreal)srcheight);
318   QRectF *dstRect = new QRectF((qreal)dstx, (qreal)dsty,
319 			       (qreal)dstwidth, (qreal)dstheight);
320 
321   if(composite == JNI_TRUE)
322     painter->fillRect( *dstRect, QColor(bg_red, bg_green, bg_blue ) );
323 
324   if( flipx == JNI_TRUE || flipy == JNI_TRUE )
325     {
326       QImage im = originalImage->toImage().mirrored ( (flipx == JNI_TRUE),
327 						      (flipy == JNI_TRUE) );
328       painter->drawImage ( *dstRect, im, *srcRect);
329     }
330   else
331     painter->drawPixmap ( *dstRect, *originalImage, *srcRect);
332 
333   delete srcRect;
334   delete dstRect;
335 }
336 
337 /**
338  * Copies an area of the image (used by Graphics)
339  */
Java_gnu_java_awt_peer_qt_QtVolatileImage_copyArea(JNIEnv * env,jobject obj,jint x,jint y,jint w,jint h,jint dx,jint dy)340 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtVolatileImage_copyArea
341 (JNIEnv *env, jobject obj , jint x, jint y, jint w, jint h, jint dx, jint dy)
342 {
343   QPixmap *image = getQtVolatileImage(env, obj);
344   assert( image );
345 
346   // FIXME
347 }
348