blob: 5971c09cdd63ce9b5548731747482ea56f566a02 [file] [log] [blame]
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.windows;
import java.awt.Composite;
import java.awt.Shape;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.pipe.Region;
import sun.java2d.pipe.PixelDrawPipe;
import sun.java2d.pipe.PixelFillPipe;
import sun.java2d.pipe.ShapeDrawPipe;
import sun.java2d.pipe.SpanIterator;
import sun.java2d.pipe.ShapeSpanIterator;
import sun.java2d.pipe.LoopPipe;
import sun.java2d.loops.GraphicsPrimitive;
public class GDIRenderer implements
PixelDrawPipe,
PixelFillPipe,
ShapeDrawPipe
{
native void doDrawLine(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x1, int y1, int x2, int y2);
public void drawLine(SunGraphics2D sg2d,
int x1, int y1, int x2, int y2)
{
int transx = sg2d.transX;
int transy = sg2d.transY;
try {
doDrawLine((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x1+transx, y1+transy, x2+transx, y2+transy);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doDrawRect(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h);
public void drawRect(SunGraphics2D sg2d,
int x, int y, int width, int height)
{
try {
doDrawRect((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x+sg2d.transX, y+sg2d.transY, width, height);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doDrawRoundRect(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h,
int arcW, int arcH);
public void drawRoundRect(SunGraphics2D sg2d,
int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
try {
doDrawRoundRect((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x+sg2d.transX, y+sg2d.transY, width, height,
arcWidth, arcHeight);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doDrawOval(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h);
public void drawOval(SunGraphics2D sg2d,
int x, int y, int width, int height)
{
try {
doDrawOval((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x+sg2d.transX, y+sg2d.transY, width, height);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doDrawArc(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h,
int angleStart, int angleExtent);
public void drawArc(SunGraphics2D sg2d,
int x, int y, int width, int height,
int startAngle, int arcAngle)
{
try {
doDrawArc((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x+sg2d.transX, y+sg2d.transY, width, height,
startAngle, arcAngle);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doDrawPoly(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int transx, int transy,
int[] xpoints, int[] ypoints,
int npoints, boolean isclosed);
public void drawPolyline(SunGraphics2D sg2d,
int xpoints[], int ypoints[],
int npoints)
{
try {
doDrawPoly((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
sg2d.transX, sg2d.transY, xpoints, ypoints, npoints, false);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
public void drawPolygon(SunGraphics2D sg2d,
int xpoints[], int ypoints[],
int npoints)
{
try {
doDrawPoly((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
sg2d.transX, sg2d.transY, xpoints, ypoints, npoints, true);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doFillRect(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h);
public void fillRect(SunGraphics2D sg2d,
int x, int y, int width, int height)
{
try {
doFillRect((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x+sg2d.transX, y+sg2d.transY, width, height);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doFillRoundRect(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h,
int arcW, int arcH);
public void fillRoundRect(SunGraphics2D sg2d,
int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
try {
doFillRoundRect((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x+sg2d.transX, y+sg2d.transY, width, height,
arcWidth, arcHeight);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doFillOval(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h);
public void fillOval(SunGraphics2D sg2d,
int x, int y, int width, int height)
{
try {
doFillOval((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x+sg2d.transX, y+sg2d.transY, width, height);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doFillArc(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h,
int angleStart, int angleExtent);
public void fillArc(SunGraphics2D sg2d,
int x, int y, int width, int height,
int startAngle, int arcAngle)
{
try {
doFillArc((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
x+sg2d.transX, y+sg2d.transY, width, height,
startAngle, arcAngle);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doFillPoly(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int transx, int transy,
int[] xpoints, int[] ypoints,
int npoints);
public void fillPolygon(SunGraphics2D sg2d,
int xpoints[], int ypoints[],
int npoints)
{
try {
doFillPoly((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
sg2d.transX, sg2d.transY, xpoints, ypoints, npoints);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
native void doShape(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int transX, int transY,
Path2D.Float p2df, boolean isfill);
void doShape(SunGraphics2D sg2d, Shape s, boolean isfill) {
Path2D.Float p2df;
int transX;
int transY;
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
if (s instanceof Path2D.Float) {
p2df = (Path2D.Float)s;
} else {
p2df = new Path2D.Float(s);
}
transX = sg2d.transX;
transY = sg2d.transY;
} else {
p2df = new Path2D.Float(s, sg2d.transform);
transX = 0;
transY = 0;
}
try {
doShape((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
transX, transY, p2df, isfill);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
// REMIND: This is just a hack to get WIDE lines to honor the
// necessary hinted pixelization rules. This should be replaced
// by a native FillSpans method or a getHintedStrokeGeneralPath()
// method that could be filled by the doShape method more quickly.
public void doFillSpans(SunGraphics2D sg2d, SpanIterator si) {
int box[] = new int[4];
GDIWindowSurfaceData sd;
try {
sd = (GDIWindowSurfaceData)sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
Region clip = sg2d.getCompClip();
Composite comp = sg2d.composite;
int eargb = sg2d.eargb;
while (si.nextSpan(box)) {
doFillRect(sd, clip, comp, eargb,
box[0], box[1], box[2]-box[0], box[3]-box[1]);
}
}
public void draw(SunGraphics2D sg2d, Shape s) {
if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
doShape(sg2d, s, false);
} else if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) {
ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
try {
doFillSpans(sg2d, si);
} finally {
si.dispose();
}
} else {
doShape(sg2d, sg2d.stroke.createStrokedShape(s), true);
}
}
public void fill(SunGraphics2D sg2d, Shape s) {
doShape(sg2d, s, true);
}
public native void devCopyArea(GDIWindowSurfaceData sData,
int srcx, int srcy,
int dx, int dy,
int w, int h);
public GDIRenderer traceWrap() {
return new Tracer();
}
public static class Tracer extends GDIRenderer {
void doDrawLine(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x1, int y1, int x2, int y2)
{
GraphicsPrimitive.tracePrimitive("GDIDrawLine");
super.doDrawLine(sData, clip, comp, color, x1, y1, x2, y2);
}
void doDrawRect(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h)
{
GraphicsPrimitive.tracePrimitive("GDIDrawRect");
super.doDrawRect(sData, clip, comp, color, x, y, w, h);
}
void doDrawRoundRect(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h,
int arcW, int arcH)
{
GraphicsPrimitive.tracePrimitive("GDIDrawRoundRect");
super.doDrawRoundRect(sData, clip, comp, color,
x, y, w, h, arcW, arcH);
}
void doDrawOval(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h)
{
GraphicsPrimitive.tracePrimitive("GDIDrawOval");
super.doDrawOval(sData, clip, comp, color, x, y, w, h);
}
void doDrawArc(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h,
int angleStart, int angleExtent)
{
GraphicsPrimitive.tracePrimitive("GDIDrawArc");
super.doDrawArc(sData, clip, comp, color, x, y, w, h,
angleStart, angleExtent);
}
void doDrawPoly(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int transx, int transy,
int[] xpoints, int[] ypoints,
int npoints, boolean isclosed)
{
GraphicsPrimitive.tracePrimitive("GDIDrawPoly");
super.doDrawPoly(sData, clip, comp, color, transx, transy,
xpoints, ypoints, npoints, isclosed);
}
void doFillRect(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h)
{
GraphicsPrimitive.tracePrimitive("GDIFillRect");
super.doFillRect(sData, clip, comp, color, x, y, w, h);
}
void doFillRoundRect(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h,
int arcW, int arcH)
{
GraphicsPrimitive.tracePrimitive("GDIFillRoundRect");
super.doFillRoundRect(sData, clip, comp, color,
x, y, w, h, arcW, arcH);
}
void doFillOval(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h)
{
GraphicsPrimitive.tracePrimitive("GDIFillOval");
super.doFillOval(sData, clip, comp, color, x, y, w, h);
}
void doFillArc(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int x, int y, int w, int h,
int angleStart, int angleExtent)
{
GraphicsPrimitive.tracePrimitive("GDIFillArc");
super.doFillArc(sData, clip, comp, color, x, y, w, h,
angleStart, angleExtent);
}
void doFillPoly(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int transx, int transy,
int[] xpoints, int[] ypoints,
int npoints)
{
GraphicsPrimitive.tracePrimitive("GDIFillPoly");
super.doFillPoly(sData, clip, comp, color, transx, transy,
xpoints, ypoints, npoints);
}
void doShape(GDIWindowSurfaceData sData,
Region clip, Composite comp, int color,
int transX, int transY,
Path2D.Float p2df, boolean isfill)
{
GraphicsPrimitive.tracePrimitive(isfill
? "GDIFillShape"
: "GDIDrawShape");
super.doShape(sData, clip, comp, color,
transX, transY, p2df, isfill);
}
public void devCopyArea(GDIWindowSurfaceData sData,
int srcx, int srcy,
int dx, int dy,
int w, int h)
{
GraphicsPrimitive.tracePrimitive("GDICopyArea");
super.devCopyArea(sData, srcx, srcy, dx, dy, w, h);
}
}
}