blob: 42e6b448f39d6904a5c488961e4fa3fafbe027b9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you 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 org.apache.pivot.scene;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import org.apache.pivot.scene.Bounds;
import org.apache.pivot.scene.Color;
import org.apache.pivot.scene.Font;
import org.apache.pivot.scene.Graphics;
import org.apache.pivot.scene.Paint;
import org.apache.pivot.scene.PathGeometry;
import org.apache.pivot.scene.Platform;
import org.apache.pivot.scene.SolidColorPaint;
import org.apache.pivot.scene.Stroke;
import org.apache.pivot.scene.Transform;
import org.apache.pivot.scene.media.Raster;
/**
* AWT graphics implementation.
*/
public class AWTGraphics extends Graphics {
private Graphics2D graphics2D;
private float alpha;
private CompositeOperation compositeOperation;
private boolean antiAliased;
private Stroke stroke;
private Paint paint;
private Font font;
private Line2D.Float line2D = new Line2D.Float();
private Rectangle2D.Float rectangle2D = new Rectangle2D.Float();
private RoundRectangle2D.Float roundRectangle2D = new RoundRectangle2D.Float();
private Arc2D.Float arc2D = new Arc2D.Float();
private Ellipse2D.Float ellipse2D = new Ellipse2D.Float();
public AWTGraphics(Graphics2D graphics2D) {
if (graphics2D == null) {
throw new IllegalArgumentException();
}
this.graphics2D = graphics2D;
setAlpha(1.0f);
setCompositeOperation(CompositeOperation.SOURCE_OVER);
setAntiAliased(false);
setStroke(new Stroke());
setPaint(new SolidColorPaint(Color.BLACK));
setFont(Platform.getPlatform().getDefaultFont());
}
// Clipping
@Override
public void clip(int x, int y, int width, int height) {
graphics2D.clipRect(x, y, width, height);
}
@Override
public Bounds getClipBounds() {
Rectangle clipBounds = graphics2D.getClipBounds();
return new Bounds(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
}
// Compositing
@Override
public float getAlpha() {
return alpha;
}
@Override
public void setAlpha(float alpha) {
if (alpha < 0
|| alpha > 1) {
throw new IllegalArgumentException("Alpha must be between 0 and 1.");
}
this.alpha = alpha;
AlphaComposite alphaComposite = (AlphaComposite)graphics2D.getComposite();
graphics2D.setComposite(alphaComposite.derive(alpha));
}
@Override
public CompositeOperation getCompositeOperation() {
return compositeOperation;
}
@Override
public void setCompositeOperation(CompositeOperation compositeOperation) {
int rule = -1;
switch (compositeOperation) {
case SOURCE_ATOP: {
rule = AlphaComposite.SRC_ATOP;
break;
}
case SOURCE_IN: {
rule = AlphaComposite.SRC_IN;
break;
}
case SOURCE_OUT: {
rule = AlphaComposite.SRC_OUT;
break;
}
case SOURCE_OVER: {
rule = AlphaComposite.SRC_OVER;
break;
}
case DESTINATION_ATOP: {
rule = AlphaComposite.DST_ATOP;
break;
}
case DESTINATION_IN: {
rule = AlphaComposite.DST_IN;
break;
}
case DESTINATION_OUT: {
rule = AlphaComposite.DST_OUT;
break;
}
case DESTINATION_OVER: {
rule = AlphaComposite.DST_OVER;
break;
}
case CLEAR: {
rule = AlphaComposite.CLEAR;
break;
}
case XOR: {
rule = AlphaComposite.XOR;
break;
}
}
graphics2D.setComposite(AlphaComposite.getInstance(rule, alpha));
}
// Anti-aliasing
@Override
public boolean isAntiAliased() {
return antiAliased;
}
@Override
public void setAntiAliased(boolean antiAliased) {
this.antiAliased = antiAliased;
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAliased ?
RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
}
// Primitive drawing/filling
@Override
public Stroke getStroke() {
return stroke;
}
@Override
public void setStroke(Stroke stroke) {
if (stroke == null) {
throw new IllegalArgumentException("stroke is null.");
}
graphics2D.setStroke((java.awt.Stroke)stroke.getNativeStroke());
}
@Override
public Paint getPaint() {
return paint;
}
@Override
public void setPaint(Paint paint) {
if (paint == null) {
throw new IllegalArgumentException("paint is null.");
}
this.paint = paint;
graphics2D.setPaint((java.awt.Paint)paint.getNativePaint());
}
@Override
public void drawLine(float x1, float y1, float x2, float y2) {
// TODO Optimize to use drawLine() when appropriate
line2D.x1 = x1;
line2D.y1 = y1;
line2D.x2 = x2;
line2D.y2 = y2;
graphics2D.draw(line2D);
}
@Override
public void drawRectangle(float x, float y, float width, float height, float cornerRadius) {
// TODO Optimize to use drawRect() or drawRoundRect() when appropriate
if (cornerRadius == 0) {
rectangle2D.x = x;
rectangle2D.y = y;
rectangle2D.width = width;
rectangle2D.height = height;
graphics2D.draw(rectangle2D);
} else {
roundRectangle2D.x = x;
roundRectangle2D.y = y;
roundRectangle2D.width = width;
roundRectangle2D.height = height;
roundRectangle2D.archeight = cornerRadius;
roundRectangle2D.arcwidth = cornerRadius;
graphics2D.draw(roundRectangle2D);
}
}
@Override
public void drawArc(float x, float y, float width, float height, float start, float extent) {
// TODO Optimize to use drawArc() when appropriate
arc2D.x = x;
arc2D.y = y;
arc2D.width = width;
arc2D.height = height;
arc2D.start = start;
arc2D.extent = extent;
graphics2D.draw(arc2D);
}
@Override
public void drawEllipse(float x, float y, float width, float height) {
// TODO Optimize to use drawOval() when appropriate
ellipse2D.x = x;
ellipse2D.y = y;
ellipse2D.width = width;
ellipse2D.height = height;
graphics2D.draw(ellipse2D);
}
@Override
public void drawPath(PathGeometry pathGeometry) {
graphics2D.draw((Path2D.Float)pathGeometry.getNativePathGeometry());
}
@Override
public void fillRectangle(float x, float y, float width, float height, float cornerRadius) {
// TODO Optimize to use fillRect() or fillRoundRect() when appropriate
if (cornerRadius == 0) {
rectangle2D.x = x;
rectangle2D.y = y;
rectangle2D.width = width;
rectangle2D.height = height;
graphics2D.fill(rectangle2D);
} else {
roundRectangle2D.x = x;
roundRectangle2D.y = y;
roundRectangle2D.width = width;
roundRectangle2D.height = height;
roundRectangle2D.archeight = cornerRadius;
roundRectangle2D.arcwidth = cornerRadius;
graphics2D.fill(roundRectangle2D);
}
}
@Override
public void fillArc(float x, float y, float width, float height, float start, float extent) {
// TODO Optimize to use fillArc() when appropriate
arc2D.x = x;
arc2D.y = y;
arc2D.width = width;
arc2D.height = height;
arc2D.start = start;
arc2D.extent = extent;
graphics2D.fill(arc2D);
}
@Override
public void fillEllipse(float x, float y, float width, float height) {
// TODO Optimize to use drawOval() when appropriate
ellipse2D.x = x;
ellipse2D.y = y;
ellipse2D.width = width;
ellipse2D.height = height;
graphics2D.draw(ellipse2D);
}
@Override
public void fillPath(PathGeometry pathGeometry) {
graphics2D.fill((Path2D.Float)pathGeometry.getNativePathGeometry());
}
@Override
public void drawRaster(Raster raster, int x, int y, int width, int height) {
graphics2D.drawImage((BufferedImage)raster.getNativeRaster(), x, y, null);
}
// Blitting
@Override
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
graphics2D.copyArea(x, y, width, height, dx, dy);
}
// Text
@Override
public Font getFont() {
return font;
}
@Override
public void setFont(Font font) {
graphics2D.setFont((java.awt.Font)font.getNativeFont());
}
@Override
public void drawText(CharSequence text, int start, int length, float x, float y) {
java.awt.Font nativeFont = (java.awt.Font)font.getNativeFont();
FontRenderContext fontRenderContext = AWTPlatform.getFontRenderContext();
GlyphVector glyphVector = nativeFont.createGlyphVector(fontRenderContext,
new CharSequenceCharacterIterator(text, start, start + length));
graphics2D.drawGlyphVector(glyphVector, x, y);
}
// Transformations
@Override
public void transform(float m11, float m12, float m21, float m22, float dx, float dy) {
// TODO
}
@Override
public Transform getCurrentTransform() {
// TODO
return null;
}
// Creation/disposal
@Override
public Graphics create() {
return new AWTGraphics((Graphics2D)graphics2D.create());
}
@Override
public void dispose() {
graphics2D.dispose();
}
@Override
public Object getNativeGraphics() {
return graphics2D;
}
}