1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.runtime
.lcdui
.mle
;
12 import cc
.squirreljme
.jvm
.mle
.PencilShelf
;
13 import cc
.squirreljme
.jvm
.mle
.brackets
.PencilBracket
;
14 import cc
.squirreljme
.jvm
.mle
.constants
.UIPixelFormat
;
15 import cc
.squirreljme
.jvm
.mle
.exceptions
.MLECallError
;
16 import cc
.squirreljme
.jvm
.mle
.scritchui
.brackets
.ScritchPencilBracket
;
17 import cc
.squirreljme
.runtime
.cldc
.debug
.Debugging
;
18 import cc
.squirreljme
.runtime
.lcdui
.scritchui
.DisplayManager
;
19 import javax
.microedition
.lcdui
.Font
;
20 import javax
.microedition
.lcdui
.Graphics
;
21 import javax
.microedition
.lcdui
.Image
;
22 import javax
.microedition
.lcdui
.Text
;
23 import javax
.microedition
.lcdui
.game
.Sprite
;
26 * This delegates drawing operations to the hardware graphics layer.
28 * This utilizes both {@link PencilShelf} and {@link PencilBracket} for native
33 public final class PencilGraphics
36 /** The hardware bracket reference. */
37 protected final PencilBracket hardware
;
40 protected final int surfaceW
;
42 /** Surface height. */
43 protected final int surfaceH
;
45 /** Is there an alpha channel? */
46 protected final boolean hasAlpha
;
48 /** Single character. */
49 private final char[] _singleChar
=
52 /** The current alpha color. */
53 private int _argbColor
;
55 /** The current blending mode. */
56 private int _blendingMode
;
58 /** The clip height. */
59 private int _clipHeight
;
61 /** The clip width. */
62 private int _clipWidth
;
64 /** The clip X position. */
67 /** The clip Y position. */
70 /** The current font used. */
73 /** The current stroke style. */
74 private int _strokeStyle
;
76 /** The current X translation. */
79 /** The current Y translation. */
83 * Initializes the pencil graphics system.
85 * @param __sw The surface width.
86 * @param __sh The surface height.
87 * @param __hardware The hardware bracket reference for drawing.
88 * @throws IllegalArgumentException If hardware graphics are not capable
89 * enough to be used at all.
90 * @throws NullPointerException On null arguments.
93 private PencilGraphics(int __sw
, int __sh
, PencilBracket __hardware
)
94 throws IllegalArgumentException
, NullPointerException
96 if (__hardware
== null)
97 throw new NullPointerException("NARG");
99 this.hardware
= __hardware
;
101 // These are used to manage the clip
102 this.surfaceW
= __sw
;
103 this.surfaceH
= __sh
;
105 // Determines which blending modes are valid
106 this.hasAlpha
= PencilShelf
.hardwareHasAlpha(__hardware
);
108 // Set initial parameters for the graphics and make sure they are
109 // properly forwarded as well
110 this.setAlphaColor(0xFF000000);
111 this.setBlendingMode(Graphics
.SRC_OVER
);
112 this.setStrokeStyle(Graphics
.SOLID
);
121 public void clipRect(int __x
, int __y
, int __w
, int __h
)
123 throw Debugging
.todo();
131 public void copyArea(int __sx
, int __sy
, int __w
, int __h
, int __dx
,
132 int __dy
, int __anchor
)
133 throws IllegalArgumentException
, IllegalStateException
135 // Forward to native call
138 PencilShelf
.hardwareCopyArea(this.hardware
,
139 __sx
, __sy
, __w
, __h
, __dx
, __dy
, __anchor
);
142 // Unwrap any potential errors.
143 catch (MLECallError e
)
145 throw e
.throwDistinct();
154 public void drawArc(int __x
, int __y
, int __w
, int __h
, int __startAngle
,
157 throw Debugging
.todo();
165 public void drawARGB16(short[] __data
, int __off
, int __scanlen
,
166 int __x
, int __y
, int __w
, int __h
)
167 throws NullPointerException
169 throw Debugging
.todo();
177 public void drawChar(char __s
, int __x
, int __y
, int __anchor
)
179 // Fill single character first
180 char[] singleChar
= this._singleChar
;
186 PencilShelf
.hardwareDrawChars(this.hardware
,
187 singleChar
, 0, 1, __x
, __y
, __anchor
);
189 catch (MLECallError e
)
191 throw e
.throwDistinct();
200 public void drawChars(char[] __s
, int __o
, int __l
, int __x
, int __y
,
202 throws IllegalArgumentException
, IndexOutOfBoundsException
,
207 throw new NullPointerException("NARG");
208 if (__o
< 0 || __l
< 0 || (__o
+ __l
) > __s
.length
)
209 throw new IndexOutOfBoundsException("IOOB");
214 PencilShelf
.hardwareDrawChars(this.hardware
,
215 __s
, __o
, __l
, __x
, __y
, __anchor
);
217 catch (MLECallError e
)
219 throw e
.throwDistinct();
228 public void drawImage(Image __i
, int __x
, int __y
, int __anchor
)
229 throws IllegalArgumentException
, NullPointerException
231 // This is a duplicate function, so it gets forwarded
232 this.drawRegion(__i
, 0, 0,
233 __i
.getWidth(), __i
.getHeight(), 0,
242 public void drawLine(int __x1
, int __y1
, int __x2
, int __y2
)
244 PencilShelf
.hardwareDrawLine(this.hardware
, __x1
, __y1
, __x2
, __y2
);
252 public void drawRGB(int[] __data
, int __off
, int __scanlen
, int __x
,
253 int __y
, int __w
, int __h
, boolean __alpha
)
254 throws NullPointerException
257 this.__drawRegion(__data
, __off
, __scanlen
, __alpha
,
258 0, 0, __w
, __h
, Sprite
.TRANS_NONE
,
259 __x
, __y
, Graphics
.TOP
| Graphics
.LEFT
, __w
, __h
,
260 __scanlen
, (__data
.length
- __off
) / __scanlen
);
268 public void drawRGB16(short[] __data
, int __off
, int __scanlen
,
269 int __x
, int __y
, int __w
, int __h
)
270 throws NullPointerException
272 throw Debugging
.todo();
280 public void drawRect(int __x
, int __y
, int __w
, int __h
)
282 // Forward to hardware
283 PencilShelf
.hardwareDrawRect(this.hardware
, __x
, __y
, __w
, __h
);
291 public void drawRegion(Image __src
, int __xsrc
, int __ysrc
,
292 int __wsrc
, int __hsrc
, int __trans
, int __xdest
, int __ydest
,
294 throws IllegalArgumentException
, NullPointerException
297 this.drawRegion(__src
, __xsrc
, __ysrc
, __wsrc
, __hsrc
,
298 __trans
, __xdest
, __ydest
, __anch
, __wsrc
, __hsrc
);
306 public void drawRegion(Image __src
, int __xsrc
, int __ysrc
,
307 int __wsrc
, int __hsrc
, int __trans
, int __xdest
, int __ydest
,
308 int __anch
, int __wdest
, int __hdest
)
309 throws IllegalArgumentException
, NullPointerException
312 throw new NullPointerException("NARG");
314 // If the image is direct, use the buffer that is inside rather than
315 // a copy, so we do not waste time copying from it!
319 if (__src
.squirreljmeIsDirect())
321 buf
= __src
.squirreljmeDirectRGBInt();
322 offset
= __src
.squirreljmeDirectOffset();
323 scanLen
= __src
.squirreljmeDirectScanLen();
326 // Image is not directly accessible, so get a copy of it
329 // Obtain image properties
330 int iW
= __src
.getWidth();
331 int iH
= __src
.getHeight();
332 int totalPixels
= iW
* iH
;
335 buf
= new int[totalPixels
];
338 __src
.getRGB(buf
, offset
, scanLen
, 0, 0, iW
, iH
);
341 // Perform the internal draw
342 this.__drawRegion(buf
, offset
, scanLen
, __src
.hasAlpha(),
343 __xsrc
, __ysrc
, __wsrc
, __hsrc
, __trans
,
344 __xdest
, __ydest
, __anch
,
345 __wdest
, __hdest
, __src
.getWidth(), __src
.getHeight());
353 public void drawRoundRect(int __x
, int __y
, int __w
, int __h
,
354 int __arcWidth
, int __arcHeight
)
356 throw Debugging
.todo();
364 public void drawString(String __s
, int __x
, int __y
, int __anchor
)
365 throws NullPointerException
368 throw new NullPointerException("NARG");
373 PencilShelf
.hardwareDrawSubstring(this.hardware
,
374 __s
, 0, __s
.length(), __x
, __y
, __anchor
);
376 catch (MLECallError e
)
378 throw e
.throwDistinct();
387 public void drawSubstring(String __s
, int __o
, int __l
,
388 int __x
, int __y
, int __anchor
)
389 throws NullPointerException
, StringIndexOutOfBoundsException
392 throw new NullPointerException("NARG");
393 if (__o
< 0 || __l
< 0 || (__o
+ __l
) > __s
.length())
394 throw new StringIndexOutOfBoundsException("IOOB");
399 PencilShelf
.hardwareDrawSubstring(this.hardware
,
400 __s
, __o
, __l
, __x
, __y
, __anchor
);
402 catch (MLECallError e
)
404 throw e
.throwDistinct();
413 public void drawText(Text __t
, int __x
, int __y
)
415 throw Debugging
.todo();
423 public void fillArc(int __x
, int __y
, int __w
, int __h
, int __startAngle
,
426 throw Debugging
.todo();
434 public void fillRect(int __x
, int __y
, int __w
, int __h
)
436 // Forward to hardware
437 PencilShelf
.hardwareFillRect(this.hardware
, __x
, __y
, __w
, __h
);
445 public void fillRoundRect(int __x
, int __y
, int __w
, int __h
,
446 int __arcWidth
, int __arcHeight
)
448 throw Debugging
.todo();
456 public void fillTriangle(int __x1
, int __y1
, int __x2
, int __y2
,
459 // Forward to hardware
460 PencilShelf
.hardwareFillTriangle(this.hardware
, __x1
, __y1
, __x2
, __y2
,
469 public int getAlpha()
471 return (this._argbColor
>> 24) & 0xFF;
479 public int getAlphaColor()
481 return this._argbColor
;
489 public int getBlendingMode()
491 return this._blendingMode
;
499 public int getBlueComponent()
501 return (this._argbColor
) & 0xFF;
509 public int getClipHeight()
511 return this._clipHeight
;
519 public int getClipWidth()
521 return this._clipWidth
;
529 public int getClipX()
531 return this._clipX
- this._transX
;
539 public int getClipY()
541 return this._clipY
- this._transY
;
549 public int getColor()
551 return this._argbColor
& 0xFFFFFF;
559 public int getDisplayColor(int __rgb
)
561 throw Debugging
.todo();
562 /*// We can just ask the software graphics for the color we are using
563 // since it should hopefully match the hardware one.
564 return this.software.getDisplayColor(__rgb);*/
572 public Font
getFont()
582 public int getGrayScale()
584 return (((this._argbColor
>> 16) & 0xFF) +
585 ((this._argbColor
>> 8) & 0xFF) +
586 ((this._argbColor
) & 0xFF)) / 3;
594 public int getGreenComponent()
596 return (this._argbColor
>> 8) & 0xFF;
604 public int getRedComponent()
606 return (this._argbColor
>> 16) & 0xFF;
614 public int getStrokeStyle()
616 return this._strokeStyle
;
624 public int getTranslateX()
634 public int getTranslateY()
644 public void setAlpha(int __a
)
645 throws IllegalArgumentException
647 this.setAlphaColor(__a
,
648 this.getRedComponent(),
649 this.getGreenComponent(),
650 this.getBlueComponent());
658 public void setAlphaColor(int __argb
)
661 this._argbColor
= __argb
;
663 // Set on the hardware side
664 PencilShelf
.hardwareSetAlphaColor(this.hardware
, __argb
);
672 public void setAlphaColor(int __a
, int __r
, int __g
, int __b
)
673 throws IllegalArgumentException
675 /* {@squirreljme.error EB3t Color out of range. (Alpha; Red; Green;
677 if (__a
< 0 || __a
> 255 || __r
< 0 || __r
> 255 ||
678 __g
< 0 || __g
> 255 || __b
< 0 || __b
> 255)
679 throw new IllegalArgumentException(String
.format(
680 "EB3t %d %d %d %d", __a
, __r
, __g
, __b
));
683 this.setAlphaColor((__a
<< 24) | (__r
<< 16) | (__g
<< 8) | __b
);
691 public void setBlendingMode(int __m
)
692 throws IllegalArgumentException
694 /* {@squirreljme.error EB3u Invalid blending mode. (The mode)} */
695 if ((__m
!= Graphics
.SRC
&& __m
!= Graphics
.SRC_OVER
) ||
696 (__m
== Graphics
.SRC
&& !this.hasAlpha
))
697 throw new IllegalArgumentException("EB3u " + __m
);
700 this._blendingMode
= __m
;
702 // Forward to both software and hardware graphics
703 PencilShelf
.hardwareSetBlendingMode(this.hardware
, __m
);
711 public void setClip(int __x
, int __y
, int __w
, int __h
)
713 // Calculate the base clip coordinates
714 int startX
= __x
+ this._transX
;
715 int startY
= __y
+ this._transY
;
716 int endX
= startX
+ __w
;
717 int endY
= startY
+ __h
;
735 // Determine the bounds of all of these
736 int clipX
= Math
.min(this.surfaceW
, Math
.max(0, startX
));
737 int clipY
= Math
.min(this.surfaceH
, Math
.max(0, startY
));
738 int clipEndX
= Math
.min(this.surfaceW
, Math
.max(0, endX
));
739 int clipEndY
= Math
.min(this.surfaceH
, Math
.max(0, endY
));
744 this._clipWidth
= clipEndX
- clipX
;
745 this._clipHeight
= clipEndY
- clipY
;
747 // Forward to both software and hardware graphics
748 PencilShelf
.hardwareSetClip(this.hardware
, __x
, __y
, __w
, __h
);
755 @SuppressWarnings("MagicNumber")
757 public void setColor(int __rgb
)
759 this.setAlphaColor((this.getAlphaColor() & 0xFF_
000000) |
760 (__rgb
& 0x00_FFFFFF
));
768 public void setColor(int __r
, int __g
, int __b
)
769 throws IllegalArgumentException
771 this.setAlphaColor(this.getAlpha(), __r
, __g
, __b
);
779 public void setFont(Font __font
)
781 // Clearing the font?
783 __font
= Font
.getDefaultFont();
788 // Set font natively from the font details
789 PencilShelf
.hardwareSetFont(this.hardware
,
790 ((PencilFontProvider
)__font
).__squirreljmePencilFont());
798 public void setGrayScale(int __v
)
800 this.setAlphaColor(this.getAlpha(), __v
, __v
, __v
);
808 public void setStrokeStyle(int __style
)
809 throws IllegalArgumentException
811 /* {@squirreljme.error EB3v Illegal stroke style.} */
812 if (__style
!= Graphics
.SOLID
&& __style
!= Graphics
.DOTTED
)
813 throw new IllegalArgumentException("EB3v");
816 this._strokeStyle
= __style
;
818 // Forward to both software and hardware graphics
819 PencilShelf
.hardwareSetStrokeStyle(this.hardware
, __style
);
827 public void translate(int __x
, int __y
)
833 // Forward to both software and hardware graphics
834 PencilShelf
.hardwareTranslate(this.hardware
, __x
, __y
);
838 * Draws a direct RGB region of an image.
840 * @param __data The source buffer.
841 * @param __off The offset into the buffer.
842 * @param __scanlen The scanline length.
843 * @param __alpha Drawing with the alpha channel?
844 * @param __xsrc The source X position.
845 * @param __ysrc The source Y position.
846 * @param __wsrc The width of the source region.
847 * @param __hsrc The height of the source region.
848 * @param __trans Sprite translation and/or rotation, see {@link Sprite}.
849 * @param __xdest The destination X position, is translated.
850 * @param __ydest The destination Y position, is translated.
851 * @param __anch The anchor point.
852 * @param __wdest The destination width.
853 * @param __hdest The destination height.
854 * @param __origImgWidth Original image width.
855 * @param __origImgHeight Original image height.
856 * @throws NullPointerException On null arguments.
859 private void __drawRegion(int[] __data
, int __off
, int __scanlen
,
860 boolean __alpha
, int __xsrc
, int __ysrc
, int __wsrc
, int __hsrc
,
861 int __trans
, int __xdest
, int __ydest
, int __anch
, int __wdest
,
862 int __hdest
, int __origImgWidth
, int __origImgHeight
)
863 throws NullPointerException
866 throw new NullPointerException("NARG");
868 // Forward to the native region drawing method
869 PencilShelf
.hardwareDrawXRGB32Region(this.hardware
,
870 __data
, __off
, __scanlen
,
871 __alpha
, __xsrc
, __ysrc
, __wsrc
, __hsrc
,
872 __trans
, __xdest
, __ydest
, __anch
,
873 __wdest
, __hdest
, __origImgWidth
, __origImgHeight
);
877 * Creates a graphics that is capable of drawing on hardware if it is
878 * supported, but falling back to software level graphics.
880 * @param __pf The {@link UIPixelFormat} used for the draw.
881 * @param __bw The buffer width, this is the scanline width of the buffer.
882 * @param __bh The buffer height.
883 * @param __buf The target buffer to draw to, this is cast to the correct
885 * @param __pal The color palette, may be {@code null}.
886 * @param __sx Starting surface X coordinate.
887 * @param __sy Starting surface Y coordinate.
888 * @param __sw Surface width.
889 * @param __sh Surface height.
890 * @throws NullPointerException On null arguments.
893 public static Graphics
hardwareGraphics(int __pf
, int __bw
,
894 int __bh
, Object __buf
, int[] __pal
, int __sx
, int __sy
,
896 throws NullPointerException
898 return new PencilGraphics(__sw
, __sh
,
899 DisplayManager
.instance().scritch().hardwareGraphics(
900 __pf
, __bw
, __bh
, __buf
, __pal
, __sx
, __sy
, __sw
, __sh
));
904 * Initializes a new graphics interface.
906 * @param __hw The hardware graphics to use.
907 * @param __sw The surface width.
908 * @param __sh The surface height.
909 * @return The wrapped graphics.
910 * @throws NullPointerException On null arguments.
913 public static Graphics
of(ScritchPencilBracket __hw
, int __sw
, int __sh
)
914 throws NullPointerException
917 throw new NullPointerException("NARG");
919 return new PencilGraphics(__sw
, __sh
, __hw
);