001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026: package javax.microedition.m2g;
027:
028: import javax.microedition.lcdui.Graphics;
029:
030: import com.sun.perseus.model.DocumentNode;
031: import com.sun.perseus.model.DirtyAreaManager;
032:
033: import com.sun.perseus.j2d.RGB;
034: import com.sun.perseus.j2d.RenderGraphics;
035: import com.sun.perseus.j2d.Transform;
036:
037: import com.sun.pisces.GraphicsSurfaceDestination;
038: import com.sun.pisces.NativeSurface;
039: import com.sun.pisces.PiscesRenderer;
040: import com.sun.pisces.RendererBase;
041:
042: /**
043: *
044: */
045: public class ScalableGraphics {
046: /**
047: * Paint used to clear offscreens.
048: */
049: static final RGB CLEAR_PAINT = new RGB(0, 0, 0, 0);
050:
051: /**
052: * The Graphics object bound to this class
053: */
054: Graphics g = null;
055:
056: /**
057: * The GraphicsSurfaceDestination used to blit the native surface to the
058: * Graphics.
059: */
060: GraphicsSurfaceDestination gsd = null;
061:
062: /**
063: * The current quality mode.
064: */
065: int qualityMode = RENDERING_QUALITY_HIGH;
066:
067: /**
068: * The DirtyAreaManager used to minimize renderings.
069: */
070: DirtyAreaManager dirtyAreaManager = new DirtyAreaManager(null);
071:
072: /**
073: * The current transparency for rendering images.
074: */
075: float alpha = 1f;
076:
077: /**
078: * The offscreen buffer, used for temporary rendering of the
079: * image.
080: */
081: NativeSurface offscreen;
082:
083: /**
084: * The PiscesRenderer associated with the offscreen.
085: */
086: PiscesRenderer pr;
087:
088: /**
089: * The offscreen width.
090: */
091: int offscreenWidth;
092:
093: /**
094: * The offscreen height.
095: */
096: int offscreenHeight;
097:
098: /**
099: * The RenderGraphics used to draw to the PiscesRenderer
100: */
101: RenderGraphics rg;
102:
103: /**
104: *
105: */
106: public static final int RENDERING_QUALITY_LOW = 1;
107:
108: /**
109: *
110: */
111: public static final int RENDERING_QUALITY_HIGH = 2;
112:
113: /**
114: * Constructor
115: */
116: private ScalableGraphics() {
117: }
118:
119: /**
120: *
121: */
122: public void bindTarget(java.lang.Object target) {
123: if (target == null) {
124: throw new NullPointerException();
125: }
126:
127: if (!(target instanceof Graphics)) {
128: throw new IllegalArgumentException();
129: }
130:
131: if (g != null) {
132: throw new IllegalStateException("bindTarget(" + target
133: + ") with g : " + g);
134: }
135:
136: g = (Graphics) target;
137: gsd = new GraphicsSurfaceDestination(g);
138: }
139:
140: /**
141: *
142: */
143: public void releaseTarget() {
144: if (g == null) {
145: throw new IllegalStateException(
146: "releaseTarget() with null current target");
147: }
148:
149: g = null;
150: gsd = null;
151: }
152:
153: /**
154: *
155: */
156: public void render(int x, int y, ScalableImage image) {
157: if (image == null) {
158: throw new NullPointerException();
159: }
160:
161: if (g == null) {
162: throw new IllegalStateException();
163: }
164:
165: DocumentNode documentNode = (DocumentNode) ((SVGImage) image)
166: .getDocument();
167:
168: int vpw = image.getViewportWidth();
169: int vph = image.getViewportHeight();
170: checkOffscreen(vpw, vph);
171:
172: if (DirtyAreaManager.ON) {
173: dirtyAreaManager.setViewport(documentNode);
174: documentNode.setUpdateListener(dirtyAreaManager);
175: }
176:
177: rg.setRenderingQuality(qualityMode == RENDERING_QUALITY_HIGH);
178:
179: documentNode.sample(documentNode.getCurrentTime());
180: documentNode.applyAnimations();
181:
182: if (DirtyAreaManager.ON) {
183: dirtyAreaManager.refresh(documentNode, rg, CLEAR_PAINT);
184: } else {
185: // Clear offscreen and paint
186: pr.setColor(0, 0, 0, 0);
187: pr.setClip(0, 0, offscreenWidth, offscreenHeight);
188: pr.clearRect(0, 0, offscreenWidth, offscreenHeight);
189: documentNode.paint(rg);
190: }
191:
192: // Now, render the image with alpha.
193: gsd.drawSurface(offscreen, 0, 0, x, y, offscreenWidth,
194: offscreenHeight, alpha);
195: }
196:
197: /**
198: * Get an offscreen buffer big enough to draw a widht by height
199: * image.
200: *
201: * @param width the desired minimal width
202: * @param height the desired minimal height.
203: */
204: void checkOffscreen(final int width, final int height) {
205: int w = width;
206: int h = height;
207: if (w <= 0) {
208: w = 1;
209: }
210:
211: if (h <= 0) {
212: h = 1;
213: }
214:
215: if (offscreen == null || offscreenWidth != w
216: || offscreenHeight != h) {
217: offscreen = new NativeSurface(w, h);
218: offscreenWidth = w;
219: offscreenHeight = h;
220:
221: pr = new PiscesRenderer(offscreen, w, h, 0, w, 1,
222: RendererBase.TYPE_INT_ARGB);
223: rg = new RenderGraphics(pr, offscreenWidth, offscreenHeight);
224: }
225: }
226:
227: /**
228: *
229: */
230: public void setRenderingQuality(int mode) {
231: if (mode != RENDERING_QUALITY_LOW
232: && mode != RENDERING_QUALITY_HIGH) {
233: throw new IllegalArgumentException("" + mode);
234: }
235:
236: this .qualityMode = mode;
237: }
238:
239: /**
240: *
241: */
242: public void setTransparency(float alpha) {
243: if (alpha < 0f || alpha > 1f) {
244: throw new IllegalArgumentException();
245: }
246:
247: this .alpha = alpha;
248: }
249:
250: /**
251: *
252: */
253: public static ScalableGraphics createInstance() {
254: return new ScalableGraphics();
255: }
256:
257: }
|