0N/A/*
2362N/A * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.java2d.pipe;
0N/A
0N/Aimport sun.java2d.SunGraphics2D;
0N/Aimport sun.java2d.SurfaceData;
0N/Aimport java.awt.Rectangle;
0N/Aimport java.awt.Shape;
0N/Aimport java.awt.BasicStroke;
0N/Aimport java.awt.geom.PathIterator;
0N/Aimport java.awt.geom.AffineTransform;
0N/Aimport java.awt.geom.Rectangle2D;
0N/Aimport sun.awt.SunHints;
0N/A
0N/A/**
0N/A * This class is used to convert raw geometry into a span iterator
0N/A * object using a simple flattening polygon scan converter.
0N/A * The iterator can be passed on to special SpanFiller loops to
0N/A * perform the actual rendering.
0N/A */
0N/Apublic abstract class SpanShapeRenderer implements ShapeDrawPipe {
0N/A final static RenderingEngine RenderEngine = RenderingEngine.getInstance();
0N/A
0N/A public static class Composite extends SpanShapeRenderer {
0N/A CompositePipe comppipe;
0N/A
0N/A public Composite(CompositePipe pipe) {
0N/A comppipe = pipe;
0N/A }
0N/A
0N/A public Object startSequence(SunGraphics2D sg, Shape s,
0N/A Rectangle devR, int[] bbox) {
0N/A return comppipe.startSequence(sg, s, devR, bbox);
0N/A }
0N/A
0N/A public void renderBox(Object ctx, int x, int y, int w, int h) {
0N/A comppipe.renderPathTile(ctx, null, 0, w, x, y, w, h);
0N/A }
0N/A
0N/A public void endSequence(Object ctx) {
0N/A comppipe.endSequence(ctx);
0N/A }
0N/A }
0N/A
1884N/A public static class Simple extends SpanShapeRenderer
1884N/A implements LoopBasedPipe
1884N/A {
0N/A public Object startSequence(SunGraphics2D sg, Shape s,
0N/A Rectangle devR, int[] bbox) {
0N/A return sg;
0N/A }
0N/A
0N/A public void renderBox(Object ctx, int x, int y, int w, int h) {
0N/A SunGraphics2D sg2d = (SunGraphics2D) ctx;
0N/A SurfaceData sd = sg2d.getSurfaceData();
0N/A sg2d.loops.fillRectLoop.FillRect(sg2d, sd, x, y, w, h);
0N/A }
0N/A
0N/A public void endSequence(Object ctx) {
0N/A }
0N/A }
0N/A
0N/A public void draw(SunGraphics2D sg, Shape s) {
0N/A if (sg.stroke instanceof BasicStroke) {
0N/A ShapeSpanIterator sr = LoopPipe.getStrokeSpans(sg, s);
0N/A try {
0N/A renderSpans(sg, sg.getCompClip(), s, sr);
0N/A } finally {
0N/A sr.dispose();
0N/A }
0N/A } else {
0N/A fill(sg, sg.stroke.createStrokedShape(s));
0N/A }
0N/A }
0N/A
0N/A public static final int NON_RECTILINEAR_TRANSFORM_MASK =
0N/A (AffineTransform.TYPE_GENERAL_TRANSFORM |
0N/A AffineTransform.TYPE_GENERAL_ROTATION);
0N/A
0N/A public void fill(SunGraphics2D sg, Shape s) {
0N/A if (s instanceof Rectangle2D &&
0N/A (sg.transform.getType() & NON_RECTILINEAR_TRANSFORM_MASK) == 0)
0N/A {
0N/A renderRect(sg, (Rectangle2D) s);
0N/A return;
0N/A }
0N/A
0N/A Region clipRegion = sg.getCompClip();
0N/A ShapeSpanIterator sr = LoopPipe.getFillSSI(sg);
0N/A try {
0N/A sr.setOutputArea(clipRegion);
0N/A sr.appendPath(s.getPathIterator(sg.transform));
0N/A renderSpans(sg, clipRegion, s, sr);
0N/A } finally {
0N/A sr.dispose();
0N/A }
0N/A }
0N/A
0N/A public abstract Object startSequence(SunGraphics2D sg, Shape s,
0N/A Rectangle devR, int[] bbox);
0N/A
0N/A public abstract void renderBox(Object ctx, int x, int y, int w, int h);
0N/A
0N/A public abstract void endSequence(Object ctx);
0N/A
0N/A public void renderRect(SunGraphics2D sg, Rectangle2D r) {
0N/A double corners[] = {
0N/A r.getX(), r.getY(), r.getWidth(), r.getHeight(),
0N/A };
0N/A corners[2] += corners[0];
0N/A corners[3] += corners[1];
0N/A if (corners[2] <= corners[0] || corners[3] <= corners[1]) {
0N/A return;
0N/A }
0N/A sg.transform.transform(corners, 0, corners, 0, 2);
0N/A if (corners[2] < corners[0]) {
0N/A double t = corners[2];
0N/A corners[2] = corners[0];
0N/A corners[0] = t;
0N/A }
0N/A if (corners[3] < corners[1]) {
0N/A double t = corners[3];
0N/A corners[3] = corners[1];
0N/A corners[1] = t;
0N/A }
0N/A int abox[] = {
0N/A (int) corners[0],
0N/A (int) corners[1],
0N/A (int) corners[2],
0N/A (int) corners[3],
0N/A };
0N/A Rectangle devR = new Rectangle(abox[0], abox[1],
0N/A abox[2] - abox[0],
0N/A abox[3] - abox[1]);
0N/A Region clipRegion = sg.getCompClip();
0N/A clipRegion.clipBoxToBounds(abox);
0N/A if (abox[0] >= abox[2] || abox[1] >= abox[3]) {
0N/A return;
0N/A }
0N/A Object context = startSequence(sg, r, devR, abox);
0N/A if (clipRegion.isRectangular()) {
0N/A renderBox(context, abox[0], abox[1],
0N/A abox[2] - abox[0],
0N/A abox[3] - abox[1]);
0N/A } else {
0N/A SpanIterator sr = clipRegion.getSpanIterator(abox);
0N/A while (sr.nextSpan(abox)) {
0N/A renderBox(context, abox[0], abox[1],
0N/A abox[2] - abox[0],
0N/A abox[3] - abox[1]);
0N/A }
0N/A }
0N/A endSequence(context);
0N/A }
0N/A
0N/A public void renderSpans(SunGraphics2D sg, Region clipRegion, Shape s,
0N/A ShapeSpanIterator sr)
0N/A {
0N/A Object context = null;
0N/A int abox[] = new int[4];
0N/A try {
0N/A sr.getPathBox(abox);
0N/A Rectangle devR = new Rectangle(abox[0], abox[1],
0N/A abox[2] - abox[0],
0N/A abox[3] - abox[1]);
0N/A clipRegion.clipBoxToBounds(abox);
0N/A if (abox[0] >= abox[2] || abox[1] >= abox[3]) {
0N/A return;
0N/A }
0N/A sr.intersectClipBox(abox[0], abox[1], abox[2], abox[3]);
0N/A context = startSequence(sg, s, devR, abox);
0N/A
0N/A spanClipLoop(context, sr, clipRegion, abox);
0N/A
0N/A } finally {
0N/A if (context != null) {
0N/A endSequence(context);
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void spanClipLoop(Object ctx, SpanIterator sr,
0N/A Region r, int[] abox) {
0N/A if (!r.isRectangular()) {
0N/A sr = r.filter(sr);
0N/A }
0N/A while (sr.nextSpan(abox)) {
0N/A int x = abox[0];
0N/A int y = abox[1];
0N/A renderBox(ctx, x, y, abox[2] - x, abox[3] - y);
0N/A }
0N/A }
0N/A}