History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/java2d/pipe/RenderingEngine.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/java2d/pipe/RenderingEngine.java+482−0
@@ -0,0 +1,482 @@
1+/*
2+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.java2d.pipe;
27+
28+import java.awt.Shape;
29+import java.awt.BasicStroke;
30+import java.awt.geom.PathIterator;
31+import java.awt.geom.AffineTransform;
32+
33+import java.security.PrivilegedAction;
34+import java.security.AccessController;
35+import java.util.ServiceLoader;
36+import sun.security.action.GetPropertyAction;
37+
38+import sun.awt.geom.PathConsumer2D;
39+
40+/**
41+ * This class abstracts a number of features for which the Java 2D
42+ * implementation relies on proprietary licensed software libraries.
43+ * Access to those features is now achieved by retrieving the singleton
44+ * instance of this class and calling the appropriate methods on it.
45+ * The 3 primary features abstracted here include:
46+ * <dl>
47+ * <dt>Shape createStrokedShape(Shape, [BasicStroke attributes]);
48+ * <dd>This method implements the functionality of the method of the
49+ * same name on the {@link BasicStroke} class.
50+ * <dt>void strokeTo(Shape, [rendering parameters], PathConsumer2D);
51+ * <dd>This method performs widening of the source path on the fly
52+ * and sends the results to the given {@link PathConsumer2D} object.
53+ * This procedure avoids having to create an intermediate Shape
54+ * object to hold the results of the {@code createStrokedShape} method.
55+ * The main user of this method is the Java 2D non-antialiasing renderer.
56+ * <dt>AATileGenerator getAATileGenerator(Shape, [rendering parameters]);
57+ * <dd>This method returns an object which can iterate over the
58+ * specified bounding box and produce tiles of coverage values for
59+ * antialiased rendering. The details of the operation of the
60+ * {@link AATileGenerator} object are explained in its class comments.
61+ * </dl>
62+ * Additionally, the following informational method supplies important
63+ * data about the implementation.
64+ * <dl>
65+ * <dt>float getMinimumAAPenSize()
66+ * <dd>This method provides information on how small the BasicStroke
67+ * line width can get before dropouts occur. Rendering with a BasicStroke
68+ * is defined to never allow the line to have breaks, gaps, or dropouts
69+ * even if the width is set to 0.0f, so this information allows the
70+ * {@link SunGraphics2D} class to detect the "thin line" case and set
71+ * the rendering attributes accordingly.
72+ * </dl>
73+ * At startup the runtime will load a single instance of this class.
74+ * It searches the classpath for a registered provider of this API
75+ * and returns either the last one it finds, or the instance whose
76+ * class name matches the value supplied in the System property
77+ * {@code sun.java2d.renderer}.
78+ * Additionally, a runtime System property flag can be set to trace
79+ * all calls to methods on the {@code RenderingEngine} in use by
80+ * setting the sun.java2d.renderer.trace property to any non-null value.
81+ * <p>
82+ * Parts of the system that need to use any of the above features should
83+ * call {@code RenderingEngine.getInstance()} to obtain the properly
84+ * registered (and possibly trace-enabled) version of the RenderingEngine.
85+ */
86+public abstract class RenderingEngine {
87+ private static RenderingEngine reImpl;
88+
89+ /**
90+ * Returns an instance of {@code RenderingEngine} as determined
91+ * by the installation environment and runtime flags.
92+ * <p>
93+ * A specific instance of the {@code RenderingEngine} can be
94+ * chosen by specifying the runtime flag:
95+ * <pre>
96+ * java -Dsun.java2d.renderer=&lt;classname&gt;
97+ * </pre>
98+ *
99+ * If no specific {@code RenderingEngine} is specified on the command
100+ * or Ductus renderer is specified, it will attempt loading the
101+ * sun.dc.DuctusRenderingEngine class using Class.forName as a fastpath;
102+ * if not found, use the ServiceLoader.
103+ * If no specific {@code RenderingEngine} is specified on the command
104+ * line then the last one returned by enumerating all subclasses of
105+ * {@code RenderingEngine} known to the ServiceLoader is used.
106+ * <p>
107+ * Runtime tracing of the actions of the {@code RenderingEngine}
108+ * can be enabled by specifying the runtime flag:
109+ * <pre>
110+ * java -Dsun.java2d.renderer.trace=&lt;any string&gt;
111+ * </pre>
112+ * @return an instance of {@code RenderingEngine}
113+ * @since 1.7
114+ */
115+ public static synchronized RenderingEngine getInstance() {
116+ if (reImpl != null) {
117+ return reImpl;
118+ }
119+
120+ reImpl = (RenderingEngine)
121+ AccessController.doPrivileged(new PrivilegedAction() {
122+ public Object run() {
123+ final String ductusREClass = "sun.dc.DuctusRenderingEngine";
124+ String reClass =
125+ System.getProperty("sun.java2d.renderer", ductusREClass);
126+ if (reClass.equals(ductusREClass)) {
127+ try {
128+ Class cls = Class.forName(ductusREClass);
129+ return cls.newInstance();
130+ } catch (ClassNotFoundException x) {
131+ // not found
132+ } catch (IllegalAccessException x) {
133+ // should not reach here
134+ } catch (InstantiationException x) {
135+ // should not reach here
136+ }
137+ }
138+
139+ ServiceLoader<RenderingEngine> reLoader =
140+ ServiceLoader.loadInstalled(RenderingEngine.class);
141+
142+ RenderingEngine service = null;
143+
144+ for (RenderingEngine re : reLoader) {
145+ service = re;
146+ if (re.getClass().getName().equals(reClass)) {
147+ break;
148+ }
149+ }
150+ return service;
151+ }
152+ });
153+
154+ if (reImpl == null) {
155+ throw new InternalError("No RenderingEngine module found");
156+ }
157+
158+ GetPropertyAction gpa =
159+ new GetPropertyAction("sun.java2d.renderer.trace");
160+ String reTrace = (String) AccessController.doPrivileged(gpa);
161+ if (reTrace != null) {
162+ reImpl = new Tracer(reImpl);
163+ }
164+
165+ return reImpl;
166+ }
167+
168+ /**
169+ * Create a widened path as specified by the parameters.
170+ * <p>
171+ * The specified {@code src} {@link Shape} is widened according
172+ * to the specified attribute parameters as per the
173+ * {@link BasicStroke} specification.
174+ *
175+ * @param src the source path to be widened
176+ * @param width the width of the widened path as per {@code BasicStroke}
177+ * @param caps the end cap decorations as per {@code BasicStroke}
178+ * @param join the segment join decorations as per {@code BasicStroke}
179+ * @param miterlimit the miter limit as per {@code BasicStroke}
180+ * @param dashes the dash length array as per {@code BasicStroke}
181+ * @param dashphase the initial dash phase as per {@code BasicStroke}
182+ * @return the widened path stored in a new {@code Shape} object
183+ * @since 1.7
184+ */
185+ public abstract Shape createStrokedShape(Shape src,
186+ float width,
187+ int caps,
188+ int join,
189+ float miterlimit,
190+ float dashes[],
191+ float dashphase);
192+
193+ /**
194+ * Sends the geometry for a widened path as specified by the parameters
195+ * to the specified consumer.
196+ * <p>
197+ * The specified {@code src} {@link Shape} is widened according
198+ * to the parameters specified by the {@link BasicStroke} object.
199+ * Adjustments are made to the path as appropriate for the
200+ * {@link VALUE_STROKE_NORMALIZE} hint if the {@code normalize}
201+ * boolean parameter is true.
202+ * Adjustments are made to the path as appropriate for the
203+ * {@link VALUE_ANTIALIAS_ON} hint if the {@code antialias}
204+ * boolean parameter is true.
205+ * <p>
206+ * The geometry of the widened path is forwarded to the indicated
207+ * {@link PathConsumer2D} object as it is calculated.
208+ *
209+ * @param src the source path to be widened
210+ * @param bs the {@code BasicSroke} object specifying the
211+ * decorations to be applied to the widened path
212+ * @param normalize indicates whether stroke normalization should
213+ * be applied
214+ * @param antialias indicates whether or not adjustments appropriate
215+ * to antialiased rendering should be applied
216+ * @param consumer the {@code PathConsumer2D} instance to forward
217+ * the widened geometry to
218+ * @since 1.7
219+ */
220+ public abstract void strokeTo(Shape src,
221+ AffineTransform at,
222+ BasicStroke bs,
223+ boolean thin,
224+ boolean normalize,
225+ boolean antialias,
226+ PathConsumer2D consumer);
227+
228+ /**
229+ * Construct an antialiased tile generator for the given shape with
230+ * the given rendering attributes and store the bounds of the tile
231+ * iteration in the bbox parameter.
232+ * The {@code at} parameter specifies a transform that should affect
233+ * both the shape and the {@code BasicStroke} attributes.
234+ * The {@code clip} parameter specifies the current clip in effect
235+ * in device coordinates and can be used to prune the data for the
236+ * operation, but the renderer is not required to perform any
237+ * clipping.
238+ * If the {@code BasicStroke} parameter is null then the shape
239+ * should be filled as is, otherwise the attributes of the
240+ * {@code BasicStroke} should be used to specify a draw operation.
241+ * The {@code thin} parameter indicates whether or not the
242+ * transformed {@code BasicStroke} represents coordinates smaller
243+ * than the minimum resolution of the antialiasing rasterizer as
244+ * specified by the {@code getMinimumAAPenWidth()} method.
245+ * <p>
246+ * Upon returning, this method will fill the {@code bbox} parameter
247+ * with 4 values indicating the bounds of the iteration of the
248+ * tile generator.
249+ * The iteration order of the tiles will be as specified by the
250+ * pseudo-code:
251+ * <pre>
252+ * for (y = bbox[1]; y < bbox[3]; y += tileheight) {
253+ * for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
254+ * }
255+ * }
256+ * </pre>
257+ * If there is no output to be rendered, this method may return
258+ * null.
259+ *
260+ * @param s the shape to be rendered (fill or draw)
261+ * @param at the transform to be applied to the shape and the
262+ * stroke attributes
263+ * @param clip the current clip in effect in device coordinates
264+ * @param bs if non-null, a {@code BasicStroke} whose attributes
265+ * should be applied to this operation
266+ * @param thin true if the transformed stroke attributes are smaller
267+ * than the minimum dropout pen width
268+ * @param normalize true if the {@code VALUE_STROKE_NORMALIZE}
269+ * {@code RenderingHint} is in effect
270+ * @param bbox returns the bounds of the iteration
271+ * @return the {@code AATileGenerator} instance to be consulted
272+ * for tile coverages, or null if there is no output to render
273+ * @since 1.7
274+ */
275+ public abstract AATileGenerator getAATileGenerator(Shape s,
276+ AffineTransform at,
277+ Region clip,
278+ BasicStroke bs,
279+ boolean thin,
280+ boolean normalize,
281+ int bbox[]);
282+
283+ /**
284+ * Construct an antialiased tile generator for the given parallelogram
285+ * store the bounds of the tile iteration in the bbox parameter.
286+ * The parallelogram is specified as a starting point and 2 delta
287+ * vectors that indicate the slopes of the 2 pairs of sides of the
288+ * parallelogram.
289+ * The 4 corners of the parallelogram are defined by the 4 points:
290+ * <ul>
291+ * <li> {@code x}, {@code y}
292+ * <li> {@code x+dx1}, {@code y+dy1}
293+ * <li> {@code x+dx1+dx2}, {@code y+dy1+dy2}
294+ * <li> {@code x+dx2}, {@code y+dy2}
295+ * </ul>
296+ * The {@code lw1} and {@code lw2} parameters provide a specification
297+ * for an optionally stroked parallelogram if they are positive numbers.
298+ * The {@code lw1} parameter is the ratio of the length of the {@code dx1},
299+ * {@code dx2} delta vector to half of the line width in that same
300+ * direction.
301+ * The {@code lw2} parameter provides the same ratio for the other delta
302+ * vector.
303+ * If {@code lw1} and {@code lw2} are both greater than zero, then
304+ * the parallelogram figure is doubled by both expanding and contracting
305+ * each delta vector by its corresponding {@code lw} value.
306+ * If either (@code lw1) or {@code lw2} are also greater than 1, then
307+ * the inner (contracted) parallelogram disappears and the figure is
308+ * simply a single expanded parallelogram.
309+ * The {@code clip} parameter specifies the current clip in effect
310+ * in device coordinates and can be used to prune the data for the
311+ * operation, but the renderer is not required to perform any
312+ * clipping.
313+ * <p>
314+ * Upon returning, this method will fill the {@code bbox} parameter
315+ * with 4 values indicating the bounds of the iteration of the
316+ * tile generator.
317+ * The iteration order of the tiles will be as specified by the
318+ * pseudo-code:
319+ * <pre>
320+ * for (y = bbox[1]; y < bbox[3]; y += tileheight) {
321+ * for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
322+ * }
323+ * }
324+ * </pre>
325+ * If there is no output to be rendered, this method may return
326+ * null.
327+ *
328+ * @param x the X coordinate of the first corner of the parallelogram
329+ * @param y the Y coordinate of the first corner of the parallelogram
330+ * @param dx1 the X coordinate delta of the first leg of the parallelogram
331+ * @param dy1 the Y coordinate delta of the first leg of the parallelogram
332+ * @param dx2 the X coordinate delta of the second leg of the parallelogram
333+ * @param dy2 the Y coordinate delta of the second leg of the parallelogram
334+ * @param lw1 the line width ratio for the first leg of the parallelogram
335+ * @param lw2 the line width ratio for the second leg of the parallelogram
336+ * @param clip the current clip in effect in device coordinates
337+ * @param bbox returns the bounds of the iteration
338+ * @return the {@code AATileGenerator} instance to be consulted
339+ * for tile coverages, or null if there is no output to render
340+ * @since 1.7
341+ */
342+ public abstract AATileGenerator getAATileGenerator(double x, double y,
343+ double dx1, double dy1,
344+ double dx2, double dy2,
345+ double lw1, double lw2,
346+ Region clip,
347+ int bbox[]);
348+
349+ /**
350+ * Returns the minimum pen width that the antialiasing rasterizer
351+ * can represent without dropouts occuring.
352+ * @since 1.7
353+ */
354+ public abstract float getMinimumAAPenSize();
355+
356+ /**
357+ * Utility method to feed a {@link PathConsumer2D} object from a
358+ * given {@link PathIterator}.
359+ * This method deals with the details of running the iterator and
360+ * feeding the consumer a segment at a time.
361+ */
362+ public static void feedConsumer(PathIterator pi, PathConsumer2D consumer) {
363+ float coords[] = new float[6];
364+ while (!pi.isDone()) {
365+ switch (pi.currentSegment(coords)) {
366+ case PathIterator.SEG_MOVETO:
367+ consumer.moveTo(coords[0], coords[1]);
368+ break;
369+ case PathIterator.SEG_LINETO:
370+ consumer.lineTo(coords[0], coords[1]);
371+ break;
372+ case PathIterator.SEG_QUADTO:
373+ consumer.quadTo(coords[0], coords[1],
374+ coords[2], coords[3]);
375+ break;
376+ case PathIterator.SEG_CUBICTO:
377+ consumer.curveTo(coords[0], coords[1],
378+ coords[2], coords[3],
379+ coords[4], coords[5]);
380+ break;
381+ case PathIterator.SEG_CLOSE:
382+ consumer.closePath();
383+ break;
384+ }
385+ pi.next();
386+ }
387+ }
388+
389+ static class Tracer extends RenderingEngine {
390+ RenderingEngine target;
391+ String name;
392+
393+ public Tracer(RenderingEngine target) {
394+ this.target = target;
395+ name = target.getClass().getName();
396+ }
397+
398+ public Shape createStrokedShape(Shape src,
399+ float width,
400+ int caps,
401+ int join,
402+ float miterlimit,
403+ float dashes[],
404+ float dashphase)
405+ {
406+ System.out.println(name+".createStrokedShape("+
407+ src.getClass().getName()+", "+
408+ "width = "+width+", "+
409+ "caps = "+caps+", "+
410+ "join = "+join+", "+
411+ "miter = "+miterlimit+", "+
412+ "dashes = "+dashes+", "+
413+ "dashphase = "+dashphase+")");
414+ return target.createStrokedShape(src,
415+ width, caps, join, miterlimit,
416+ dashes, dashphase);
417+ }
418+
419+ public void strokeTo(Shape src,
420+ AffineTransform at,
421+ BasicStroke bs,
422+ boolean thin,
423+ boolean normalize,
424+ boolean antialias,
425+ PathConsumer2D consumer)
426+ {
427+ System.out.println(name+".strokeTo("+
428+ src.getClass().getName()+", "+
429+ at+", "+
430+ bs+", "+
431+ (thin ? "thin" : "wide")+", "+
432+ (normalize ? "normalized" : "pure")+", "+
433+ (antialias ? "AA" : "non-AA")+", "+
434+ consumer.getClass().getName()+")");
435+ target.strokeTo(src, at, bs, thin, normalize, antialias, consumer);
436+ }
437+
438+ public float getMinimumAAPenSize() {
439+ System.out.println(name+".getMinimumAAPenSize()");
440+ return target.getMinimumAAPenSize();
441+ }
442+
443+ public AATileGenerator getAATileGenerator(Shape s,
444+ AffineTransform at,
445+ Region clip,
446+ BasicStroke bs,
447+ boolean thin,
448+ boolean normalize,
449+ int bbox[])
450+ {
451+ System.out.println(name+".getAATileGenerator("+
452+ s.getClass().getName()+", "+
453+ at+", "+
454+ clip+", "+
455+ bs+", "+
456+ (thin ? "thin" : "wide")+", "+
457+ (normalize ? "normalized" : "pure")+")");
458+ return target.getAATileGenerator(s, at, clip,
459+ bs, thin, normalize,
460+ bbox);
461+ }
462+ public AATileGenerator getAATileGenerator(double x, double y,
463+ double dx1, double dy1,
464+ double dx2, double dy2,
465+ double lw1, double lw2,
466+ Region clip,
467+ int bbox[])
468+ {
469+ System.out.println(name+".getAATileGenerator("+
470+ x+", "+y+", "+
471+ dx1+", "+dy1+", "+
472+ dx2+", "+dy2+", "+
473+ lw1+", "+lw2+", "+
474+ clip+")");
475+ return target.getAATileGenerator(x, y,
476+ dx1, dy1,
477+ dx2, dy2,
478+ lw1, lw2,
479+ clip, bbox);
480+ }
481+ }
482+}