diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
commit | edbf3b6af777b721cd2a1ef461947e51e88241e1 (patch) | |
tree | f09427b843b192cccf8c3b5328cb81dddf6489fa /awt/com | |
parent | d5193d9394c5e58176d7bcdf50ef017f8a3b9e1e (diff) | |
download | frameworks_native-edbf3b6af777b721cd2a1ef461947e51e88241e1.zip frameworks_native-edbf3b6af777b721cd2a1ef461947e51e88241e1.tar.gz frameworks_native-edbf3b6af777b721cd2a1ef461947e51e88241e1.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'awt/com')
-rw-r--r-- | awt/com/android/internal/awt/AndroidGraphics2D.java | 1354 | ||||
-rw-r--r-- | awt/com/android/internal/awt/AndroidGraphicsConfiguration.java | 96 | ||||
-rw-r--r-- | awt/com/android/internal/awt/AndroidGraphicsFactory.java | 87 | ||||
-rw-r--r-- | awt/com/android/internal/awt/AndroidImageDecoder.java | 274 | ||||
-rw-r--r-- | awt/com/android/internal/awt/AndroidJavaBlitter.java | 536 | ||||
-rw-r--r-- | awt/com/android/internal/awt/AndroidNativeEventQueue.java | 75 | ||||
-rw-r--r-- | awt/com/android/internal/awt/AndroidWTK.java | 88 | ||||
-rw-r--r-- | awt/com/android/internal/awt/AwtFactory.java | 52 | ||||
-rw-r--r-- | awt/com/android/internal/awt/ImageOutputStreamWrapper.java | 66 |
9 files changed, 2628 insertions, 0 deletions
diff --git a/awt/com/android/internal/awt/AndroidGraphics2D.java b/awt/com/android/internal/awt/AndroidGraphics2D.java new file mode 100644 index 0000000..9a8ae02 --- /dev/null +++ b/awt/com/android/internal/awt/AndroidGraphics2D.java @@ -0,0 +1,1354 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.awt; + +import com.android.internal.awt.AndroidGraphicsConfiguration; +import com.android.internal.graphics.NativeUtils; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; +import java.awt.geom.GeneralPath; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.PathIterator; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.DataBuffer; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.WritableRaster; +import java.awt.image.renderable.RenderableImage; +import java.text.AttributedCharacterIterator; +import java.util.Map; + +import org.apache.harmony.awt.gl.ImageSurface; +import org.apache.harmony.awt.gl.MultiRectArea; +import org.apache.harmony.awt.gl.Surface; +import org.apache.harmony.awt.gl.font.AndroidGlyphVector; +import org.apache.harmony.awt.gl.font.FontMetricsImpl; +import org.apache.harmony.awt.gl.image.OffscreenImage; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Path; + +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Region; +import android.graphics.Typeface; +import android.graphics.PixelXorXfermode; +import android.view.Display; +import android.view.WindowManager; +import android.content.Context; + +public class AndroidGraphics2D extends Graphics2D { + + private int displayWidth, displayHeight; + + protected Surface dstSurf = null; + protected MultiRectArea clip = null; + + protected Composite composite = AlphaComposite.SrcOver; + protected AffineTransform transform = new AffineTransform(); + + private static AndroidGraphics2D mAg; + private static Canvas mC; + + // Android Paint + public static Paint mP; + + private static java.awt.Font mFnt; + + // Cached Matrix + public static Matrix mM; + private static FontMetrics mFm; + private static RenderingHints mRh; + private static Color mBc; + + private Area mCurrClip; + + public final static double RAD_360 = Math.PI / 180 * 360; + + // Image drawing + private AndroidJavaBlitter blitter; + private DirectColorModel cm; + private SinglePixelPackedSampleModel sm; + private WritableRaster wr; + + + public static AndroidGraphics2D getInstance() { + if (mAg == null) { + throw new RuntimeException("AndroidGraphics2D not instantiated!"); + } + return mAg; + } + + public static AndroidGraphics2D getInstance(Context ctx, Canvas c, Paint p) { + if (c == null || ctx == null) { + throw new RuntimeException( + "Illegal argument, Canvas cannot be null!"); + } + mAg = new AndroidGraphics2D(ctx, c, p); + return mAg; + } + + private AndroidGraphics2D(Context ctx, Canvas c, Paint p) { + super(); + mC = c; + mP = p; + mM = new Matrix(); + mM.reset(); + mM = mC.getMatrix(); + Rect r = mC.getClipBounds(); + int cl[] = {-1, r.top, r.left, -2, r.top, r.right, -2, r.bottom, r.right, -2, r.bottom, r.left}; + mCurrClip = new Area(createShape(cl)); + if(ctx != null) { + WindowManager wm = (WindowManager)ctx.getSystemService(Context.WINDOW_SERVICE); + Display d = wm.getDefaultDisplay(); + displayWidth = d.getWidth(); + displayHeight = d.getHeight(); + } + blitter = new AndroidJavaBlitter(c); + cm = new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000); + sm = new SinglePixelPackedSampleModel( + DataBuffer.TYPE_INT, displayWidth, displayHeight, cm.getMasks()); + wr = Raster.createWritableRaster(sm, null); + dstSurf = new ImageSurface(cm, wr); + } + + @Override + public void addRenderingHints(Map<?, ?> hints) { + if (mRh == null) { + mRh = (RenderingHints) hints; + } + mRh.add((RenderingHints) hints); + } + + public float[] getMatrix() { + float[] f = new float[9]; + mC.getMatrix().getValues(f); + return f; + } + + /** + * + * @return a Matrix in Android format + */ + public float[] getInverseMatrix() { + AffineTransform af = new AffineTransform(createAWTMatrix(getMatrix())); + try { + af = af.createInverse(); + } catch (NoninvertibleTransformException e) { + } + return createMatrix(af); + } + + private Path getPath(Shape s) { + Path path = new Path(); + PathIterator pi = s.getPathIterator(null); + while (pi.isDone() == false) { + getCurrentSegment(pi, path); + pi.next(); + } + return path; + } + + private void getCurrentSegment(PathIterator pi, Path path) { + float[] coordinates = new float[6]; + int type = pi.currentSegment(coordinates); + switch (type) { + case PathIterator.SEG_MOVETO: + path.moveTo(coordinates[0], coordinates[1]); + break; + case PathIterator.SEG_LINETO: + path.lineTo(coordinates[0], coordinates[1]); + break; + case PathIterator.SEG_QUADTO: + path.quadTo(coordinates[0], coordinates[1], coordinates[2], + coordinates[3]); + break; + case PathIterator.SEG_CUBICTO: + path.cubicTo(coordinates[0], coordinates[1], coordinates[2], + coordinates[3], coordinates[4], coordinates[5]); + break; + case PathIterator.SEG_CLOSE: + path.close(); + break; + default: + break; + } + } + + private Shape createShape(int[] arr) { + Shape s = new GeneralPath(); + for(int i = 0; i < arr.length; i++) { + int type = arr[i]; + switch (type) { + case -1: + //MOVETO + ((GeneralPath)s).moveTo(arr[++i], arr[++i]); + break; + case -2: + //LINETO + ((GeneralPath)s).lineTo(arr[++i], arr[++i]); + break; + case -3: + //QUADTO + ((GeneralPath)s).quadTo(arr[++i], arr[++i], arr[++i], + arr[++i]); + break; + case -4: + //CUBICTO + ((GeneralPath)s).curveTo(arr[++i], arr[++i], arr[++i], + arr[++i], arr[++i], arr[++i]); + break; + case -5: + //CLOSE + return s; + default: + break; + } + } + return s; + } + /* + public int[] getPixels() { + return mC.getPixels(); + }*/ + + public static float getRadian(float degree) { + return (float) ((Math.PI / 180) * degree); + } + + private Shape getShape() { + return null; + } + + public static float getDegree(float radian) { + return (float) ((180 / Math.PI) * radian); + } + + /* + * Degree in radian + */ + public static float getEllipsisX(float degree, float princAxis) { + return (float) Math.cos(degree) * princAxis; + } + + public static float getEllipsisY(float degree, float conAxis) { + return (float) Math.sin(degree) * conAxis; + } + + @Override + public void clip(Shape s) { + mC.clipPath(getPath(s)); + } + + public void setCanvas(Canvas c) { + mC = c; + } + + @Override + public void draw(Shape s) { + if (mP == null) { + mP = new Paint(); + } + Paint.Style tmp = mP.getStyle(); + mP.setStyle(Paint.Style.STROKE); + mC.drawPath(getPath(s), mP); + mP.setStyle(tmp); + } +/* + private ArrayList getSegments(Shape s) { + ArrayList arr = new ArrayList(); + PathIterator pi = s.getPathIterator(null); + while (pi.isDone() == false) { + getCurrentSegment(pi, arr); + pi.next(); + } + return arr; + } + + private void getCurrentSegment(PathIterator pi, ArrayList arr) { + float[] coordinates = new float[6]; + int type = pi.currentSegment(coordinates); + switch (type) { + case PathIterator.SEG_MOVETO: + arr.add(new Integer(-1)); + break; + case PathIterator.SEG_LINETO: + arr.add(new Integer(-2)); + break; + case PathIterator.SEG_QUADTO: + arr.add(new Integer(-3)); + break; + case PathIterator.SEG_CUBICTO: + arr.add(new Integer(-4)); + break; + case PathIterator.SEG_CLOSE: + arr.add(new Integer(-5)); + break; + default: + break; + } + } +*/ + /* + * Convenience method, not standard AWT + */ + public void draw(Path s) { + if (mP == null) { + mP = new Paint(); + } + Paint.Style tmp = mP.getStyle(); + mP.setStyle(Paint.Style.STROKE); + s.transform(mM); + mC.drawPath(s, mP); + mP.setStyle(tmp); + } + + @Override + public void drawGlyphVector(GlyphVector g, float x, float y) { + // TODO draw at x, y + // draw(g.getOutline()); + /* + Matrix matrix = new Matrix(); + matrix.setTranslate(x, y); + Path pth = getPath(g.getOutline()); + pth.transform(matrix); + draw(pth); + */ + Path path = new Path(); + char[] c = ((AndroidGlyphVector)g).getGlyphs(); + mP.getTextPath(c, 0, c.length, x, y, path); + mC.drawPath(path, mP); + } + + @Override + public void drawRenderableImage(RenderableImage img, AffineTransform xform) { + throw new RuntimeException("Not implemented!"); + } + + @Override + public void drawRenderedImage(RenderedImage img, AffineTransform xform) { + throw new RuntimeException("Not implemented!"); + } + + @Override + public void drawString(AttributedCharacterIterator iterator, float x, + float y) { + throw new RuntimeException("AttributedCharacterIterator not supported!"); + + } + + @Override + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + throw new RuntimeException("AttributedCharacterIterator not supported!"); + + } + + @Override + public void drawString(String s, float x, float y) { + if (mP == null) { + mP = new Paint(); + } + Paint.Style tmp = mP.getStyle(); + + mP.setStyle(Paint.Style.FILL); + Path pth = new Path(); + mP.getTextPath(s, 0, s.length(), x, y, pth); + mC.drawPath(pth, mP); + mP.setStyle(tmp); + } + + @Override + public void drawString(String str, int x, int y) { + if (mP == null) { + mP = new Paint(); + } + Paint.Style tmp = mP.getStyle(); + mP.setStrokeWidth(0); + + mC.drawText(str.toCharArray(), 0, str.toCharArray().length, x, y, + mP); + mP.setStyle(tmp); + } + + @Override + public void fill(Shape s) { + if (mP == null) { + mP = new Paint(); + } + Paint.Style tmp = mP.getStyle(); + mP.setStyle(Paint.Style.FILL); + mC.drawPath(getPath(s), mP); + mP.setStyle(tmp); + } + + @Override + public Color getBackground() { + return mBc; + } + + @Override + public Composite getComposite() { + throw new RuntimeException("Composite not implemented!"); + } + + @Override + public GraphicsConfiguration getDeviceConfiguration() { + return new AndroidGraphicsConfiguration(); + } + + @Override + public FontRenderContext getFontRenderContext() { + return new FontRenderContext(getTransform(), mP.isAntiAlias(), true); + } + + @Override + public java.awt.Paint getPaint() { + throw new RuntimeException("AWT Paint not implemented in Android!"); + } + + public static Canvas getAndroidCanvas() { + return mC; + } + + public static Paint getAndroidPaint() { + return mP; + } + + @Override + public RenderingHints getRenderingHints() { + return mRh; + } + + @Override + public Stroke getStroke() { + if (mP != null) { + return new BasicStroke(mP.getStrokeWidth(), mP.getStrokeCap() + .ordinal(), mP.getStrokeJoin().ordinal()); + } + return null; + } + + @Override + public AffineTransform getTransform() { + return new AffineTransform(createAWTMatrix(getMatrix())); + } + + @Override + public boolean hit(Rectangle rect, Shape s, boolean onStroke) { + // ???AWT TODO check if on stroke + return s.intersects(rect.getX(), rect.getY(), rect.getWidth(), rect + .getHeight()); + } + + @Override + public void rotate(double theta) { + mM.preRotate((float) AndroidGraphics2D + .getDegree((float) (RAD_360 - theta))); + mC.concat(mM); + } + + @Override + public void rotate(double theta, double x, double y) { + mM.preRotate((float) AndroidGraphics2D.getDegree((float) theta), + (float) x, (float) y); + mC.concat(mM); + } + + @Override + public void scale(double sx, double sy) { + mM.setScale((float) sx, (float) sy); + mC.concat(mM); + } + + @Override + public void setBackground(Color color) { + mBc = color; + mC.clipRect(new Rect(0, 0, mC.getWidth(), mC.getHeight())); + // TODO don't limit to current clip + mC.drawARGB(color.getAlpha(), color.getRed(), color.getGreen(), color + .getBlue()); + } + + @Override + public void setComposite(Composite comp) { + throw new RuntimeException("Composite not implemented!"); + } + + public void setSpaint(Paint paint) { + mP = paint; + } + + @Override + public void setPaint(java.awt.Paint paint) { + setColor((Color)paint); + } + + @Override + public Object getRenderingHint(RenderingHints.Key key) { + if (mRh == null) { + return null; + } + return mRh.get(key); + } + + @Override + public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { + if (mRh == null) { + mRh = new RenderingHints(hintKey, hintValue); + } else { + mRh.put(hintKey, hintValue); + } + applyHints(); + } + + @Override + public void setRenderingHints(Map<?, ?> hints) { + mRh = (RenderingHints) hints; + applyHints(); + } + + private void applyHints() { + Object o; + + // TODO do something like this: + /* + * Set s = mRh.keySet(); Iterator it = s.iterator(); while(it.hasNext()) { + * o = it.next(); } + */ + + // ///////////////////////////////////////////////////////////////////// + // not supported in skia + /* + * o = mRh.get(RenderingHints.KEY_ALPHA_INTERPOLATION); if + * (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) { } else + * if (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) { } + * else if (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) { } + * + * o = mRh.get(RenderingHints.KEY_COLOR_RENDERING); if + * (o.equals(RenderingHints.VALUE_COLOR_RENDER_DEFAULT)) { } else if + * (o.equals(RenderingHints.VALUE_COLOR_RENDER_QUALITY)) { } else if + * (o.equals(RenderingHints.VALUE_COLOR_RENDER_SPEED)) { } + * + * o = mRh.get(RenderingHints.KEY_DITHERING); if + * (o.equals(RenderingHints.VALUE_DITHER_DEFAULT)) { } else if + * (o.equals(RenderingHints.VALUE_DITHER_DISABLE)) { } else if + * (o.equals(RenderingHints.VALUE_DITHER_ENABLE)) { } + * + * o = mRh.get(RenderingHints.KEY_FRACTIONALMETRICS); if + * (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT)) { } else + * if (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_OFF)) { } else if + * (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_ON)) { } + * + * o = mRh.get(RenderingHints.KEY_INTERPOLATION); if + * (o.equals(RenderingHints.VALUE_INTERPOLATION_BICUBIC)) { } else if + * (o.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) { } else if + * (o .equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) { } + * + * o = mRh.get(RenderingHints.KEY_RENDERING); if + * (o.equals(RenderingHints.VALUE_RENDER_DEFAULT)) { } else if + * (o.equals(RenderingHints.VALUE_RENDER_QUALITY)) { } else if + * (o.equals(RenderingHints.VALUE_RENDER_SPEED)) { } + * + * o = mRh.get(RenderingHints.KEY_STROKE_CONTROL); if + * (o.equals(RenderingHints.VALUE_STROKE_DEFAULT)) { } else if + * (o.equals(RenderingHints.VALUE_STROKE_NORMALIZE)) { } else if + * (o.equals(RenderingHints.VALUE_STROKE_PURE)) { } + */ + + o = mRh.get(RenderingHints.KEY_ANTIALIASING); + if (o != null) { + if (o.equals(RenderingHints.VALUE_ANTIALIAS_DEFAULT)) { + mP.setAntiAlias(false); + } else if (o.equals(RenderingHints.VALUE_ANTIALIAS_OFF)) { + mP.setAntiAlias(false); + } else if (o.equals(RenderingHints.VALUE_ANTIALIAS_ON)) { + mP.setAntiAlias(true); + } + } + + o = mRh.get(RenderingHints.KEY_TEXT_ANTIALIASING); + if (o != null) { + if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT)) { + mP.setAntiAlias(false); + } else if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)) { + mP.setAntiAlias(false); + } else if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_ON)) { + mP.setAntiAlias(true); + } + } + } + + @Override + public void setStroke(Stroke s) { + if (mP == null) { + mP = new Paint(); + } + BasicStroke bs = (BasicStroke) s; + mP.setStyle(Paint.Style.STROKE); + mP.setStrokeWidth(bs.getLineWidth()); + + int cap = bs.getEndCap(); + if (cap == 0) { + mP.setStrokeCap(Paint.Cap.BUTT); + } else if (cap == 1) { + mP.setStrokeCap(Paint.Cap.ROUND); + } else if (cap == 2) { + mP.setStrokeCap(Paint.Cap.SQUARE); + } + + int join = bs.getLineJoin(); + if (join == 0) { + mP.setStrokeJoin(Paint.Join.MITER); + } else if (join == 1) { + mP.setStrokeJoin(Paint.Join.ROUND); + } else if (join == 2) { + mP.setStrokeJoin(Paint.Join.BEVEL); + } + } + + public static float[] createMatrix(AffineTransform Tx) { + double[] at = new double[9]; + Tx.getMatrix(at); + float[] f = new float[at.length]; + f[0] = (float) at[0]; + f[1] = (float) at[2]; + f[2] = (float) at[4]; + f[3] = (float) at[1]; + f[4] = (float) at[3]; + f[5] = (float) at[5]; + f[6] = 0; + f[7] = 0; + f[8] = 1; + return f; + } + + private float[] createAWTMatrix(float[] matrix) { + float[] at = new float[9]; + at[0] = matrix[0]; + at[1] = matrix[3]; + at[2] = matrix[1]; + at[3] = matrix[4]; + at[4] = matrix[2]; + at[5] = matrix[5]; + at[6] = 0; + at[7] = 0; + at[8] = 1; + return at; + } + + public static Matrix createMatrixObj(AffineTransform Tx) { + Matrix m = new Matrix(); + m.reset(); + m.setValues(createMatrix(Tx)); + return m; + } + + @Override + public void setTransform(AffineTransform Tx) { + mM.reset(); + /* + * if(Tx.isIdentity()) { mM = new Matrix(); } + */ + mM.setValues(createMatrix(Tx)); + Matrix m = new Matrix(); + m.setValues(getInverseMatrix()); + mC.concat(m); + mC.concat(mM); + } + + @Override + public void shear(double shx, double shy) { + mM.setSkew((float) shx, (float) shy); + mC.concat(mM); + } + + @Override + public void transform(AffineTransform Tx) { + Matrix m = new Matrix(); + m.setValues(createMatrix(Tx)); + mC.concat(m); + } + + @Override + public void translate(double tx, double ty) { + mM.setTranslate((float) tx, (float) ty); + mC.concat(mM); + } + + @Override + public void translate(int x, int y) { + mM.setTranslate((float) x, (float) y); + mC.concat(mM); + } + + @Override + public void clearRect(int x, int y, int width, int height) { + mC.clipRect(x, y, x + width, y + height); + if (mBc != null) { + mC.drawARGB(mBc.getAlpha(), mBc.getBlue(), mBc.getGreen(), mBc + .getRed()); + } else { + mC.drawARGB(0xff, 0xff, 0xff, 0xff); + } + } + + @Override + public void clipRect(int x, int y, int width, int height) { + int cl[] = {-1, x, y, -2, x, y + width, -2, x + height, y + width, -2, x + height, y}; + Shape shp = createShape(cl); + mCurrClip.intersect(new Area(shp)); + mC.clipRect(new Rect(x, y, x + width, y + height), Region.Op.INTERSECT); + } + + @Override + public void copyArea(int sx, int sy, int width, int height, int dx, int dy) { + copyArea(mC, sx, sy, width + dx, height + dy, dx, dy); + } + + @Override + public Graphics create() { + return this; + } + + @Override + public void dispose() { + mC = null; + mP = null; + } + + @Override + public void drawArc(int x, int y, int width, int height, int sa, int ea) { + if (mP == null) { + mP = new Paint(); + } + mP.setStrokeWidth(0); + mC.drawArc(new RectF(x, y, x + width, y + height), 360 - (ea + sa), + ea, true, mP); + } + + + // ???AWT: only used for debuging, delete in final version + public void drawBitmap(Bitmap bm, float x, float y, Paint p) { + mC.drawBitmap(bm, x, y, null); + } + + @Override + public boolean drawImage(Image image, int x, int y, Color bgcolor, + ImageObserver imageObserver) { + + if(image == null) { + return true; + } + + boolean done = false; + boolean somebits = false; + Surface srcSurf = null; + if(image instanceof OffscreenImage){ + OffscreenImage oi = (OffscreenImage) image; + if((oi.getState() & ImageObserver.ERROR) != 0) { + return false; + } + done = oi.prepareImage(imageObserver); + somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0; + srcSurf = oi.getImageSurface(); + }else{ + done = true; + srcSurf = Surface.getImageSurface(image); + } + + if(done || somebits) { + int w = srcSurf.getWidth(); + int h = srcSurf.getHeight(); + + blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, (AffineTransform) transform.clone(), + composite, bgcolor, clip); + } + return done; + } + + @Override + public boolean drawImage(Image image, int x, int y, ImageObserver imageObserver) { + return drawImage(image, x, y, null, imageObserver); + } + + @Override + public boolean drawImage(Image image, int x, int y, int width, int height, + Color bgcolor, ImageObserver imageObserver) { + + if(image == null) { + return true; + } + if(width == 0 || height == 0) { + return true; + } + + boolean done = false; + boolean somebits = false; + Surface srcSurf = null; + + if(image instanceof OffscreenImage){ + OffscreenImage oi = (OffscreenImage) image; + if((oi.getState() & ImageObserver.ERROR) != 0) { + return false; + } + done = oi.prepareImage(imageObserver); + somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0; + srcSurf = oi.getImageSurface(); + }else{ + done = true; + srcSurf = Surface.getImageSurface(image); + } + + if(done || somebits) { + int w = srcSurf.getWidth(); + int h = srcSurf.getHeight(); + if(w == width && h == height){ + blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, + (AffineTransform) transform.clone(), + composite, bgcolor, clip); + }else{ + AffineTransform xform = new AffineTransform(); + xform.setToScale((float)width / w, (float)height / h); + blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, + (AffineTransform) transform.clone(), + xform, composite, bgcolor, clip); + } + } + return done; + } + + @Override + public boolean drawImage(Image image, int x, int y, int width, int height, + ImageObserver imageObserver) { + return drawImage(image, x, y, width, height, null, imageObserver); + } + + @Override + public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, Color bgcolor, + ImageObserver imageObserver) { + + if(image == null) { + return true; + } + if(dx1 == dx2 || dy1 == dy2 || sx1 == sx2 || sy1 == sy2) { + return true; + } + + boolean done = false; + boolean somebits = false; + Surface srcSurf = null; + if(image instanceof OffscreenImage){ + OffscreenImage oi = (OffscreenImage) image; + if((oi.getState() & ImageObserver.ERROR) != 0) { + return false; + } + done = oi.prepareImage(imageObserver); + somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0; + srcSurf = oi.getImageSurface(); + }else{ + done = true; + srcSurf = Surface.getImageSurface(image); + } + + if(done || somebits) { + + int dstX = dx1; + int dstY = dy1; + int srcX = sx1; + int srcY = sy1; + + int dstW = dx2 - dx1; + int dstH = dy2 - dy1; + int srcW = sx2 - sx1; + int srcH = sy2 - sy1; + + if(srcW == dstW && srcH == dstH){ + blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH, + (AffineTransform) transform.clone(), + composite, bgcolor, clip); + }else{ + AffineTransform xform = new AffineTransform(); + xform.setToScale((float)dstW / srcW, (float)dstH / srcH); + blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH, + (AffineTransform) transform.clone(), + xform, composite, bgcolor, clip); + } + } + return done; + } + + @Override + public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, ImageObserver imageObserver) { + + return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, + imageObserver); + } + + @Override + public void drawImage(BufferedImage bufImage, BufferedImageOp op, + int x, int y) { + + if(bufImage == null) { + return; + } + + if(op == null) { + drawImage(bufImage, x, y, null); + } else if(op instanceof AffineTransformOp){ + AffineTransformOp atop = (AffineTransformOp) op; + AffineTransform xform = atop.getTransform(); + Surface srcSurf = Surface.getImageSurface(bufImage); + int w = srcSurf.getWidth(); + int h = srcSurf.getHeight(); + blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, + (AffineTransform) transform.clone(), xform, + composite, null, clip); + } else { + bufImage = op.filter(bufImage, null); + Surface srcSurf = Surface.getImageSurface(bufImage); + int w = srcSurf.getWidth(); + int h = srcSurf.getHeight(); + blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, + (AffineTransform) transform.clone(), + composite, null, clip); + } + } + + @Override + public boolean drawImage(Image image, AffineTransform trans, + ImageObserver imageObserver) { + + if(image == null) { + return true; + } + if(trans == null || trans.isIdentity()) { + return drawImage(image, 0, 0, imageObserver); + } + + boolean done = false; + boolean somebits = false; + Surface srcSurf = null; + if(image instanceof OffscreenImage){ + OffscreenImage oi = (OffscreenImage) image; + if((oi.getState() & ImageObserver.ERROR) != 0) { + return false; + } + done = oi.prepareImage(imageObserver); + somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0; + srcSurf = oi.getImageSurface(); + }else{ + done = true; + srcSurf = Surface.getImageSurface(image); + } + + if(done || somebits) { + int w = srcSurf.getWidth(); + int h = srcSurf.getHeight(); + AffineTransform xform = (AffineTransform) transform.clone(); + xform.concatenate(trans); + blitter.blit(0, 0, srcSurf, 0, 0, dstSurf, w, h, xform, composite, + null, clip); + } + return done; + } + + @Override + public void drawLine(int x1, int y1, int x2, int y2) { + if (mP == null) { + mP = new Paint(); + } + mC.drawLine(x1, y1, x2, y2, mP); + } + + @Override + public void drawOval(int x, int y, int width, int height) { + if (mP == null) { + mP = new Paint(); + } + mP.setStyle(Paint.Style.STROKE); + mC.drawOval(new RectF(x, y, x + width, y + height), mP); + } + + @Override + public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) { + if (mP == null) { + mP = new Paint(); + } + mC.drawLine(xpoints[npoints - 1], ypoints[npoints - 1], xpoints[0], + ypoints[0], mP); + for (int i = 0; i < npoints - 1; i++) { + mC.drawLine(xpoints[i], ypoints[i], xpoints[i + 1], + ypoints[i + 1], mP); + } + } + + @Override + public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) { + for (int i = 0; i < npoints - 1; i++) { + drawLine(xpoints[i], ypoints[i], xpoints[i + 1], ypoints[i + 1]); + } + + } + + @Override + public void drawRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) { + if (mP == null) { + mP = new Paint(); + } + mC.drawRoundRect(new RectF(x, y, width, height), arcWidth, + arcHeight, mP); + } + + @Override + public void fillArc(int x, int y, int width, int height, int sa, int ea) { + if (mP == null) { + mP = new Paint(); + } + + Paint.Style tmp = mP.getStyle(); + mP.setStyle(Paint.Style.FILL_AND_STROKE); + mC.drawArc(new RectF(x, y, x + width, y + height), 360 - (sa + ea), + ea, true, mP); + + mP.setStyle(tmp); + } + + @Override + public void fillOval(int x, int y, int width, int height) { + if (mP == null) { + mP = new Paint(); + } + Paint.Style tmp = mP.getStyle(); + mP.setStyle(Paint.Style.FILL); + mC.drawOval(new RectF(x, y, x + width, y + height), mP); + mP.setStyle(tmp); + } + + @Override + public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) { + if (mP == null) { + mP = new Paint(); + } + Paint.Style tmp = mP.getStyle(); + mC.save(Canvas.CLIP_SAVE_FLAG); + + mP.setStyle(Paint.Style.FILL); + + GeneralPath filledPolygon = new GeneralPath( + GeneralPath.WIND_EVEN_ODD, npoints); + filledPolygon.moveTo(xpoints[0], ypoints[0]); + for (int index = 1; index < xpoints.length; index++) { + filledPolygon.lineTo(xpoints[index], ypoints[index]); + } + filledPolygon.closePath(); + Path path = getPath(filledPolygon); + mC.clipPath(path); + mC.drawPath(path, mP); + + mP.setStyle(tmp); + mC.restore(); + } + + @Override + public void fillRect(int x, int y, int width, int height) { + if (mP == null) { + mP = new Paint(); + } + Paint.Style tmp = mP.getStyle(); + mP.setStyle(Paint.Style.FILL); + mC.drawRect(new Rect(x, y, x + width, y + height), mP); + mP.setStyle(tmp); + } + + @Override + public void drawRect(int x, int y, int width, int height) { + int[] xpoints = { x, x, x + width, x + width }; + int[] ypoints = { y, y + height, y + height, y }; + drawPolygon(xpoints, ypoints, 4); + } + + @Override + public void fillRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) { + if (mP == null) { + mP = new Paint(); + } + mP.setStyle(Paint.Style.FILL); + mC.drawRoundRect(new RectF(x, y, x + width, y + height), arcWidth, + arcHeight, mP); + } + + @Override + public Shape getClip() { + return mCurrClip; + } + + @Override + public Rectangle getClipBounds() { + Rect r = mC.getClipBounds(); + return new Rectangle(r.left, r.top, r.width(), r.height()); + } + + @Override + public Color getColor() { + if (mP != null) { + return new Color(mP.getColor()); + } + return null; + } + + @Override + public Font getFont() { + return mFnt; + } + + @Override + public FontMetrics getFontMetrics(Font font) { + mFm = new FontMetricsImpl(font); + return mFm; + } + + @Override + public void setClip(int x, int y, int width, int height) { + int cl[] = {-1, x, y, -2, x, y + width, -2, x + height, y + width, -2, x + height, y}; + mCurrClip = new Area(createShape(cl)); + mC.clipRect(x, y, x + width, y + height, Region.Op.REPLACE); + + } + + @Override + public void setClip(Shape clip) { + mCurrClip = new Area(clip); + mC.clipPath(getPath(clip), Region.Op.REPLACE); + } + + @Override + public void setColor(Color c) { + if (mP == null) { + mP = new Paint(); + } + mP.setColor(c.getRGB()); + } + + /** + * Font mapping: + * + * Family: + * + * Android AWT + * ------------------------------------- + * serif Serif / TimesRoman + * sans-serif SansSerif / Helvetica + * monospace Monospaced / Courier + * + * Style: + * + * Android AWT + * ------------------------------------- + * normal Plain + * bold bold + * italic italic + * + */ + @Override + public void setFont(Font font) { + if (font == null) { + return; + } + if (mP == null) { + mP = new Paint(); + } + + mFnt = font; + Typeface tf = null; + int sty = font.getStyle(); + String nam = font.getName(); + String aF = ""; + if (nam != null) { + if (nam.equalsIgnoreCase("Serif") + || nam.equalsIgnoreCase("TimesRoman")) { + aF = "serif"; + } else if (nam.equalsIgnoreCase("SansSerif") + || nam.equalsIgnoreCase("Helvetica")) { + aF = "sans-serif"; + } else if (nam.equalsIgnoreCase("Monospaced") + || nam.equalsIgnoreCase("Courier")) { + aF = "monospace"; + } + } + + switch (sty) { + case Font.PLAIN: + tf = Typeface.create(aF, Typeface.NORMAL); + break; + case Font.BOLD: + tf = Typeface.create(aF, Typeface.BOLD); + break; + case Font.ITALIC: + tf = Typeface.create(aF, Typeface.ITALIC); + break; + case Font.BOLD | Font.ITALIC: + tf = Typeface.create(aF, Typeface.BOLD_ITALIC); + break; + default: + tf = Typeface.DEFAULT; + } + + mP.setTextSize(font.getSize()); + mP.setTypeface(tf); + } + + @Override + public void drawBytes(byte[] data, int offset, int length, int x, int y) { + drawString(new String(data, offset, length), x, y); + } + + @Override + public void drawPolygon(Polygon p) { + drawPolygon(p.xpoints, p.ypoints, p.npoints); + } + + @Override + public void fillPolygon(Polygon p) { + fillPolygon(p.xpoints, p.ypoints, p.npoints); + } + + @Override + public Rectangle getClipBounds(Rectangle r) { + Shape clip = getClip(); + if (clip != null) { + Rectangle b = clip.getBounds(); + r.x = b.x; + r.y = b.y; + r.width = b.width; + r.height = b.height; + } + return r; + } + + @Override + public boolean hitClip(int x, int y, int width, int height) { + return getClipBounds().intersects(new Rectangle(x, y, width, height)); + } + + @Override + public void drawChars(char[] data, int offset, int length, int x, int y) { + mC.drawText(data, offset, length, x, y, mP); + } + + @Override + public void setPaintMode() { + if (mP == null) { + mP = new Paint(); + } + mP.setXfermode(null); + } + + @Override + public void setXORMode(Color color) { + if (mP == null) { + mP = new Paint(); + } + mP.setXfermode(new PixelXorXfermode(color.getRGB())); + } + + @Override + public void fill3DRect(int x, int y, int width, int height, boolean raised) { + Color color = getColor(); + Color colorUp, colorDown; + if (raised) { + colorUp = color.brighter(); + colorDown = color.darker(); + setColor(color); + } else { + colorUp = color.darker(); + colorDown = color.brighter(); + setColor(colorUp); + } + + width--; + height--; + fillRect(x+1, y+1, width-1, height-1); + + setColor(colorUp); + fillRect(x, y, width, 1); + fillRect(x, y+1, 1, height); + + setColor(colorDown); + fillRect(x+width, y, 1, height); + fillRect(x+1, y+height, width, 1); + } + + @Override + public void draw3DRect(int x, int y, int width, int height, boolean raised) { + Color color = getColor(); + Color colorUp, colorDown; + if (raised) { + colorUp = color.brighter(); + colorDown = color.darker(); + } else { + colorUp = color.darker(); + colorDown = color.brighter(); + } + + setColor(colorUp); + fillRect(x, y, width, 1); + fillRect(x, y+1, 1, height); + + setColor(colorDown); + fillRect(x+width, y, 1, height); + fillRect(x+1, y+height, width, 1); + } + + public void copyArea(Canvas canvas, int sx, int sy, int width, int height, int dx, int dy) { + sx += getTransform().getTranslateX(); + sy += getTransform().getTranslateY(); + + NativeUtils.nativeScrollRect(canvas, + new Rect(sx, sy, sx + width, sy + height), + dx, dy); + } +} diff --git a/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java b/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java new file mode 100644 index 0000000..0c888cd --- /dev/null +++ b/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java @@ -0,0 +1,96 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.awt; + +import com.android.internal.awt.AndroidGraphics2D; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.VolatileImage; + +import android.graphics.Canvas; + +public class AndroidGraphicsConfiguration extends GraphicsConfiguration { + + @Override + public BufferedImage createCompatibleImage(int width, int height) { + // TODO Auto-generated method stub + return null; + } + + @Override + public BufferedImage createCompatibleImage(int width, int height, + int transparency) { + // TODO Auto-generated method stub + return null; + } + + @Override + public VolatileImage createCompatibleVolatileImage(int width, int height) { + // TODO Auto-generated method stub + return null; + } + + @Override + public VolatileImage createCompatibleVolatileImage(int width, int height, + int transparency) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Rectangle getBounds() { + Canvas c = AndroidGraphics2D.getAndroidCanvas(); + if(c != null) + return new Rectangle(0, 0, c.getWidth(), c.getHeight()); + return null; + } + + @Override + public ColorModel getColorModel() { + // TODO Auto-generated method stub + return null; + } + + @Override + public ColorModel getColorModel(int transparency) { + // TODO Auto-generated method stub + return null; + } + + @Override + public AffineTransform getDefaultTransform() { + return new AffineTransform(); + } + + @Override + public GraphicsDevice getDevice() { + // TODO Auto-generated method stub + return null; + } + + @Override + public AffineTransform getNormalizingTransform() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/awt/com/android/internal/awt/AndroidGraphicsFactory.java b/awt/com/android/internal/awt/AndroidGraphicsFactory.java new file mode 100644 index 0000000..ca255b5 --- /dev/null +++ b/awt/com/android/internal/awt/AndroidGraphicsFactory.java @@ -0,0 +1,87 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.awt; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; +import java.awt.peer.FontPeer; + +import org.apache.harmony.awt.gl.MultiRectArea; +import org.apache.harmony.awt.gl.font.AndroidFont; +import org.apache.harmony.awt.gl.font.FontManager; +import org.apache.harmony.awt.gl.font.FontMetricsImpl; +import org.apache.harmony.awt.gl.font.AndroidFontManager; +import org.apache.harmony.awt.wtk.NativeWindow; +import org.apache.harmony.awt.wtk.WindowFactory; +import org.apache.harmony.awt.gl.CommonGraphics2DFactory; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.content.Context; + +public class AndroidGraphicsFactory extends CommonGraphics2DFactory { + + public GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf) { + // TODO Auto-generated method stub + return null; + } + + public Font embedFont(String fontFilePath) { + // TODO Auto-generated method stub + return null; + } + + public FontManager getFontManager() { + return AndroidFontManager.inst; + } + + public FontMetrics getFontMetrics(Font font) { + return new FontMetricsImpl(font); + } + + public FontPeer getFontPeer(Font font) { + //return getFontManager().getFontPeer(font.getName(), font.getStyle(), font.getSize()); + return new AndroidFont(font.getName(), font.getStyle(), font.getSize()); + } + + public Graphics2D getGraphics2D(NativeWindow win, int translateX, + int translateY, MultiRectArea clip) { + // TODO Auto-generated method stub + return null; + } + + public Graphics2D getGraphics2D(NativeWindow win, int translateX, + int translateY, int width, int height) { + // TODO Auto-generated method stub + return null; + } + + public Graphics2D getGraphics2D(Context ctx, Canvas c, Paint p) { + return AndroidGraphics2D.getInstance(ctx, c, p); + } + + public Graphics2D getGraphics2D(Canvas c, Paint p) { + throw new RuntimeException("Not supported!"); + } + + public Graphics2D getGraphics2D() { + return AndroidGraphics2D.getInstance(); + } + +} diff --git a/awt/com/android/internal/awt/AndroidImageDecoder.java b/awt/com/android/internal/awt/AndroidImageDecoder.java new file mode 100644 index 0000000..81b2e1a --- /dev/null +++ b/awt/com/android/internal/awt/AndroidImageDecoder.java @@ -0,0 +1,274 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.awt; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import java.awt.Transparency; +import java.awt.color.ColorSpace; +//import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageConsumer; +import java.awt.image.IndexColorModel; +import java.io.IOException; +import java.io.InputStream; +import java.util.Hashtable; + +import org.apache.harmony.awt.gl.image.DecodingImageSource; +import org.apache.harmony.awt.gl.image.ImageDecoder; +import org.apache.harmony.awt.internal.nls.Messages; + +public class AndroidImageDecoder extends ImageDecoder { + + private static final int hintflags = + ImageConsumer.SINGLEFRAME | // PNG is a static image + ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible + ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines + + // Each pixel is a grayscale sample. + private static final int PNG_COLOR_TYPE_GRAY = 0; + // Each pixel is an R,G,B triple. + private static final int PNG_COLOR_TYPE_RGB = 2; + // Each pixel is a palette index, a PLTE chunk must appear. + private static final int PNG_COLOR_TYPE_PLTE = 3; + // Each pixel is a grayscale sample, followed by an alpha sample. + private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4; + // Each pixel is an R,G,B triple, followed by an alpha sample. + private static final int PNG_COLOR_TYPE_RGBA = 6; + + private static final int NB_OF_LINES_PER_CHUNK = 1; // 0 = full image + + Bitmap bm; // The image as decoded by Android + + // Header information + int imageWidth; // Image size + int imageHeight; + int colorType; // One of the PNG_ constants from above + int bitDepth; // Number of bits per color + byte cmap[]; // The color palette for index color models + ColorModel model; // The corresponding AWT color model + + boolean transferInts; // Is transfer of type int or byte? + int dataElementsPerPixel; + + // Buffers for decoded image data + byte byteOut[]; + int intOut[]; + + + public AndroidImageDecoder(DecodingImageSource src, InputStream is) { + super(src, is); + dataElementsPerPixel = 1; + } + + @Override + /** + * All the decoding is done in Android + * + * AWT???: Method returns only once the image is completly + * decoded; decoding is not done asynchronously + */ + public void decodeImage() throws IOException { + try { + bm = BitmapFactory.decodeStream(inputStream); + if (bm == null) { + throw new IOException("Input stream empty and no image cached"); + } + + // Check size + imageWidth = bm.getWidth(); + imageHeight = bm.getHeight(); + if (imageWidth < 0 || imageHeight < 0 ) { + throw new RuntimeException("Illegal image size: " + + imageWidth + ", " + imageHeight); + } + + // We got the image fully decoded; now send all image data to AWT + setDimensions(imageWidth, imageHeight); + model = createColorModel(); + setColorModel(model); + setHints(hintflags); + setProperties(new Hashtable<Object, Object>()); // Empty + sendPixels(NB_OF_LINES_PER_CHUNK != 0 ? NB_OF_LINES_PER_CHUNK : imageHeight); + imageComplete(ImageConsumer.STATICIMAGEDONE); + } catch (IOException e) { + throw e; + } catch (RuntimeException e) { + imageComplete(ImageConsumer.IMAGEERROR); + throw e; + } finally { + closeStream(); + } + } + + /** + * Create the AWT color model + * + * ???AWT: Android Bitmaps are always of type: ARGB-8888-Direct color model + * + * However, we leave the code here for a more powerfull decoder + * that returns a native model, and the conversion is then handled + * in AWT. With such a decoder, we would need to get the colorType, + * the bitDepth, (and the color palette for an index color model) + * from the image and construct the correct color model here. + */ + private ColorModel createColorModel() { + ColorModel cm = null; + int bmModel = 5; // TODO This doesn't exist: bm.getColorModel(); + cmap = null; + + switch (bmModel) { + // A1_MODEL + case 1: + colorType = PNG_COLOR_TYPE_GRAY; + bitDepth = 1; + break; + + // A8_MODEL + case 2: + colorType = PNG_COLOR_TYPE_GRAY_ALPHA; + bitDepth = 8; + break; + + // INDEX8_MODEL + // RGB_565_MODEL + // ARGB_8888_MODEL + case 3: + case 4: + case 5: + colorType = bm.hasAlpha() ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB; + bitDepth = 8; + break; + + default: + // awt.3C=Unknown PNG color type + throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$ + } + + switch (colorType) { + + case PNG_COLOR_TYPE_GRAY: { + if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) { + // awt.3C=Unknown PNG color type + throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$ + } + + // Create gray color model + int numEntries = 1 << bitDepth; + int scaleFactor = 255 / (numEntries-1); + byte comps[] = new byte[numEntries]; + for (int i = 0; i < numEntries; i++) { + comps[i] = (byte) (i * scaleFactor); + } + cm = new IndexColorModel(bitDepth, numEntries, comps, comps, comps); + + transferInts = false; + break; + } + + case PNG_COLOR_TYPE_RGB: { + if (bitDepth != 8) { + // awt.3C=Unknown PNG color type + throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$ + } + + cm = new DirectColorModel(24, 0xff0000, 0xFF00, 0xFF); + + transferInts = true; + break; + } + + case PNG_COLOR_TYPE_PLTE: { + if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) { + // awt.3C=Unknown PNG color type + throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$ + } + + if (cmap == null) { + throw new IllegalStateException("Palette color type is not supported"); + } + + cm = new IndexColorModel(bitDepth, cmap.length / 3, cmap, 0, false); + + transferInts = false; + break; + } + + case PNG_COLOR_TYPE_GRAY_ALPHA: { + if (bitDepth != 8) { + // awt.3C=Unknown PNG color type + throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$ + } + + cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), + true, false, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + + transferInts = false; + dataElementsPerPixel = 2; + break; + } + + case PNG_COLOR_TYPE_RGBA: { + if (bitDepth != 8) { + // awt.3C=Unknown PNG color type + throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$ + } + + cm = ColorModel.getRGBdefault(); + + transferInts = true; + break; + } + default: + // awt.3C=Unknown PNG color type + throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$ + } + + return cm; + } + + private void sendPixels(int nbOfLinesPerChunk) { + int w = imageWidth; + int h = imageHeight; + int n = 1; + if (nbOfLinesPerChunk > 0 && nbOfLinesPerChunk <= h) { + n = nbOfLinesPerChunk; + } + + if (transferInts) { + // Create output buffer + intOut = new int[w * n]; + for (int yi = 0; yi < h; yi += n) { + // Last chunk might contain less liness + if (n > 1 && h - yi < n ) { + n = h - yi; + } + bm.getPixels(intOut, 0, w, 0, yi, w, n); + setPixels(0, yi, w, n, model, intOut, 0, w); + } + } else { + // Android bitmaps always store ints (ARGB-8888 direct model) + throw new RuntimeException("Byte transfer not supported"); + } + } + +} diff --git a/awt/com/android/internal/awt/AndroidJavaBlitter.java b/awt/com/android/internal/awt/AndroidJavaBlitter.java new file mode 100644 index 0000000..423b534 --- /dev/null +++ b/awt/com/android/internal/awt/AndroidJavaBlitter.java @@ -0,0 +1,536 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.awt; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import org.apache.harmony.awt.gl.MultiRectArea; +import org.apache.harmony.awt.gl.Surface; +import org.apache.harmony.awt.gl.XORComposite; +import org.apache.harmony.awt.gl.render.Blitter; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; + +public class AndroidJavaBlitter implements Blitter { + + private Canvas canvas; + private Paint paint; + private int colorCache; + + public AndroidJavaBlitter(Canvas c) { + this.canvas = c; + this.paint = new Paint(); + this.paint.setStrokeWidth(1); + } + + /** + * Instead of multiplication and division we are using values from + * Lookup tables. + */ + static byte mulLUT[][]; // Lookup table for multiplication + static byte divLUT[][]; // Lookup table for division + + static{ + mulLUT = new byte[256][256]; + for(int i = 0; i < 256; i++){ + for(int j = 0; j < 256; j++){ + mulLUT[i][j] = (byte)((float)(i * j)/255 + 0.5f); + } + } + divLUT = new byte[256][256]; + for(int i = 1; i < 256; i++){ + for(int j = 0; j < i; j++){ + divLUT[i][j] = (byte)(((float)j / 255) / ((float)i/ 255) * 255 + 0.5f); + } + for(int j = i; j < 256; j++){ + divLUT[i][j] = (byte)255; + } + } + } + + final static int AlphaCompositeMode = 1; + final static int XORMode = 2; + + public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY, + Surface dstSurf, int width, int height, AffineTransform sysxform, + AffineTransform xform, Composite comp, Color bgcolor, + MultiRectArea clip) { + + if(xform == null){ + blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height, + sysxform, comp, bgcolor, clip); + }else{ + double scaleX = xform.getScaleX(); + double scaleY = xform.getScaleY(); + double scaledX = dstX / scaleX; + double scaledY = dstY / scaleY; + AffineTransform at = new AffineTransform(); + at.setToTranslation(scaledX, scaledY); + xform.concatenate(at); + sysxform.concatenate(xform); + blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height, + sysxform, comp, bgcolor, clip); + } + + } + + public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY, + Surface dstSurf, int width, int height, AffineTransform sysxform, + Composite comp, Color bgcolor, MultiRectArea clip) { + + if(sysxform == null) { + sysxform = new AffineTransform(); + } + int type = sysxform.getType(); + switch(type){ + case AffineTransform.TYPE_TRANSLATION: + dstX += sysxform.getTranslateX(); + dstY += sysxform.getTranslateY(); + case AffineTransform.TYPE_IDENTITY: + simpleBlit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, + width, height, comp, bgcolor, clip); + break; + default: + int srcW = srcSurf.getWidth(); + int srcH = srcSurf.getHeight(); + + int w = srcX + width < srcW ? width : srcW - srcX; + int h = srcY + height < srcH ? height : srcH - srcY; + + ColorModel srcCM = srcSurf.getColorModel(); + Raster srcR = srcSurf.getRaster().createChild(srcX, srcY, + w, h, 0, 0, null); + + ColorModel dstCM = dstSurf.getColorModel(); + WritableRaster dstR = dstSurf.getRaster(); + + transformedBlit(srcCM, srcR, 0, 0, dstCM, dstR, dstX, dstY, w, h, + sysxform, comp, bgcolor, clip); + + } + } + + public void simpleBlit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY, + Surface dstSurf, int width, int height, Composite comp, + Color bgcolor, MultiRectArea clip) { + + // TODO It's possible, though unlikely that we might encounter non-int[] + // data buffers. In this case the following code needs to have several + // branches that take this into account. + data = (DataBufferInt)srcSurf.getRaster().getDataBuffer(); + int[] pixels = data.getData(); + if (!srcSurf.getColorModel().hasAlpha()) { + // This wouldn't be necessary if Android supported RGB_888. + for (int i = 0; i < pixels.length; i++) { + pixels[i] = pixels[i] | 0xff000000; + } + } + bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); + canvas.drawBitmap(bmap, dstX, dstY, paint); + } + + public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY, + Surface dstSurf, int width, int height, Composite comp, + Color bgcolor, MultiRectArea clip) { + + javaBlt(srcX, srcY, srcSurf.getWidth(), srcSurf.getHeight(), + srcSurf.getColorModel(), srcSurf.getRaster(), dstX, dstY, + dstSurf.getWidth(), dstSurf.getHeight(), + dstSurf.getColorModel(), dstSurf.getRaster(), + width, height, comp, bgcolor, clip); + + } + + public void javaBlt(int srcX, int srcY, int srcW, int srcH, + ColorModel srcCM, Raster srcRast, int dstX, int dstY, + int dstW, int dstH, ColorModel dstCM, WritableRaster dstRast, + int width, int height, Composite comp, Color bgcolor, + MultiRectArea clip){ + + int srcX2 = srcW - 1; + int srcY2 = srcH - 1; + int dstX2 = dstW - 1; + int dstY2 = dstH - 1; + + if(srcX < 0){ + width += srcX; + srcX = 0; + } + if(srcY < 0){ + height += srcY; + srcY = 0; + } + + if(dstX < 0){ + width += dstX; + srcX -= dstX; + dstX = 0; + } + if(dstY < 0){ + height += dstY; + srcY -= dstY; + dstY = 0; + } + + if(srcX > srcX2 || srcY > srcY2) { + return; + } + if(dstX > dstX2 || dstY > dstY2) { + return; + } + + if(srcX + width > srcX2) { + width = srcX2 - srcX + 1; + } + if(srcY + height > srcY2) { + height = srcY2 - srcY + 1; + } + if(dstX + width > dstX2) { + width = dstX2 - dstX + 1; + } + if(dstY + height > dstY2) { + height = dstY2 - dstY + 1; + } + + if(width <= 0 || height <= 0) { + return; + } + + int clipRects[]; + if(clip != null) { + clipRects = clip.rect; + } else { + clipRects = new int[]{5, 0, 0, dstW - 1, dstH - 1}; + } + + boolean isAlphaComp = false; + int rule = 0; + float alpha = 0; + boolean isXORComp = false; + Color xorcolor = null; + CompositeContext cont = null; + + if(comp instanceof AlphaComposite){ + isAlphaComp = true; + AlphaComposite ac = (AlphaComposite) comp; + rule = ac.getRule(); + alpha = ac.getAlpha(); + }else if(comp instanceof XORComposite){ + isXORComp = true; + XORComposite xcomp = (XORComposite) comp; + xorcolor = xcomp.getXORColor(); + }else{ + cont = comp.createContext(srcCM, dstCM, null); + } + + for(int i = 1; i < clipRects[0]; i += 4){ + int _sx = srcX; + int _sy = srcY; + + int _dx = dstX; + int _dy = dstY; + + int _w = width; + int _h = height; + + int cx = clipRects[i]; // Clipping left top X + int cy = clipRects[i + 1]; // Clipping left top Y + int cx2 = clipRects[i + 2]; // Clipping right bottom X + int cy2 = clipRects[i + 3]; // Clipping right bottom Y + + if(_dx > cx2 || _dy > cy2 || dstX2 < cx || dstY2 < cy) { + continue; + } + + if(cx > _dx){ + int shx = cx - _dx; + _w -= shx; + _dx = cx; + _sx += shx; + } + + if(cy > _dy){ + int shy = cy - _dy; + _h -= shy; + _dy = cy; + _sy += shy; + } + + if(_dx + _w > cx2 + 1){ + _w = cx2 - _dx + 1; + } + + if(_dy + _h > cy2 + 1){ + _h = cy2 - _dy + 1; + } + + if(_sx > srcX2 || _sy > srcY2) { + continue; + } + + if(isAlphaComp){ + alphaCompose(_sx, _sy, srcCM, srcRast, _dx, _dy, + dstCM, dstRast, _w, _h, rule, alpha, bgcolor); + }else if(isXORComp){ + xorCompose(_sx, _sy, srcCM, srcRast, _dx, _dy, + dstCM, dstRast, _w, _h, xorcolor); + }else{ + Raster sr = srcRast.createChild(_sx, _sy, _w, _h, 0, 0, null); + WritableRaster dr = dstRast.createWritableChild(_dx, _dy, + _w, _h, 0, 0, null); + cont.compose(sr, dr, dr); + } + } + + } + + DataBufferInt data; + Bitmap bmap, bmp; + + void alphaCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast, + int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast, + int width, int height, int rule, float alpha, Color bgcolor){ + + Object srcPixel = getTransferArray(srcRast, 1); + data = (DataBufferInt)srcRast.getDataBuffer(); + int pix[] = data.getData(); + bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565); + canvas.drawBitmap(bmap, dstX, dstY, paint); + } + + void render(int[] img, int x, int y, int width, int height) { + canvas.drawBitmap(Bitmap.createBitmap(img, width, height, Bitmap.Config.ARGB_8888), x, y, paint); + } + + void xorCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast, + int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast, + int width, int height, Color xorcolor){ + + data = (DataBufferInt)srcRast.getDataBuffer(); + int pix[] = data.getData(); + bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565); + canvas.drawBitmap(bmap, dstX, dstY, paint); + } + + private void transformedBlit(ColorModel srcCM, Raster srcR, int srcX, int srcY, + ColorModel dstCM, WritableRaster dstR, int dstX, int dstY, + int width, int height, AffineTransform at, Composite comp, + Color bgcolor, MultiRectArea clip) { + + data = (DataBufferInt)srcR.getDataBuffer(); + int[] pixels = data.getData(); + if (!srcCM.hasAlpha()) { + // This wouldn't be necessary if Android supported RGB_888. + for (int i = 0; i < pixels.length; i++) { + pixels[i] = pixels[i] | 0xff000000; + } + } + bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); + + Matrix tm = new Matrix(); + tm.setConcat(canvas.getMatrix(), AndroidGraphics2D.createMatrixObj(at)); + if(at.getType() > 1) { + bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, true); + } else { + bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, false); + } + canvas.drawBitmap(bmp, dstX + (float)at.getTranslateX(), dstY + (float)at.getTranslateY(), paint); + } + + private Rectangle2D getBounds2D(AffineTransform at, Rectangle r) { + int x = r.x; + int y = r.y; + int width = r.width; + int height = r.height; + + float[] corners = { + x, y, + x + width, y, + x + width, y + height, + x, y + height + }; + + at.transform(corners, 0, corners, 0, 4); + + Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0); + bounds.add(corners[2], corners[3]); + bounds.add(corners[4], corners[5]); + bounds.add(corners[6], corners[7]); + + return bounds; + } + + private int compose(int srcRGB, boolean isSrcAlphaPre, + int dstRGB, boolean dstHasAlpha, boolean isDstAlphaPre, + int rule, int srcConstAlpha){ + + int sa, sr, sg, sb, da, dr, dg, db; + + sa = (srcRGB >> 24) & 0xff; + sr = (srcRGB >> 16) & 0xff; + sg = (srcRGB >> 8) & 0xff; + sb = srcRGB & 0xff; + + if(isSrcAlphaPre){ + sa = mulLUT[srcConstAlpha][sa] & 0xff; + sr = mulLUT[srcConstAlpha][sr] & 0xff; + sg = mulLUT[srcConstAlpha][sg] & 0xff; + sb = mulLUT[srcConstAlpha][sb] & 0xff; + }else{ + sa = mulLUT[srcConstAlpha][sa] & 0xff; + sr = mulLUT[sa][sr] & 0xff; + sg = mulLUT[sa][sg] & 0xff; + sb = mulLUT[sa][sb] & 0xff; + } + + da = (dstRGB >> 24) & 0xff; + dr = (dstRGB >> 16) & 0xff; + dg = (dstRGB >> 8) & 0xff; + db = dstRGB & 0xff; + + if(!isDstAlphaPre){ + dr = mulLUT[da][dr] & 0xff; + dg = mulLUT[da][dg] & 0xff; + db = mulLUT[da][db] & 0xff; + } + + int Fs = 0; + int Fd = 0; + switch(rule){ + case AlphaComposite.CLEAR: + break; + + case AlphaComposite.DST: + Fd = 255; + break; + + case AlphaComposite.DST_ATOP: + Fs = 255 - da; + Fd = sa; + break; + + case AlphaComposite.DST_IN: + Fd = sa; + break; + + case AlphaComposite.DST_OUT: + Fd = 255 - sa; + break; + + case AlphaComposite.DST_OVER: + Fs = 255 - da; + Fd = 255; + break; + + case AlphaComposite.SRC: + Fs = 255; + break; + + case AlphaComposite.SRC_ATOP: + Fs = da; + Fd = 255 - sa; + break; + + case AlphaComposite.SRC_IN: + Fs = da; + break; + + case AlphaComposite.SRC_OUT: + Fs = 255 - da; + break; + + case AlphaComposite.SRC_OVER: + Fs = 255; + Fd = 255 - sa; + break; + + case AlphaComposite.XOR: + Fs = 255 - da; + Fd = 255 - sa; + break; + } + dr = (mulLUT[sr][Fs] & 0xff) + (mulLUT[dr][Fd] & 0xff); + dg = (mulLUT[sg][Fs] & 0xff) + (mulLUT[dg][Fd] & 0xff); + db = (mulLUT[sb][Fs] & 0xff) + (mulLUT[db][Fd] & 0xff); + + da = (mulLUT[sa][Fs] & 0xff) + (mulLUT[da][Fd] & 0xff); + + if(!isDstAlphaPre){ + if(da != 255){ + dr = divLUT[da][dr] & 0xff; + dg = divLUT[da][dg] & 0xff; + db = divLUT[da][db] & 0xff; + } + } + if(!dstHasAlpha) { + da = 0xff; + } + dstRGB = (da << 24) | (dr << 16) | (dg << 8) | db; + + return dstRGB; + + } + + /** + * Allocate an array that can be use to store the result for a + * Raster.getDataElements call. + * @param raster Raster (type) where the getDataElements call will be made. + * @param nbPixels How many pixels to store in the array at most + * @return the result array or null + */ + private Object getTransferArray(Raster raster, int nbPixels) { + int transferType = raster.getTransferType(); + int nbDataElements = raster.getSampleModel().getNumDataElements(); + int n = nbDataElements * nbPixels; + switch (transferType) { + case DataBuffer.TYPE_BYTE: + return new byte[n]; + case DataBuffer.TYPE_SHORT: + case DataBuffer.TYPE_USHORT: + return new short[n]; + case DataBuffer.TYPE_INT: + return new int[n]; + case DataBuffer.TYPE_FLOAT: + return new float[n]; + case DataBuffer.TYPE_DOUBLE: + return new double[n]; + case DataBuffer.TYPE_UNDEFINED: + default: + return null; + } + } + + /** + * Draw a pixel + */ + private void dot(int x, int y, int clr) { + if (colorCache != clr) { + paint.setColor(clr); + colorCache = clr; + } + canvas.drawLine(x, y, x + 1, y + 1, paint); + } +} diff --git a/awt/com/android/internal/awt/AndroidNativeEventQueue.java b/awt/com/android/internal/awt/AndroidNativeEventQueue.java new file mode 100644 index 0000000..fc30614 --- /dev/null +++ b/awt/com/android/internal/awt/AndroidNativeEventQueue.java @@ -0,0 +1,75 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.awt; + +import org.apache.harmony.awt.wtk.NativeEventQueue; + +public class AndroidNativeEventQueue extends NativeEventQueue { + + private Object eventMonitor; + + public AndroidNativeEventQueue() { + super(); + eventMonitor = getEventMonitor(); + } + + @Override + public void awake() { + synchronized (eventMonitor) { + eventMonitor.notify(); + } + } + + @Override + public void dispatchEvent() { + //???AWT + System.out.println(getClass()+": empty method called"); + } + + @Override + public long getJavaWindow() { + //???AWT + System.out.println(getClass()+": empty method called"); + return 0; + } + + @Override + public void performLater(Task task) { + //???AWT + System.out.println(getClass()+": empty method called"); + } + + @Override + public void performTask(Task task) { + //???AWT + System.out.println(getClass()+": empty method called"); + } + + @Override + public boolean waitEvent() { + while (isEmpty() ) { + synchronized (eventMonitor) { + try { + eventMonitor.wait(1000); + } catch (InterruptedException ignore) { + } + } + } + return false; + } + +} diff --git a/awt/com/android/internal/awt/AndroidWTK.java b/awt/com/android/internal/awt/AndroidWTK.java new file mode 100644 index 0000000..1609d11 --- /dev/null +++ b/awt/com/android/internal/awt/AndroidWTK.java @@ -0,0 +1,88 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.awt; + +import java.awt.GraphicsDevice; + +import org.apache.harmony.awt.wtk.CursorFactory; +import org.apache.harmony.awt.wtk.GraphicsFactory; +import org.apache.harmony.awt.wtk.NativeEventQueue; +import org.apache.harmony.awt.wtk.NativeIM; +import org.apache.harmony.awt.wtk.NativeMouseInfo; +import org.apache.harmony.awt.wtk.NativeRobot; +import org.apache.harmony.awt.wtk.SystemProperties; +import org.apache.harmony.awt.wtk.WTK; +import org.apache.harmony.awt.wtk.WindowFactory; + +public class AndroidWTK extends WTK { + + private AndroidGraphicsFactory mAgf; + private AndroidNativeEventQueue mAneq; + + @Override + public CursorFactory getCursorFactory() { + // TODO Auto-generated method stub + return null; + } + + @Override + public GraphicsFactory getGraphicsFactory() { + if(mAgf == null) { + mAgf = new AndroidGraphicsFactory(); + } + return mAgf; + } + + @Override + public NativeEventQueue getNativeEventQueue() { + if(mAneq == null) { + mAneq = new AndroidNativeEventQueue(); + } + return mAneq; + } + + @Override + public NativeIM getNativeIM() { + // TODO Auto-generated method stub + return null; + } + + @Override + public NativeMouseInfo getNativeMouseInfo() { + // TODO Auto-generated method stub + return null; + } + + @Override + public NativeRobot getNativeRobot(GraphicsDevice screen) { + // TODO Auto-generated method stub + return null; + } + + @Override + public SystemProperties getSystemProperties() { + // TODO Auto-generated method stub + return null; + } + + @Override + public WindowFactory getWindowFactory() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/awt/com/android/internal/awt/AwtFactory.java b/awt/com/android/internal/awt/AwtFactory.java new file mode 100644 index 0000000..6e667b2 --- /dev/null +++ b/awt/com/android/internal/awt/AwtFactory.java @@ -0,0 +1,52 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.awt; + +import java.awt.Graphics2D; +import java.awt.Toolkit; + +import org.apache.harmony.awt.wtk.GraphicsFactory; + +import android.graphics.Canvas; +import android.graphics.Paint; + +public class AwtFactory { + + private static GraphicsFactory gf; + + /** + * Use this method to get acces to AWT drawing primitives and to + * render into the surface area of a Android widget. Origin and + * clip of the returned graphics object are the same as in the + * corresponding Android widget. + * + * @param c Canvas of the android widget to draw into + * @param p The default drawing parameters such as font, + * stroke, foreground and background colors, etc. + * @return The AWT Graphics object that makes all AWT + * drawing primitives available in the androind world. + */ + public static Graphics2D getAwtGraphics(Canvas c, Paint p) { + // AWT?? TODO: test it! + if (null == gf) { + Toolkit tk = Toolkit.getDefaultToolkit(); + gf = tk.getGraphicsFactory(); + } + return gf.getGraphics2D(c, p); + } + +} diff --git a/awt/com/android/internal/awt/ImageOutputStreamWrapper.java b/awt/com/android/internal/awt/ImageOutputStreamWrapper.java new file mode 100644 index 0000000..92185fd --- /dev/null +++ b/awt/com/android/internal/awt/ImageOutputStreamWrapper.java @@ -0,0 +1,66 @@ +/* + * Copyright 2007, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.awt; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.imageio.stream.ImageOutputStream; + +public class ImageOutputStreamWrapper extends OutputStream { + + protected ImageOutputStream mIos; + + private byte[] mBuff; + + public ImageOutputStreamWrapper(ImageOutputStream ios) { + if (null == ios) { + throw new IllegalArgumentException("ImageOutputStream must not be null"); + } + this.mIos = ios; + this.mBuff = new byte[1]; + } + + public ImageOutputStream getImageOutputStream() { + return mIos; + } + + @Override + public void write(int oneByte) throws IOException { + mBuff[0] = (byte)oneByte; + mIos.write(mBuff, 0, 1); + } + + public void write(byte[] b) throws IOException { + mIos.write(b, 0, b.length); + } + + public void write(byte[] b, int off, int len) throws IOException { + mIos.write(b, off, len); + } + + public void flush() throws IOException { + mIos.flush(); + } + + public void close() throws IOException { + if (mIos == null) { + throw new IOException("Stream already closed"); + } + mIos = null; + } +} |