|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 package javax.microedition.lcdui; |
|
18 |
|
19 import java.io.*; |
|
20 |
|
21 import javax.microedition.lcdui.game.Sprite; |
|
22 |
|
23 import org.eclipse.swt.graphics.Internal_GfxPackageSupport; |
|
24 |
|
25 /** |
|
26 * Class containing graphical data of image.<br> |
|
27 * <br> |
|
28 * Image path handling is not implemented correctly, for example "standard" |
|
29 * LCDUI accepts path "/TestMIDlets/images/100x100.png" but corresponding path |
|
30 * with this image-class must be "/100x100.png". |
|
31 */ |
|
32 public class Image |
|
33 { |
|
34 |
|
35 private static Image createImageReturnValue; |
|
36 |
|
37 private org.eclipse.swt.graphics.Image eswtImage; |
|
38 private int eswtImageWidth; |
|
39 private int eswtImageHeight; |
|
40 private boolean mutable; |
|
41 private com.nokia.mj.impl.rt.support.Finalizer finalizer; |
|
42 |
|
43 // buffer has package visibility so that it can be used as |
|
44 // a lock in other classes |
|
45 ImageBuffer graphicsBuffer; |
|
46 |
|
47 // Graphics for transferring instance |
|
48 // between application and UI thread |
|
49 Graphics tempGraphics; |
|
50 |
|
51 /** |
|
52 * Constructor. |
|
53 */ |
|
54 Image(org.eclipse.swt.graphics.Image eswtImage, boolean isMutable) |
|
55 { |
|
56 this.eswtImage = eswtImage; |
|
57 this.mutable = isMutable; |
|
58 eswtImageWidth = eswtImage.getBounds().width; |
|
59 eswtImageHeight = eswtImage.getBounds().height; |
|
60 graphicsBuffer = new ImageBuffer(this); |
|
61 finalizer = ((finalizer != null) ? finalizer |
|
62 : new com.nokia.mj.impl.rt.support.Finalizer() |
|
63 { |
|
64 public void finalizeImpl() |
|
65 { |
|
66 if(finalizer != null) |
|
67 { |
|
68 finalizer = null; |
|
69 if(!ESWTUIThreadRunner.isDisposed()) |
|
70 { |
|
71 dispose(); |
|
72 } |
|
73 } |
|
74 } |
|
75 }); |
|
76 ESWTUIThreadRunner.update(getClass().getName(), 1); |
|
77 } |
|
78 |
|
79 /** |
|
80 * Called by finalizer when Image is ready to free its resources. |
|
81 */ |
|
82 void dispose() |
|
83 { |
|
84 ESWTUIThreadRunner.update(getClass().getName(), -1); |
|
85 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
86 { |
|
87 public void run() |
|
88 { |
|
89 if(eswtImage != null) |
|
90 { |
|
91 eswtImage.dispose(); |
|
92 eswtImage = null; |
|
93 } |
|
94 graphicsBuffer.dispose(); |
|
95 } |
|
96 }); |
|
97 } |
|
98 |
|
99 /** |
|
100 * Return eSWT Image object. |
|
101 */ |
|
102 org.eclipse.swt.graphics.Image getESWTImage() |
|
103 { |
|
104 return eswtImage; |
|
105 } |
|
106 |
|
107 /** |
|
108 * Return eSWT Image object. |
|
109 * |
|
110 * @param img Image |
|
111 * @return eSWT Image |
|
112 */ |
|
113 static org.eclipse.swt.graphics.Image getESWTImage(Image img) |
|
114 { |
|
115 if(img != null) |
|
116 { |
|
117 return img.eswtImage; |
|
118 } |
|
119 return null; |
|
120 } |
|
121 |
|
122 /** |
|
123 * Creates new mutable image where every pixel is white. |
|
124 * |
|
125 * @param w The width of the image to be created. |
|
126 * @param h The height of the image to be created. |
|
127 * @return Image created. |
|
128 * @throws IllegalArgumentException if width or height are zero or less. |
|
129 */ |
|
130 public static Image createImage(int w, int h) |
|
131 { |
|
132 if(w <= 0 || h <= 0) |
|
133 { |
|
134 throw new IllegalArgumentException( |
|
135 MsgRepository.IMAGE_EXCEPTION_INVALID_DIMENSIONS); |
|
136 } |
|
137 |
|
138 final int width = w; |
|
139 final int height = h; |
|
140 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
141 { |
|
142 public void run() |
|
143 { |
|
144 org.eclipse.swt.graphics.Image eswtImg = |
|
145 eswtCreateImage(width, height); |
|
146 |
|
147 if(eswtImg != null) |
|
148 { |
|
149 createImageReturnValue = new Image(eswtImg, true); |
|
150 } |
|
151 else |
|
152 { |
|
153 createImageReturnValue = null; |
|
154 throw new OutOfMemoryError(); |
|
155 } |
|
156 } |
|
157 }); |
|
158 return createImageReturnValue; |
|
159 } |
|
160 |
|
161 /** |
|
162 * Creates an immutable image with the specified size from the existing |
|
163 * image source. |
|
164 * |
|
165 * @param srcImage the source of image. |
|
166 * @param width the width of the new image. |
|
167 * @param height the height of the new image. |
|
168 * @return the resized Image. |
|
169 * @throws NullPointerException if aImage is null. |
|
170 */ |
|
171 static Image createImage(Image srcImage, int width, int height) |
|
172 { |
|
173 if(srcImage == null) |
|
174 { |
|
175 throw new NullPointerException( |
|
176 MsgRepository.IMAGE_EXCEPTION_IS_NULL); |
|
177 } |
|
178 final Image finalImage = srcImage; |
|
179 final int finalWidth = width; |
|
180 final int finalHeight = height; |
|
181 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
182 { |
|
183 public void run() |
|
184 { |
|
185 org.eclipse.swt.graphics.Image eswtImg = |
|
186 eswtCreateImage(finalImage.eswtImage, finalWidth, finalHeight); |
|
187 |
|
188 if(eswtImg != null) |
|
189 { |
|
190 createImageReturnValue = new Image(eswtImg, false); |
|
191 } |
|
192 else |
|
193 { |
|
194 createImageReturnValue = null; |
|
195 throw new OutOfMemoryError(); |
|
196 } |
|
197 } |
|
198 }); |
|
199 return createImageReturnValue; |
|
200 } |
|
201 |
|
202 /** |
|
203 * Creates immutable image from existing image source. |
|
204 * |
|
205 * @param srcImage The source of image. |
|
206 * @return Image created. |
|
207 * @throws NullPointerException if source image is null. |
|
208 */ |
|
209 public static Image createImage(Image srcImage) |
|
210 { |
|
211 if(srcImage == null) |
|
212 { |
|
213 throw new NullPointerException( |
|
214 MsgRepository.IMAGE_EXCEPTION_IS_NULL); |
|
215 } |
|
216 |
|
217 if(!srcImage.isMutable()) |
|
218 { |
|
219 return srcImage; |
|
220 } |
|
221 |
|
222 final Image finalImage = srcImage; |
|
223 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
224 { |
|
225 public void run() |
|
226 { |
|
227 org.eclipse.swt.graphics.Image eswtImg = |
|
228 eswtCreateImage(finalImage.eswtImage); |
|
229 |
|
230 if(eswtImg != null) |
|
231 { |
|
232 createImageReturnValue = new Image(eswtImg, false); |
|
233 } |
|
234 else |
|
235 { |
|
236 createImageReturnValue = null; |
|
237 throw new OutOfMemoryError(); |
|
238 } |
|
239 } |
|
240 }); |
|
241 return createImageReturnValue; |
|
242 } |
|
243 |
|
244 /** |
|
245 * Creates an immutable image from named resource. |
|
246 * |
|
247 * @param name The name of the resource. |
|
248 * @return Image created. |
|
249 * @throws NullPointerException if name is null. |
|
250 * @throws IOException If resource doesn't exist, data cannot be loaded or |
|
251 * data is invalid. |
|
252 */ |
|
253 public static Image createImage(String name) throws IOException |
|
254 { |
|
255 if(name == null) |
|
256 { |
|
257 throw new NullPointerException( |
|
258 MsgRepository.IMAGE_EXCEPTION_FILE_NAME_IS_NULL); |
|
259 } |
|
260 |
|
261 String fileName = name; |
|
262 if(!fileName.startsWith("/")) |
|
263 { |
|
264 fileName = "/" + fileName; |
|
265 } |
|
266 |
|
267 InputStream stream = Image.class.getResourceAsStream(fileName); |
|
268 if(stream == null) |
|
269 { |
|
270 throw new IOException(MsgRepository.IMAGE_EXCEPTION_IO_ERROR); |
|
271 } |
|
272 Image image = createImage(stream); |
|
273 try |
|
274 { |
|
275 stream.close(); |
|
276 } |
|
277 catch(IOException e) |
|
278 { |
|
279 // ignore |
|
280 } |
|
281 return image; |
|
282 } |
|
283 |
|
284 /** |
|
285 * Creates immutable image from stream. Thread's execution is blocked until |
|
286 * this method is finished. |
|
287 * |
|
288 * @param stream The stream. |
|
289 * @return Image created. |
|
290 * @throws NullPointerException if stream is null. |
|
291 * @throws java.io.IOException If I/O error occurs or data from stream is |
|
292 * invalid. |
|
293 */ |
|
294 public static Image createImage(InputStream stream) throws java.io.IOException |
|
295 { |
|
296 if(stream == null) |
|
297 { |
|
298 throw new NullPointerException( |
|
299 MsgRepository.IMAGE_EXCEPTION_FILE_STREAM_IS_NULL); |
|
300 } |
|
301 final InputStream finalStream = stream; |
|
302 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
303 { |
|
304 public void run() |
|
305 { |
|
306 org.eclipse.swt.graphics.Image eswtImg = eswtCreateImage(finalStream); |
|
307 |
|
308 if(eswtImg != null) |
|
309 { |
|
310 createImageReturnValue = new Image(eswtImg, false); |
|
311 } |
|
312 else |
|
313 { |
|
314 createImageReturnValue = null; |
|
315 } |
|
316 } |
|
317 }); |
|
318 if(createImageReturnValue == null) |
|
319 { |
|
320 throw new IOException(MsgRepository.IMAGE_EXCEPTION_IO_ERROR); |
|
321 } |
|
322 return createImageReturnValue; |
|
323 } |
|
324 |
|
325 /** |
|
326 * Creates new immutable image from image data provided. |
|
327 * |
|
328 * @param imgData Image data. |
|
329 * @param imgOffset Start offset in image data. |
|
330 * @param imgLength Length of data used. |
|
331 * @return Image created. |
|
332 * @throws ArrayIndexOutOfBoundsException if imgOffset and imgLength |
|
333 * specifies invalid range. |
|
334 * @throws NullPointerException if imgData is null. |
|
335 * @throws IllegalArgumentException if imgData content is invalid. |
|
336 */ |
|
337 public static Image createImage(byte[] imgData, int imgOffset, int imgLength) |
|
338 { |
|
339 if(imgData == null) |
|
340 { |
|
341 throw new NullPointerException( |
|
342 MsgRepository.IMAGE_EXCEPTION_DATA_IS_NULL); |
|
343 } |
|
344 if(imgOffset + imgLength > imgData.length) |
|
345 { |
|
346 throw new ArrayIndexOutOfBoundsException( |
|
347 MsgRepository.IMAGE_EXCEPTION_INVALID_BOUNDS); |
|
348 } |
|
349 if(imgOffset < 0 || imgLength < 0) |
|
350 { |
|
351 throw new ArrayIndexOutOfBoundsException( |
|
352 MsgRepository.IMAGE_EXCEPTION_INVALID_BOUNDS); |
|
353 } |
|
354 |
|
355 InputStream inputStream = new ByteArrayInputStream(imgData, imgOffset, imgLength); |
|
356 try |
|
357 { |
|
358 createImageReturnValue = createImage(inputStream); |
|
359 } |
|
360 catch(IOException e) |
|
361 { |
|
362 throw new IllegalArgumentException( |
|
363 MsgRepository.IMAGE_EXCEPTION_INVALID_DATA); |
|
364 } |
|
365 finally |
|
366 { |
|
367 try |
|
368 { |
|
369 inputStream.close(); |
|
370 } |
|
371 catch(IOException e) |
|
372 { |
|
373 // ignore |
|
374 } |
|
375 } |
|
376 return createImageReturnValue; |
|
377 } |
|
378 |
|
379 /** |
|
380 * Creates an immutable image from specified region of existing source image |
|
381 * with specified transform. |
|
382 * |
|
383 * @param srcImage Source image. |
|
384 * @param x Region's x. |
|
385 * @param y Region's y. |
|
386 * @param w Regions width. |
|
387 * @param h Regions height. |
|
388 * @param transform Transform, one of the transforms specified in |
|
389 * Sprite-class. |
|
390 * @return Image created. |
|
391 * @throws NullPointerException if img is null. |
|
392 * @throws IllegalArgumentException if Region specified exceeds the source |
|
393 * image or if w or h is zero or less or if transform is not one |
|
394 * defined in Sprite-class. |
|
395 */ |
|
396 public static Image createImage(Image srcImage, |
|
397 int x, |
|
398 int y, |
|
399 int w, |
|
400 int h, |
|
401 int transform) |
|
402 { |
|
403 if(srcImage == null) |
|
404 { |
|
405 throw new NullPointerException( |
|
406 MsgRepository.IMAGE_EXCEPTION_IS_NULL); |
|
407 } |
|
408 if(w <= 0 || h <= 0) |
|
409 { |
|
410 throw new IllegalArgumentException( |
|
411 MsgRepository.IMAGE_EXCEPTION_INVALID_DIMENSIONS); |
|
412 } |
|
413 if(!validateTransform(transform)) |
|
414 { |
|
415 throw new IllegalArgumentException( |
|
416 MsgRepository.IMAGE_EXCEPTION_INVALID_TRANSFORM); |
|
417 } |
|
418 if(!validateRegion(srcImage.getWidth(), srcImage.getHeight(), x, y, w, h)) |
|
419 { |
|
420 throw new IllegalArgumentException( |
|
421 MsgRepository.IMAGE_EXCEPTION_INVALID_REGION); |
|
422 } |
|
423 |
|
424 final Image fImage = srcImage; |
|
425 final int fx = x; |
|
426 final int fy = y; |
|
427 final int fw = w; |
|
428 final int fh = h; |
|
429 final int fTransform = transform; |
|
430 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
431 { |
|
432 public void run() |
|
433 { |
|
434 org.eclipse.swt.internal.qt.graphics.Image srcCgImage = |
|
435 Internal_GfxPackageSupport.getImage(fImage.getESWTImage()); |
|
436 |
|
437 org.eclipse.swt.internal.qt.graphics.Image cgImage = |
|
438 new org.eclipse.swt.internal.qt.graphics.Image( |
|
439 srcCgImage, fx, fy, fw, fh); |
|
440 |
|
441 cgImage.transform(getCgTransformValue(fTransform)); |
|
442 |
|
443 org.eclipse.swt.graphics.Image eswtImg = |
|
444 Internal_GfxPackageSupport.new_Image( |
|
445 ESWTUIThreadRunner.getInstance().getDisplay(), |
|
446 cgImage); |
|
447 |
|
448 if(eswtImg != null) |
|
449 { |
|
450 createImageReturnValue = new Image(eswtImg, false); |
|
451 } |
|
452 else |
|
453 { |
|
454 createImageReturnValue = null; |
|
455 throw new OutOfMemoryError(); |
|
456 } |
|
457 } |
|
458 }); |
|
459 return createImageReturnValue; |
|
460 } |
|
461 |
|
462 /** |
|
463 * Validates that a specified region is fully located within the image |
|
464 * bounds. Method is package-private, used by Graphics.drawRegion as well. |
|
465 */ |
|
466 static boolean validateRegion(int srcWidth, int srcHeight, int x, int y, |
|
467 int w, int h) |
|
468 { |
|
469 return x >= 0 && y >= 0 && w <= srcWidth && h <= srcHeight; |
|
470 } |
|
471 |
|
472 /** |
|
473 * Validates if transform has a valid value. Method is package-private, used |
|
474 * by Graphics.drawRegion as well. |
|
475 */ |
|
476 static boolean validateTransform(int transform) |
|
477 { |
|
478 return transform == Sprite.TRANS_NONE |
|
479 || transform == Sprite.TRANS_MIRROR |
|
480 || transform == Sprite.TRANS_MIRROR_ROT90 |
|
481 || transform == Sprite.TRANS_MIRROR_ROT180 |
|
482 || transform == Sprite.TRANS_MIRROR_ROT270 |
|
483 || transform == Sprite.TRANS_ROT90 |
|
484 || transform == Sprite.TRANS_ROT180 |
|
485 || transform == Sprite.TRANS_ROT270; |
|
486 } |
|
487 |
|
488 /** |
|
489 * Maps LCDUI transform constants to Common Graphics. Method is package-private, used |
|
490 * by Graphics.drawRegion as well. |
|
491 */ |
|
492 static int getCgTransformValue(int transform) |
|
493 { |
|
494 int retVal = org.eclipse.swt.internal.qt.graphics.Image.TRANS_NONE; |
|
495 switch(transform) |
|
496 { |
|
497 case Sprite.TRANS_NONE: |
|
498 retVal = org.eclipse.swt.internal.qt.graphics.Image.TRANS_NONE; |
|
499 break; |
|
500 case Sprite.TRANS_ROT90: |
|
501 retVal = org.eclipse.swt.internal.qt.graphics.Image.TRANS_ROT90; |
|
502 break; |
|
503 case Sprite.TRANS_ROT180: |
|
504 retVal = |
|
505 org.eclipse.swt.internal.qt.graphics.Image.TRANS_ROT180; |
|
506 break; |
|
507 case Sprite.TRANS_ROT270: |
|
508 retVal = |
|
509 org.eclipse.swt.internal.qt.graphics.Image.TRANS_ROT270; |
|
510 break; |
|
511 case Sprite.TRANS_MIRROR: |
|
512 retVal = |
|
513 org.eclipse.swt.internal.qt.graphics.Image.TRANS_MIRROR; |
|
514 break; |
|
515 case Sprite.TRANS_MIRROR_ROT90: |
|
516 retVal = org.eclipse.swt.internal.qt.graphics. |
|
517 Image.TRANS_MIRROR_ROT90; |
|
518 break; |
|
519 case Sprite.TRANS_MIRROR_ROT180: |
|
520 retVal = org.eclipse.swt.internal.qt.graphics. |
|
521 Image.TRANS_MIRROR_ROT180; |
|
522 break; |
|
523 case Sprite.TRANS_MIRROR_ROT270: |
|
524 retVal = org.eclipse.swt.internal.qt.graphics. |
|
525 Image.TRANS_MIRROR_ROT270; |
|
526 break; |
|
527 default: |
|
528 break; |
|
529 } |
|
530 return retVal; |
|
531 } |
|
532 |
|
533 /** |
|
534 * Creates eSWT image as a copy of existing image. |
|
535 * |
|
536 * @param image - image to be copied. |
|
537 * @return new eSWT image. |
|
538 */ |
|
539 private static org.eclipse.swt.graphics.Image eswtCreateImage( |
|
540 org.eclipse.swt.graphics.Image srcImage) |
|
541 { |
|
542 org.eclipse.swt.graphics.Image ret = null; |
|
543 try |
|
544 { |
|
545 org.eclipse.swt.internal.qt.graphics.Image cgImage = |
|
546 Internal_GfxPackageSupport.getImage(srcImage); |
|
547 |
|
548 org.eclipse.swt.internal.qt.graphics.Image cgImage2 = |
|
549 new org.eclipse.swt.internal.qt.graphics.Image(cgImage); |
|
550 |
|
551 ret = Internal_GfxPackageSupport.new_Image( |
|
552 ESWTUIThreadRunner.getInstance().getDisplay(), cgImage2); |
|
553 } |
|
554 catch(IllegalArgumentException ex) |
|
555 { |
|
556 // Device is null or there's no current device. |
|
557 ret = null; |
|
558 } |
|
559 catch(org.eclipse.swt.SWTException ex) |
|
560 { |
|
561 ret = null; |
|
562 } |
|
563 catch(org.eclipse.swt.SWTError err) |
|
564 { |
|
565 ret = null; |
|
566 } |
|
567 return ret; |
|
568 } |
|
569 |
|
570 /** |
|
571 * Creates eSWT image of the specified size from the given image. |
|
572 */ |
|
573 static org.eclipse.swt.graphics.Image eswtCreateImage( |
|
574 org.eclipse.swt.graphics.Image image, int newWidth, int newHeight) |
|
575 { |
|
576 org.eclipse.swt.graphics.Image ret = null; |
|
577 try |
|
578 { |
|
579 ret = new org.eclipse.swt.graphics.Image( |
|
580 ESWTUIThreadRunner.getInstance().getDisplay(), |
|
581 image.getImageData().scaledTo(newWidth, newHeight)); |
|
582 } |
|
583 catch(IllegalArgumentException ex) |
|
584 { |
|
585 // Device is null or there's no current device. |
|
586 ret = null; |
|
587 } |
|
588 catch(org.eclipse.swt.SWTException ex) |
|
589 { |
|
590 ret = null; |
|
591 } |
|
592 catch(org.eclipse.swt.SWTError err) |
|
593 { |
|
594 ret = null; |
|
595 } |
|
596 return ret; |
|
597 } |
|
598 |
|
599 /** |
|
600 * Creates eSWT image of the specified size. |
|
601 */ |
|
602 static org.eclipse.swt.graphics.Image eswtCreateImage(int width, int height) |
|
603 { |
|
604 org.eclipse.swt.graphics.Image ret = null; |
|
605 try |
|
606 { |
|
607 ret = new org.eclipse.swt.graphics.Image( |
|
608 ESWTUIThreadRunner.getInstance().getDisplay(), width, height); |
|
609 } |
|
610 catch(IllegalArgumentException ex) |
|
611 { |
|
612 // Device is null or there's no current device. |
|
613 ret = null; |
|
614 } |
|
615 catch(org.eclipse.swt.SWTException ex) |
|
616 { |
|
617 ret = null; |
|
618 } |
|
619 catch(org.eclipse.swt.SWTError err) |
|
620 { |
|
621 ret = null; |
|
622 } |
|
623 return ret; |
|
624 } |
|
625 |
|
626 /** |
|
627 * Creates and eSWT image out of the InputStream. |
|
628 */ |
|
629 static org.eclipse.swt.graphics.Image eswtCreateImage(InputStream inputStream) |
|
630 { |
|
631 org.eclipse.swt.graphics.Image ret = null; |
|
632 try |
|
633 { |
|
634 ret = new org.eclipse.swt.graphics.Image( |
|
635 ESWTUIThreadRunner.getInstance().getDisplay(), inputStream); |
|
636 } |
|
637 catch(IllegalArgumentException ex) |
|
638 { |
|
639 // Device is null or there's no current device. |
|
640 ret = null; |
|
641 } |
|
642 catch(org.eclipse.swt.SWTException ex) |
|
643 { |
|
644 ret = null; |
|
645 } |
|
646 catch(org.eclipse.swt.SWTError err) |
|
647 { |
|
648 ret = null; |
|
649 } |
|
650 return ret; |
|
651 } |
|
652 |
|
653 /** |
|
654 * Synchronizes any pending draw commands to this image. The buffer sync |
|
655 * must be executed in UI thread and if this method is not requested to switch to |
|
656 * UI thread, the caller must take care of serializing the call over the graphicsBuffer |
|
657 * of this instance. |
|
658 * |
|
659 * @param switchToUIThread If true the sync is run in UI thread, oherwise |
|
660 * caller must take care of switching to UI thread |
|
661 */ |
|
662 void sync(boolean switchToUIThread) |
|
663 { |
|
664 if(switchToUIThread) |
|
665 { |
|
666 synchronized(graphicsBuffer) |
|
667 { |
|
668 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
669 { |
|
670 public void run() |
|
671 { |
|
672 graphicsBuffer.sync(); |
|
673 } |
|
674 }); |
|
675 } |
|
676 } |
|
677 else |
|
678 { |
|
679 graphicsBuffer.sync(); |
|
680 } |
|
681 } |
|
682 |
|
683 /** |
|
684 * Creates new image from specified RGB array data. |
|
685 * |
|
686 * @param rgbData Pixel data. |
|
687 * @param width Width of the image to be created. |
|
688 * @param height Height of the image to be created. |
|
689 * @param processAlpha true if there's alpha channel in image data. |
|
690 * Otherwise method assumes that all pixels are fully opaque. |
|
691 * @return Image created. |
|
692 * @throws NullPointerException if rgb is null. |
|
693 * @throws IllegalArgumentException if w or h is zero or less. |
|
694 * @throws ArrayIndexOutOfBoundsException if the w and h parameters doesn't |
|
695 * match the length of the data array provided. |
|
696 */ |
|
697 public static Image createRGBImage(int[] rgbData, |
|
698 int width, |
|
699 int height, |
|
700 boolean processAlpha) |
|
701 { |
|
702 |
|
703 if(rgbData == null) |
|
704 { |
|
705 throw new NullPointerException( |
|
706 MsgRepository.IMAGE_EXCEPTION_DATA_IS_NULL); |
|
707 } |
|
708 if(width <= 0 || height <= 0) |
|
709 { |
|
710 throw new IllegalArgumentException( |
|
711 MsgRepository.IMAGE_EXCEPTION_INVALID_DIMENSIONS); |
|
712 } |
|
713 if(width * height > rgbData.length) |
|
714 { |
|
715 throw new ArrayIndexOutOfBoundsException( |
|
716 MsgRepository.IMAGE_EXCEPTION_INVALID_BOUNDS); |
|
717 } |
|
718 |
|
719 final int[] rgb = rgbData; |
|
720 final int w = width; |
|
721 final int h = height; |
|
722 final boolean alpha = processAlpha; |
|
723 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
724 { |
|
725 public void run() |
|
726 { |
|
727 org.eclipse.swt.internal.qt.graphics.Image cgImage = |
|
728 new org.eclipse.swt.internal.qt.graphics.Image(rgb, w, h, alpha); |
|
729 |
|
730 org.eclipse.swt.graphics.Image eswtImg = |
|
731 Internal_GfxPackageSupport.new_Image( |
|
732 ESWTUIThreadRunner.getInstance().getDisplay(), cgImage); |
|
733 |
|
734 if(eswtImg != null) |
|
735 { |
|
736 createImageReturnValue = new Image(eswtImg, false); |
|
737 } |
|
738 else |
|
739 { |
|
740 createImageReturnValue = null; |
|
741 throw new OutOfMemoryError(); |
|
742 } |
|
743 } |
|
744 }); |
|
745 return createImageReturnValue; |
|
746 } |
|
747 |
|
748 /** |
|
749 * Returns ARGB data of image region to an int[] array. |
|
750 * |
|
751 * @param rgbData - array to be filled with ARGB data. |
|
752 * @param offset - first index in the array to store the data. |
|
753 * @param length - relative distance in the array between corresponding |
|
754 * pixels of consecutive rows. |
|
755 * @param xPos - x-coordinate of the top-left corner of the region. |
|
756 * @param yPos - y-coordinate of the top-left corner of the region. |
|
757 * @param width - width of the region. |
|
758 * @param height - height of the region. |
|
759 */ |
|
760 public void getRGB(int[] rgbData, |
|
761 int offset, |
|
762 int length, |
|
763 int xPos, |
|
764 int yPos, |
|
765 int width, |
|
766 int height) |
|
767 { |
|
768 |
|
769 if(rgbData == null) |
|
770 { |
|
771 throw new NullPointerException( |
|
772 MsgRepository.IMAGE_EXCEPTION_DATA_IS_NULL); |
|
773 } |
|
774 if(!validateRegion(this.getWidth(), this.getHeight(), |
|
775 xPos, yPos, width, height)) |
|
776 { |
|
777 throw new IllegalArgumentException( |
|
778 MsgRepository.IMAGE_EXCEPTION_INVALID_BOUNDS); |
|
779 } |
|
780 if(Math.abs(length) < width) |
|
781 { |
|
782 throw new IllegalArgumentException( |
|
783 MsgRepository.IMAGE_EXCEPTION_INVALID_SCANLENGTH); |
|
784 } |
|
785 |
|
786 synchronized(graphicsBuffer) |
|
787 { |
|
788 final int[] localRgbData = rgbData; |
|
789 final int localOffset = offset; |
|
790 final int localLength = length; |
|
791 final int localX = xPos; |
|
792 final int localY = yPos; |
|
793 final int localW = width; |
|
794 final int localH = height; |
|
795 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
796 { |
|
797 public void run() |
|
798 { |
|
799 graphicsBuffer.sync(); |
|
800 org.eclipse.swt.internal.qt.graphics.Image cgImage = Internal_GfxPackageSupport.getImage(eswtImage); |
|
801 cgImage.getRGB(localRgbData, localOffset, localLength, |
|
802 localX, localY, localW, localH); |
|
803 } |
|
804 }); |
|
805 } |
|
806 } |
|
807 |
|
808 /** |
|
809 * Creates a new Graphics-objects that is able to draw to this image. |
|
810 * |
|
811 * @return New Graphics-object. |
|
812 * @throws IllegalStateException if image is immutable. |
|
813 */ |
|
814 public Graphics getGraphics() |
|
815 { |
|
816 if(mutable) |
|
817 { |
|
818 tempGraphics = null; |
|
819 ESWTUIThreadRunner.safeSyncExec(new Runnable() |
|
820 { |
|
821 public void run() |
|
822 { |
|
823 tempGraphics = graphicsBuffer.getGraphics(); |
|
824 } |
|
825 }); |
|
826 return tempGraphics; |
|
827 } |
|
828 throw new IllegalStateException(MsgRepository.IMAGE_EXCEPTION_IMMUTABLE); |
|
829 } |
|
830 |
|
831 /** |
|
832 * Gets width of the image. |
|
833 * |
|
834 * @return Image width. |
|
835 */ |
|
836 public int getWidth() |
|
837 { |
|
838 return eswtImageWidth; |
|
839 } |
|
840 |
|
841 /** |
|
842 * Gets height of the image. |
|
843 * |
|
844 * @return Image height. |
|
845 */ |
|
846 public int getHeight() |
|
847 { |
|
848 return eswtImageHeight; |
|
849 } |
|
850 |
|
851 /** |
|
852 * Check is it possible to modify this image. |
|
853 * |
|
854 * @return true, if image is mutable. |
|
855 */ |
|
856 public boolean isMutable() |
|
857 { |
|
858 return mutable; |
|
859 } |
|
860 |
|
861 } |