View Javadoc

1   /*
2    *  Nokia API for MicroEmulator
3    *  Copyright (C) 2003 Markus Heberling <markus@heberling.net>
4    *
5    *  It is licensed under the following two licenses as alternatives:
6    *    1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
7    *    2. Apache License (the "AL") Version 2.0
8    *
9    *  You may not use this file except in compliance with at least one of
10   *  the above two licenses.
11   *
12   *  You may obtain a copy of the LGPL at
13   *      http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
14   *
15   *  You may obtain a copy of the AL at
16   *      http://www.apache.org/licenses/LICENSE-2.0
17   *
18   *  Unless required by applicable law or agreed to in writing, software
19   *  distributed under the License is distributed on an "AS IS" BASIS,
20   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   *  See the LGPL or the AL for the specific language governing permissions and
22   *  limitations.
23   *
24   *  Contributor(s):
25   *    Bartek Teodorczyk <barteo@barteo.net>
26   */
27  
28  package com.nokia.mid.ui;
29  
30  import javax.microedition.lcdui.Graphics;
31  import javax.microedition.lcdui.Image;
32  import javax.microedition.lcdui.game.Sprite;
33  
34  import org.microemu.device.DisplayGraphics;
35  import org.microemu.device.MutableImage;
36  
37  
38  
39  public class DirectGraphicsImp implements DirectGraphics{
40      
41      
42      private Graphics graphics;
43      private int alphaComponent;
44      
45      /**
46       * @param g
47       */
48      public DirectGraphicsImp(Graphics g) {
49          graphics = g;
50      }
51      
52      /**
53       * @param img
54       * @param x
55       * @param y
56       * @param anchor
57       * @param manipulation ignored, since manipulations are not supported at the moment
58       */
59      public void drawImage(Image img, int x, int y, int anchor, int manipulation) {
60          if(img == null) {
61              throw new NullPointerException();
62          }
63          int transform;
64          switch (manipulation) {
65              case FLIP_HORIZONTAL:
66                  transform = Sprite.TRANS_MIRROR_ROT180;
67                  break;
68              case FLIP_VERTICAL:
69                  transform = Sprite.TRANS_MIRROR;
70                  break;
71              case ROTATE_90:
72                  transform = Sprite.TRANS_ROT90;
73                  break;
74              case ROTATE_180:
75                  transform = Sprite.TRANS_ROT180;
76                  break;
77              case ROTATE_270:
78                  transform = Sprite.TRANS_ROT270;
79                  break;
80              default:
81                  transform = -1;
82          }
83          if(anchor >= 64 || transform == -1) {
84              throw new IllegalArgumentException();
85          } else {
86              graphics.drawRegion(
87                      img, 
88                      x + graphics.getTranslateX(), y + graphics.getTranslateY(), 
89                      img.getWidth(), img.getHeight(), 
90                      transform, 
91                      x + graphics.getTranslateX(), y + graphics.getTranslateY(), anchor);
92              return;
93          }
94      }
95      
96      /**
97       * @param argb
98       */
99      public void setARGBColor(int argb) {
100         alphaComponent=(argb >> 24 & 0xff);
101         graphics.setColor(argb & 0xffffff);
102     }
103     
104     /**
105      * @return
106      */
107     public int getAlphaComponent() {
108         return alphaComponent;
109     }
110     
111     /**
112      * @return
113      */
114     public int getNativePixelFormat() {
115         return TYPE_BYTE_1_GRAY;
116     }
117     
118     /** Not supported
119      * @param xPoints
120      * @param xOffset
121      * @param yPoints
122      * @param yOffset
123      * @param nPoints
124      * @param argbColor
125      */
126     public void drawPolygon(int xPoints[], int xOffset, int yPoints[], int yOffset, int nPoints, int argbColor) {
127         System.out.println("public void drawPolygon(int xPoints[], int xOffset, int yPoints[], int yOffset, int nPoints, int argbColor)");
128     }
129     
130     /** Not supported
131      * @param x1
132      * @param y1
133      * @param x2
134      * @param y2
135      * @param x3
136      * @param y3
137      * @param argbColor
138      */
139     public void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int argbColor) {
140         System.out.println("public void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int argbColor)");
141     }
142     
143     /** Not supported
144      * @param xPoints
145      * @param xOffset
146      * @param yPoints
147      * @param yOffset
148      * @param nPoints
149      * @param argbColor
150      */
151     public void fillPolygon(int xPoints[], int xOffset, int yPoints[], int yOffset, int nPoints, int argbColor) {
152         System.out.println("public void fillPolygon(int xPoints[], int xOffset, int yPoints[], int yOffset, int nPoints, int argbColor)");
153     }
154     
155     /** Not supported
156      * @param x1
157      * @param y1
158      * @param x2
159      * @param y2
160      * @param x3
161      * @param y3
162      * @param argbColor
163      */
164     public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int argbColor) {
165         System.out.println("public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int argbColor)");
166     }
167     
168     //manipulations are not supported!
169     /**
170      * @param pix
171      * @param alpha
172      * @param off
173      * @param scanlen
174      * @param x
175      * @param y
176      * @param width
177      * @param height
178      * @param manipulation ignored, since manipulations are not supported at the moment
179      * @param format
180      */
181     public void drawPixels(byte[] pix, byte[] alpha, int off, int scanlen, int x, int y, int width, int height, int manipulation, int format) {
182         System.out.println("public void drawPixels(byte[] pix, byte[] alpha, int off, int scanlen, int x, int y, int width, int height, int manipulation, int format)");
183         if (pix == null) {
184             throw new NullPointerException();
185         }
186         if (width < 0 || height < 0) {
187             throw new IllegalArgumentException();
188         }
189         
190         Graphics g=graphics;
191         int c;
192         
193         if (format == TYPE_BYTE_1_GRAY) {
194             
195             int b=7;
196             
197             for (int yj = 0; yj < height; yj++) {
198                 int line = off + yj * scanlen;
199                 int ypos = yj * width;
200                 for (int xj = 0; xj < width; xj++) {
201                     c=doAlpha(pix, alpha, (line + xj) /8,b);
202                     if((c >> 24 & 0xff)!=0)//alpha
203                     {
204                         if (g.getColor()!=c) g.setColor(c);
205                         g.drawLine(xj+x,yj+y,xj+x,yj+y);
206                     }
207                     b--;
208                     if(b<0)b=7;
209                 }
210             }
211         }
212         else if (format == TYPE_BYTE_1_GRAY_VERTICAL) {
213             int ods = off / scanlen;
214             int oms = off % scanlen;
215             int b=0;
216             for (int yj = 0; yj < height; yj++) {
217                 int ypos = yj * width;
218                 int tmp = (ods + yj) /8 * scanlen+oms;
219                 for (int xj = 0; xj < width; xj++) {
220                     c=doAlpha(pix, alpha, tmp + xj, b);
221                     if (g.getColor()!=c) g.setColor(c);
222                     if((c >> 24 & 0xff)!=0) //alpha
223                         g.drawLine(xj+x,yj+y,xj+x,yj+y);
224                 }
225                 b++;
226                 if(b>7) b=0;
227             }
228         } else
229             throw new IllegalArgumentException();
230     }
231     
232     /** Only TYPE_USHORT_4444_ARGB format supported
233      * @param pix
234      * @param trans
235      * @param off
236      * @param scanlen
237      * @param x
238      * @param y
239      * @param width
240      * @param height
241      * @param manipulation
242      * @param format
243      */
244     public void drawPixels(short pix[], boolean trans, int off, int scanlen, int x, int y, int width, int height, int manipulation, int format) {
245         //        System.out.println("public void drawPixels(short pix[], boolean trans, int off, int scanlen, int x, int y, int width, int height, int manipulation, int format)");
246         if (format != TYPE_USHORT_4444_ARGB) {
247             throw new IllegalArgumentException("Illegal format: " + format);
248         }
249         
250         //Graphics g = image.getGraphics();
251         Graphics g = graphics;
252         
253         for (int iy = 0; iy < height; iy++) {
254             for (int ix = 0; ix < width; ix ++) {
255                 int c=toARGB(pix[off + ix + iy * scanlen],TYPE_USHORT_4444_ARGB);
256                 if (!isTransparent(c)) {
257                     g.setColor(c);
258                     g.drawLine(x + ix, y + iy,x + ix, y + iy);
259                 }
260             }
261         }
262         
263         //graphics.drawImage(image, 0, 0, Graphics.TOP | Graphics.LEFT);
264     }
265     
266     /** Not supported
267      * @param pix
268      * @param trans
269      * @param off
270      * @param scanlen
271      * @param x
272      * @param y
273      * @param width
274      * @param height
275      * @param manipulation
276      * @param format
277      */
278     public void drawPixels(int pix[], boolean trans, int off, int scanlen, int x, int y, int width, int height, int manipulation, int format) {
279         System.out.println("public void drawPixels(int pix[], boolean trans, int off, int scanlen, int x, int y, int width, int height, int manipulation, int format)");
280         throw new IllegalArgumentException();
281     }
282     
283     /** Not supported
284      * @param pix
285      * @param alpha
286      * @param offset
287      * @param scanlen
288      * @param x
289      * @param y
290      * @param width
291      * @param height
292      * @param format
293      */
294     public void getPixels(byte pix[], byte alpha[], int offset, int scanlen, int x, int y, int width, int height, int format) {
295         System.out.println("public void getPixels(byte pix[], byte alpha[], int offset, int scanlen, int x, int y, int width, int height, int format)");
296         throw new IllegalArgumentException();
297     }
298     
299     /** Only TYPE_USHORT_4444_ARGB format supported
300      * @param pix
301      * @param offset
302      * @param scanlen
303      * @param x
304      * @param y
305      * @param width
306      * @param height
307      * @param format
308      */
309     public void getPixels(short pix[], int offset, int scanlen, int x, int y, int width, int height, int format) {
310         //        System.out.println("public void getPixels(short pix[], int offset, int scanlen, int x, int y, int width, int height, int format)");
311         switch (format) {
312             case TYPE_USHORT_4444_ARGB: {
313                 //DeviceDisplay dd = DeviceFactory.getDevice().getDeviceDisplay();
314                 //MutableImage img = (MutableImage)dd.getDisplayImage();
315                 MutableImage img=((DisplayGraphics)graphics).getImage();
316                 
317                 int [] data=img.getData();
318                 
319                 for (int iy = 0; iy < height; iy++) {
320                     for (int ix = 0; ix < width; ix++) {
321                         //pix[offset + ix + iy * scanlen] = (short) img.getPixel(x + ix, y + iy);
322                         //System.out.println(data[ix+iy*width]+" "+a+" "+r+" "+g+" "+b);
323                         pix[offset + ix + iy * scanlen]=(short)fromARGB(data[ix+iy*width],TYPE_USHORT_4444_ARGB);
324                     }
325                 }
326                 break;
327             }
328             case TYPE_USHORT_444_RGB: {
329                 //DeviceDisplay dd = DeviceFactory.getDevice().getDeviceDisplay();
330                 //MutableImage img = (MutableImage)dd.getDisplayImage();
331                 MutableImage img=((DisplayGraphics)graphics).getImage();
332                 
333                 int [] data=img.getData();
334                 
335                 for (int iy = 0; iy < height; iy++) {
336                     for (int ix = 0; ix < width; ix++) {
337                         //pix[offset + ix + iy * scanlen] = (short) img.getPixel(x + ix, y + iy);
338                         //System.out.println(data[ix+iy*width]+" "+a+" "+r+" "+g+" "+b);
339                         pix[offset + ix + iy * scanlen]=(short)fromARGB(data[ix+iy*width],TYPE_USHORT_444_RGB);
340                     }
341                 }
342                 break;
343             }            
344             default: throw new IllegalArgumentException("Illegal format: " + format);
345         }
346     }
347     
348     
349     
350     
351     /** Not supported
352      * @param pix
353      * @param offset
354      * @param scanlen
355      * @param x
356      * @param y
357      * @param width
358      * @param height
359      * @param format
360      */
361     public void getPixels(int pix[], int offset, int scanlen, int x, int y, int width, int height, int format) {
362         System.out.println("public void getPixels(int pix[], int offset, int scanlen, int x, int y, int width, int height, int format");
363         throw new IllegalArgumentException();
364     }
365     
366     
367     private static int doAlpha(byte[] pix, byte[] alpha, int pos, int shift) {
368         int p;
369         int a;
370         if (isBitSet(pix[pos],shift))
371             p=0;
372         else
373             p=0x00FFFFFF;
374         if (alpha == null || isBitSet(alpha[pos],shift))
375             a=0xFF000000;
376         else
377             a=0;
378         return p|a;
379     }
380     
381     
382     private static boolean isBitSet(byte b, int pos) {
383         return ((b & (byte)(1 << pos)) != 0);
384     }
385     
386     
387     private static int toARGB(int s, int type) {
388         switch (type) {
389             case TYPE_USHORT_4444_ARGB: {
390                 int a=((s)&0xF000)>>>12;
391                 int r=((s)&0x0F00)>>>8;
392                 int g=((s)&0x00F0)>>>4;
393                 int b=((s)&0x000F);
394                 
395                 //System.out.println("t"+a+" "+r+" "+g+" "+b);
396                 s=((a*15)<<24)|((r*15)<<16)|((g*15)<<8)|(b*15);
397                 break;
398             }
399             case TYPE_USHORT_444_RGB: {
400                 int r=((s)&0x0F00)>>>8;
401                 int g=((s)&0x00F0)>>>4;
402                 int b=((s)&0x000F);
403                 
404                 //System.out.println("t"+a+" "+r+" "+g+" "+b);
405                 s=((r*15)<<16)|((g*15)<<8)|(b*15);
406                 break;
407             }
408         }
409         return s;
410     }
411     
412     private static int fromARGB(int s, int type) {
413         switch (type) {
414             case TYPE_USHORT_4444_ARGB: {
415                 int a=((s)&0xFF000000)>>>24;
416                 int r=((s)&0x00FF0000)>>>16;
417                 int g=((s)&0x0000FF00)>>>8;
418                 int b=((s)&0x000000FF);
419                 s=((a/15)<<12)|((r/15)<<8)|((g/15)<<4)|(b/15);
420                 break;
421             }
422             case TYPE_USHORT_444_RGB: {
423                 int r=((s)&0x00FF0000)>>>16;
424                 int g=((s)&0x0000FF00)>>>8;
425                 int b=((s)&0x000000FF);
426                 s=((r/15)<<8)|((g/15)<<4)|(b/15);
427                 break;
428             }
429         }
430         return s;
431     }
432     
433     private static boolean isTransparent(int s) {
434         return (s&0xFF000000)==0;
435     }
436 }