Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/java2d/pipe/LoopPipe.java
38918 views
/*1* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.pipe;2627import java.awt.Font;28import java.awt.Shape;29import java.awt.BasicStroke;30import java.awt.Polygon;31import java.awt.geom.AffineTransform;32import java.awt.geom.PathIterator;33import java.awt.geom.RoundRectangle2D;34import java.awt.geom.Ellipse2D;35import java.awt.geom.Arc2D;36import java.awt.geom.IllegalPathStateException;37import java.awt.geom.Path2D;38import java.awt.font.GlyphVector;39import sun.java2d.SunGraphics2D;40import sun.java2d.SurfaceData;41import sun.java2d.loops.FontInfo;42import sun.java2d.loops.DrawPolygons;43import sun.java2d.loops.FillParallelogram;44import sun.java2d.loops.DrawParallelogram;45import sun.awt.SunHints;4647public class LoopPipe48implements PixelDrawPipe,49PixelFillPipe,50ParallelogramPipe,51ShapeDrawPipe,52LoopBasedPipe53{54final static RenderingEngine RenderEngine = RenderingEngine.getInstance();5556public void drawLine(SunGraphics2D sg2d,57int x1, int y1, int x2, int y2)58{59int tX = sg2d.transX;60int tY = sg2d.transY;61sg2d.loops.drawLineLoop.DrawLine(sg2d, sg2d.getSurfaceData(),62x1 + tX, y1 + tY,63x2 + tX, y2 + tY);64}6566public void drawRect(SunGraphics2D sg2d,67int x, int y, int width, int height)68{69sg2d.loops.drawRectLoop.DrawRect(sg2d, sg2d.getSurfaceData(),70x + sg2d.transX,71y + sg2d.transY,72width, height);73}7475public void drawRoundRect(SunGraphics2D sg2d,76int x, int y, int width, int height,77int arcWidth, int arcHeight)78{79sg2d.shapepipe.draw(sg2d,80new RoundRectangle2D.Float(x, y, width, height,81arcWidth, arcHeight));82}8384public void drawOval(SunGraphics2D sg2d,85int x, int y, int width, int height)86{87sg2d.shapepipe.draw(sg2d, new Ellipse2D.Float(x, y, width, height));88}8990public void drawArc(SunGraphics2D sg2d,91int x, int y, int width, int height,92int startAngle, int arcAngle)93{94sg2d.shapepipe.draw(sg2d, new Arc2D.Float(x, y, width, height,95startAngle, arcAngle,96Arc2D.OPEN));97}9899public void drawPolyline(SunGraphics2D sg2d,100int xPoints[], int yPoints[],101int nPoints)102{103int nPointsArray[] = { nPoints };104sg2d.loops.drawPolygonsLoop.DrawPolygons(sg2d, sg2d.getSurfaceData(),105xPoints, yPoints,106nPointsArray, 1,107sg2d.transX, sg2d.transY,108false);109}110111public void drawPolygon(SunGraphics2D sg2d,112int xPoints[], int yPoints[],113int nPoints)114{115int nPointsArray[] = { nPoints };116sg2d.loops.drawPolygonsLoop.DrawPolygons(sg2d, sg2d.getSurfaceData(),117xPoints, yPoints,118nPointsArray, 1,119sg2d.transX, sg2d.transY,120true);121}122123public void fillRect(SunGraphics2D sg2d,124int x, int y, int width, int height)125{126sg2d.loops.fillRectLoop.FillRect(sg2d, sg2d.getSurfaceData(),127x + sg2d.transX,128y + sg2d.transY,129width, height);130}131132public void fillRoundRect(SunGraphics2D sg2d,133int x, int y, int width, int height,134int arcWidth, int arcHeight)135{136sg2d.shapepipe.fill(sg2d,137new RoundRectangle2D.Float(x, y, width, height,138arcWidth, arcHeight));139}140141public void fillOval(SunGraphics2D sg2d,142int x, int y, int width, int height)143{144sg2d.shapepipe.fill(sg2d, new Ellipse2D.Float(x, y, width, height));145}146147public void fillArc(SunGraphics2D sg2d,148int x, int y, int width, int height,149int startAngle, int arcAngle)150{151sg2d.shapepipe.fill(sg2d, new Arc2D.Float(x, y, width, height,152startAngle, arcAngle,153Arc2D.PIE));154}155156public void fillPolygon(SunGraphics2D sg2d,157int xPoints[], int yPoints[],158int nPoints)159{160ShapeSpanIterator sr = getFillSSI(sg2d);161162try {163sr.setOutputArea(sg2d.getCompClip());164sr.appendPoly(xPoints, yPoints, nPoints, sg2d.transX, sg2d.transY);165fillSpans(sg2d, sr);166} finally {167sr.dispose();168}169}170171172public void draw(SunGraphics2D sg2d, Shape s) {173if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {174Path2D.Float p2df;175int transX;176int transY;177if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {178if (s instanceof Path2D.Float) {179p2df = (Path2D.Float)s;180} else {181p2df = new Path2D.Float(s);182}183transX = sg2d.transX;184transY = sg2d.transY;185} else {186p2df = new Path2D.Float(s, sg2d.transform);187transX = 0;188transY = 0;189}190sg2d.loops.drawPathLoop.DrawPath(sg2d, sg2d.getSurfaceData(),191transX, transY, p2df);192return;193}194195if (sg2d.strokeState == SunGraphics2D.STROKE_CUSTOM) {196fill(sg2d, sg2d.stroke.createStrokedShape(s));197return;198}199200ShapeSpanIterator sr = getStrokeSpans(sg2d, s);201202try {203fillSpans(sg2d, sr);204} finally {205sr.dispose();206}207}208209/**210* Return a ShapeSpanIterator instance that normalizes as211* appropriate for a fill operation as per the settings in212* the specified SunGraphics2D object.213*214* The ShapeSpanIterator will be newly constructed and ready215* to start taking in geometry.216*217* Note that the caller is responsible for calling dispose()218* on the returned ShapeSpanIterator inside a try/finally block:219* <pre>220* ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);221* try {222* ssi.setOutputArea(clip);223* ssi.appendPath(...); // or appendPoly224* // iterate the spans from ssi and operate on them225* } finally {226* ssi.dispose();227* }228* </pre>229*/230public static ShapeSpanIterator getFillSSI(SunGraphics2D sg2d) {231boolean adjust = ((sg2d.stroke instanceof BasicStroke) &&232sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);233return new ShapeSpanIterator(adjust);234}235236/*237* Return a ShapeSpanIterator ready to iterate the spans of the wide238* outline of Shape s using the attributes of the SunGraphics2D239* object.240*241* The ShapeSpanIterator returned will be fully constructed242* and filled with the geometry from the Shape widened by the243* appropriate BasicStroke and normalization parameters taken244* from the SunGraphics2D object and be ready to start returning245* spans.246*247* Note that the caller is responsible for calling dispose()248* on the returned ShapeSpanIterator inside a try/finally block.249* <pre>250* ShapeSpanIterator ssi = LoopPipe.getStrokeSpans(sg2d, s);251* try {252* // iterate the spans from ssi and operate on them253* } finally {254* ssi.dispose();255* }256* </pre>257*258* REMIND: This should return a SpanIterator interface object259* but the caller needs to dispose() the object and that method260* is only on ShapeSpanIterator.261* TODO: Add a dispose() method to the SpanIterator interface.262*/263public static ShapeSpanIterator getStrokeSpans(SunGraphics2D sg2d,264Shape s)265{266ShapeSpanIterator sr = new ShapeSpanIterator(false);267268try {269sr.setOutputArea(sg2d.getCompClip());270sr.setRule(PathIterator.WIND_NON_ZERO);271272BasicStroke bs = (BasicStroke) sg2d.stroke;273boolean thin = (sg2d.strokeState <= SunGraphics2D.STROKE_THINDASHED);274boolean normalize =275(sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);276277RenderEngine.strokeTo(s,278sg2d.transform, bs,279thin, normalize, false, sr);280} catch (Throwable t) {281sr.dispose();282sr = null;283throw new InternalError("Unable to Stroke shape ("+284t.getMessage()+")", t);285}286return sr;287}288289public void fill(SunGraphics2D sg2d, Shape s) {290if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {291Path2D.Float p2df;292int transX;293int transY;294if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {295if (s instanceof Path2D.Float) {296p2df = (Path2D.Float)s;297} else {298p2df = new Path2D.Float(s);299}300transX = sg2d.transX;301transY = sg2d.transY;302} else {303p2df = new Path2D.Float(s, sg2d.transform);304transX = 0;305transY = 0;306}307sg2d.loops.fillPathLoop.FillPath(sg2d, sg2d.getSurfaceData(),308transX, transY, p2df);309return;310}311312ShapeSpanIterator sr = getFillSSI(sg2d);313try {314sr.setOutputArea(sg2d.getCompClip());315AffineTransform at =316((sg2d.transformState == SunGraphics2D.TRANSFORM_ISIDENT)317? null318: sg2d.transform);319sr.appendPath(s.getPathIterator(at));320fillSpans(sg2d, sr);321} finally {322sr.dispose();323}324}325326private static void fillSpans(SunGraphics2D sg2d, SpanIterator si) {327// REMIND: Eventually, the plan is that it will not be possible for328// fs to be null since the FillSpans loop will be the fundamental329// loop implemented for any destination type...330if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {331si = sg2d.clipRegion.filter(si);332// REMIND: Region.filter produces a Java-only iterator333// with no native counterpart...334} else {335sun.java2d.loops.FillSpans fs = sg2d.loops.fillSpansLoop;336if (fs != null) {337fs.FillSpans(sg2d, sg2d.getSurfaceData(), si);338return;339}340}341int spanbox[] = new int[4];342SurfaceData sd = sg2d.getSurfaceData();343while (si.nextSpan(spanbox)) {344int x = spanbox[0];345int y = spanbox[1];346int w = spanbox[2] - x;347int h = spanbox[3] - y;348sg2d.loops.fillRectLoop.FillRect(sg2d, sd, x, y, w, h);349}350}351352public void fillParallelogram(SunGraphics2D sg2d,353double ux1, double uy1,354double ux2, double uy2,355double x, double y,356double dx1, double dy1,357double dx2, double dy2)358{359FillParallelogram fp = sg2d.loops.fillParallelogramLoop;360fp.FillParallelogram(sg2d, sg2d.getSurfaceData(),361x, y, dx1, dy1, dx2, dy2);362}363364public void drawParallelogram(SunGraphics2D sg2d,365double ux1, double uy1,366double ux2, double uy2,367double x, double y,368double dx1, double dy1,369double dx2, double dy2,370double lw1, double lw2)371{372DrawParallelogram dp = sg2d.loops.drawParallelogramLoop;373dp.DrawParallelogram(sg2d, sg2d.getSurfaceData(),374x, y, dx1, dy1, dx2, dy2, lw1, lw2);375}376}377378379