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 (114 of 18352 files). Show all

Unified · Split

114 files
  1. java/pkg/sun/java2d/pipe/AAShapePipe.class +0 −0
  2. java/pkg/sun/java2d/pipe/AAShapePipe.java +215 −0
  3. java/pkg/sun/java2d/pipe/AATextRenderer.class +0 −0
  4. java/pkg/sun/java2d/pipe/AATextRenderer.java +45 −0
  5. java/pkg/sun/java2d/pipe/AATileGenerator.class +0 −0
  6. java/pkg/sun/java2d/pipe/AATileGenerator.java +111 −0
  7. java/pkg/sun/java2d/pipe/AlphaColorPipe.class +0 −0
  8. java/pkg/sun/java2d/pipe/AlphaColorPipe.java +90 −0
  9. java/pkg/sun/java2d/pipe/AlphaPaintPipe$TileContext.class +0 −0
  10. java/pkg/sun/java2d/pipe/AlphaPaintPipe.class +0 −0
  11. java/pkg/sun/java2d/pipe/AlphaPaintPipe.java +206 −0
  12. java/pkg/sun/java2d/pipe/BufferedBufImgOps.java +393 −0
  13. java/pkg/sun/java2d/pipe/BufferedContext.class +0 −0
  14. java/pkg/sun/java2d/pipe/BufferedContext.java +470 −0
  15. java/pkg/sun/java2d/pipe/BufferedMaskBlit.java +163 −0
  16. java/pkg/sun/java2d/pipe/BufferedMaskFill.java +153 −0
  17. java/pkg/sun/java2d/pipe/BufferedOpCodes.class +0 −0
  18. java/pkg/sun/java2d/pipe/BufferedOpCodes.java +99 −0
  19. java/pkg/sun/java2d/pipe/BufferedPaints.class +0 −0
  20. java/pkg/sun/java2d/pipe/BufferedPaints.java +533 −0
  21. java/pkg/sun/java2d/pipe/BufferedRenderPipe$1.class +0 −0
  22. java/pkg/sun/java2d/pipe/BufferedRenderPipe$AAParallelogramPipe.class +0 −0
  23. java/pkg/sun/java2d/pipe/BufferedRenderPipe$BufferedDrawHandler.class +0 −0
  24. java/pkg/sun/java2d/pipe/BufferedRenderPipe.class +0 −0
  25. java/pkg/sun/java2d/pipe/BufferedRenderPipe.java +601 −0
  26. java/pkg/sun/java2d/pipe/BufferedTextPipe.java +168 −0
  27. java/pkg/sun/java2d/pipe/CompositePipe.class +0 −0
  28. java/pkg/sun/java2d/pipe/CompositePipe.java +50 −0
  29. java/pkg/sun/java2d/pipe/DrawImage.class +0 −0
  30. java/pkg/sun/java2d/pipe/DrawImage.java +1110 −0
  31. java/pkg/sun/java2d/pipe/DrawImagePipe.class +0 −0
  32. java/pkg/sun/java2d/pipe/DrawImagePipe.java +86 −0
  33. java/pkg/sun/java2d/pipe/GeneralCompositePipe$TileContext.class +0 −0
  34. java/pkg/sun/java2d/pipe/GeneralCompositePipe.class +0 −0
  35. java/pkg/sun/java2d/pipe/GeneralCompositePipe.java +154 −0
  36. java/pkg/sun/java2d/pipe/GlyphListLoopPipe.class +0 −0
  37. java/pkg/sun/java2d/pipe/GlyphListLoopPipe.java +60 −0
  38. java/pkg/sun/java2d/pipe/GlyphListPipe.class +0 −0
  39. java/pkg/sun/java2d/pipe/GlyphListPipe.java +147 −0
  40. java/pkg/sun/java2d/pipe/LCDTextRenderer.class +0 −0
  41. java/pkg/sun/java2d/pipe/LCDTextRenderer.java +44 −0
  42. java/pkg/sun/java2d/pipe/LoopBasedPipe.class +0 −0
  43. java/pkg/sun/java2d/pipe/LoopBasedPipe.java +37 −0
  44. java/pkg/sun/java2d/pipe/LoopPipe.class +0 −0
  45. java/pkg/sun/java2d/pipe/LoopPipe.java +378 −0
  46. java/pkg/sun/java2d/pipe/NullPipe.class +0 −0
  47. java/pkg/sun/java2d/pipe/NullPipe.java +155 −0
  48. java/pkg/sun/java2d/pipe/OutlineTextRenderer.class +0 −0
  49. java/pkg/sun/java2d/pipe/OutlineTextRenderer.java +145 −0
  50. java/pkg/sun/java2d/pipe/ParallelogramPipe.class +0 −0
  51. java/pkg/sun/java2d/pipe/ParallelogramPipe.java +76 −0
  52. java/pkg/sun/java2d/pipe/PixelDrawPipe.class +0 −0
  53. java/pkg/sun/java2d/pipe/PixelDrawPipe.java +67 −0
  54. java/pkg/sun/java2d/pipe/PixelFillPipe.class +0 −0
  55. java/pkg/sun/java2d/pipe/PixelFillPipe.java +61 −0
  56. java/pkg/sun/java2d/pipe/PixelToParallelogramConverter.class +0 −0
  57. java/pkg/sun/java2d/pipe/PixelToParallelogramConverter.java +429 −0
  58. java/pkg/sun/java2d/pipe/PixelToShapeConverter.class +0 −0
  59. java/pkg/sun/java2d/pipe/PixelToShapeConverter.java +133 −0
  60. java/pkg/sun/java2d/pipe/Region$ImmutableRegion.class +0 −0
  61. java/pkg/sun/java2d/pipe/Region.class +0 −0
  62. java/pkg/sun/java2d/pipe/Region.java +1255 −0
  63. java/pkg/sun/java2d/pipe/RegionClipSpanIterator.class +0 −0
  64. java/pkg/sun/java2d/pipe/RegionClipSpanIterator.java +392 −0
  65. java/pkg/sun/java2d/pipe/RegionIterator.class +0 −0
  66. java/pkg/sun/java2d/pipe/RegionIterator.java +101 −0
  67. java/pkg/sun/java2d/pipe/RegionSpanIterator.class +0 −0
  68. java/pkg/sun/java2d/pipe/RegionSpanIterator.java +210 −0
  69. java/pkg/sun/java2d/pipe/RenderBuffer.class +0 −0
  70. java/pkg/sun/java2d/pipe/RenderBuffer.java +294 −0
  71. java/pkg/sun/java2d/pipe/RenderQueue.class +0 −0
  72. java/pkg/sun/java2d/pipe/RenderQueue.java +223 −0
  73. java/pkg/sun/java2d/pipe/RenderingEngine$1.class +0 −0
  74. java/pkg/sun/java2d/pipe/RenderingEngine$Tracer.class +0 −0
  75. java/pkg/sun/java2d/pipe/RenderingEngine.class +0 −0
  76. java/pkg/sun/java2d/pipe/RenderingEngine.java +482 −0
  77. java/pkg/sun/java2d/pipe/ShapeDrawPipe.class +0 −0
  78. java/pkg/sun/java2d/pipe/ShapeDrawPipe.java +40 −0
  79. java/pkg/sun/java2d/pipe/ShapeSpanIterator.class +0 −0
  80. java/pkg/sun/java2d/pipe/ShapeSpanIterator.java +201 −0
  81. java/pkg/sun/java2d/pipe/SolidTextRenderer.class +0 −0
  82. java/pkg/sun/java2d/pipe/SolidTextRenderer.java +44 −0
  83. java/pkg/sun/java2d/pipe/SpanClipRenderer$SCRcontext.class +0 −0
  84. java/pkg/sun/java2d/pipe/SpanClipRenderer.class +0 −0
  85. java/pkg/sun/java2d/pipe/SpanClipRenderer.java +141 −0
  86. java/pkg/sun/java2d/pipe/SpanIterator.class +0 −0
  87. java/pkg/sun/java2d/pipe/SpanIterator.java +95 −0
  88. java/pkg/sun/java2d/pipe/SpanShapeRenderer$Composite.class +0 −0
  89. java/pkg/sun/java2d/pipe/SpanShapeRenderer$Simple.class +0 −0
  90. java/pkg/sun/java2d/pipe/SpanShapeRenderer.class +0 −0
  91. java/pkg/sun/java2d/pipe/SpanShapeRenderer.java +216 −0
  92. java/pkg/sun/java2d/pipe/TextPipe.class +0 −0
  93. java/pkg/sun/java2d/pipe/TextPipe.java +49 −0
  94. java/pkg/sun/java2d/pipe/TextRenderer.class +0 −0
  95. java/pkg/sun/java2d/pipe/TextRenderer.java +98 −0
  96. java/pkg/sun/java2d/pipe/ValidatePipe.class +0 −0
  97. java/pkg/sun/java2d/pipe/ValidatePipe.java +241 −0
  98. java/pkg/sun/java2d/pipe/hw/AccelDeviceEventListener.class +0 −0
  99. java/pkg/sun/java2d/pipe/hw/AccelDeviceEventListener.java +59 −0
  100. java/pkg/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java +167 −0
  101. java/pkg/sun/java2d/pipe/hw/AccelGraphicsConfig.class +0 −0
  102. java/pkg/sun/java2d/pipe/hw/AccelGraphicsConfig.java +95 −0
  103. java/pkg/sun/java2d/pipe/hw/AccelSurface.class +0 −0
  104. java/pkg/sun/java2d/pipe/hw/AccelSurface.java +136 −0
  105. java/pkg/sun/java2d/pipe/hw/AccelTypedVolatileImage.java +74 −0
  106. java/pkg/sun/java2d/pipe/hw/BufferedContextProvider.class +0 −0
  107. java/pkg/sun/java2d/pipe/hw/BufferedContextProvider.java +45 −0
  108. java/pkg/sun/java2d/pipe/hw/ContextCapabilities.class +0 −0
  109. java/pkg/sun/java2d/pipe/hw/ContextCapabilities.java +128 −0
  110. java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities$VSyncType.class +0 −0
  111. java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities.class +0 −0
  112. java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java +154 −0
  113. java/pkg/sun/java2d/pipe/hw/mkfile +15 −0
  114. java/pkg/sun/java2d/pipe/mkfile +56 −0
java/pkg/sun/java2d/pipe/AAShapePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AAShapePipe.java+215−0
@@ -0,0 +1,215 @@
1/*
2 * Copyright (c) 1997, 2011, 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
26package sun.java2d.pipe;
27
28import java.awt.BasicStroke;
29import java.awt.Rectangle;
30import java.awt.Shape;
31import java.awt.geom.Rectangle2D;
32import java.awt.geom.PathIterator;
33import sun.awt.SunHints;
34import sun.java2d.SunGraphics2D;
35
36/**
37 * This class is used to convert raw geometry into 8-bit alpha tiles
38 * using an AATileGenerator for application by the next stage of
39 * the pipeline.
40 * This class sets up the Generator and computes the alpha tiles
41 * and then passes them on to a CompositePipe object for painting.
42 */
43public class AAShapePipe
44 implements ShapeDrawPipe, ParallelogramPipe
45{
46 static RenderingEngine renderengine = RenderingEngine.getInstance();
47
48 CompositePipe outpipe;
49
50 public AAShapePipe(CompositePipe pipe) {
51 outpipe = pipe;
52 }
53
54 public void draw(SunGraphics2D sg, Shape s) {
55 BasicStroke bs;
56
57 if (sg.stroke instanceof BasicStroke) {
58 bs = (BasicStroke) sg.stroke;
59 } else {
60 s = sg.stroke.createStrokedShape(s);
61 bs = null;
62 }
63
64 renderPath(sg, s, bs);
65 }
66
67 public void fill(SunGraphics2D sg, Shape s) {
68 renderPath(sg, s, null);
69 }
70
71 private static Rectangle2D computeBBox(double ux1, double uy1,
72 double ux2, double uy2)
73 {
74 if ((ux2 -= ux1) < 0) {
75 ux1 += ux2;
76 ux2 = -ux2;
77 }
78 if ((uy2 -= uy1) < 0) {
79 uy1 += uy2;
80 uy2 = -uy2;
81 }
82 return new Rectangle2D.Double(ux1, uy1, ux2, uy2);
83 }
84
85 public void fillParallelogram(SunGraphics2D sg,
86 double ux1, double uy1,
87 double ux2, double uy2,
88 double x, double y,
89 double dx1, double dy1,
90 double dx2, double dy2)
91 {
92 Region clip = sg.getCompClip();
93 int abox[] = new int[4];
94 AATileGenerator aatg =
95 renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
96 clip, abox);
97 if (aatg == null) {
98 // Nothing to render
99 return;
100 }
101
102 renderTiles(sg, computeBBox(ux1, uy1, ux2, uy2), aatg, abox);
103 }
104
105 public void drawParallelogram(SunGraphics2D sg,
106 double ux1, double uy1,
107 double ux2, double uy2,
108 double x, double y,
109 double dx1, double dy1,
110 double dx2, double dy2,
111 double lw1, double lw2)
112 {
113 Region clip = sg.getCompClip();
114 int abox[] = new int[4];
115 AATileGenerator aatg =
116 renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, lw1, lw2,
117 clip, abox);
118 if (aatg == null) {
119 // Nothing to render
120 return;
121 }
122
123 // Note that bbox is of the original shape, not the wide path.
124 // This is appropriate for handing to Paint methods...
125 renderTiles(sg, computeBBox(ux1, uy1, ux2, uy2), aatg, abox);
126 }
127
128 private static byte[] theTile;
129
130 public synchronized static byte[] getAlphaTile(int len) {
131 byte[] t = theTile;
132 if (t == null || t.length < len) {
133 t = new byte[len];
134 } else {
135 theTile = null;
136 }
137 return t;
138 }
139
140 public synchronized static void dropAlphaTile(byte[] t) {
141 theTile = t;
142 }
143
144 public void renderPath(SunGraphics2D sg, Shape s, BasicStroke bs) {
145 boolean adjust = (bs != null &&
146 sg.strokeHint != SunHints.INTVAL_STROKE_PURE);
147 boolean thin = (sg.strokeState <= sg.STROKE_THINDASHED);
148
149 Region clip = sg.getCompClip();
150 int abox[] = new int[4];
151 AATileGenerator aatg =
152 renderengine.getAATileGenerator(s, sg.transform, clip,
153 bs, thin, adjust, abox);
154 if (aatg == null) {
155 // Nothing to render
156 return;
157 }
158
159 renderTiles(sg, s, aatg, abox);
160 }
161
162 public void renderTiles(SunGraphics2D sg, Shape s,
163 AATileGenerator aatg, int abox[])
164 {
165 Object context = null;
166 byte alpha[] = null;
167 try {
168 context = outpipe.startSequence(sg, s,
169 new Rectangle(abox[0], abox[1],
170 abox[2] - abox[0],
171 abox[3] - abox[1]),
172 abox);
173
174 int tw = aatg.getTileWidth();
175 int th = aatg.getTileHeight();
176 alpha = getAlphaTile(tw * th);
177
178 byte[] atile;
179
180 for (int y = abox[1]; y < abox[3]; y += th) {
181 for (int x = abox[0]; x < abox[2]; x += tw) {
182 int w = Math.min(tw, abox[2] - x);
183 int h = Math.min(th, abox[3] - y);
184
185 int a = aatg.getTypicalAlpha();
186 if (a == 0x00 ||
187 outpipe.needTile(context, x, y, w, h) == false)
188 {
189 aatg.nextTile();
190 outpipe.skipTile(context, x, y);
191 continue;
192 }
193 if (a == 0xff) {
194 atile = null;
195 aatg.nextTile();
196 } else {
197 atile = alpha;
198 aatg.getAlpha(alpha, 0, tw);
199 }
200
201 outpipe.renderPathTile(context, atile, 0, tw,
202 x, y, w, h);
203 }
204 }
205 } finally {
206 aatg.dispose();
207 if (context != null) {
208 outpipe.endSequence(context);
209 }
210 if (alpha != null) {
211 dropAlphaTile(alpha);
212 }
213 }
214 }
215}
java/pkg/sun/java2d/pipe/AATextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AATextRenderer.java+45−0
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2000, 2005, 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
26package sun.java2d.pipe;
27
28import java.awt.font.GlyphVector;
29import sun.java2d.SunGraphics2D;
30import sun.font.GlyphList;
31
32/**
33 * A delegate pipe of SG2D for drawing anti-aliased text with
34 * a solid source colour to an opaque destination.
35 */
36
37public class AATextRenderer extends GlyphListLoopPipe
38 implements LoopBasedPipe
39{
40 protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
41 sg2d.loops.drawGlyphListAALoop.DrawGlyphListAA(sg2d, sg2d.surfaceData,
42 gl);
43 }
44
45}
java/pkg/sun/java2d/pipe/AATileGenerator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AATileGenerator.java+111−0
@@ -0,0 +1,111 @@
1/*
2 * Copyright (c) 2007, 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
26package sun.java2d.pipe;
27
28/**
29 * The API for an object that generates alpha coverage tiles for a given
30 * path.
31 * The {@link RenderingEngine} will be consulted as a factory to return
32 * one of these objects for a given Shape and a given set of rendering
33 * attributes.
34 * This object will iterate through the bounds of the rendering primitive
35 * and return tiles of a constant size as specified by the getTileWidth()
36 * and getTileHeight() parameters.
37 * The iteration order of the tiles will be as specified by the pseudo-code:
38 * <pre>
39 * int bbox[] = {left, top, right, bottom};
40 * AATileGenerator aatg = renderengine.getAATileGenerator(..., bbox);
41 * int tw = aatg.getTileWidth();
42 * int th = aatg.getTileHeight();
43 * byte tile[] = new byte[tw * th];
44 * for (y = top; y < bottom; y += th) {
45 * for (x = left; x < right; x += tw) {
46 * int a = aatg.getTypicalAlpha();
47 * int w = Math.min(tw, right-x);
48 * int h = Math.min(th, bottom-y);
49 * if (a == 0x00) {
50 * // can skip this tile...
51 * aatg.nextTile();
52 * } else if (a == 0xff) {
53 * // can treat this tile like a fillRect
54 * aatg.nextTile();
55 * doFill(x, y, w, h);
56 * } else {
57 * aatg.getAlpha(tile, 0, tw);
58 * handleAlpha(tile, x, y, w, h);
59 * }
60 * }
61 * }
62 * aatg.dispose();
63 * </pre>
64 * The bounding box for the iteration will be returned by the
65 * {@code RenderingEngine} via an argument to the getAATileGenerator() method.
66 */
67public interface AATileGenerator {
68 /**
69 * Gets the width of the tiles that the generator batches output into.
70 * @return the width of the standard alpha tile
71 */
72 public int getTileWidth();
73
74 /**
75 * Gets the height of the tiles that the generator batches output into.
76 * @return the height of the standard alpha tile
77 */
78 public int getTileHeight();
79
80 /**
81 * Gets the typical alpha value that will characterize the current
82 * tile.
83 * The answer may be 0x00 to indicate that the current tile has
84 * no coverage in any of its pixels, or it may be 0xff to indicate
85 * that the current tile is completely covered by the path, or any
86 * other value to indicate non-trivial coverage cases.
87 * @return 0x00 for no coverage, 0xff for total coverage, or any other
88 * value for partial coverage of the tile
89 */
90 public int getTypicalAlpha();
91
92 /**
93 * Skips the current tile and moves on to the next tile.
94 * Either this method, or the getAlpha() method should be called
95 * once per tile, but not both.
96 */
97 public void nextTile();
98
99 /**
100 * Gets the alpha coverage values for the current tile.
101 * Either this method, or the nextTile() method should be called
102 * once per tile, but not both.
103 */
104 public void getAlpha(byte tile[], int offset, int rowstride);
105
106 /**
107 * Disposes this tile generator.
108 * No further calls will be made on this instance.
109 */
110 public void dispose();
111}
java/pkg/sun/java2d/pipe/AlphaColorPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AlphaColorPipe.java+90−0
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 1997, 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
26package sun.java2d.pipe;
27
28import java.awt.Rectangle;
29import java.awt.Shape;
30import sun.java2d.SunGraphics2D;
31
32/**
33 * This class implements a CompositePipe that renders path alpha tiles
34 * into a destination that supports direct alpha compositing of a solid
35 * color, according to one of the rules in the AlphaComposite class.
36 */
37public class AlphaColorPipe implements CompositePipe, ParallelogramPipe {
38 public AlphaColorPipe() {
39 }
40
41 public Object startSequence(SunGraphics2D sg, Shape s, Rectangle dev,
42 int[] abox) {
43 return sg;
44 }
45
46 public boolean needTile(Object context, int x, int y, int w, int h) {
47 return true;
48 }
49
50 public void renderPathTile(Object context,
51 byte[] atile, int offset, int tilesize,
52 int x, int y, int w, int h) {
53 SunGraphics2D sg = (SunGraphics2D) context;
54
55 sg.alphafill.MaskFill(sg, sg.getSurfaceData(), sg.composite,
56 x, y, w, h,
57 atile, offset, tilesize);
58 }
59
60 public void skipTile(Object context, int x, int y) {
61 return;
62 }
63
64 public void endSequence(Object context) {
65 return;
66 }
67
68 public void fillParallelogram(SunGraphics2D sg,
69 double ux1, double uy1,
70 double ux2, double uy2,
71 double x, double y,
72 double dx1, double dy1,
73 double dx2, double dy2)
74 {
75 sg.alphafill.FillAAPgram(sg, sg.getSurfaceData(), sg.composite,
76 x, y, dx1, dy1, dx2, dy2);
77 }
78
79 public void drawParallelogram(SunGraphics2D sg,
80 double ux1, double uy1,
81 double ux2, double uy2,
82 double x, double y,
83 double dx1, double dy1,
84 double dx2, double dy2,
85 double lw1, double lw2)
86 {
87 sg.alphafill.DrawAAPgram(sg, sg.getSurfaceData(), sg.composite,
88 x, y, dx1, dy1, dx2, dy2, lw1, lw2);
89 }
90}
java/pkg/sun/java2d/pipe/AlphaPaintPipe$TileContext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AlphaPaintPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AlphaPaintPipe.java+206−0
@@ -0,0 +1,206 @@
1/*
2 * Copyright (c) 1997, 2002, 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
26package sun.java2d.pipe;
27
28import java.lang.ref.WeakReference;
29import java.awt.Rectangle;
30import java.awt.Shape;
31import java.awt.PaintContext;
32import java.awt.Transparency;
33import java.awt.image.ColorModel;
34import java.awt.image.Raster;
35import java.awt.image.WritableRaster;
36import java.awt.image.BufferedImage;
37import sun.awt.image.BufImgSurfaceData;
38import sun.java2d.SunGraphics2D;
39import sun.java2d.SurfaceData;
40import sun.java2d.loops.Blit;
41import sun.java2d.loops.MaskBlit;
42import sun.java2d.loops.CompositeType;
43import sun.java2d.loops.GraphicsPrimitiveMgr;
44
45/**
46 * This class implements a CompositePipe that renders path alpha tiles
47 * into a destination according to the Composite attribute of a
48 * SunGraphics2D.
49 */
50public class AlphaPaintPipe implements CompositePipe {
51 static WeakReference cachedLastRaster;
52 static WeakReference cachedLastColorModel;
53 static WeakReference cachedLastData;
54
55 static class TileContext {
56 SunGraphics2D sunG2D;
57 PaintContext paintCtxt;
58 ColorModel paintModel;
59 WeakReference lastRaster;
60 WeakReference lastData;
61 MaskBlit lastMask;
62 Blit lastBlit;
63 SurfaceData dstData;
64
65 public TileContext(SunGraphics2D sg, PaintContext pc) {
66 sunG2D = sg;
67 paintCtxt = pc;
68 paintModel = pc.getColorModel();
69 dstData = sg.getSurfaceData();
70 synchronized (AlphaPaintPipe.class) {
71 if (cachedLastColorModel != null &&
72 cachedLastColorModel.get() == paintModel)
73 {
74 this.lastRaster = cachedLastRaster;
75 this.lastData = cachedLastData;
76 }
77 }
78 }
79 }
80
81 public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR,
82 int[] abox) {
83 PaintContext paintContext =
84 sg.paint.createContext(sg.getDeviceColorModel(),
85 devR,
86 s.getBounds2D(),
87 sg.cloneTransform(),
88 sg.getRenderingHints());
89 return new TileContext(sg, paintContext);
90 }
91
92 public boolean needTile(Object context, int x, int y, int w, int h) {
93 return true;
94 }
95
96 private static final int TILE_SIZE = 32;
97
98 public void renderPathTile(Object ctx,
99 byte[] atile, int offset, int tilesize,
100 int x, int y, int w, int h) {
101 TileContext context = (TileContext) ctx;
102 PaintContext paintCtxt = context.paintCtxt;
103 SunGraphics2D sg = context.sunG2D;
104 SurfaceData dstData = context.dstData;
105 SurfaceData srcData = null;
106 Raster lastRas = null;
107 if (context.lastData != null && context.lastRaster != null) {
108 srcData = (SurfaceData) context.lastData.get();
109 lastRas = (Raster) context.lastRaster.get();
110 if (srcData == null || lastRas == null) {
111 srcData = null;
112 lastRas = null;
113 }
114 }
115 ColorModel paintModel = context.paintModel;
116
117 for (int rely = 0; rely < h; rely += TILE_SIZE) {
118 int ty = y + rely;
119 int th = Math.min(h-rely, TILE_SIZE);
120 for (int relx = 0; relx < w; relx += TILE_SIZE) {
121 int tx = x + relx;
122 int tw = Math.min(w-relx, TILE_SIZE);
123
124 Raster srcRaster = paintCtxt.getRaster(tx, ty, tw, th);
125 if ((srcRaster.getMinX() != 0) || (srcRaster.getMinY() != 0)) {
126 srcRaster = srcRaster.createTranslatedChild(0, 0);
127 }
128 if (lastRas != srcRaster) {
129 lastRas = srcRaster;
130 context.lastRaster = new WeakReference(lastRas);
131 // REMIND: This will fail for a non-Writable raster!
132 BufferedImage bImg =
133 new BufferedImage(paintModel,
134 (WritableRaster) srcRaster,
135 paintModel.isAlphaPremultiplied(),
136 null);
137 srcData = BufImgSurfaceData.createData(bImg);
138 context.lastData = new WeakReference(srcData);
139 context.lastMask = null;
140 context.lastBlit = null;
141 }
142
143 if (atile == null) {
144 if (context.lastBlit == null) {
145 CompositeType comptype = sg.imageComp;
146 if (CompositeType.SrcOverNoEa.equals(comptype) &&
147 paintModel.getTransparency() == Transparency.OPAQUE)
148 {
149 comptype = CompositeType.SrcNoEa;
150 }
151 context.lastBlit =
152 Blit.getFromCache(srcData.getSurfaceType(),
153 comptype,
154 dstData.getSurfaceType());
155 }
156 context.lastBlit.Blit(srcData, dstData,
157 sg.composite, null,
158 0, 0, tx, ty, tw, th);
159 } else {
160 if (context.lastMask == null) {
161 CompositeType comptype = sg.imageComp;
162 if (CompositeType.SrcOverNoEa.equals(comptype) &&
163 paintModel.getTransparency() == Transparency.OPAQUE)
164 {
165 comptype = CompositeType.SrcNoEa;
166 }
167 context.lastMask =
168 MaskBlit.getFromCache(srcData.getSurfaceType(),
169 comptype,
170 dstData.getSurfaceType());
171 }
172
173 int toff = offset + rely * tilesize + relx;
174 context.lastMask.MaskBlit(srcData, dstData,
175 sg.composite, null,
176 0, 0, tx, ty, tw, th,
177 atile, toff, tilesize);
178 }
179 }
180 }
181 }
182
183 public void skipTile(Object context, int x, int y) {
184 return;
185 }
186
187 public void endSequence(Object ctx) {
188 TileContext context = (TileContext) ctx;
189 if (context.paintCtxt != null) {
190 context.paintCtxt.dispose();
191 }
192 synchronized (AlphaPaintPipe.class) {
193 if (context.lastData != null) {
194 cachedLastRaster = context.lastRaster;
195 if (cachedLastColorModel == null ||
196 cachedLastColorModel.get() != context.paintModel)
197 {
198 // Avoid creating new WeakReference if possible
199 cachedLastColorModel =
200 new WeakReference(context.paintModel);
201 }
202 cachedLastData = context.lastData;
203 }
204 }
205 }
206}
java/pkg/sun/java2d/pipe/BufferedBufImgOps.java+393−0
@@ -0,0 +1,393 @@
1/*
2 * Copyright (c) 2007, 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
26package sun.java2d.pipe;
27
28import java.awt.color.ColorSpace;
29import java.awt.image.AffineTransformOp;
30import java.awt.image.BufferedImage;
31import java.awt.image.BufferedImageOp;
32import java.awt.image.BufferedImageOp;
33import java.awt.image.ByteLookupTable;
34import java.awt.image.ColorModel;
35import java.awt.image.ConvolveOp;
36import java.awt.image.IndexColorModel;
37import java.awt.image.Kernel;
38import java.awt.image.LookupOp;
39import java.awt.image.LookupTable;
40import java.awt.image.RescaleOp;
41import java.awt.image.ShortLookupTable;
42import sun.java2d.SurfaceData;
43import sun.java2d.loops.CompositeType;
44import static sun.java2d.pipe.BufferedOpCodes.*;
45
46public class BufferedBufImgOps {
47
48 public static void enableBufImgOp(RenderQueue rq, SurfaceData srcData,
49 BufferedImage srcImg,
50 BufferedImageOp biop)
51 {
52 if (biop instanceof ConvolveOp) {
53 enableConvolveOp(rq, srcData, (ConvolveOp)biop);
54 } else if (biop instanceof RescaleOp) {
55 enableRescaleOp(rq, srcData, srcImg, (RescaleOp)biop);
56 } else if (biop instanceof LookupOp) {
57 enableLookupOp(rq, srcData, srcImg, (LookupOp)biop);
58 } else {
59 throw new InternalError("Unknown BufferedImageOp");
60 }
61 }
62
63 public static void disableBufImgOp(RenderQueue rq, BufferedImageOp biop) {
64 if (biop instanceof ConvolveOp) {
65 disableConvolveOp(rq);
66 } else if (biop instanceof RescaleOp) {
67 disableRescaleOp(rq);
68 } else if (biop instanceof LookupOp) {
69 disableLookupOp(rq);
70 } else {
71 throw new InternalError("Unknown BufferedImageOp");
72 }
73 }
74
75/**************************** ConvolveOp support ****************************/
76
77 public static boolean isConvolveOpValid(ConvolveOp cop) {
78 Kernel kernel = cop.getKernel();
79 int kw = kernel.getWidth();
80 int kh = kernel.getHeight();
81 // REMIND: we currently can only handle 3x3 and 5x5 kernels,
82 // but hopefully this is just a temporary restriction;
83 // see native shader comments for more details
84 if (!(kw == 3 && kh == 3) && !(kw == 5 && kh == 5)) {
85 return false;
86 }
87 return true;
88 }
89
90 private static void enableConvolveOp(RenderQueue rq,
91 SurfaceData srcData,
92 ConvolveOp cop)
93 {
94 // assert rq.lock.isHeldByCurrentThread();
95 boolean edgeZero =
96 cop.getEdgeCondition() == ConvolveOp.EDGE_ZERO_FILL;
97 Kernel kernel = cop.getKernel();
98 int kernelWidth = kernel.getWidth();
99 int kernelHeight = kernel.getHeight();
100 int kernelSize = kernelWidth * kernelHeight;
101 int sizeofFloat = 4;
102 int totalBytesRequired = 4 + 8 + 12 + (kernelSize * sizeofFloat);
103
104 RenderBuffer buf = rq.getBuffer();
105 rq.ensureCapacityAndAlignment(totalBytesRequired, 4);
106 buf.putInt(ENABLE_CONVOLVE_OP);
107 buf.putLong(srcData.getNativeOps());
108 buf.putInt(edgeZero ? 1 : 0);
109 buf.putInt(kernelWidth);
110 buf.putInt(kernelHeight);
111 buf.put(kernel.getKernelData(null));
112 }
113
114 private static void disableConvolveOp(RenderQueue rq) {
115 // assert rq.lock.isHeldByCurrentThread();
116 RenderBuffer buf = rq.getBuffer();
117 rq.ensureCapacity(4);
118 buf.putInt(DISABLE_CONVOLVE_OP);
119 }
120
121/**************************** RescaleOp support *****************************/
122
123 public static boolean isRescaleOpValid(RescaleOp rop,
124 BufferedImage srcImg)
125 {
126 int numFactors = rop.getNumFactors();
127 ColorModel srcCM = srcImg.getColorModel();
128
129 if (srcCM instanceof IndexColorModel) {
130 throw new
131 IllegalArgumentException("Rescaling cannot be "+
132 "performed on an indexed image");
133 }
134 if (numFactors != 1 &&
135 numFactors != srcCM.getNumColorComponents() &&
136 numFactors != srcCM.getNumComponents())
137 {
138 throw new IllegalArgumentException("Number of scaling constants "+
139 "does not equal the number of"+
140 " of color or color/alpha "+
141 " components");
142 }
143
144 int csType = srcCM.getColorSpace().getType();
145 if (csType != ColorSpace.TYPE_RGB &&
146 csType != ColorSpace.TYPE_GRAY)
147 {
148 // Not prepared to deal with other color spaces
149 return false;
150 }
151
152 if (numFactors == 2 || numFactors > 4) {
153 // Not really prepared to handle this at the native level, so...
154 return false;
155 }
156
157 return true;
158 }
159
160 private static void enableRescaleOp(RenderQueue rq,
161 SurfaceData srcData,
162 BufferedImage srcImg,
163 RescaleOp rop)
164 {
165 // assert rq.lock.isHeldByCurrentThread();
166 ColorModel srcCM = srcImg.getColorModel();
167 boolean nonPremult =
168 srcCM.hasAlpha() &&
169 srcCM.isAlphaPremultiplied();
170
171 /*
172 * Note: The user-provided scale factors and offsets are arranged
173 * in R/G/B/A order, regardless of the raw data order of the
174 * underlying Raster/DataBuffer. The source image data is ultimately
175 * converted into RGBA data when uploaded to an OpenGL texture
176 * (even for TYPE_GRAY), so the scale factors and offsets are already
177 * in the order expected by the native OpenGL code.
178 *
179 * However, the offsets provided by the user are in a range dictated
180 * by the size of each color/alpha band in the source image. For
181 * example, for 8/8/8 data each offset is in the range [0,255],
182 * for 5/5/5 data each offset is in the range [0,31], and so on.
183 * The OpenGL shader only thinks in terms of [0,1], so below we need
184 * to normalize the user-provided offset values into the range [0,1].
185 */
186 int numFactors = rop.getNumFactors();
187 float[] origScaleFactors = rop.getScaleFactors(null);
188 float[] origOffsets = rop.getOffsets(null);
189
190 // To make things easier, we will always pass all four bands
191 // down to native code...
192 float[] normScaleFactors;
193 float[] normOffsets;
194
195 if (numFactors == 1) {
196 normScaleFactors = new float[4];
197 normOffsets = new float[4];
198 for (int i = 0; i < 3; i++) {
199 normScaleFactors[i] = origScaleFactors[0];
200 normOffsets[i] = origOffsets[0];
201 }
202 // Leave alpha untouched...
203 normScaleFactors[3] = 1.0f;
204 normOffsets[3] = 0.0f;
205 } else if (numFactors == 3) {
206 normScaleFactors = new float[4];
207 normOffsets = new float[4];
208 for (int i = 0; i < 3; i++) {
209 normScaleFactors[i] = origScaleFactors[i];
210 normOffsets[i] = origOffsets[i];
211 }
212 // Leave alpha untouched...
213 normScaleFactors[3] = 1.0f;
214 normOffsets[3] = 0.0f;
215 } else { // (numFactors == 4)
216 normScaleFactors = origScaleFactors;
217 normOffsets = origOffsets;
218 }
219
220 // The user-provided offsets are specified in the range
221 // of each source color band, but the OpenGL shader only wants
222 // to deal with data in the range [0,1], so we need to normalize
223 // each offset value to the range [0,1] here.
224 if (srcCM.getNumComponents() == 1) {
225 // Gray data
226 int nBits = srcCM.getComponentSize(0);
227 int maxValue = (1 << nBits) - 1;
228 for (int i = 0; i < 3; i++) {
229 normOffsets[i] /= maxValue;
230 }
231 } else {
232 // RGB(A) data
233 for (int i = 0; i < srcCM.getNumComponents(); i++) {
234 int nBits = srcCM.getComponentSize(i);
235 int maxValue = (1 << nBits) - 1;
236 normOffsets[i] /= maxValue;
237 }
238 }
239
240 int sizeofFloat = 4;
241 int totalBytesRequired = 4 + 8 + 4 + (4 * sizeofFloat * 2);
242
243 RenderBuffer buf = rq.getBuffer();
244 rq.ensureCapacityAndAlignment(totalBytesRequired, 4);
245 buf.putInt(ENABLE_RESCALE_OP);
246 buf.putLong(srcData.getNativeOps());
247 buf.putInt(nonPremult ? 1 : 0);
248 buf.put(normScaleFactors);
249 buf.put(normOffsets);
250 }
251
252 private static void disableRescaleOp(RenderQueue rq) {
253 // assert rq.lock.isHeldByCurrentThread();
254 RenderBuffer buf = rq.getBuffer();
255 rq.ensureCapacity(4);
256 buf.putInt(DISABLE_RESCALE_OP);
257 }
258
259/**************************** LookupOp support ******************************/
260
261 public static boolean isLookupOpValid(LookupOp lop,
262 BufferedImage srcImg)
263 {
264 LookupTable table = lop.getTable();
265 int numComps = table.getNumComponents();
266 ColorModel srcCM = srcImg.getColorModel();
267
268 if (srcCM instanceof IndexColorModel) {
269 throw new
270 IllegalArgumentException("LookupOp cannot be "+
271 "performed on an indexed image");
272 }
273 if (numComps != 1 &&
274 numComps != srcCM.getNumComponents() &&
275 numComps != srcCM.getNumColorComponents())
276 {
277 throw new IllegalArgumentException("Number of arrays in the "+
278 " lookup table ("+
279 numComps+
280 ") is not compatible with"+
281 " the src image: "+srcImg);
282 }
283
284 int csType = srcCM.getColorSpace().getType();
285 if (csType != ColorSpace.TYPE_RGB &&
286 csType != ColorSpace.TYPE_GRAY)
287 {
288 // Not prepared to deal with other color spaces
289 return false;
290 }
291
292 if (numComps == 2 || numComps > 4) {
293 // Not really prepared to handle this at the native level, so...
294 return false;
295 }
296
297 // The LookupTable spec says that "all arrays must be the
298 // same size" but unfortunately the constructors do not
299 // enforce that. Also, our native code only works with
300 // arrays no larger than 256 elements, so check both of
301 // these restrictions here.
302 if (table instanceof ByteLookupTable) {
303 byte[][] data = ((ByteLookupTable)table).getTable();
304 for (int i = 1; i < data.length; i++) {
305 if (data[i].length > 256 ||
306 data[i].length != data[i-1].length)
307 {
308 return false;
309 }
310 }
311 } else if (table instanceof ShortLookupTable) {
312 short[][] data = ((ShortLookupTable)table).getTable();
313 for (int i = 1; i < data.length; i++) {
314 if (data[i].length > 256 ||
315 data[i].length != data[i-1].length)
316 {
317 return false;
318 }
319 }
320 } else {
321 return false;
322 }
323
324 return true;
325 }
326
327 private static void enableLookupOp(RenderQueue rq,
328 SurfaceData srcData,
329 BufferedImage srcImg,
330 LookupOp lop)
331 {
332 // assert rq.lock.isHeldByCurrentThread();
333 boolean nonPremult =
334 srcImg.getColorModel().hasAlpha() &&
335 srcImg.isAlphaPremultiplied();
336
337 LookupTable table = lop.getTable();
338 int numBands = table.getNumComponents();
339 int offset = table.getOffset();
340 int bandLength;
341 int bytesPerElem;
342 boolean shortData;
343
344 if (table instanceof ShortLookupTable) {
345 short[][] data = ((ShortLookupTable)table).getTable();
346 bandLength = data[0].length;
347 bytesPerElem = 2;
348 shortData = true;
349 } else { // (table instanceof ByteLookupTable)
350 byte[][] data = ((ByteLookupTable)table).getTable();
351 bandLength = data[0].length;
352 bytesPerElem = 1;
353 shortData = false;
354 }
355
356 // Adjust the LUT length so that it ends on a 4-byte boundary
357 int totalLutBytes = numBands * bandLength * bytesPerElem;
358 int paddedLutBytes = (totalLutBytes + 3) & (~3);
359 int padding = paddedLutBytes - totalLutBytes;
360 int totalBytesRequired = 4 + 8 + 20 + paddedLutBytes;
361
362 RenderBuffer buf = rq.getBuffer();
363 rq.ensureCapacityAndAlignment(totalBytesRequired, 4);
364 buf.putInt(ENABLE_LOOKUP_OP);
365 buf.putLong(srcData.getNativeOps());
366 buf.putInt(nonPremult ? 1 : 0);
367 buf.putInt(shortData ? 1 : 0);
368 buf.putInt(numBands);
369 buf.putInt(bandLength);
370 buf.putInt(offset);
371 if (shortData) {
372 short[][] data = ((ShortLookupTable)table).getTable();
373 for (int i = 0; i < numBands; i++) {
374 buf.put(data[i]);
375 }
376 } else {
377 byte[][] data = ((ByteLookupTable)table).getTable();
378 for (int i = 0; i < numBands; i++) {
379 buf.put(data[i]);
380 }
381 }
382 if (padding != 0) {
383 buf.position(buf.position() + padding);
384 }
385 }
386
387 private static void disableLookupOp(RenderQueue rq) {
388 // assert rq.lock.isHeldByCurrentThread();
389 RenderBuffer buf = rq.getBuffer();
390 rq.ensureCapacity(4);
391 buf.putInt(DISABLE_LOOKUP_OP);
392 }
393}
java/pkg/sun/java2d/pipe/BufferedContext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedContext.java+470−0
@@ -0,0 +1,470 @@
1/*
2 * Copyright (c) 2005, 2008, 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
26package sun.java2d.pipe;
27
28import java.awt.AlphaComposite;
29import java.awt.Color;
30import java.awt.Composite;
31import java.awt.Paint;
32import java.awt.geom.AffineTransform;
33import sun.java2d.pipe.hw.AccelSurface;
34import sun.java2d.InvalidPipeException;
35import sun.java2d.SunGraphics2D;
36import sun.java2d.loops.XORComposite;
37import static sun.java2d.pipe.BufferedOpCodes.*;
38import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN;
39
40/**
41 * Base context class for managing state in a single-threaded rendering
42 * environment. Each state-setting operation (e.g. SET_COLOR) is added to
43 * the provided RenderQueue, which will be processed at a later time by a
44 * single thread. Note that the RenderQueue lock must be acquired before
45 * calling the validate() method (or any other method in this class). See
46 * the RenderQueue class comments for a sample usage scenario.
47 *
48 * @see RenderQueue
49 */
50public abstract class BufferedContext {
51
52 /*
53 * The following flags help the internals of validate() determine
54 * the appropriate (meaning correct, or optimal) code path when
55 * setting up the current context. The flags can be bitwise OR'd
56 * together as needed.
57 */
58
59 /**
60 * Indicates that no flags are needed; take all default code paths.
61 */
62 public static final int NO_CONTEXT_FLAGS = (0 << 0);
63 /**
64 * Indicates that the source surface (or color value, if it is a simple
65 * rendering operation) is opaque (has an alpha value of 1.0). If this
66 * flag is present, it allows us to disable blending in certain
67 * situations in order to improve performance.
68 */
69 public static final int SRC_IS_OPAQUE = (1 << 0);
70 /**
71 * Indicates that the operation uses an alpha mask, which may determine
72 * the code path that is used when setting up the current paint state.
73 */
74 public static final int USE_MASK = (1 << 1);
75
76 protected RenderQueue rq;
77 protected RenderBuffer buf;
78
79 /**
80 * This is a reference to the most recently validated BufferedContext. If
81 * this value is null, it means that there is no current context. It is
82 * provided here so that validate() only needs to do a quick reference
83 * check to see if the BufferedContext passed to that method is the same
84 * as the one we've cached here.
85 */
86 protected static BufferedContext currentContext;
87
88 private AccelSurface validatedSrcData;
89 private AccelSurface validatedDstData;
90 private Region validatedClip;
91 private Composite validatedComp;
92 private Paint validatedPaint;
93 // renamed from isValidatedPaintAColor as part of a work around for 6764257
94 private boolean isValidatedPaintJustAColor;
95 private int validatedRGB;
96 private int validatedFlags;
97 private boolean xformInUse;
98 private int transX;
99 private int transY;
100
101 protected BufferedContext(RenderQueue rq) {
102 this.rq = rq;
103 this.buf = rq.getBuffer();
104 }
105
106 /**
107 * Fetches the BufferedContextContext associated with the dst. surface
108 * and validates the context using the given parameters. Most rendering
109 * operations will call this method first in order to set the necessary
110 * state before issuing rendering commands.
111 *
112 * Note: must be called while the RenderQueue lock is held.
113 *
114 * @throws InvalidPipeException if either src or dest surface is not valid
115 * or lost
116 * @see RenderQueue#lock
117 * @see RenderQueue#unlock
118 */
119 public static void validateContext(AccelSurface srcData,
120 AccelSurface dstData,
121 Region clip, Composite comp,
122 AffineTransform xform,
123 Paint paint, SunGraphics2D sg2d,
124 int flags)
125 {
126 // assert rq.lock.isHeldByCurrentThread();
127 BufferedContext d3dc = dstData.getContext();
128 d3dc.validate(srcData, dstData,
129 clip, comp, xform, paint, sg2d, flags);
130 }
131
132 /**
133 * Fetches the BufferedContextassociated with the surface
134 * and disables all context state settings.
135 *
136 * Note: must be called while the RenderQueue lock is held.
137 *
138 * @throws InvalidPipeException if the surface is not valid
139 * or lost
140 * @see RenderQueue#lock
141 * @see RenderQueue#unlock
142 */
143 public static void validateContext(AccelSurface surface) {
144 // assert rt.lock.isHeldByCurrentThread();
145 validateContext(surface, surface,
146 null, null, null, null, null, NO_CONTEXT_FLAGS);
147 }
148
149 /**
150 * Validates the given parameters against the current state for this
151 * context. If this context is not current, it will be made current
152 * for the given source and destination surfaces, and the viewport will
153 * be updated. Then each part of the context state (clip, composite,
154 * etc.) is checked against the previous value. If the value has changed
155 * since the last call to validate(), it will be updated accordingly.
156 *
157 * Note that the SunGraphics2D parameter is only used for the purposes
158 * of validating a (non-null) Paint parameter. In all other cases it
159 * is safe to pass a null SunGraphics2D and it will be ignored.
160 *
161 * Note: must be called while the RenderQueue lock is held.
162 *
163 * @throws InvalidPipeException if either src or dest surface is not valid
164 * or lost
165 */
166 public void validate(AccelSurface srcData, AccelSurface dstData,
167 Region clip, Composite comp,
168 AffineTransform xform,
169 Paint paint, SunGraphics2D sg2d, int flags)
170 {
171 // assert rq.lock.isHeldByCurrentThread();
172
173 boolean updateClip = false;
174 boolean updatePaint = false;
175
176 if (!dstData.isValid() ||
177 dstData.isSurfaceLost() || srcData.isSurfaceLost())
178 {
179 invalidateContext();
180 throw new InvalidPipeException("bounds changed or surface lost");
181 }
182
183 if (paint instanceof Color) {
184 // REMIND: not 30-bit friendly
185 int newRGB = ((Color)paint).getRGB();
186 if (isValidatedPaintJustAColor) {
187 if (newRGB != validatedRGB) {
188 validatedRGB = newRGB;
189 updatePaint = true;
190 }
191 } else {
192 validatedRGB = newRGB;
193 updatePaint = true;
194 isValidatedPaintJustAColor = true;
195 }
196 } else if (validatedPaint != paint) {
197 updatePaint = true;
198 // this should be set when we are switching from paint to color
199 // in which case this condition will be true
200 isValidatedPaintJustAColor = false;
201 }
202
203 if ((currentContext != this) ||
204 (srcData != validatedSrcData) ||
205 (dstData != validatedDstData))
206 {
207 if (dstData != validatedDstData) {
208 // the clip is dependent on the destination surface, so we
209 // need to update it if we have a new destination surface
210 updateClip = true;
211 }
212
213 if (paint == null) {
214 // make sure we update the color state (otherwise, it might
215 // not be updated if this is the first time the context
216 // is being validated)
217 updatePaint = true;
218 }
219
220 // update the current source and destination surfaces
221 setSurfaces(srcData, dstData);
222
223 currentContext = this;
224 validatedSrcData = srcData;
225 validatedDstData = dstData;
226 }
227
228 // validate clip
229 if ((clip != validatedClip) || updateClip) {
230 if (clip != null) {
231 if (updateClip ||
232 validatedClip == null ||
233 !(validatedClip.isRectangular() && clip.isRectangular()) ||
234 ((clip.getLoX() != validatedClip.getLoX() ||
235 clip.getLoY() != validatedClip.getLoY() ||
236 clip.getHiX() != validatedClip.getHiX() ||
237 clip.getHiY() != validatedClip.getHiY())))
238 {
239 setClip(clip);
240 }
241 } else {
242 resetClip();
243 }
244 validatedClip = clip;
245 }
246
247 // validate composite (note that a change in the context flags
248 // may require us to update the composite state, even if the
249 // composite has not changed)
250 if ((comp != validatedComp) || (flags != validatedFlags)) {
251 if (comp != null) {
252 setComposite(comp, flags);
253 } else {
254 resetComposite();
255 }
256 // the paint state is dependent on the composite state, so make
257 // sure we update the color below
258 updatePaint = true;
259 validatedComp = comp;
260 validatedFlags = flags;
261 }
262
263 // validate transform
264 boolean txChanged = false;
265 if (xform == null) {
266 if (xformInUse) {
267 resetTransform();
268 xformInUse = false;
269 txChanged = true;
270 } else if (sg2d != null) {
271 if (transX != sg2d.transX || transY != sg2d.transY) {
272 txChanged = true;
273 }
274 }
275 if (sg2d != null) {
276 transX = sg2d.transX;
277 transY = sg2d.transY;
278 }
279 } else {
280 setTransform(xform);
281 xformInUse = true;
282 txChanged = true;
283 }
284 // non-Color paints may require paint revalidation
285 if (!isValidatedPaintJustAColor && txChanged) {
286 updatePaint = true;
287 }
288
289 // validate paint
290 if (updatePaint) {
291 if (paint != null) {
292 BufferedPaints.setPaint(rq, sg2d, paint, flags);
293 } else {
294 BufferedPaints.resetPaint(rq);
295 }
296 validatedPaint = paint;
297 }
298
299 // mark dstData dirty
300 // REMIND: is this really needed now? we do it in SunGraphics2D..
301 dstData.markDirty();
302 }
303
304 /**
305 * Invalidates the surfaces associated with this context. This is
306 * useful when the context is no longer needed, and we want to break
307 * the chain caused by these surface references.
308 *
309 * Note: must be called while the RenderQueue lock is held.
310 *
311 * @see RenderQueue#lock
312 * @see RenderQueue#unlock
313 */
314 public void invalidateSurfaces() {
315 validatedSrcData = null;
316 validatedDstData = null;
317 }
318
319 private void setSurfaces(AccelSurface srcData,
320 AccelSurface dstData)
321 {
322 // assert rq.lock.isHeldByCurrentThread();
323 rq.ensureCapacityAndAlignment(20, 4);
324 buf.putInt(SET_SURFACES);
325 buf.putLong(srcData.getNativeOps());
326 buf.putLong(dstData.getNativeOps());
327 }
328
329 private void resetClip() {
330 // assert rq.lock.isHeldByCurrentThread();
331 rq.ensureCapacity(4);
332 buf.putInt(RESET_CLIP);
333 }
334
335 private void setClip(Region clip) {
336 // assert rq.lock.isHeldByCurrentThread();
337 if (clip.isRectangular()) {
338 rq.ensureCapacity(20);
339 buf.putInt(SET_RECT_CLIP);
340 buf.putInt(clip.getLoX()).putInt(clip.getLoY());
341 buf.putInt(clip.getHiX()).putInt(clip.getHiY());
342 } else {
343 rq.ensureCapacity(28); // so that we have room for at least a span
344 buf.putInt(BEGIN_SHAPE_CLIP);
345 buf.putInt(SET_SHAPE_CLIP_SPANS);
346 // include a placeholder for the span count
347 int countIndex = buf.position();
348 buf.putInt(0);
349 int spanCount = 0;
350 int remainingSpans = buf.remaining() / BYTES_PER_SPAN;
351 int span[] = new int[4];
352 SpanIterator si = clip.getSpanIterator();
353 while (si.nextSpan(span)) {
354 if (remainingSpans == 0) {
355 buf.putInt(countIndex, spanCount);
356 rq.flushNow();
357 buf.putInt(SET_SHAPE_CLIP_SPANS);
358 countIndex = buf.position();
359 buf.putInt(0);
360 spanCount = 0;
361 remainingSpans = buf.remaining() / BYTES_PER_SPAN;
362 }
363 buf.putInt(span[0]); // x1
364 buf.putInt(span[1]); // y1
365 buf.putInt(span[2]); // x2
366 buf.putInt(span[3]); // y2
367 spanCount++;
368 remainingSpans--;
369 }
370 buf.putInt(countIndex, spanCount);
371 rq.ensureCapacity(4);
372 buf.putInt(END_SHAPE_CLIP);
373 }
374 }
375
376 private void resetComposite() {
377 // assert rq.lock.isHeldByCurrentThread();
378 rq.ensureCapacity(4);
379 buf.putInt(RESET_COMPOSITE);
380 }
381
382 private void setComposite(Composite comp, int flags) {
383 // assert rq.lock.isHeldByCurrentThread();
384 if (comp instanceof AlphaComposite) {
385 AlphaComposite ac = (AlphaComposite)comp;
386 rq.ensureCapacity(16);
387 buf.putInt(SET_ALPHA_COMPOSITE);
388 buf.putInt(ac.getRule());
389 buf.putFloat(ac.getAlpha());
390 buf.putInt(flags);
391 } else if (comp instanceof XORComposite) {
392 int xorPixel = ((XORComposite)comp).getXorPixel();
393 rq.ensureCapacity(8);
394 buf.putInt(SET_XOR_COMPOSITE);
395 buf.putInt(xorPixel);
396 } else {
397 throw new InternalError("not yet implemented");
398 }
399 }
400
401 private void resetTransform() {
402 // assert rq.lock.isHeldByCurrentThread();
403 rq.ensureCapacity(4);
404 buf.putInt(RESET_TRANSFORM);
405 }
406
407 private void setTransform(AffineTransform xform) {
408 // assert rq.lock.isHeldByCurrentThread();
409 rq.ensureCapacityAndAlignment(52, 4);
410 buf.putInt(SET_TRANSFORM);
411 buf.putDouble(xform.getScaleX());
412 buf.putDouble(xform.getShearY());
413 buf.putDouble(xform.getShearX());
414 buf.putDouble(xform.getScaleY());
415 buf.putDouble(xform.getTranslateX());
416 buf.putDouble(xform.getTranslateY());
417 }
418
419 /**
420 * Resets this context's surfaces and all attributes.
421 *
422 * Note: must be called while the RenderQueue lock is held.
423 *
424 * @see RenderQueue#lock
425 * @see RenderQueue#unlock
426 */
427 public void invalidateContext() {
428 resetTransform();
429 resetComposite();
430 resetClip();
431 BufferedPaints.resetPaint(rq);
432 invalidateSurfaces();
433 validatedComp = null;
434 validatedClip = null;
435 validatedPaint = null;
436 isValidatedPaintJustAColor = false;
437 xformInUse = false;
438 }
439
440 /**
441 * Returns a singleton {@code RenderQueue} object used by the rendering
442 * pipeline.
443 *
444 * @return a render queue
445 * @see RenderQueue
446 */
447 public abstract RenderQueue getRenderQueue();
448
449 /**
450 * Saves the the state of this context.
451 * It may reset the current context.
452 *
453 * Note: must be called while the RenderQueue lock is held.
454 *
455 * @see RenderQueue#lock
456 * @see RenderQueue#unlock
457 */
458 public abstract void saveState();
459
460 /**
461 * Restores the native state of this context.
462 * It may reset the current context.
463 *
464 * Note: must be called while the RenderQueue lock is held.
465 *
466 * @see RenderQueue#lock
467 * @see RenderQueue#unlock
468 */
469 public abstract void restoreState();
470}
java/pkg/sun/java2d/pipe/BufferedMaskBlit.java+163−0
@@ -0,0 +1,163 @@
1/*
2 * Copyright (c) 2007, 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
26package sun.java2d.pipe;
27
28import java.awt.AlphaComposite;
29import java.awt.Composite;
30import sun.java2d.SurfaceData;
31import sun.java2d.loops.Blit;
32import sun.java2d.loops.CompositeType;
33import sun.java2d.loops.MaskBlit;
34import sun.java2d.loops.SurfaceType;
35import static sun.java2d.pipe.BufferedOpCodes.*;
36
37/**
38 * The MaskBlit operation is expressed as:
39 * dst = ((src <MODE> dst) * pathA) + (dst * (1 - pathA))
40 *
41 * The OGL/D3D implementation of the MaskBlit operation differs from the above
42 * equation because it is not possible to perform such a complex operation in
43 * OpenGL/Direct3D (without the use of advanced techniques like fragment
44 * shaders and multitexturing). Therefore, the BufferedMaskBlit operation
45 * is expressed as:
46 * dst = (src * pathA) <SrcOver> dst
47 *
48 * This simplified formula is only equivalent to the "true" MaskBlit equation
49 * in the following situations:
50 * - <MODE> is SrcOver
51 * - <MODE> is Src, extra alpha == 1.0, and the source surface is opaque
52 *
53 * Therefore, we register BufferedMaskBlit primitives for only the SurfaceType
54 * and CompositeType restrictions mentioned above. In addition for the Src
55 * case, we must override the composite with a SrcOver (no extra alpha)
56 * instance, so that we set up the OpenGL/Direct3D blending mode to match the
57 * BufferedMaskBlit equation.
58 */
59public abstract class BufferedMaskBlit extends MaskBlit {
60
61 private static final int ST_INT_ARGB = 0;
62 private static final int ST_INT_ARGB_PRE = 1;
63 private static final int ST_INT_RGB = 2;
64 private static final int ST_INT_BGR = 3;
65
66 private final RenderQueue rq;
67 private final int srcTypeVal;
68 private Blit blitop;
69
70 protected BufferedMaskBlit(RenderQueue rq,
71 SurfaceType srcType,
72 CompositeType compType,
73 SurfaceType dstType)
74 {
75 super(srcType, compType, dstType);
76 this.rq = rq;
77 if (srcType == SurfaceType.IntArgb) {
78 this.srcTypeVal = ST_INT_ARGB;
79 } else if (srcType == SurfaceType.IntArgbPre) {
80 this.srcTypeVal = ST_INT_ARGB_PRE;
81 } else if (srcType == SurfaceType.IntRgb) {
82 this.srcTypeVal = ST_INT_RGB;
83 } else if (srcType == SurfaceType.IntBgr) {
84 this.srcTypeVal = ST_INT_BGR;
85 } else {
86 throw new InternalError("unrecognized source surface type");
87 }
88 }
89
90 @Override
91 public void MaskBlit(SurfaceData src, SurfaceData dst,
92 Composite comp, Region clip,
93 int srcx, int srcy,
94 int dstx, int dsty,
95 int width, int height,
96 byte[] mask, int maskoff, int maskscan)
97 {
98 if (width <= 0 || height <= 0) {
99 return;
100 }
101
102 if (mask == null) {
103 // no mask involved; delegate to regular blit loop
104 if (blitop == null) {
105 blitop = Blit.getFromCache(src.getSurfaceType(),
106 CompositeType.AnyAlpha,
107 this.getDestType());
108 }
109 blitop.Blit(src, dst,
110 comp, clip,
111 srcx, srcy, dstx, dsty,
112 width, height);
113 return;
114 }
115
116 AlphaComposite acomp = (AlphaComposite)comp;
117 if (acomp.getRule() != AlphaComposite.SRC_OVER) {
118 comp = AlphaComposite.SrcOver;
119 }
120
121 rq.lock();
122 try {
123 validateContext(dst, comp, clip);
124
125 RenderBuffer buf = rq.getBuffer();
126 int totalBytesRequired = 20 + (width * height * 4);
127
128 /*
129 * REMIND: we should fix this so that it works with tiles that
130 * are larger than the entire buffer, but the native
131 * OGL/D3DMaskBlit isn't even prepared for tiles larger
132 * than 32x32 pixels, so there's no urgency here...
133 */
134 rq.ensureCapacity(totalBytesRequired);
135
136 // enqueue parameters and tile pixels
137 int newpos = enqueueTile(buf.getAddress(), buf.position(),
138 src, src.getNativeOps(), srcTypeVal,
139 mask, mask.length, maskoff, maskscan,
140 srcx, srcy, dstx, dsty,
141 width, height);
142
143 buf.position(newpos);
144 } finally {
145 rq.unlock();
146 }
147 }
148
149 private native int enqueueTile(long buf, int bpos,
150 SurfaceData srcData,
151 long pSrcOps, int srcType,
152 byte[] mask, int masklen,
153 int maskoff, int maskscan,
154 int srcx, int srcy, int dstx, int dsty,
155 int width, int height);
156
157 /**
158 * Validates the context state using the given destination surface
159 * and composite/clip values.
160 */
161 protected abstract void validateContext(SurfaceData dstData,
162 Composite comp, Region clip);
163}
java/pkg/sun/java2d/pipe/BufferedMaskFill.java+153−0
@@ -0,0 +1,153 @@
1/*
2 * Copyright (c) 2007, 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
26package sun.java2d.pipe;
27
28import java.awt.AlphaComposite;
29import java.awt.Composite;
30import sun.java2d.SunGraphics2D;
31import sun.java2d.SurfaceData;
32import sun.java2d.loops.CompositeType;
33import sun.java2d.loops.MaskFill;
34import sun.java2d.loops.SurfaceType;
35import static sun.java2d.pipe.BufferedOpCodes.*;
36
37/**
38 * The MaskFill operation is expressed as:
39 * dst = ((src <MODE> dst) * pathA) + (dst * (1 - pathA))
40 *
41 * The OGL/D3D implementation of the MaskFill operation differs from the above
42 * equation because it is not possible to perform such a complex operation in
43 * OpenGL/Direct3D (without the use of advanced techniques like fragment
44 * shaders and multitexturing). Therefore, the BufferedMaskFill operation
45 * is expressed as:
46 * dst = (src * pathA) <SrcOver> dst
47 *
48 * This simplified formula is only equivalent to the "true" MaskFill equation
49 * in the following situations:
50 * - <MODE> is SrcOver
51 * - <MODE> is Src, extra alpha == 1.0, and the source paint is opaque
52 *
53 * Therefore, we register BufferedMaskFill primitives for only the SurfaceType
54 * and CompositeType restrictions mentioned above. In addition, for the
55 * SrcNoEa case we must override the incoming composite with a SrcOver (no
56 * extra alpha) instance, so that we set up the OpenGL/Direct3D blending
57 * mode to match the BufferedMaskFill equation.
58 */
59public abstract class BufferedMaskFill extends MaskFill {
60
61 protected final RenderQueue rq;
62
63 protected BufferedMaskFill(RenderQueue rq,
64 SurfaceType srcType,
65 CompositeType compType,
66 SurfaceType dstType)
67 {
68 super(srcType, compType, dstType);
69 this.rq = rq;
70 }
71
72 @Override
73 public void MaskFill(SunGraphics2D sg2d, SurfaceData sData,
74 Composite comp,
75 final int x, final int y, final int w, final int h,
76 final byte[] mask,
77 final int maskoff, final int maskscan)
78 {
79 AlphaComposite acomp = (AlphaComposite)comp;
80 if (acomp.getRule() != AlphaComposite.SRC_OVER) {
81 comp = AlphaComposite.SrcOver;
82 }
83
84 rq.lock();
85 try {
86 validateContext(sg2d, comp, BufferedContext.USE_MASK);
87
88 // we adjust the mask length so that the mask ends on a
89 // 4-byte boundary
90 int maskBytesRequired;
91 if (mask != null) {
92 // we adjust the mask length so that the mask ends on a
93 // 4-byte boundary
94 maskBytesRequired = (mask.length + 3) & (~3);
95 } else {
96 // mask not needed
97 maskBytesRequired = 0;
98 }
99 int totalBytesRequired = 32 + maskBytesRequired;
100
101 RenderBuffer buf = rq.getBuffer();
102 if (totalBytesRequired <= buf.capacity()) {
103 if (totalBytesRequired > buf.remaining()) {
104 // process the queue first and then enqueue the mask
105 rq.flushNow();
106 }
107
108 buf.putInt(MASK_FILL);
109 // enqueue parameters
110 buf.putInt(x).putInt(y).putInt(w).putInt(h);
111 buf.putInt(maskoff);
112 buf.putInt(maskscan);
113 buf.putInt(maskBytesRequired);
114 if (mask != null) {
115 // enqueue the mask
116 int padding = maskBytesRequired - mask.length;
117 buf.put(mask);
118 if (padding != 0) {
119 buf.position(buf.position() + padding);
120 }
121 }
122 } else {
123 // queue is too small to accomodate entire mask; perform
124 // the operation directly on the queue flushing thread
125 rq.flushAndInvokeNow(new Runnable() {
126 public void run() {
127 maskFill(x, y, w, h,
128 maskoff, maskscan, mask.length, mask);
129 }
130 });
131 }
132 } finally {
133 rq.unlock();
134 }
135 }
136
137 /**
138 * Called as a separate Runnable when the operation is too large to fit
139 * on the RenderQueue. The OGL/D3D pipelines each have their own (small)
140 * native implementation of this method.
141 */
142 protected abstract void maskFill(int x, int y, int w, int h,
143 int maskoff, int maskscan, int masklen,
144 byte[] mask);
145
146 /**
147 * Validates the state in the provided SunGraphics2D object and sets up
148 * any special resources for this operation (e.g. enabling gradient
149 * shading).
150 */
151 protected abstract void validateContext(SunGraphics2D sg2d,
152 Composite comp, int ctxflags);
153}
java/pkg/sun/java2d/pipe/BufferedOpCodes.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedOpCodes.java+99−0
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 2005, 2008, 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
26package sun.java2d.pipe;
27
28public class BufferedOpCodes {
29 // draw ops
30 public static final int DRAW_LINE = 10;
31 public static final int DRAW_RECT = 11;
32 public static final int DRAW_POLY = 12;
33 public static final int DRAW_PIXEL = 13;
34 public static final int DRAW_SCANLINES = 14;
35 public static final int DRAW_PARALLELOGRAM = 15;
36 public static final int DRAW_AAPARALLELOGRAM = 16;
37
38 // fill ops
39 public static final int FILL_RECT = 20;
40 public static final int FILL_SPANS = 21;
41 public static final int FILL_PARALLELOGRAM = 22;
42 public static final int FILL_AAPARALLELOGRAM = 23;
43
44 // copy-related ops
45 public static final int COPY_AREA = 30;
46 public static final int BLIT = 31;
47 public static final int MASK_FILL = 32;
48 public static final int MASK_BLIT = 33;
49 public static final int SURFACE_TO_SW_BLIT = 34;
50
51 // text-related ops
52 public static final int DRAW_GLYPH_LIST = 40;
53
54 // state-related ops
55 public static final int SET_RECT_CLIP = 51;
56 public static final int BEGIN_SHAPE_CLIP = 52;
57 public static final int SET_SHAPE_CLIP_SPANS = 53;
58 public static final int END_SHAPE_CLIP = 54;
59 public static final int RESET_CLIP = 55;
60 public static final int SET_ALPHA_COMPOSITE = 56;
61 public static final int SET_XOR_COMPOSITE = 57;
62 public static final int RESET_COMPOSITE = 58;
63 public static final int SET_TRANSFORM = 59;
64 public static final int RESET_TRANSFORM = 60;
65
66 // context-related ops
67 public static final int SET_SURFACES = 70;
68 public static final int SET_SCRATCH_SURFACE = 71;
69 public static final int FLUSH_SURFACE = 72;
70 public static final int DISPOSE_SURFACE = 73;
71 public static final int DISPOSE_CONFIG = 74;
72 public static final int INVALIDATE_CONTEXT = 75;
73 public static final int SYNC = 76;
74 public static final int RESTORE_DEVICES = 77;
75 public static final int SAVE_STATE = 78;
76 public static final int RESTORE_STATE = 79;
77
78 // multibuffering ops
79 public static final int SWAP_BUFFERS = 80;
80
81 // special no-op op code (mainly used for achieving 8-byte alignment)
82 public static final int NOOP = 90;
83
84 // paint-related ops
85 public static final int RESET_PAINT = 100;
86 public static final int SET_COLOR = 101;
87 public static final int SET_GRADIENT_PAINT = 102;
88 public static final int SET_LINEAR_GRADIENT_PAINT = 103;
89 public static final int SET_RADIAL_GRADIENT_PAINT = 104;
90 public static final int SET_TEXTURE_PAINT = 105;
91
92 // BufferedImageOp-related ops
93 public static final int ENABLE_CONVOLVE_OP = 120;
94 public static final int DISABLE_CONVOLVE_OP = 121;
95 public static final int ENABLE_RESCALE_OP = 122;
96 public static final int DISABLE_RESCALE_OP = 123;
97 public static final int ENABLE_LOOKUP_OP = 124;
98 public static final int DISABLE_LOOKUP_OP = 125;
99}
java/pkg/sun/java2d/pipe/BufferedPaints.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedPaints.java+533−0
@@ -0,0 +1,533 @@
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
26package sun.java2d.pipe;
27
28import java.awt.Color;
29import java.awt.GradientPaint;
30import java.awt.LinearGradientPaint;
31import java.awt.MultipleGradientPaint;
32import java.awt.MultipleGradientPaint.ColorSpaceType;
33import java.awt.MultipleGradientPaint.CycleMethod;
34import java.awt.Paint;
35import java.awt.RadialGradientPaint;
36import java.awt.TexturePaint;
37import java.awt.geom.AffineTransform;
38import java.awt.geom.Point2D;
39import java.awt.geom.Rectangle2D;
40import java.awt.image.AffineTransformOp;
41import java.awt.image.BufferedImage;
42import sun.awt.image.PixelConverter;
43import sun.java2d.SunGraphics2D;
44import sun.java2d.SurfaceData;
45import sun.java2d.loops.CompositeType;
46import sun.java2d.loops.SurfaceType;
47import static sun.java2d.pipe.BufferedOpCodes.*;
48
49public class BufferedPaints {
50
51 static void setPaint(RenderQueue rq, SunGraphics2D sg2d,
52 Paint paint, int ctxflags)
53 {
54 if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
55 setColor(rq, sg2d.pixel);
56 } else {
57 boolean useMask = (ctxflags & BufferedContext.USE_MASK) != 0;
58 switch (sg2d.paintState) {
59 case SunGraphics2D.PAINT_GRADIENT:
60 setGradientPaint(rq, sg2d,
61 (GradientPaint)paint, useMask);
62 break;
63 case SunGraphics2D.PAINT_LIN_GRADIENT:
64 setLinearGradientPaint(rq, sg2d,
65 (LinearGradientPaint)paint, useMask);
66 break;
67 case SunGraphics2D.PAINT_RAD_GRADIENT:
68 setRadialGradientPaint(rq, sg2d,
69 (RadialGradientPaint)paint, useMask);
70 break;
71 case SunGraphics2D.PAINT_TEXTURE:
72 setTexturePaint(rq, sg2d,
73 (TexturePaint)paint, useMask);
74 break;
75 default:
76 break;
77 }
78 }
79 }
80
81 static void resetPaint(RenderQueue rq) {
82 // assert rq.lock.isHeldByCurrentThread();
83 rq.ensureCapacity(4);
84 RenderBuffer buf = rq.getBuffer();
85 buf.putInt(RESET_PAINT);
86 }
87
88/****************************** Color support *******************************/
89
90 private static void setColor(RenderQueue rq, int pixel) {
91 // assert rq.lock.isHeldByCurrentThread();
92 rq.ensureCapacity(8);
93 RenderBuffer buf = rq.getBuffer();
94 buf.putInt(SET_COLOR);
95 buf.putInt(pixel);
96 }
97
98/************************* GradientPaint support ****************************/
99
100 /**
101 * Note: This code is factored out into a separate static method
102 * so that it can be shared by both the Gradient and LinearGradient
103 * implementations. LinearGradient uses this code (for the
104 * two-color sRGB case only) because it can be much faster than the
105 * equivalent implementation that uses fragment shaders.
106 *
107 * We use OpenGL's texture coordinate generator to automatically
108 * apply a smooth gradient (either cyclic or acyclic) to the geometry
109 * being rendered. This technique is almost identical to the one
110 * described in the comments for BufferedPaints.setTexturePaint(),
111 * except the calculations take place in one dimension instead of two.
112 * Instead of an anchor rectangle in the TexturePaint case, we use
113 * the vector between the two GradientPaint end points in our
114 * calculations. The generator uses a single plane equation that
115 * takes the (x,y) location (in device space) of the fragment being
116 * rendered to calculate a (u) texture coordinate for that fragment:
117 * u = Ax + By + Cz + Dw
118 *
119 * The gradient renderer uses a two-pixel 1D texture where the first
120 * pixel contains the first GradientPaint color, and the second pixel
121 * contains the second GradientPaint color. (Note that we use the
122 * GL_CLAMP_TO_EDGE wrapping mode for acyclic gradients so that we
123 * clamp the colors properly at the extremes.) The following diagram
124 * attempts to show the layout of the texture containing the two
125 * GradientPaint colors (C1 and C2):
126 *
127 * +-----------------+
128 * | C1 | C2 |
129 * | | |
130 * +-----------------+
131 * u=0 .25 .5 .75 1
132 *
133 * We calculate our plane equation constants (A,B,D) such that u=0.25
134 * corresponds to the first GradientPaint end point in user space and
135 * u=0.75 corresponds to the second end point. This is somewhat
136 * non-obvious, but since the gradient colors are generated by
137 * interpolating between C1 and C2, we want the pure color at the
138 * end points, and we will get the pure color only when u correlates
139 * to the center of a texel. The following chart shows the expected
140 * color for some sample values of u (where C' is the color halfway
141 * between C1 and C2):
142 *
143 * u value acyclic (GL_CLAMP) cyclic (GL_REPEAT)
144 * ------- ------------------ ------------------
145 * -0.25 C1 C2
146 * 0.0 C1 C'
147 * 0.25 C1 C1
148 * 0.5 C' C'
149 * 0.75 C2 C2
150 * 1.0 C2 C'
151 * 1.25 C2 C1
152 *
153 * Original inspiration for this technique came from UMD's Agile2D
154 * project (GradientManager.java).
155 */
156 private static void setGradientPaint(RenderQueue rq, AffineTransform at,
157 Color c1, Color c2,
158 Point2D pt1, Point2D pt2,
159 boolean isCyclic, boolean useMask)
160 {
161 // convert gradient colors to IntArgbPre format
162 PixelConverter pc = PixelConverter.ArgbPre.instance;
163 int pixel1 = pc.rgbToPixel(c1.getRGB(), null);
164 int pixel2 = pc.rgbToPixel(c2.getRGB(), null);
165
166 // calculate plane equation constants
167 double x = pt1.getX();
168 double y = pt1.getY();
169 at.translate(x, y);
170 // now gradient point 1 is at the origin
171 x = pt2.getX() - x;
172 y = pt2.getY() - y;
173 double len = Math.sqrt(x * x + y * y);
174 at.rotate(x, y);
175 // now gradient point 2 is on the positive x-axis
176 at.scale(2*len, 1);
177 // now gradient point 2 is at (0.5, 0)
178 at.translate(-0.25, 0);
179 // now gradient point 1 is at (0.25, 0), point 2 is at (0.75, 0)
180
181 double p0, p1, p3;
182 try {
183 at.invert();
184 p0 = at.getScaleX();
185 p1 = at.getShearX();
186 p3 = at.getTranslateX();
187 } catch (java.awt.geom.NoninvertibleTransformException e) {
188 p0 = p1 = p3 = 0.0;
189 }
190
191 // assert rq.lock.isHeldByCurrentThread();
192 rq.ensureCapacityAndAlignment(44, 12);
193 RenderBuffer buf = rq.getBuffer();
194 buf.putInt(SET_GRADIENT_PAINT);
195 buf.putInt(useMask ? 1 : 0);
196 buf.putInt(isCyclic ? 1 : 0);
197 buf.putDouble(p0).putDouble(p1).putDouble(p3);
198 buf.putInt(pixel1).putInt(pixel2);
199 }
200
201 private static void setGradientPaint(RenderQueue rq,
202 SunGraphics2D sg2d,
203 GradientPaint paint,
204 boolean useMask)
205 {
206 setGradientPaint(rq, (AffineTransform)sg2d.transform.clone(),
207 paint.getColor1(), paint.getColor2(),
208 paint.getPoint1(), paint.getPoint2(),
209 paint.isCyclic(), useMask);
210 }
211
212/************************** TexturePaint support ****************************/
213
214 /**
215 * We use OpenGL's texture coordinate generator to automatically
216 * map the TexturePaint image to the geometry being rendered. The
217 * generator uses two separate plane equations that take the (x,y)
218 * location (in device space) of the fragment being rendered to
219 * calculate (u,v) texture coordinates for that fragment:
220 * u = Ax + By + Cz + Dw
221 * v = Ex + Fy + Gz + Hw
222 *
223 * Since we use a 2D orthographic projection, we can assume that z=0
224 * and w=1 for any fragment. So we need to calculate appropriate
225 * values for the plane equation constants (A,B,D) and (E,F,H) such
226 * that {u,v}=0 for the top-left of the TexturePaint's anchor
227 * rectangle and {u,v}=1 for the bottom-right of the anchor rectangle.
228 * We can easily make the texture image repeat for {u,v} values
229 * outside the range [0,1] by specifying the GL_REPEAT texture wrap
230 * mode.
231 *
232 * Calculating the plane equation constants is surprisingly simple.
233 * We can think of it as an inverse matrix operation that takes
234 * device space coordinates and transforms them into user space
235 * coordinates that correspond to a location relative to the anchor
236 * rectangle. First, we translate and scale the current user space
237 * transform by applying the anchor rectangle bounds. We then take
238 * the inverse of this affine transform. The rows of the resulting
239 * inverse matrix correlate nicely to the plane equation constants
240 * we were seeking.
241 */
242 private static void setTexturePaint(RenderQueue rq,
243 SunGraphics2D sg2d,
244 TexturePaint paint,
245 boolean useMask)
246 {
247 BufferedImage bi = paint.getImage();
248 SurfaceData dstData = sg2d.surfaceData;
249 SurfaceData srcData =
250 dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
251 CompositeType.SrcOver, null);
252 boolean filter =
253 (sg2d.interpolationType !=
254 AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
255
256 // calculate plane equation constants
257 AffineTransform at = (AffineTransform)sg2d.transform.clone();
258 Rectangle2D anchor = paint.getAnchorRect();
259 at.translate(anchor.getX(), anchor.getY());
260 at.scale(anchor.getWidth(), anchor.getHeight());
261
262 double xp0, xp1, xp3, yp0, yp1, yp3;
263 try {
264 at.invert();
265 xp0 = at.getScaleX();
266 xp1 = at.getShearX();
267 xp3 = at.getTranslateX();
268 yp0 = at.getShearY();
269 yp1 = at.getScaleY();
270 yp3 = at.getTranslateY();
271 } catch (java.awt.geom.NoninvertibleTransformException e) {
272 xp0 = xp1 = xp3 = yp0 = yp1 = yp3 = 0.0;
273 }
274
275 // assert rq.lock.isHeldByCurrentThread();
276 rq.ensureCapacityAndAlignment(68, 12);
277 RenderBuffer buf = rq.getBuffer();
278 buf.putInt(SET_TEXTURE_PAINT);
279 buf.putInt(useMask ? 1 : 0);
280 buf.putInt(filter ? 1 : 0);
281 buf.putLong(srcData.getNativeOps());
282 buf.putDouble(xp0).putDouble(xp1).putDouble(xp3);
283 buf.putDouble(yp0).putDouble(yp1).putDouble(yp3);
284 }
285
286/****************** Shared MultipleGradientPaint support ********************/
287
288 /**
289 * The maximum number of gradient "stops" supported by our native
290 * fragment shader implementations.
291 *
292 * This value has been empirically determined and capped to allow
293 * our native shaders to run on all shader-level graphics hardware,
294 * even on the older, more limited GPUs. Even the oldest Nvidia
295 * hardware could handle 16, or even 32 fractions without any problem.
296 * But the first-generation boards from ATI would fall back into
297 * software mode (which is unusably slow) for values larger than 12;
298 * it appears that those boards do not have enough native registers
299 * to support the number of array accesses required by our gradient
300 * shaders. So for now we will cap this value at 12, but we can
301 * re-evaluate this in the future as hardware becomes more capable.
302 */
303 public static final int MULTI_MAX_FRACTIONS = 12;
304
305 /**
306 * Helper function to convert a color component in sRGB space to
307 * linear RGB space. Copied directly from the
308 * MultipleGradientPaintContext class.
309 */
310 public static int convertSRGBtoLinearRGB(int color) {
311 float input, output;
312
313 input = color / 255.0f;
314 if (input <= 0.04045f) {
315 output = input / 12.92f;
316 } else {
317 output = (float)Math.pow((input + 0.055) / 1.055, 2.4);
318 }
319
320 return Math.round(output * 255.0f);
321 }
322
323 /**
324 * Helper function to convert a (non-premultiplied) Color in sRGB
325 * space to an IntArgbPre pixel value, optionally in linear RGB space.
326 * Based on the PixelConverter.ArgbPre.rgbToPixel() method.
327 */
328 private static int colorToIntArgbPrePixel(Color c, boolean linear) {
329 int rgb = c.getRGB();
330 if (!linear && ((rgb >> 24) == -1)) {
331 return rgb;
332 }
333 int a = rgb >>> 24;
334 int r = (rgb >> 16) & 0xff;
335 int g = (rgb >> 8) & 0xff;
336 int b = (rgb ) & 0xff;
337 if (linear) {
338 r = convertSRGBtoLinearRGB(r);
339 g = convertSRGBtoLinearRGB(g);
340 b = convertSRGBtoLinearRGB(b);
341 }
342 int a2 = a + (a >> 7);
343 r = (r * a2) >> 8;
344 g = (g * a2) >> 8;
345 b = (b * a2) >> 8;
346 return ((a << 24) | (r << 16) | (g << 8) | (b));
347 }
348
349 /**
350 * Converts the given array of Color objects into an int array
351 * containing IntArgbPre pixel values. If the linear parameter
352 * is true, the Color values will be converted into a linear RGB
353 * color space before being returned.
354 */
355 private static int[] convertToIntArgbPrePixels(Color[] colors,
356 boolean linear)
357 {
358 int[] pixels = new int[colors.length];
359 for (int i = 0; i < colors.length; i++) {
360 pixels[i] = colorToIntArgbPrePixel(colors[i], linear);
361 }
362 return pixels;
363 }
364
365/********************** LinearGradientPaint support *************************/
366
367 /**
368 * This method uses techniques that are nearly identical to those
369 * employed in setGradientPaint() above. The primary difference
370 * is that at the native level we use a fragment shader to manually
371 * apply the plane equation constants to the current fragment position
372 * to calculate the gradient position in the range [0,1] (the native
373 * code for GradientPaint does the same, except that it uses OpenGL's
374 * automatic texture coordinate generation facilities).
375 *
376 * One other minor difference worth mentioning is that
377 * setGradientPaint() calculates the plane equation constants
378 * such that the gradient end points are positioned at 0.25 and 0.75
379 * (for reasons discussed in the comments for that method). In
380 * contrast, for LinearGradientPaint we setup the equation constants
381 * such that the gradient end points fall at 0.0 and 1.0. The
382 * reason for this difference is that in the fragment shader we
383 * have more control over how the gradient values are interpreted
384 * (depending on the paint's CycleMethod).
385 */
386 private static void setLinearGradientPaint(RenderQueue rq,
387 SunGraphics2D sg2d,
388 LinearGradientPaint paint,
389 boolean useMask)
390 {
391 boolean linear =
392 (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
393 Color[] colors = paint.getColors();
394 int numStops = colors.length;
395 Point2D pt1 = paint.getStartPoint();
396 Point2D pt2 = paint.getEndPoint();
397 AffineTransform at = paint.getTransform();
398 at.preConcatenate(sg2d.transform);
399
400 if (!linear && numStops == 2 &&
401 paint.getCycleMethod() != CycleMethod.REPEAT)
402 {
403 // delegate to the optimized two-color gradient codepath
404 boolean isCyclic =
405 (paint.getCycleMethod() != CycleMethod.NO_CYCLE);
406 setGradientPaint(rq, at,
407 colors[0], colors[1],
408 pt1, pt2,
409 isCyclic, useMask);
410 return;
411 }
412
413 int cycleMethod = paint.getCycleMethod().ordinal();
414 float[] fractions = paint.getFractions();
415 int[] pixels = convertToIntArgbPrePixels(colors, linear);
416
417 // calculate plane equation constants
418 double x = pt1.getX();
419 double y = pt1.getY();
420 at.translate(x, y);
421 // now gradient point 1 is at the origin
422 x = pt2.getX() - x;
423 y = pt2.getY() - y;
424 double len = Math.sqrt(x * x + y * y);
425 at.rotate(x, y);
426 // now gradient point 2 is on the positive x-axis
427 at.scale(len, 1);
428 // now gradient point 1 is at (0.0, 0), point 2 is at (1.0, 0)
429
430 float p0, p1, p3;
431 try {
432 at.invert();
433 p0 = (float)at.getScaleX();
434 p1 = (float)at.getShearX();
435 p3 = (float)at.getTranslateX();
436 } catch (java.awt.geom.NoninvertibleTransformException e) {
437 p0 = p1 = p3 = 0.0f;
438 }
439
440 // assert rq.lock.isHeldByCurrentThread();
441 rq.ensureCapacity(20 + 12 + (numStops*4*2));
442 RenderBuffer buf = rq.getBuffer();
443 buf.putInt(SET_LINEAR_GRADIENT_PAINT);
444 buf.putInt(useMask ? 1 : 0);
445 buf.putInt(linear ? 1 : 0);
446 buf.putInt(cycleMethod);
447 buf.putInt(numStops);
448 buf.putFloat(p0);
449 buf.putFloat(p1);
450 buf.putFloat(p3);
451 buf.put(fractions);
452 buf.put(pixels);
453 }
454
455/********************** RadialGradientPaint support *************************/
456
457 /**
458 * This method calculates six m** values and a focusX value that
459 * are used by the native fragment shader. These techniques are
460 * based on a whitepaper by Daniel Rice on radial gradient performance
461 * (attached to the bug report for 6521533). One can refer to that
462 * document for the complete set of formulas and calculations, but
463 * the basic goal is to compose a transform that will convert an
464 * (x,y) position in device space into a "u" value that represents
465 * the relative distance to the gradient focus point. The resulting
466 * value can be used to look up the appropriate color by linearly
467 * interpolating between the two nearest colors in the gradient.
468 */
469 private static void setRadialGradientPaint(RenderQueue rq,
470 SunGraphics2D sg2d,
471 RadialGradientPaint paint,
472 boolean useMask)
473 {
474 boolean linear =
475 (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
476 int cycleMethod = paint.getCycleMethod().ordinal();
477 float[] fractions = paint.getFractions();
478 Color[] colors = paint.getColors();
479 int numStops = colors.length;
480 int[] pixels = convertToIntArgbPrePixels(colors, linear);
481 Point2D center = paint.getCenterPoint();
482 Point2D focus = paint.getFocusPoint();
483 float radius = paint.getRadius();
484
485 // save original (untransformed) center and focus points
486 double cx = center.getX();
487 double cy = center.getY();
488 double fx = focus.getX();
489 double fy = focus.getY();
490
491 // transform from gradient coords to device coords
492 AffineTransform at = paint.getTransform();
493 at.preConcatenate(sg2d.transform);
494 focus = at.transform(focus, focus);
495
496 // transform unit circle to gradient coords; we start with the
497 // unit circle (center=(0,0), focus on positive x-axis, radius=1)
498 // and then transform into gradient space
499 at.translate(cx, cy);
500 at.rotate(fx - cx, fy - cy);
501 at.scale(radius, radius);
502
503 // invert to get mapping from device coords to unit circle
504 try {
505 at.invert();
506 } catch (Exception e) {
507 at.setToScale(0.0, 0.0);
508 }
509 focus = at.transform(focus, focus);
510
511 // clamp the focus point so that it does not rest on, or outside
512 // of, the circumference of the gradient circle
513 fx = Math.min(focus.getX(), 0.99);
514
515 // assert rq.lock.isHeldByCurrentThread();
516 rq.ensureCapacity(20 + 28 + (numStops*4*2));
517 RenderBuffer buf = rq.getBuffer();
518 buf.putInt(SET_RADIAL_GRADIENT_PAINT);
519 buf.putInt(useMask ? 1 : 0);
520 buf.putInt(linear ? 1 : 0);
521 buf.putInt(numStops);
522 buf.putInt(cycleMethod);
523 buf.putFloat((float)at.getScaleX());
524 buf.putFloat((float)at.getShearX());
525 buf.putFloat((float)at.getTranslateX());
526 buf.putFloat((float)at.getShearY());
527 buf.putFloat((float)at.getScaleY());
528 buf.putFloat((float)at.getTranslateY());
529 buf.putFloat((float)fx);
530 buf.put(fractions);
531 buf.put(pixels);
532 }
533}
java/pkg/sun/java2d/pipe/BufferedRenderPipe$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedRenderPipe$AAParallelogramPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedRenderPipe$BufferedDrawHandler.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedRenderPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedRenderPipe.java+601−0
@@ -0,0 +1,601 @@
1/*
2 * Copyright (c) 2005, 2008, 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
26package sun.java2d.pipe;
27
28import java.awt.BasicStroke;
29import java.awt.Polygon;
30import java.awt.Shape;
31import java.awt.geom.AffineTransform;
32import java.awt.geom.Arc2D;
33import java.awt.geom.Ellipse2D;
34import java.awt.geom.Path2D;
35import java.awt.geom.IllegalPathStateException;
36import java.awt.geom.PathIterator;
37import java.awt.geom.Rectangle2D;
38import java.awt.geom.RoundRectangle2D;
39import sun.java2d.SunGraphics2D;
40import sun.java2d.loops.ProcessPath;
41import static sun.java2d.pipe.BufferedOpCodes.*;
42
43/**
44 * Base class for enqueuing rendering operations in a single-threaded
45 * rendering environment. Instead of each operation being rendered
46 * immediately by the underlying graphics library, the operation will be
47 * added to the provided RenderQueue, which will be processed at a later
48 * time by a single thread.
49 *
50 * This class provides implementations of drawLine(), drawRect(), drawPoly(),
51 * fillRect(), draw(Shape), and fill(Shape), which are useful for a
52 * hardware-accelerated renderer. The other draw*() and fill*() methods
53 * simply delegate to draw(Shape) and fill(Shape), respectively.
54 */
55public abstract class BufferedRenderPipe
56 implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe, ParallelogramPipe
57{
58 ParallelogramPipe aapgrampipe = new AAParallelogramPipe();
59
60 static final int BYTES_PER_POLY_POINT = 8;
61 static final int BYTES_PER_SCANLINE = 12;
62 static final int BYTES_PER_SPAN = 16;
63
64 protected RenderQueue rq;
65 protected RenderBuffer buf;
66 private BufferedDrawHandler drawHandler;
67
68 public BufferedRenderPipe(RenderQueue rq) {
69 this.rq = rq;
70 this.buf = rq.getBuffer();
71 this.drawHandler = new BufferedDrawHandler();
72 }
73
74 public ParallelogramPipe getAAParallelogramPipe() {
75 return aapgrampipe;
76 }
77
78 /**
79 * Validates the state in the provided SunGraphics2D object and sets up
80 * any special resources for this operation (e.g. enabling gradient
81 * shading).
82 */
83 protected abstract void validateContext(SunGraphics2D sg2d);
84 protected abstract void validateContextAA(SunGraphics2D sg2d);
85
86 public void drawLine(SunGraphics2D sg2d,
87 int x1, int y1, int x2, int y2)
88 {
89 int transx = sg2d.transX;
90 int transy = sg2d.transY;
91 rq.lock();
92 try {
93 validateContext(sg2d);
94 rq.ensureCapacity(20);
95 buf.putInt(DRAW_LINE);
96 buf.putInt(x1 + transx);
97 buf.putInt(y1 + transy);
98 buf.putInt(x2 + transx);
99 buf.putInt(y2 + transy);
100 } finally {
101 rq.unlock();
102 }
103 }
104
105 public void drawRect(SunGraphics2D sg2d,
106 int x, int y, int width, int height)
107 {
108 rq.lock();
109 try {
110 validateContext(sg2d);
111 rq.ensureCapacity(20);
112 buf.putInt(DRAW_RECT);
113 buf.putInt(x + sg2d.transX);
114 buf.putInt(y + sg2d.transY);
115 buf.putInt(width);
116 buf.putInt(height);
117 } finally {
118 rq.unlock();
119 }
120 }
121
122 public void fillRect(SunGraphics2D sg2d,
123 int x, int y, int width, int height)
124 {
125 rq.lock();
126 try {
127 validateContext(sg2d);
128 rq.ensureCapacity(20);
129 buf.putInt(FILL_RECT);
130 buf.putInt(x + sg2d.transX);
131 buf.putInt(y + sg2d.transY);
132 buf.putInt(width);
133 buf.putInt(height);
134 } finally {
135 rq.unlock();
136 }
137 }
138
139 public void drawRoundRect(SunGraphics2D sg2d,
140 int x, int y, int width, int height,
141 int arcWidth, int arcHeight)
142 {
143 draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
144 arcWidth, arcHeight));
145 }
146
147 public void fillRoundRect(SunGraphics2D sg2d,
148 int x, int y, int width, int height,
149 int arcWidth, int arcHeight)
150 {
151 fill(sg2d, new RoundRectangle2D.Float(x, y, width, height,
152 arcWidth, arcHeight));
153 }
154
155 public void drawOval(SunGraphics2D sg2d,
156 int x, int y, int width, int height)
157 {
158 draw(sg2d, new Ellipse2D.Float(x, y, width, height));
159 }
160
161 public void fillOval(SunGraphics2D sg2d,
162 int x, int y, int width, int height)
163 {
164 fill(sg2d, new Ellipse2D.Float(x, y, width, height));
165 }
166
167 public void drawArc(SunGraphics2D sg2d,
168 int x, int y, int width, int height,
169 int startAngle, int arcAngle)
170 {
171 draw(sg2d, new Arc2D.Float(x, y, width, height,
172 startAngle, arcAngle,
173 Arc2D.OPEN));
174 }
175
176 public void fillArc(SunGraphics2D sg2d,
177 int x, int y, int width, int height,
178 int startAngle, int arcAngle)
179 {
180 fill(sg2d, new Arc2D.Float(x, y, width, height,
181 startAngle, arcAngle,
182 Arc2D.PIE));
183 }
184
185 protected void drawPoly(final SunGraphics2D sg2d,
186 final int[] xPoints, final int[] yPoints,
187 final int nPoints, final boolean isClosed)
188 {
189 if (xPoints == null || yPoints == null) {
190 throw new NullPointerException("coordinate array");
191 }
192 if (xPoints.length < nPoints || yPoints.length < nPoints) {
193 throw new ArrayIndexOutOfBoundsException("coordinate array");
194 }
195
196 if (nPoints < 2) {
197 // render nothing
198 return;
199 } else if (nPoints == 2 && !isClosed) {
200 // render a simple line
201 drawLine(sg2d, xPoints[0], yPoints[0], xPoints[1], yPoints[1]);
202 return;
203 }
204
205 rq.lock();
206 try {
207 validateContext(sg2d);
208
209 int pointBytesRequired = nPoints * BYTES_PER_POLY_POINT;
210 int totalBytesRequired = 20 + pointBytesRequired;
211
212 if (totalBytesRequired <= buf.capacity()) {
213 if (totalBytesRequired > buf.remaining()) {
214 // process the queue first and then enqueue the points
215 rq.flushNow();
216 }
217 buf.putInt(DRAW_POLY);
218 // enqueue parameters
219 buf.putInt(nPoints);
220 buf.putInt(isClosed ? 1 : 0);
221 buf.putInt(sg2d.transX);
222 buf.putInt(sg2d.transY);
223 // enqueue the points
224 buf.put(xPoints, 0, nPoints);
225 buf.put(yPoints, 0, nPoints);
226 } else {
227 // queue is too small to accomodate all points; perform the
228 // operation directly on the queue flushing thread
229 rq.flushAndInvokeNow(new Runnable() {
230 public void run() {
231 drawPoly(xPoints, yPoints,
232 nPoints, isClosed,
233 sg2d.transX, sg2d.transY);
234 }
235 });
236 }
237 } finally {
238 rq.unlock();
239 }
240 }
241
242 protected abstract void drawPoly(int[] xPoints, int[] yPoints,
243 int nPoints, boolean isClosed,
244 int transX, int transY);
245
246 public void drawPolyline(SunGraphics2D sg2d,
247 int[] xPoints, int[] yPoints,
248 int nPoints)
249 {
250 drawPoly(sg2d, xPoints, yPoints, nPoints, false);
251 }
252
253 public void drawPolygon(SunGraphics2D sg2d,
254 int[] xPoints, int[] yPoints,
255 int nPoints)
256 {
257 drawPoly(sg2d, xPoints, yPoints, nPoints, true);
258 }
259
260 public void fillPolygon(SunGraphics2D sg2d,
261 int[] xPoints, int[] yPoints,
262 int nPoints)
263 {
264 fill(sg2d, new Polygon(xPoints, yPoints, nPoints));
265 }
266
267 private class BufferedDrawHandler
268 extends ProcessPath.DrawHandler
269 {
270 BufferedDrawHandler() {
271 // these are bogus values; the caller will use validate()
272 // to ensure that they are set properly prior to each usage
273 super(0, 0, 0, 0);
274 }
275
276 /**
277 * This method needs to be called prior to each draw/fillPath()
278 * operation to ensure the clip bounds are up to date.
279 */
280 void validate(SunGraphics2D sg2d) {
281 Region clip = sg2d.getCompClip();
282 setBounds(clip.getLoX(), clip.getLoY(),
283 clip.getHiX(), clip.getHiY(),
284 sg2d.strokeHint);
285 }
286
287 /**
288 * drawPath() support...
289 */
290
291 public void drawLine(int x1, int y1, int x2, int y2) {
292 // assert rq.lock.isHeldByCurrentThread();
293 rq.ensureCapacity(20);
294 buf.putInt(DRAW_LINE);
295 buf.putInt(x1);
296 buf.putInt(y1);
297 buf.putInt(x2);
298 buf.putInt(y2);
299 }
300
301 public void drawPixel(int x, int y) {
302 // assert rq.lock.isHeldByCurrentThread();
303 rq.ensureCapacity(12);
304 buf.putInt(DRAW_PIXEL);
305 buf.putInt(x);
306 buf.putInt(y);
307 }
308
309 /**
310 * fillPath() support...
311 */
312
313 private int scanlineCount;
314 private int scanlineCountIndex;
315 private int remainingScanlines;
316
317 private void resetFillPath() {
318 buf.putInt(DRAW_SCANLINES);
319 scanlineCountIndex = buf.position();
320 buf.putInt(0);
321 scanlineCount = 0;
322 remainingScanlines = buf.remaining() / BYTES_PER_SCANLINE;
323 }
324
325 private void updateScanlineCount() {
326 buf.putInt(scanlineCountIndex, scanlineCount);
327 }
328
329 /**
330 * Called from fillPath() to indicate that we are about to
331 * start issuing drawScanline() calls.
332 */
333 public void startFillPath() {
334 rq.ensureCapacity(20); // to ensure room for at least a scanline
335 resetFillPath();
336 }
337
338 public void drawScanline(int x1, int x2, int y) {
339 if (remainingScanlines == 0) {
340 updateScanlineCount();
341 rq.flushNow();
342 resetFillPath();
343 }
344 buf.putInt(x1);
345 buf.putInt(x2);
346 buf.putInt(y);
347 scanlineCount++;
348 remainingScanlines--;
349 }
350
351 /**
352 * Called from fillPath() to indicate that we are done
353 * issuing drawScanline() calls.
354 */
355 public void endFillPath() {
356 updateScanlineCount();
357 }
358 }
359
360 protected void drawPath(SunGraphics2D sg2d,
361 Path2D.Float p2df, int transx, int transy)
362 {
363 rq.lock();
364 try {
365 validateContext(sg2d);
366 drawHandler.validate(sg2d);
367 ProcessPath.drawPath(drawHandler, p2df, transx, transy);
368 } finally {
369 rq.unlock();
370 }
371 }
372
373 protected void fillPath(SunGraphics2D sg2d,
374 Path2D.Float p2df, int transx, int transy)
375 {
376 rq.lock();
377 try {
378 validateContext(sg2d);
379 drawHandler.validate(sg2d);
380 drawHandler.startFillPath();
381 ProcessPath.fillPath(drawHandler, p2df, transx, transy);
382 drawHandler.endFillPath();
383 } finally {
384 rq.unlock();
385 }
386 }
387
388 private native int fillSpans(RenderQueue rq, long buf,
389 int pos, int limit,
390 SpanIterator si, long iterator,
391 int transx, int transy);
392
393 protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
394 int transx, int transy)
395 {
396 rq.lock();
397 try {
398 validateContext(sg2d);
399 rq.ensureCapacity(24); // so that we have room for at least a span
400 int newpos = fillSpans(rq, buf.getAddress(),
401 buf.position(), buf.capacity(),
402 si, si.getNativeIterator(),
403 transx, transy);
404 buf.position(newpos);
405 } finally {
406 rq.unlock();
407 }
408 }
409
410 public void fillParallelogram(SunGraphics2D sg2d,
411 double ux1, double uy1,
412 double ux2, double uy2,
413 double x, double y,
414 double dx1, double dy1,
415 double dx2, double dy2)
416 {
417 rq.lock();
418 try {
419 validateContext(sg2d);
420 rq.ensureCapacity(28);
421 buf.putInt(FILL_PARALLELOGRAM);
422 buf.putFloat((float) x);
423 buf.putFloat((float) y);
424 buf.putFloat((float) dx1);
425 buf.putFloat((float) dy1);
426 buf.putFloat((float) dx2);
427 buf.putFloat((float) dy2);
428 } finally {
429 rq.unlock();
430 }
431 }
432
433 public void drawParallelogram(SunGraphics2D sg2d,
434 double ux1, double uy1,
435 double ux2, double uy2,
436 double x, double y,
437 double dx1, double dy1,
438 double dx2, double dy2,
439 double lw1, double lw2)
440 {
441 rq.lock();
442 try {
443 validateContext(sg2d);
444 rq.ensureCapacity(36);
445 buf.putInt(DRAW_PARALLELOGRAM);
446 buf.putFloat((float) x);
447 buf.putFloat((float) y);
448 buf.putFloat((float) dx1);
449 buf.putFloat((float) dy1);
450 buf.putFloat((float) dx2);
451 buf.putFloat((float) dy2);
452 buf.putFloat((float) lw1);
453 buf.putFloat((float) lw2);
454 } finally {
455 rq.unlock();
456 }
457 }
458
459 private class AAParallelogramPipe implements ParallelogramPipe {
460 public void fillParallelogram(SunGraphics2D sg2d,
461 double ux1, double uy1,
462 double ux2, double uy2,
463 double x, double y,
464 double dx1, double dy1,
465 double dx2, double dy2)
466 {
467 rq.lock();
468 try {
469 validateContextAA(sg2d);
470 rq.ensureCapacity(28);
471 buf.putInt(FILL_AAPARALLELOGRAM);
472 buf.putFloat((float) x);
473 buf.putFloat((float) y);
474 buf.putFloat((float) dx1);
475 buf.putFloat((float) dy1);
476 buf.putFloat((float) dx2);
477 buf.putFloat((float) dy2);
478 } finally {
479 rq.unlock();
480 }
481 }
482
483 public void drawParallelogram(SunGraphics2D sg2d,
484 double ux1, double uy1,
485 double ux2, double uy2,
486 double x, double y,
487 double dx1, double dy1,
488 double dx2, double dy2,
489 double lw1, double lw2)
490 {
491 rq.lock();
492 try {
493 validateContextAA(sg2d);
494 rq.ensureCapacity(36);
495 buf.putInt(DRAW_AAPARALLELOGRAM);
496 buf.putFloat((float) x);
497 buf.putFloat((float) y);
498 buf.putFloat((float) dx1);
499 buf.putFloat((float) dy1);
500 buf.putFloat((float) dx2);
501 buf.putFloat((float) dy2);
502 buf.putFloat((float) lw1);
503 buf.putFloat((float) lw2);
504 } finally {
505 rq.unlock();
506 }
507 }
508 }
509
510 public void draw(SunGraphics2D sg2d, Shape s) {
511 if (sg2d.strokeState == sg2d.STROKE_THIN) {
512 if (s instanceof Polygon) {
513 if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE) {
514 Polygon p = (Polygon)s;
515 drawPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
516 return;
517 }
518 }
519 Path2D.Float p2df;
520 int transx, transy;
521 if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
522 if (s instanceof Path2D.Float) {
523 p2df = (Path2D.Float)s;
524 } else {
525 p2df = new Path2D.Float(s);
526 }
527 transx = sg2d.transX;
528 transy = sg2d.transY;
529 } else {
530 p2df = new Path2D.Float(s, sg2d.transform);
531 transx = 0;
532 transy = 0;
533 }
534 drawPath(sg2d, p2df, transx, transy);
535 } else if (sg2d.strokeState < sg2d.STROKE_CUSTOM) {
536 ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
537 try {
538 fillSpans(sg2d, si, 0, 0);
539 } finally {
540 si.dispose();
541 }
542 } else {
543 fill(sg2d, sg2d.stroke.createStrokedShape(s));
544 }
545 }
546
547 public void fill(SunGraphics2D sg2d, Shape s) {
548 int transx, transy;
549
550 if (sg2d.strokeState == sg2d.STROKE_THIN) {
551 // Here we are able to use fillPath() for
552 // high-quality fills.
553 Path2D.Float p2df;
554 if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
555 if (s instanceof Path2D.Float) {
556 p2df = (Path2D.Float)s;
557 } else {
558 p2df = new Path2D.Float(s);
559 }
560 transx = sg2d.transX;
561 transy = sg2d.transY;
562 } else {
563 p2df = new Path2D.Float(s, sg2d.transform);
564 transx = 0;
565 transy = 0;
566 }
567 fillPath(sg2d, p2df, transx, transy);
568 return;
569 }
570
571 AffineTransform at;
572 if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
573 // Transform (translation) will be done by FillSpans (we could
574 // delegate to fillPolygon() here, but most hardware accelerated
575 // libraries cannot handle non-convex polygons, so we will use
576 // the FillSpans approach by default)
577 at = null;
578 transx = sg2d.transX;
579 transy = sg2d.transY;
580 } else {
581 // Transform will be done by the PathIterator
582 at = sg2d.transform;
583 transx = transy = 0;
584 }
585
586 ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
587 try {
588 // Subtract transx/y from the SSI clip to match the
589 // (potentially untranslated) geometry fed to it
590 Region clip = sg2d.getCompClip();
591 ssi.setOutputAreaXYXY(clip.getLoX() - transx,
592 clip.getLoY() - transy,
593 clip.getHiX() - transx,
594 clip.getHiY() - transy);
595 ssi.appendPath(s.getPathIterator(at));
596 fillSpans(sg2d, ssi, transx, transy);
597 } finally {
598 ssi.dispose();
599 }
600 }
601}
java/pkg/sun/java2d/pipe/BufferedTextPipe.java+168−0
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) 2007, 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
26package sun.java2d.pipe;
27
28import java.awt.AlphaComposite;
29import java.awt.Composite;
30import sun.font.GlyphList;
31import sun.java2d.SunGraphics2D;
32import sun.java2d.SurfaceData;
33import static sun.java2d.pipe.BufferedOpCodes.*;
34
35public abstract class BufferedTextPipe extends GlyphListPipe {
36
37 private static final int BYTES_PER_GLYPH_IMAGE = 8;
38 private static final int BYTES_PER_GLYPH_POSITION = 8;
39
40 /**
41 * The following offsets are used to pack the parameters in
42 * createPackedParams(). (They are also used at the native level when
43 * unpacking the params.)
44 */
45 private static final int OFFSET_CONTRAST = 8;
46 private static final int OFFSET_RGBORDER = 2;
47 private static final int OFFSET_SUBPIXPOS = 1;
48 private static final int OFFSET_POSITIONS = 0;
49
50 /**
51 * Packs the given parameters into a single int value in order to save
52 * space on the rendering queue. Note that most of these parameters
53 * are only used for rendering LCD-optimized text, but conditionalizing
54 * this work wouldn't make any impact on performance, so we will pack
55 * those parameters even in the non-LCD case.
56 */
57 private static int createPackedParams(SunGraphics2D sg2d, GlyphList gl) {
58 return
59 (((gl.usePositions() ? 1 : 0) << OFFSET_POSITIONS) |
60 ((gl.isSubPixPos() ? 1 : 0) << OFFSET_SUBPIXPOS) |
61 ((gl.isRGBOrder() ? 1 : 0) << OFFSET_RGBORDER ) |
62 ((sg2d.lcdTextContrast & 0xff) << OFFSET_CONTRAST ));
63 }
64
65 protected final RenderQueue rq;
66
67 protected BufferedTextPipe(RenderQueue rq) {
68 this.rq = rq;
69 }
70
71 @Override
72 protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
73 /*
74 * The native drawGlyphList() only works with two composite types:
75 * - CompositeType.SrcOver (with any extra alpha), or
76 * - CompositeType.Xor
77 */
78 Composite comp = sg2d.composite;
79 if (comp == AlphaComposite.Src) {
80 /*
81 * In addition to the composite types listed above, the logic
82 * in OGL/D3DSurfaceData.validatePipe() allows for
83 * CompositeType.SrcNoEa, but only in the presence of an opaque
84 * color. If we reach this case, we know the color is opaque,
85 * and therefore SrcNoEa is the same as SrcOverNoEa, so we
86 * override the composite here.
87 */
88 comp = AlphaComposite.SrcOver;
89 }
90
91 rq.lock();
92 try {
93 validateContext(sg2d, comp);
94 enqueueGlyphList(sg2d, gl);
95 } finally {
96 rq.unlock();
97 }
98 }
99
100 private void enqueueGlyphList(final SunGraphics2D sg2d,
101 final GlyphList gl)
102 {
103 // assert rq.lock.isHeldByCurrentThread();
104 RenderBuffer buf = rq.getBuffer();
105 final int totalGlyphs = gl.getNumGlyphs();
106 int glyphBytesRequired = totalGlyphs * BYTES_PER_GLYPH_IMAGE;
107 int posBytesRequired =
108 gl.usePositions() ? totalGlyphs * BYTES_PER_GLYPH_POSITION : 0;
109 int totalBytesRequired = 24 + glyphBytesRequired + posBytesRequired;
110
111 final long[] images = gl.getImages();
112 final float glyphListOrigX = gl.getX() + 0.5f;
113 final float glyphListOrigY = gl.getY() + 0.5f;
114
115 // make sure the RenderQueue keeps a hard reference to the FontStrike
116 // so that the associated glyph images are not disposed while enqueued
117 rq.addReference(gl.getStrike());
118
119 if (totalBytesRequired <= buf.capacity()) {
120 if (totalBytesRequired > buf.remaining()) {
121 // process the queue first and then enqueue the glyphs
122 rq.flushNow();
123 }
124 rq.ensureAlignment(20);
125 buf.putInt(DRAW_GLYPH_LIST);
126 // enqueue parameters
127 buf.putInt(totalGlyphs);
128 buf.putInt(createPackedParams(sg2d, gl));
129 buf.putFloat(glyphListOrigX);
130 buf.putFloat(glyphListOrigY);
131 // now enqueue glyph information
132 buf.put(images, 0, totalGlyphs);
133 if (gl.usePositions()) {
134 float[] positions = gl.getPositions();
135 buf.put(positions, 0, 2*totalGlyphs);
136 }
137 } else {
138 // queue is too small to accomodate glyphs; perform
139 // the operation directly on the queue flushing thread
140 rq.flushAndInvokeNow(new Runnable() {
141 public void run() {
142 drawGlyphList(totalGlyphs, gl.usePositions(),
143 gl.isSubPixPos(), gl.isRGBOrder(),
144 sg2d.lcdTextContrast,
145 glyphListOrigX, glyphListOrigY,
146 images, gl.getPositions());
147 }
148 });
149 }
150 }
151
152 /**
153 * Called as a separate Runnable when the operation is too large to fit
154 * on the RenderQueue. The OGL/D3D pipelines each have their own (small)
155 * native implementation of this method.
156 */
157 protected abstract void drawGlyphList(int numGlyphs, boolean usePositions,
158 boolean subPixPos, boolean rgbOrder,
159 int lcdContrast,
160 float glOrigX, float glOrigY,
161 long[] images, float[] positions);
162
163 /**
164 * Validates the state in the provided SunGraphics2D object.
165 */
166 protected abstract void validateContext(SunGraphics2D sg2d,
167 Composite comp);
168}
java/pkg/sun/java2d/pipe/CompositePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/CompositePipe.java+50−0
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1997, 2007, 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
26package sun.java2d.pipe;
27
28import java.awt.Rectangle;
29import java.awt.Shape;
30import sun.java2d.SunGraphics2D;
31
32/**
33 * This interface defines the set of calls used by a rendering pipeline
34 * based on an AATileGenerator to communicate the alpha tile sequence
35 * to the output (compositing) stages of the pipeline.
36 */
37public interface CompositePipe {
38 public Object startSequence(SunGraphics2D sg, Shape s, Rectangle dev,
39 int[] abox);
40
41 public boolean needTile(Object context, int x, int y, int w, int h);
42
43 public void renderPathTile(Object context,
44 byte[] atile, int offset, int tilesize,
45 int x, int y, int w, int h);
46
47 public void skipTile(Object context, int x, int y);
48
49 public void endSequence(Object context);
50}
java/pkg/sun/java2d/pipe/DrawImage.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/DrawImage.java+1110−0
@@ -0,0 +1,1110 @@
1/*
2 * Copyright (c) 2001, 2008, 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
26package sun.java2d.pipe;
27
28import java.awt.AlphaComposite;
29import java.awt.Color;
30import java.awt.Graphics2D;
31import java.awt.Image;
32import java.awt.Rectangle;
33import java.awt.Transparency;
34import java.awt.geom.AffineTransform;
35import java.awt.geom.NoninvertibleTransformException;
36import java.awt.image.AffineTransformOp;
37import java.awt.image.BufferedImage;
38import java.awt.image.BufferedImageOp;
39import java.awt.image.ColorModel;
40import java.awt.image.DataBuffer;
41import java.awt.image.DirectColorModel;
42import java.awt.image.ImageObserver;
43import java.awt.image.IndexColorModel;
44import java.awt.image.Raster;
45import java.awt.image.VolatileImage;
46import java.awt.image.WritableRaster;
47import java.awt.image.ImagingOpException;
48import sun.awt.SunHints;
49import sun.awt.image.ImageRepresentation;
50import sun.awt.image.ToolkitImage;
51import sun.java2d.InvalidPipeException;
52import sun.java2d.SunGraphics2D;
53import sun.java2d.SurfaceData;
54import sun.java2d.loops.Blit;
55import sun.java2d.loops.BlitBg;
56import sun.java2d.loops.TransformHelper;
57import sun.java2d.loops.MaskBlit;
58import sun.java2d.loops.CompositeType;
59import sun.java2d.loops.ScaledBlit;
60import sun.java2d.loops.SurfaceType;
61
62public class DrawImage implements DrawImagePipe
63{
64 public boolean copyImage(SunGraphics2D sg, Image img,
65 int x, int y,
66 Color bgColor)
67 {
68 int imgw = img.getWidth(null);
69 int imgh = img.getHeight(null);
70 if (isSimpleTranslate(sg)) {
71 return renderImageCopy(sg, img, bgColor,
72 x + sg.transX, y + sg.transY,
73 0, 0, imgw, imgh);
74 }
75 AffineTransform atfm = sg.transform;
76 if ((x | y) != 0) {
77 atfm = new AffineTransform(atfm);
78 atfm.translate(x, y);
79 }
80 transformImage(sg, img, atfm, sg.interpolationType,
81 0, 0, imgw, imgh, bgColor);
82 return true;
83 }
84
85 public boolean copyImage(SunGraphics2D sg, Image img,
86 int dx, int dy, int sx, int sy, int w, int h,
87 Color bgColor)
88 {
89 if (isSimpleTranslate(sg)) {
90 return renderImageCopy(sg, img, bgColor,
91 dx + sg.transX, dy + sg.transY,
92 sx, sy, w, h);
93 }
94 scaleImage(sg, img, dx, dy, (dx + w), (dy + h),
95 sx, sy, (sx + w), (sy + h), bgColor);
96 return true;
97 }
98
99 public boolean scaleImage(SunGraphics2D sg, Image img, int x, int y,
100 int width, int height,
101 Color bgColor)
102 {
103 int imgw = img.getWidth(null);
104 int imgh = img.getHeight(null);
105 // Only accelerate scale if:
106 // - w/h positive values
107 // - sg transform integer translate/identity only
108 // - no bgColor in operation
109 if ((width > 0) && (height > 0) && isSimpleTranslate(sg)) {
110 double dx1 = x + sg.transX;
111 double dy1 = y + sg.transY;
112 double dx2 = dx1 + width;
113 double dy2 = dy1 + height;
114 if (renderImageScale(sg, img, bgColor, sg.interpolationType,
115 0, 0, imgw, imgh,
116 dx1, dy1, dx2, dy2))
117 {
118 return true;
119 }
120 }
121
122 AffineTransform atfm = sg.transform;
123 if ((x | y) != 0 || width != imgw || height != imgh) {
124 atfm = new AffineTransform(atfm);
125 atfm.translate(x, y);
126 atfm.scale(((double)width)/imgw, ((double)height)/imgh);
127 }
128 transformImage(sg, img, atfm, sg.interpolationType,
129 0, 0, imgw, imgh, bgColor);
130 return true;
131 }
132
133 /*
134 * This method is only called in those circumstances where the
135 * operation has a non-null secondary transform specfied. Its
136 * role is to check for various optimizations based on the types
137 * of both the secondary and SG2D transforms and to do some
138 * quick calculations to avoid having to combine the transforms
139 * and/or to call a more generalized method.
140 */
141 protected void transformImage(SunGraphics2D sg, Image img, int x, int y,
142 AffineTransform extraAT, int interpType)
143 {
144 int txtype = extraAT.getType();
145 int imgw = img.getWidth(null);
146 int imgh = img.getHeight(null);
147 boolean checkfinalxform;
148
149 if (sg.transformState <= sg.TRANSFORM_ANY_TRANSLATE &&
150 (txtype == AffineTransform.TYPE_IDENTITY ||
151 txtype == AffineTransform.TYPE_TRANSLATION))
152 {
153 // First optimization - both are some kind of translate
154
155 // Combine the translations and check if interpolation is necessary.
156 double tx = extraAT.getTranslateX();
157 double ty = extraAT.getTranslateY();
158 tx += sg.transform.getTranslateX();
159 ty += sg.transform.getTranslateY();
160 int itx = (int) Math.floor(tx + 0.5);
161 int ity = (int) Math.floor(ty + 0.5);
162 if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
163 (closeToInteger(itx, tx) && closeToInteger(ity, ty)))
164 {
165 renderImageCopy(sg, img, null, x+itx, y+ity, 0, 0, imgw, imgh);
166 return;
167 }
168 checkfinalxform = false;
169 } else if (sg.transformState <= sg.TRANSFORM_TRANSLATESCALE &&
170 ((txtype & (AffineTransform.TYPE_FLIP |
171 AffineTransform.TYPE_MASK_ROTATION |
172 AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0))
173 {
174 // Second optimization - both are some kind of translate or scale
175
176 // Combine the scales and check if interpolation is necessary.
177
178 // Transform source bounds by extraAT,
179 // then translate the bounds again by x, y
180 // then transform the bounds again by sg.transform
181 double coords[] = new double[] {
182 0, 0, imgw, imgh,
183 };
184 extraAT.transform(coords, 0, coords, 0, 2);
185 coords[0] += x;
186 coords[1] += y;
187 coords[2] += x;
188 coords[3] += y;
189 sg.transform.transform(coords, 0, coords, 0, 2);
190
191 if (tryCopyOrScale(sg, img, 0, 0, imgw, imgh,
192 null, interpType, coords))
193 {
194 return;
195 }
196 checkfinalxform = false;
197 } else {
198 checkfinalxform = true;
199 }
200
201 // Begin Transform
202 AffineTransform tx = new AffineTransform(sg.transform);
203 tx.translate(x, y);
204 tx.concatenate(extraAT);
205
206 // Do not try any more optimizations if either of the cases
207 // above was tried as we have already verified that the
208 // resulting transform will not simplify.
209 if (checkfinalxform) {
210 // In this case neither of the above simple transform
211 // pairs was found so we will do some final tests on
212 // the final rendering transform which may be the
213 // simple product of two complex transforms.
214 transformImage(sg, img, tx, interpType, 0, 0, imgw, imgh, null);
215 } else {
216 renderImageXform(sg, img, tx, interpType, 0, 0, imgw, imgh, null);
217 }
218 }
219
220 /*
221 * This method is called with a final rendering transform that
222 * has combined all of the information about the Graphics2D
223 * transform attribute with the transformations specified by
224 * the arguments to the drawImage call.
225 * Its role is to see if the combined transform ends up being
226 * acceleratable by either a renderImageCopy or renderImageScale
227 * once all of the math is done.
228 *
229 * Note: The transform supplied here has an origin that is
230 * already adjusted to point to the device location where
231 * the (sx1, sy1) location of the source image should be placed.
232 */
233 protected void transformImage(SunGraphics2D sg, Image img,
234 AffineTransform tx, int interpType,
235 int sx1, int sy1, int sx2, int sy2,
236 Color bgColor)
237 {
238 // Transform 3 source corners by tx and analyze them
239 // for simplified operations (Copy or Scale). Using
240 // 3 points lets us analyze any kind of transform,
241 // even transforms that involve very tiny amounts of
242 // rotation or skew to see if they degenerate to a
243 // simple scale or copy operation within the allowable
244 // error bounds.
245 // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2)
246 // because the transform is already translated such that
247 // the origin is where sx1, sy1 should go.
248 double coords[] = new double[6];
249 /* index: 0 1 2 3 4 5 */
250 /* coord: (0, 0), (w, h), (0, h) */
251 coords[2] = sx2 - sx1;
252 coords[3] = coords[5] = sy2 - sy1;
253 tx.transform(coords, 0, coords, 0, 3);
254 // First test if the X coords of the transformed UL
255 // and LL points match and that the Y coords of the
256 // transformed LR and LL points also match.
257 // If they do then it is a "rectilinear" transform and
258 // tryCopyOrScale will make sure it is upright and
259 // integer-based.
260 if (Math.abs(coords[0] - coords[4]) < MAX_TX_ERROR &&
261 Math.abs(coords[3] - coords[5]) < MAX_TX_ERROR &&
262 tryCopyOrScale(sg, img, sx1, sy1, sx2, sy2,
263 bgColor, interpType, coords))
264 {
265 return;
266 }
267
268 renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, bgColor);
269 }
270
271 /*
272 * Check the bounding coordinates of the transformed source
273 * image to see if they fall on integer coordinates such
274 * that they will cause no interpolation anomalies if we
275 * use our simplified Blit or ScaledBlit operations instead
276 * of a full transform operation.
277 */
278 protected boolean tryCopyOrScale(SunGraphics2D sg,
279 Image img,
280 int sx1, int sy1,
281 int sx2, int sy2,
282 Color bgColor, int interpType,
283 double coords[])
284 {
285 double dx = coords[0];
286 double dy = coords[1];
287 double dw = coords[2] - dx;
288 double dh = coords[3] - dy;
289 // First check if width and height are very close to img w&h.
290 if (closeToInteger(sx2-sx1, dw) && closeToInteger(sy2-sy1, dh)) {
291 // Round location to nearest pixel and then test
292 // if it will cause interpolation anomalies.
293 int idx = (int) Math.floor(dx + 0.5);
294 int idy = (int) Math.floor(dy + 0.5);
295 if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
296 (closeToInteger(idx, dx) && closeToInteger(idy, dy)))
297 {
298 renderImageCopy(sg, img, bgColor,
299 idx, idy,
300 sx1, sy1, sx2-sx1, sy2-sy1);
301 return true;
302 }
303 }
304 // (For now) We can only use our ScaledBlits if the image
305 // is upright (i.e. dw & dh both > 0)
306 if (dw > 0 && dh > 0) {
307 if (renderImageScale(sg, img, bgColor, interpType,
308 sx1, sy1, sx2, sy2,
309 coords[0], coords[1], coords[2], coords[3]))
310 {
311 return true;
312 }
313 }
314 return false;
315 }
316
317 /*
318 * Return a BufferedImage of the requested type with the indicated
319 * subimage of the original image located at 0,0 in the new image.
320 * If a bgColor is supplied, composite the original image over that
321 * color with a SrcOver operation, otherwise make a SrcNoEa copy.
322 */
323 BufferedImage makeBufferedImage(Image img, Color bgColor, int type,
324 int sx1, int sy1, int sx2, int sy2)
325 {
326 BufferedImage bimg = new BufferedImage(sx2-sx1, sy2-sy1, type);
327 Graphics2D g2d = bimg.createGraphics();
328 g2d.setComposite(AlphaComposite.Src);
329 if (bgColor != null) {
330 g2d.setColor(bgColor);
331 g2d.fillRect(0, 0, sx2-sx1, sy2-sy1);
332 g2d.setComposite(AlphaComposite.SrcOver);
333 }
334 g2d.drawImage(img, -sx1, -sy1, null);
335 g2d.dispose();
336 return bimg;
337 }
338
339 protected void renderImageXform(SunGraphics2D sg, Image img,
340 AffineTransform tx, int interpType,
341 int sx1, int sy1, int sx2, int sy2,
342 Color bgColor)
343 {
344 Region clip = sg.getCompClip();
345 SurfaceData dstData = sg.surfaceData;
346 SurfaceData srcData = dstData.getSourceSurfaceData(img,
347 sg.TRANSFORM_GENERIC,
348 sg.imageComp,
349 bgColor);
350
351 if (srcData == null) {
352 img = getBufferedImage(img);
353 srcData = dstData.getSourceSurfaceData(img,
354 sg.TRANSFORM_GENERIC,
355 sg.imageComp,
356 bgColor);
357 if (srcData == null) {
358 // REMIND: Is this correct? Can this happen?
359 return;
360 }
361 }
362
363 if (isBgOperation(srcData, bgColor)) {
364 // We cannot perform bg operations during transform so make
365 // an opaque temp image with the appropriate background
366 // and work from there.
367 img = makeBufferedImage(img, bgColor, BufferedImage.TYPE_INT_RGB,
368 sx1, sy1, sx2, sy2);
369 // Temp image has appropriate subimage at 0,0 now.
370 sx2 -= sx1;
371 sy2 -= sy1;
372 sx1 = sy1 = 0;
373
374 srcData = dstData.getSourceSurfaceData(img,
375 sg.TRANSFORM_GENERIC,
376 sg.imageComp,
377 bgColor);
378 }
379
380 SurfaceType srcType = srcData.getSurfaceType();
381 TransformHelper helper = TransformHelper.getFromCache(srcType);
382
383 if (helper == null) {
384 /* We have no helper for this source image type.
385 * But we know that we do have helpers for both RGB and ARGB,
386 * so convert to one of those types depending on transparency.
387 * ARGB_PRE might be a better choice if the source image has
388 * alpha, but it may cause some recursion here since we only
389 * tend to have converters that convert to ARGB.
390 */
391 int type = ((srcData.getTransparency() == Transparency.OPAQUE)
392 ? BufferedImage.TYPE_INT_RGB
393 : BufferedImage.TYPE_INT_ARGB);
394 img = makeBufferedImage(img, null, type, sx1, sy1, sx2, sy2);
395 // Temp image has appropriate subimage at 0,0 now.
396 sx2 -= sx1;
397 sy2 -= sy1;
398 sx1 = sy1 = 0;
399
400 srcData = dstData.getSourceSurfaceData(img,
401 sg.TRANSFORM_GENERIC,
402 sg.imageComp,
403 null);
404 srcType = srcData.getSurfaceType();
405 helper = TransformHelper.getFromCache(srcType);
406 // assert(helper != null);
407 }
408
409 AffineTransform itx;
410 try {
411 itx = tx.createInverse();
412 } catch (NoninvertibleTransformException e) {
413 // Non-invertible transform means no output
414 return;
415 }
416
417 /*
418 * Find the maximum bounds on the destination that will be
419 * affected by the transformed source. First, transform all
420 * four corners of the source and then min and max the resulting
421 * destination coordinates of the transformed corners.
422 * Note that tx already has the offset to sx1,sy1 accounted
423 * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the
424 * source coordinates.
425 */
426 double coords[] = new double[8];
427 /* corner: UL UR LL LR */
428 /* index: 0 1 2 3 4 5 6 7 */
429 /* coord: (0, 0), (w, 0), (0, h), (w, h) */
430 coords[2] = coords[6] = sx2 - sx1;
431 coords[5] = coords[7] = sy2 - sy1;
432 tx.transform(coords, 0, coords, 0, 4);
433 double ddx1, ddy1, ddx2, ddy2;
434 ddx1 = ddx2 = coords[0];
435 ddy1 = ddy2 = coords[1];
436 for (int i = 2; i < coords.length; i += 2) {
437 double d = coords[i];
438 if (ddx1 > d) ddx1 = d;
439 else if (ddx2 < d) ddx2 = d;
440 d = coords[i+1];
441 if (ddy1 > d) ddy1 = d;
442 else if (ddy2 < d) ddy2 = d;
443 }
444 int dx1 = (int) Math.floor(ddx1);
445 int dy1 = (int) Math.floor(ddy1);
446 int dx2 = (int) Math.ceil(ddx2);
447 int dy2 = (int) Math.ceil(ddy2);
448
449 SurfaceType dstType = dstData.getSurfaceType();
450 MaskBlit maskblit;
451 Blit blit;
452 if (sg.compositeState <= sg.COMP_ALPHA) {
453 /* NOTE: We either have, or we can make,
454 * a MaskBlit for any alpha composite type
455 */
456 maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre,
457 sg.imageComp,
458 dstType);
459
460 /* NOTE: We can only use the native TransformHelper
461 * func to go directly to the dest if both the helper
462 * and the MaskBlit are native.
463 * All helpers are native at this point, but some MaskBlit
464 * objects are implemented in Java, so we need to check.
465 */
466 if (maskblit.getNativePrim() != 0) {
467 // We can render directly.
468 helper.Transform(maskblit, srcData, dstData,
469 sg.composite, clip,
470 itx, interpType,
471 sx1, sy1, sx2, sy2,
472 dx1, dy1, dx2, dy2,
473 null, 0, 0);
474 return;
475 }
476 blit = null;
477 } else {
478 /* NOTE: We either have, or we can make,
479 * a Blit for any composite type, even Custom
480 */
481 maskblit = null;
482 blit = Blit.getFromCache(SurfaceType.IntArgbPre,
483 sg.imageComp,
484 dstType);
485 }
486
487 // We need to transform to a temp image and then copy
488 // just the pieces that are valid data to the dest.
489 BufferedImage tmpimg = new BufferedImage(dx2-dx1, dy2-dy1,
490 BufferedImage.TYPE_INT_ARGB);
491 SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg);
492 SurfaceType tmpType = tmpData.getSurfaceType();
493 MaskBlit tmpmaskblit =
494 MaskBlit.getFromCache(SurfaceType.IntArgbPre,
495 CompositeType.SrcNoEa,
496 tmpType);
497 /*
498 * The helper function fills a temporary edges buffer
499 * for us with the bounding coordinates of each scanline
500 * in the following format:
501 *
502 * edges[0, 1] = [top y, bottom y)
503 * edges[2, 3] = [left x, right x) of top row
504 * ...
505 * edges[h*2, h*2+1] = [left x, right x) of bottom row
506 *
507 * all coordinates in the edges array will be relative to dx1, dy1
508 *
509 * edges thus has to be h*2+2 in length
510 */
511 int edges[] = new int[(dy2-dy1)*2+2];
512 // It is important that edges[0]=edges[1]=0 when we call
513 // Transform in case it must return early and we would
514 // not want to render anything on an error condition.
515 helper.Transform(tmpmaskblit, srcData, tmpData,
516 AlphaComposite.Src, null,
517 itx, interpType,
518 sx1, sy1, sx2, sy2,
519 0, 0, dx2-dx1, dy2-dy1,
520 edges, dx1, dy1);
521
522 /*
523 * Now copy the results, scanline by scanline, into the dest.
524 * The edges array helps us minimize the work.
525 */
526 int index = 2;
527 for (int y = edges[0]; y < edges[1]; y++) {
528 int relx1 = edges[index++];
529 int relx2 = edges[index++];
530 if (relx1 >= relx2) {
531 continue;
532 }
533 if (maskblit != null) {
534 maskblit.MaskBlit(tmpData, dstData,
535 sg.composite, clip,
536 relx1, y,
537 dx1+relx1, dy1+y,
538 relx2 - relx1, 1,
539 null, 0, 0);
540 } else {
541 blit.Blit(tmpData, dstData,
542 sg.composite, clip,
543 relx1, y,
544 dx1+relx1, dy1+y,
545 relx2 - relx1, 1);
546 }
547 }
548 }
549
550 // Render an image using only integer translation
551 // (no scale or transform or sub-pixel interpolated translations).
552 protected boolean renderImageCopy(SunGraphics2D sg, Image img,
553 Color bgColor,
554 int dx, int dy,
555 int sx, int sy,
556 int w, int h)
557 {
558 Region clip = sg.getCompClip();
559 SurfaceData dstData = sg.surfaceData;
560
561 int attempts = 0;
562 // Loop up to twice through; this gives us a chance to
563 // revalidate the surfaceData objects in case of an exception
564 // and try it once more
565 while (true) {
566 SurfaceData srcData =
567 dstData.getSourceSurfaceData(img,
568 sg.TRANSFORM_ISIDENT,
569 sg.imageComp,
570 bgColor);
571 if (srcData == null) {
572 return false;
573 }
574
575 try {
576 SurfaceType srcType = srcData.getSurfaceType();
577 SurfaceType dstType = dstData.getSurfaceType();
578 blitSurfaceData(sg, clip,
579 srcData, dstData, srcType, dstType,
580 sx, sy, dx, dy, w, h, bgColor);
581 return true;
582 } catch (NullPointerException e) {
583 if (!(SurfaceData.isNull(dstData) ||
584 SurfaceData.isNull(srcData)))
585 {
586 // Something else caused the exception, throw it...
587 throw e;
588 }
589 return false;
590 // NOP if we have been disposed
591 } catch (InvalidPipeException e) {
592 // Always catch the exception; try this a couple of times
593 // and fail silently if the system is not yet ready to
594 // revalidate the source or dest surfaceData objects.
595 ++attempts;
596 clip = sg.getCompClip(); // ensures sg.surfaceData is valid
597 dstData = sg.surfaceData;
598 if (SurfaceData.isNull(dstData) ||
599 SurfaceData.isNull(srcData) || (attempts > 1))
600 {
601 return false;
602 }
603 }
604 }
605 }
606
607 // Render an image using only integer scaling (no transform).
608 protected boolean renderImageScale(SunGraphics2D sg, Image img,
609 Color bgColor, int interpType,
610 int sx1, int sy1,
611 int sx2, int sy2,
612 double dx1, double dy1,
613 double dx2, double dy2)
614 {
615 // Currently only NEAREST_NEIGHBOR interpolation is implemented
616 // for ScaledBlit operations.
617 if (interpType != AffineTransformOp.TYPE_NEAREST_NEIGHBOR) {
618 return false;
619 }
620
621 Region clip = sg.getCompClip();
622 SurfaceData dstData = sg.surfaceData;
623
624 int attempts = 0;
625 // Loop up to twice through; this gives us a chance to
626 // revalidate the surfaceData objects in case of an exception
627 // and try it once more
628 while (true) {
629 SurfaceData srcData =
630 dstData.getSourceSurfaceData(img,
631 sg.TRANSFORM_TRANSLATESCALE,
632 sg.imageComp,
633 bgColor);
634
635 if (srcData == null || isBgOperation(srcData, bgColor)) {
636 return false;
637 }
638
639 try {
640 SurfaceType srcType = srcData.getSurfaceType();
641 SurfaceType dstType = dstData.getSurfaceType();
642 return scaleSurfaceData(sg, clip,
643 srcData, dstData, srcType, dstType,
644 sx1, sy1, sx2, sy2,
645 dx1, dy1, dx2, dy2);
646 } catch (NullPointerException e) {
647 if (!SurfaceData.isNull(dstData)) {
648 // Something else caused the exception, throw it...
649 throw e;
650 }
651 return false;
652 // NOP if we have been disposed
653 } catch (InvalidPipeException e) {
654 // Always catch the exception; try this a couple of times
655 // and fail silently if the system is not yet ready to
656 // revalidate the source or dest surfaceData objects.
657 ++attempts;
658 clip = sg.getCompClip(); // ensures sg.surfaceData is valid
659 dstData = sg.surfaceData;
660 if (SurfaceData.isNull(dstData) ||
661 SurfaceData.isNull(srcData) || (attempts > 1))
662 {
663 return false;
664 }
665 }
666 }
667 }
668
669 public boolean scaleImage(SunGraphics2D sg, Image img,
670 int dx1, int dy1, int dx2, int dy2,
671 int sx1, int sy1, int sx2, int sy2,
672 Color bgColor)
673 {
674 int srcW, srcH, dstW, dstH;
675 int srcX, srcY, dstX, dstY;
676 boolean srcWidthFlip = false;
677 boolean srcHeightFlip = false;
678 boolean dstWidthFlip = false;
679 boolean dstHeightFlip = false;
680
681 if (sx2 > sx1) {
682 srcW = sx2 - sx1;
683 srcX = sx1;
684 } else {
685 srcWidthFlip = true;
686 srcW = sx1 - sx2;
687 srcX = sx2;
688 }
689 if (sy2 > sy1) {
690 srcH = sy2-sy1;
691 srcY = sy1;
692 } else {
693 srcHeightFlip = true;
694 srcH = sy1-sy2;
695 srcY = sy2;
696 }
697 if (dx2 > dx1) {
698 dstW = dx2 - dx1;
699 dstX = dx1;
700 } else {
701 dstW = dx1 - dx2;
702 dstWidthFlip = true;
703 dstX = dx2;
704 }
705 if (dy2 > dy1) {
706 dstH = dy2 - dy1;
707 dstY = dy1;
708 } else {
709 dstH = dy1 - dy2;
710 dstHeightFlip = true;
711 dstY = dy2;
712 }
713 if (srcW <= 0 || srcH <= 0) {
714 return true;
715 }
716 // Only accelerate scale if it does not involve a flip or transform
717 if ((srcWidthFlip == dstWidthFlip) &&
718 (srcHeightFlip == dstHeightFlip) &&
719 isSimpleTranslate(sg))
720 {
721 double ddx1 = dstX + sg.transX;
722 double ddy1 = dstY + sg.transY;
723 double ddx2 = ddx1 + dstW;
724 double ddy2 = ddy1 + dstH;
725 if (renderImageScale(sg, img, bgColor, sg.interpolationType,
726 srcX, srcY, srcX+srcW, srcY+srcH,
727 ddx1, ddy1, ddx2, ddy2))
728 {
729 return true;
730 }
731 }
732
733 AffineTransform atfm = new AffineTransform(sg.transform);
734 atfm.translate(dx1, dy1);
735 double m00 = (double)(dx2-dx1)/(sx2-sx1);
736 double m11 = (double)(dy2-dy1)/(sy2-sy1);
737 atfm.scale(m00, m11);
738 atfm.translate(srcX-sx1, srcY-sy1);
739
740 int imgW = img.getWidth(null);
741 int imgH = img.getHeight(null);
742 srcW += srcX;
743 srcH += srcY;
744 // Make sure we are not out of bounds
745 if (srcW > imgW) {
746 srcW = imgW;
747 }
748 if (srcH > imgH) {
749 srcH = imgH;
750 }
751 if (srcX < 0) {
752 atfm.translate(-srcX, 0);
753 srcX = 0;
754 }
755 if (srcY < 0) {
756 atfm.translate(0, -srcY);
757 srcY = 0;
758 }
759 if (srcX >= srcW || srcY >= srcH) {
760 return true;
761 }
762 // Note: src[WH] are currently the right and bottom coordinates.
763 // The following two lines would adjust src[WH] back to being
764 // dimensions.
765 // srcW -= srcX;
766 // srcH -= srcY;
767 // Since transformImage needs right and bottom coords we will
768 // omit this adjustment.
769
770 transformImage(sg, img, atfm, sg.interpolationType,
771 srcX, srcY, srcW, srcH, bgColor);
772 return true;
773 }
774
775 /**
776 ** Utilities
777 ** The following methods are used by the public methods above
778 ** for performing various operations
779 **/
780
781 /*
782 * This constant represents a tradeoff between the
783 * need to make sure that image transformations are
784 * "very close" to integer device coordinates before
785 * we decide to use an integer scale or copy operation
786 * as a substitute and the fact that roundoff errors
787 * in AffineTransforms are frequently introduced by
788 * performing multiple sequential operations on them.
789 *
790 * The evaluation of bug 4990624 details the potential
791 * for this error cutoff to result in display anomalies
792 * in different types of image operations and how this
793 * value represents a good compromise here.
794 */
795 private static final double MAX_TX_ERROR = .0001;
796
797 public static boolean closeToInteger(int i, double d) {
798 return (Math.abs(d-i) < MAX_TX_ERROR);
799 }
800
801 public static boolean isSimpleTranslate(SunGraphics2D sg) {
802 int ts = sg.transformState;
803 if (ts <= sg.TRANSFORM_INT_TRANSLATE) {
804 // Integer translates are always "simple"
805 return true;
806 }
807 if (ts >= sg.TRANSFORM_TRANSLATESCALE) {
808 // Scales and beyond are always "not simple"
809 return false;
810 }
811 // non-integer translates are only simple when not interpolating
812 if (sg.interpolationType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR) {
813 return true;
814 }
815 return false;
816 }
817
818 protected static boolean isBgOperation(SurfaceData srcData, Color bgColor) {
819 // If we cannot get the srcData, then cannot assume anything about
820 // the image
821 return ((srcData == null) ||
822 ((bgColor != null) &&
823 (srcData.getTransparency() != Transparency.OPAQUE)));
824 }
825
826 protected BufferedImage getBufferedImage(Image img) {
827 if (img instanceof BufferedImage) {
828 return (BufferedImage)img;
829 }
830 // Must be VolatileImage; get BufferedImage representation
831 return ((VolatileImage)img).getSnapshot();
832 }
833
834 /*
835 * Return the color model to be used with this BufferedImage and
836 * transform.
837 */
838 private ColorModel getTransformColorModel(SunGraphics2D sg,
839 BufferedImage bImg,
840 AffineTransform tx) {
841 ColorModel cm = bImg.getColorModel();
842 ColorModel dstCM = cm;
843
844 if (tx.isIdentity()) {
845 return dstCM;
846 }
847 int type = tx.getType();
848 boolean needTrans =
849 ((type&(tx.TYPE_MASK_ROTATION|tx.TYPE_GENERAL_TRANSFORM)) != 0);
850 if (! needTrans && type != tx.TYPE_TRANSLATION && type != tx.TYPE_IDENTITY)
851 {
852 double[] mtx = new double[4];
853 tx.getMatrix(mtx);
854 // Check out the matrix. A non-integral scale will force ARGB
855 // since the edge conditions cannot be guaranteed.
856 needTrans = (mtx[0] != (int)mtx[0] || mtx[3] != (int)mtx[3]);
857 }
858
859 if (sg.renderHint != SunHints.INTVAL_RENDER_QUALITY) {
860 if (cm instanceof IndexColorModel) {
861 Raster raster = bImg.getRaster();
862 IndexColorModel icm = (IndexColorModel) cm;
863 // Just need to make sure that we have a transparent pixel
864 if (needTrans && cm.getTransparency() == cm.OPAQUE) {
865 // Fix 4221407
866 if (raster instanceof sun.awt.image.BytePackedRaster) {
867 dstCM = ColorModel.getRGBdefault();
868 }
869 else {
870 double[] matrix = new double[6];
871 tx.getMatrix(matrix);
872 if (matrix[1] == 0. && matrix[2] ==0.
873 && matrix[4] == 0. && matrix[5] == 0.) {
874 // Only scaling so do not need to create
875 }
876 else {
877 int mapSize = icm.getMapSize();
878 if (mapSize < 256) {
879 int[] cmap = new int[mapSize+1];
880 icm.getRGBs(cmap);
881 cmap[mapSize] = 0x0000;
882 dstCM = new
883 IndexColorModel(icm.getPixelSize(),
884 mapSize+1,
885 cmap, 0, true, mapSize,
886 DataBuffer.TYPE_BYTE);
887 }
888 else {
889 dstCM = ColorModel.getRGBdefault();
890 }
891 } /* if (matrix[0] < 1.f ...) */
892 } /* raster instanceof sun.awt.image.BytePackedRaster */
893 } /* if (cm.getTransparency() == cm.OPAQUE) */
894 } /* if (cm instanceof IndexColorModel) */
895 else if (needTrans && cm.getTransparency() == cm.OPAQUE) {
896 // Need a bitmask transparency
897 // REMIND: for now, use full transparency since no loops
898 // for bitmask
899 dstCM = ColorModel.getRGBdefault();
900 }
901 } /* if (sg.renderHint == RENDER_QUALITY) */
902 else {
903
904 if (cm instanceof IndexColorModel ||
905 (needTrans && cm.getTransparency() == cm.OPAQUE))
906 {
907 // Need a bitmask transparency
908 // REMIND: for now, use full transparency since no loops
909 // for bitmask
910 dstCM = ColorModel.getRGBdefault();
911 }
912 }
913
914 return dstCM;
915 }
916
917 protected void blitSurfaceData(SunGraphics2D sg,
918 Region clipRegion,
919 SurfaceData srcData,
920 SurfaceData dstData,
921 SurfaceType srcType,
922 SurfaceType dstType,
923 int sx, int sy, int dx, int dy,
924 int w, int h,
925 Color bgColor)
926 {
927 if (w <= 0 || h <= 0) {
928 /*
929 * Fix for bugid 4783274 - BlitBg throws an exception for
930 * a particular set of anomalous parameters.
931 * REMIND: The native loops do proper clipping and would
932 * detect this situation themselves, but the Java loops
933 * all seem to trust their parameters a little too well
934 * to the point where they will try to process a negative
935 * area of pixels and throw exceptions. The real fix is
936 * to modify the Java loops to do proper clipping so that
937 * they can deal with negative dimensions as well as
938 * improperly large dimensions, but that fix is too risky
939 * to integrate for Mantis at this point. In the meantime
940 * eliminating the negative or zero dimensions here is
941 * "correct" and saves them from some nasty exceptional
942 * conditions, one of which is the test case of 4783274.
943 */
944 return;
945 }
946 CompositeType comp = sg.imageComp;
947 if (CompositeType.SrcOverNoEa.equals(comp) &&
948 (srcData.getTransparency() == Transparency.OPAQUE ||
949 (bgColor != null &&
950 bgColor.getTransparency() == Transparency.OPAQUE)))
951 {
952 comp = CompositeType.SrcNoEa;
953 }
954 if (!isBgOperation(srcData, bgColor)) {
955 Blit blit = Blit.getFromCache(srcType, comp, dstType);
956 blit.Blit(srcData, dstData, sg.composite, clipRegion,
957 sx, sy, dx, dy, w, h);
958 } else {
959 BlitBg blit = BlitBg.getFromCache(srcType, comp, dstType);
960 blit.BlitBg(srcData, dstData, sg.composite, clipRegion,
961 bgColor.getRGB(), sx, sy, dx, dy, w, h);
962 }
963 }
964
965 protected boolean scaleSurfaceData(SunGraphics2D sg,
966 Region clipRegion,
967 SurfaceData srcData,
968 SurfaceData dstData,
969 SurfaceType srcType,
970 SurfaceType dstType,
971 int sx1, int sy1,
972 int sx2, int sy2,
973 double dx1, double dy1,
974 double dx2, double dy2)
975 {
976 CompositeType comp = sg.imageComp;
977 if (CompositeType.SrcOverNoEa.equals(comp) &&
978 (srcData.getTransparency() == Transparency.OPAQUE))
979 {
980 comp = CompositeType.SrcNoEa;
981 }
982
983 ScaledBlit blit = ScaledBlit.getFromCache(srcType, comp, dstType);
984 if (blit != null) {
985 blit.Scale(srcData, dstData, sg.composite, clipRegion,
986 sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
987 return true;
988 }
989 return false;
990 }
991
992 protected static boolean imageReady(ToolkitImage sunimg,
993 ImageObserver observer)
994 {
995 if (sunimg.hasError()) {
996 if (observer != null) {
997 observer.imageUpdate(sunimg,
998 ImageObserver.ERROR|ImageObserver.ABORT,
999 -1, -1, -1, -1);
1000 }
1001 return false;
1002 }
1003 return true;
1004 }
1005
1006 public boolean copyImage(SunGraphics2D sg, Image img,
1007 int x, int y,
1008 Color bgColor,
1009 ImageObserver observer) {
1010 if (!(img instanceof ToolkitImage)) {
1011 return copyImage(sg, img, x, y, bgColor);
1012 } else {
1013 ToolkitImage sunimg = (ToolkitImage)img;
1014 if (!imageReady(sunimg, observer)) {
1015 return false;
1016 }
1017 ImageRepresentation ir = sunimg.getImageRep();
1018 return ir.drawToBufImage(sg, sunimg, x, y, bgColor, observer);
1019 }
1020 }
1021
1022 public boolean copyImage(SunGraphics2D sg, Image img,
1023 int dx, int dy, int sx, int sy, int w, int h,
1024 Color bgColor,
1025 ImageObserver observer) {
1026 if (!(img instanceof ToolkitImage)) {
1027 return copyImage(sg, img, dx, dy, sx, sy, w, h, bgColor);
1028 } else {
1029 ToolkitImage sunimg = (ToolkitImage)img;
1030 if (!imageReady(sunimg, observer)) {
1031 return false;
1032 }
1033 ImageRepresentation ir = sunimg.getImageRep();
1034 return ir.drawToBufImage(sg, sunimg,
1035 dx, dy, (dx + w), (dy + h),
1036 sx, sy, (sx + w), (sy + h),
1037 bgColor, observer);
1038 }
1039 }
1040
1041 public boolean scaleImage(SunGraphics2D sg, Image img,
1042 int x, int y,
1043 int width, int height,
1044 Color bgColor,
1045 ImageObserver observer) {
1046 if (!(img instanceof ToolkitImage)) {
1047 return scaleImage(sg, img, x, y, width, height, bgColor);
1048 } else {
1049 ToolkitImage sunimg = (ToolkitImage)img;
1050 if (!imageReady(sunimg, observer)) {
1051 return false;
1052 }
1053 ImageRepresentation ir = sunimg.getImageRep();
1054 return ir.drawToBufImage(sg, sunimg, x, y, width, height, bgColor,
1055 observer);
1056 }
1057 }
1058
1059 public boolean scaleImage(SunGraphics2D sg, Image img,
1060 int dx1, int dy1, int dx2, int dy2,
1061 int sx1, int sy1, int sx2, int sy2,
1062 Color bgColor,
1063 ImageObserver observer) {
1064 if (!(img instanceof ToolkitImage)) {
1065 return scaleImage(sg, img, dx1, dy1, dx2, dy2,
1066 sx1, sy1, sx2, sy2, bgColor);
1067 } else {
1068 ToolkitImage sunimg = (ToolkitImage)img;
1069 if (!imageReady(sunimg, observer)) {
1070 return false;
1071 }
1072 ImageRepresentation ir = sunimg.getImageRep();
1073 return ir.drawToBufImage(sg, sunimg, dx1, dy1, dx2, dy2,
1074 sx1, sy1, sx2, sy2, bgColor, observer);
1075 }
1076 }
1077
1078 public boolean transformImage(SunGraphics2D sg, Image img,
1079 AffineTransform atfm,
1080 ImageObserver observer) {
1081 if (!(img instanceof ToolkitImage)) {
1082 transformImage(sg, img, 0, 0, atfm, sg.interpolationType);
1083 return true;
1084 } else {
1085 ToolkitImage sunimg = (ToolkitImage)img;
1086 if (!imageReady(sunimg, observer)) {
1087 return false;
1088 }
1089 ImageRepresentation ir = sunimg.getImageRep();
1090 return ir.drawToBufImage(sg, sunimg, atfm, observer);
1091 }
1092 }
1093
1094 public void transformImage(SunGraphics2D sg, BufferedImage img,
1095 BufferedImageOp op, int x, int y)
1096 {
1097 if (op != null) {
1098 if (op instanceof AffineTransformOp) {
1099 AffineTransformOp atop = (AffineTransformOp) op;
1100 transformImage(sg, img, x, y,
1101 atop.getTransform(),
1102 atop.getInterpolationType());
1103 return;
1104 } else {
1105 img = op.filter(img, null);
1106 }
1107 }
1108 copyImage(sg, img, x, y, null);
1109 }
1110}
java/pkg/sun/java2d/pipe/DrawImagePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/DrawImagePipe.java+86−0
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) 2001, 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
26package sun.java2d.pipe;
27
28import java.awt.Color;
29import java.awt.Image;
30import java.awt.image.BufferedImage;
31import java.awt.image.BufferedImageOp;
32import java.awt.image.ImageObserver;
33import java.awt.geom.AffineTransform;
34import sun.java2d.SunGraphics2D;
35
36/**
37 * This interface defines the set of calls that pipeline objects
38 * can use to pass on responsibility for performing various
39 * image copy commands.
40 * There are 3 types of image copies handled by this class:
41 * - copyImage: These methods simply copy the pixels
42 * from the src to dest, either from (0, 0) (implicit)
43 * or from a given (sx, sy) location.
44 * - scaleImage: These methods copy from src to dest while
45 * scaling the source image. The src and dest rectangles
46 * are used to specify the scale.
47 * - copyImageBg: These methods behave the same as the
48 * copyImage methods except they substitute the given
49 * background color for any transparent pixels.
50 * - scaleImageBg: These methods behave the same as the
51 * scaleImage methods except they substitute the given
52 * background color for any transparent pixels.
53 * - transformImage....
54 */
55public interface DrawImagePipe {
56
57 public boolean copyImage(SunGraphics2D sg, Image img,
58 int x, int y,
59 Color bgColor,
60 ImageObserver observer);
61
62 public boolean copyImage(SunGraphics2D sg, Image img,
63 int dx, int dy, int sx, int sy, int w, int h,
64 Color bgColor,
65 ImageObserver observer);
66
67 public boolean scaleImage(SunGraphics2D sg, Image img, int x, int y,
68 int width, int height,
69 Color bgColor,
70 ImageObserver observer);
71
72 public boolean scaleImage(SunGraphics2D sg, Image img,
73 int dx1, int dy1, int dx2, int dy2,
74 int sx1, int sy1, int sx2, int sy2,
75 Color bgColor,
76 ImageObserver observer);
77
78 public boolean transformImage(SunGraphics2D sg, Image img,
79 AffineTransform atfm,
80 ImageObserver observer);
81
82 public void transformImage(SunGraphics2D sg, BufferedImage img,
83 BufferedImageOp op, int x, int y);
84
85
86}
java/pkg/sun/java2d/pipe/GeneralCompositePipe$TileContext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/GeneralCompositePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/GeneralCompositePipe.java+154−0
@@ -0,0 +1,154 @@
1/*
2 * Copyright (c) 1997, 2002, 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
26package sun.java2d.pipe;
27
28import java.awt.AlphaComposite;
29import java.awt.CompositeContext;
30import java.awt.PaintContext;
31import java.awt.Rectangle;
32import java.awt.Shape;
33import java.awt.RenderingHints;
34import java.awt.image.ColorModel;
35import java.awt.image.BufferedImage;
36import java.awt.image.Raster;
37import java.awt.image.WritableRaster;
38import sun.awt.image.BufImgSurfaceData;
39import sun.java2d.SunGraphics2D;
40import sun.java2d.SurfaceData;
41import sun.java2d.loops.Blit;
42import sun.java2d.loops.MaskBlit;
43import sun.java2d.loops.CompositeType;
44
45public class GeneralCompositePipe implements CompositePipe {
46 class TileContext {
47 SunGraphics2D sunG2D;
48 PaintContext paintCtxt;
49 CompositeContext compCtxt;
50 ColorModel compModel;
51 Object pipeState;
52
53 public TileContext(SunGraphics2D sg, PaintContext pCtx,
54 CompositeContext cCtx, ColorModel cModel) {
55 sunG2D = sg;
56 paintCtxt = pCtx;
57 compCtxt = cCtx;
58 compModel = cModel;
59 }
60 }
61
62 public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR,
63 int[] abox) {
64 RenderingHints hints = sg.getRenderingHints();
65 ColorModel model = sg.getDeviceColorModel();
66 PaintContext paintContext =
67 sg.paint.createContext(model, devR, s.getBounds2D(),
68 sg.cloneTransform(),
69 hints);
70 CompositeContext compositeContext =
71 sg.composite.createContext(paintContext.getColorModel(), model,
72 hints);
73 return new TileContext(sg, paintContext, compositeContext, model);
74 }
75
76 public boolean needTile(Object ctx, int x, int y, int w, int h) {
77 return true;
78 }
79
80 /**
81 * GeneralCompositePipe.renderPathTile works with custom composite operator
82 * provided by an application
83 */
84 public void renderPathTile(Object ctx,
85 byte[] atile, int offset, int tilesize,
86 int x, int y, int w, int h) {
87 TileContext context = (TileContext) ctx;
88 PaintContext paintCtxt = context.paintCtxt;
89 CompositeContext compCtxt = context.compCtxt;
90 SunGraphics2D sg = context.sunG2D;
91
92 Raster srcRaster = paintCtxt.getRaster(x, y, w, h);
93 ColorModel paintModel = paintCtxt.getColorModel();
94
95 Raster dstRaster;
96 Raster dstIn;
97 WritableRaster dstOut;
98
99 SurfaceData sd = sg.getSurfaceData();
100 dstRaster = sd.getRaster(x, y, w, h);
101 if (dstRaster instanceof WritableRaster && atile == null) {
102 dstOut = (WritableRaster) dstRaster;
103 dstOut = dstOut.createWritableChild(x, y, w, h, 0, 0, null);
104 dstIn = dstOut;
105 } else {
106 dstIn = dstRaster.createChild(x, y, w, h, 0, 0, null);
107 dstOut = dstIn.createCompatibleWritableRaster();
108 }
109
110 compCtxt.compose(srcRaster, dstIn, dstOut);
111
112 if (dstRaster != dstOut && dstOut.getParent() != dstRaster) {
113 if (dstRaster instanceof WritableRaster && atile == null) {
114 ((WritableRaster) dstRaster).setDataElements(x, y, dstOut);
115 } else {
116 ColorModel cm = sg.getDeviceColorModel();
117 BufferedImage resImg =
118 new BufferedImage(cm, dstOut,
119 cm.isAlphaPremultiplied(),
120 null);
121 SurfaceData resData = BufImgSurfaceData.createData(resImg);
122 if (atile == null) {
123 Blit blit = Blit.getFromCache(resData.getSurfaceType(),
124 CompositeType.SrcNoEa,
125 sd.getSurfaceType());
126 blit.Blit(resData, sd, AlphaComposite.Src, null,
127 0, 0, x, y, w, h);
128 } else {
129 MaskBlit blit = MaskBlit.getFromCache(resData.getSurfaceType(),
130 CompositeType.SrcNoEa,
131 sd.getSurfaceType());
132 blit.MaskBlit(resData, sd, AlphaComposite.Src, null,
133 0, 0, x, y, w, h,
134 atile, offset, tilesize);
135 }
136 }
137 }
138 }
139
140 public void skipTile(Object ctx, int x, int y) {
141 return;
142 }
143
144 public void endSequence(Object ctx) {
145 TileContext context = (TileContext) ctx;
146 if (context.paintCtxt != null) {
147 context.paintCtxt.dispose();
148 }
149 if (context.compCtxt != null) {
150 context.compCtxt.dispose();
151 }
152 }
153
154}
java/pkg/sun/java2d/pipe/GlyphListLoopPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/GlyphListLoopPipe.java+60−0
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 2005, 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
26package sun.java2d.pipe;
27
28import java.awt.font.GlyphVector;
29import sun.awt.SunHints;
30import sun.java2d.SunGraphics2D;
31import sun.font.GlyphList;
32
33/**
34 * A delegate pipe of SG2D which implements redispatching of
35 * for the src mode loops in the drawGlyphVector case where
36 * the installed loop may not match the glyphvector.
37 */
38
39public abstract class GlyphListLoopPipe extends GlyphListPipe
40 implements LoopBasedPipe
41{
42 protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl,
43 int aaHint) {
44 switch (aaHint) {
45 case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
46 sg2d.loops.drawGlyphListLoop.
47 DrawGlyphList(sg2d, sg2d.surfaceData, gl);
48 return;
49 case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
50 sg2d.loops.drawGlyphListAALoop.
51 DrawGlyphListAA(sg2d, sg2d.surfaceData, gl);
52 return;
53 case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
54 case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
55 sg2d.loops.drawGlyphListLCDLoop.
56 DrawGlyphListLCD(sg2d,sg2d.surfaceData, gl);
57 return;
58 }
59 }
60}
java/pkg/sun/java2d/pipe/GlyphListPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/GlyphListPipe.java+147−0
@@ -0,0 +1,147 @@
1/*
2 * Copyright (c) 2000, 2005, 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
26package sun.java2d.pipe;
27
28import java.awt.Font;
29import java.awt.Rectangle;
30import java.awt.Shape;
31import java.awt.font.FontRenderContext;
32import java.awt.font.GlyphVector;
33import java.awt.font.TextLayout;
34
35import sun.awt.SunHints;
36import sun.java2d.SunGraphics2D;
37import sun.java2d.SurfaceData;
38import sun.font.GlyphList;
39import sun.java2d.loops.FontInfo;
40
41/**
42 * A delegate pipe of SG2D for drawing text.
43 */
44
45public abstract class GlyphListPipe implements TextPipe {
46
47 public void drawString(SunGraphics2D sg2d, String s,
48 double x, double y)
49 {
50 FontInfo info = sg2d.getFontInfo();
51 if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
52 SurfaceData.outlineTextRenderer.drawString(sg2d, s, x, y);
53 return;
54 }
55
56 float devx, devy;
57 if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
58 double origin[] = {x + info.originX, y + info.originY};
59 sg2d.transform.transform(origin, 0, origin, 0, 1);
60 devx = (float)origin[0];
61 devy = (float)origin[1];
62 } else {
63 devx = (float)(x + info.originX + sg2d.transX);
64 devy = (float)(y + info.originY + sg2d.transY);
65 }
66 /* setFromString returns false if shaping is needed, and we then back
67 * off to a TextLayout. Such text may benefit slightly from a lower
68 * overhead in this approach over the approach in previous releases.
69 */
70 GlyphList gl = GlyphList.getInstance();
71 if (gl.setFromString(info, s, devx, devy)) {
72 drawGlyphList(sg2d, gl);
73 gl.dispose();
74 } else {
75 gl.dispose(); // release this asap.
76 TextLayout tl = new TextLayout(s, sg2d.getFont(),
77 sg2d.getFontRenderContext());
78 tl.draw(sg2d, (float)x, (float)y);
79 }
80 }
81
82 public void drawChars(SunGraphics2D sg2d,
83 char data[], int offset, int length,
84 int ix, int iy)
85 {
86 FontInfo info = sg2d.getFontInfo();
87 float x, y;
88 if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
89 SurfaceData.outlineTextRenderer.drawChars(
90 sg2d, data, offset, length, ix, iy);
91 return;
92 }
93 if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
94 double origin[] = {ix + info.originX, iy + info.originY};
95 sg2d.transform.transform(origin, 0, origin, 0, 1);
96 x = (float) origin[0];
97 y = (float) origin[1];
98 } else {
99 x = ix + info.originX + sg2d.transX;
100 y = iy + info.originY + sg2d.transY;
101 }
102 GlyphList gl = GlyphList.getInstance();
103 if (gl.setFromChars(info, data, offset, length, x, y)) {
104 drawGlyphList(sg2d, gl);
105 gl.dispose();
106 } else {
107 gl.dispose(); // release this asap.
108 TextLayout tl = new TextLayout(new String(data, offset, length),
109 sg2d.getFont(),
110 sg2d.getFontRenderContext());
111 tl.draw(sg2d, ix, iy);
112
113 }
114 }
115
116 public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector gv,
117 float x, float y)
118 {
119 FontRenderContext frc = gv.getFontRenderContext();
120 FontInfo info = sg2d.getGVFontInfo(gv.getFont(), frc);
121 if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
122 SurfaceData.outlineTextRenderer.drawGlyphVector(sg2d, gv, x, y);
123 return;
124 }
125 if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
126 double origin[] = {x, y};
127 sg2d.transform.transform(origin, 0, origin, 0, 1);
128 x = (float) origin[0];
129 y = (float) origin[1];
130 } else {
131 x += sg2d.transX; // don't use the glyph info origin, already in gv.
132 y += sg2d.transY;
133 }
134
135 GlyphList gl = GlyphList.getInstance();
136 gl.setFromGlyphVector(info, gv, x, y);
137 drawGlyphList(sg2d, gl, info.aaHint);
138 gl.dispose();
139 }
140
141 protected abstract void drawGlyphList(SunGraphics2D sg2d, GlyphList gl);
142
143 protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl,
144 int aaHint) {
145 drawGlyphList(sg2d, gl);
146 }
147}
java/pkg/sun/java2d/pipe/LCDTextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/LCDTextRenderer.java+44−0
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005, 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
26package sun.java2d.pipe;
27
28import java.awt.font.GlyphVector;
29import sun.java2d.SunGraphics2D;
30import sun.font.GlyphList;
31import static sun.awt.SunHints.*;
32
33/**
34 * A delegate pipe of SG2D for drawing LCD text with
35 * a solid source colour to an opaque destination.
36 */
37
38public class LCDTextRenderer extends GlyphListLoopPipe {
39
40 protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
41 sg2d.loops.drawGlyphListLCDLoop.
42 DrawGlyphListLCD(sg2d, sg2d.surfaceData, gl);
43 }
44}
java/pkg/sun/java2d/pipe/LoopBasedPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/LoopBasedPipe.java+37−0
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) 2009, 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
26package sun.java2d.pipe;
27
28/**
29 * This is a marker interface used by Pipes that need RenderLoops.
30 * RenderLoops are validated in SurfaceData when a pipe is recognised to
31 * implement this interface.
32 *
33 * @author Mario Torre <neugens@aicas.com>
34 */
35public interface LoopBasedPipe {
36
37}
java/pkg/sun/java2d/pipe/LoopPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/LoopPipe.java+378−0
@@ -0,0 +1,378 @@
1/*
2 * Copyright (c) 1999, 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
26package sun.java2d.pipe;
27
28import java.awt.Font;
29import java.awt.Shape;
30import java.awt.BasicStroke;
31import java.awt.Polygon;
32import java.awt.geom.AffineTransform;
33import java.awt.geom.PathIterator;
34import java.awt.geom.RoundRectangle2D;
35import java.awt.geom.Ellipse2D;
36import java.awt.geom.Arc2D;
37import java.awt.geom.IllegalPathStateException;
38import java.awt.geom.Path2D;
39import java.awt.font.GlyphVector;
40import sun.java2d.SunGraphics2D;
41import sun.java2d.SurfaceData;
42import sun.java2d.loops.FontInfo;
43import sun.java2d.loops.DrawPolygons;
44import sun.java2d.loops.FillParallelogram;
45import sun.java2d.loops.DrawParallelogram;
46import sun.awt.SunHints;
47
48public class LoopPipe
49 implements PixelDrawPipe,
50 PixelFillPipe,
51 ParallelogramPipe,
52 ShapeDrawPipe,
53 LoopBasedPipe
54{
55 final static RenderingEngine RenderEngine = RenderingEngine.getInstance();
56
57 public void drawLine(SunGraphics2D sg2d,
58 int x1, int y1, int x2, int y2)
59 {
60 int tX = sg2d.transX;
61 int tY = sg2d.transY;
62 sg2d.loops.drawLineLoop.DrawLine(sg2d, sg2d.getSurfaceData(),
63 x1 + tX, y1 + tY,
64 x2 + tX, y2 + tY);
65 }
66
67 public void drawRect(SunGraphics2D sg2d,
68 int x, int y, int width, int height)
69 {
70 sg2d.loops.drawRectLoop.DrawRect(sg2d, sg2d.getSurfaceData(),
71 x + sg2d.transX,
72 y + sg2d.transY,
73 width, height);
74 }
75
76 public void drawRoundRect(SunGraphics2D sg2d,
77 int x, int y, int width, int height,
78 int arcWidth, int arcHeight)
79 {
80 sg2d.shapepipe.draw(sg2d,
81 new RoundRectangle2D.Float(x, y, width, height,
82 arcWidth, arcHeight));
83 }
84
85 public void drawOval(SunGraphics2D sg2d,
86 int x, int y, int width, int height)
87 {
88 sg2d.shapepipe.draw(sg2d, new Ellipse2D.Float(x, y, width, height));
89 }
90
91 public void drawArc(SunGraphics2D sg2d,
92 int x, int y, int width, int height,
93 int startAngle, int arcAngle)
94 {
95 sg2d.shapepipe.draw(sg2d, new Arc2D.Float(x, y, width, height,
96 startAngle, arcAngle,
97 Arc2D.OPEN));
98 }
99
100 public void drawPolyline(SunGraphics2D sg2d,
101 int xPoints[], int yPoints[],
102 int nPoints)
103 {
104 int nPointsArray[] = { nPoints };
105 sg2d.loops.drawPolygonsLoop.DrawPolygons(sg2d, sg2d.getSurfaceData(),
106 xPoints, yPoints,
107 nPointsArray, 1,
108 sg2d.transX, sg2d.transY,
109 false);
110 }
111
112 public void drawPolygon(SunGraphics2D sg2d,
113 int xPoints[], int yPoints[],
114 int nPoints)
115 {
116 int nPointsArray[] = { nPoints };
117 sg2d.loops.drawPolygonsLoop.DrawPolygons(sg2d, sg2d.getSurfaceData(),
118 xPoints, yPoints,
119 nPointsArray, 1,
120 sg2d.transX, sg2d.transY,
121 true);
122 }
123
124 public void fillRect(SunGraphics2D sg2d,
125 int x, int y, int width, int height)
126 {
127 sg2d.loops.fillRectLoop.FillRect(sg2d, sg2d.getSurfaceData(),
128 x + sg2d.transX,
129 y + sg2d.transY,
130 width, height);
131 }
132
133 public void fillRoundRect(SunGraphics2D sg2d,
134 int x, int y, int width, int height,
135 int arcWidth, int arcHeight)
136 {
137 sg2d.shapepipe.fill(sg2d,
138 new RoundRectangle2D.Float(x, y, width, height,
139 arcWidth, arcHeight));
140 }
141
142 public void fillOval(SunGraphics2D sg2d,
143 int x, int y, int width, int height)
144 {
145 sg2d.shapepipe.fill(sg2d, new Ellipse2D.Float(x, y, width, height));
146 }
147
148 public void fillArc(SunGraphics2D sg2d,
149 int x, int y, int width, int height,
150 int startAngle, int arcAngle)
151 {
152 sg2d.shapepipe.fill(sg2d, new Arc2D.Float(x, y, width, height,
153 startAngle, arcAngle,
154 Arc2D.PIE));
155 }
156
157 public void fillPolygon(SunGraphics2D sg2d,
158 int xPoints[], int yPoints[],
159 int nPoints)
160 {
161 ShapeSpanIterator sr = getFillSSI(sg2d);
162
163 try {
164 sr.setOutputArea(sg2d.getCompClip());
165 sr.appendPoly(xPoints, yPoints, nPoints, sg2d.transX, sg2d.transY);
166 fillSpans(sg2d, sr);
167 } finally {
168 sr.dispose();
169 }
170 }
171
172
173 public void draw(SunGraphics2D sg2d, Shape s) {
174 if (sg2d.strokeState == sg2d.STROKE_THIN) {
175 Path2D.Float p2df;
176 int transX;
177 int transY;
178 if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
179 if (s instanceof Path2D.Float) {
180 p2df = (Path2D.Float)s;
181 } else {
182 p2df = new Path2D.Float(s);
183 }
184 transX = sg2d.transX;
185 transY = sg2d.transY;
186 } else {
187 p2df = new Path2D.Float(s, sg2d.transform);
188 transX = 0;
189 transY = 0;
190 }
191 sg2d.loops.drawPathLoop.DrawPath(sg2d, sg2d.getSurfaceData(),
192 transX, transY, p2df);
193 return;
194 }
195
196 if (sg2d.strokeState == sg2d.STROKE_CUSTOM) {
197 fill(sg2d, sg2d.stroke.createStrokedShape(s));
198 return;
199 }
200
201 ShapeSpanIterator sr = getStrokeSpans(sg2d, s);
202
203 try {
204 fillSpans(sg2d, sr);
205 } finally {
206 sr.dispose();
207 }
208 }
209
210 /**
211 * Return a ShapeSpanIterator instance that normalizes as
212 * appropriate for a fill operation as per the settings in
213 * the specified SunGraphics2D object.
214 *
215 * The ShapeSpanIterator will be newly constructed and ready
216 * to start taking in geometry.
217 *
218 * Note that the caller is responsible for calling dispose()
219 * on the returned ShapeSpanIterator inside a try/finally block:
220 * <pre>
221 * ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
222 * try {
223 * ssi.setOutputArea(clip);
224 * ssi.appendPath(...); // or appendPoly
225 * // iterate the spans from ssi and operate on them
226 * } finally {
227 * ssi.dispose();
228 * }
229 * </pre>
230 */
231 public static ShapeSpanIterator getFillSSI(SunGraphics2D sg2d) {
232 boolean adjust = ((sg2d.stroke instanceof BasicStroke) &&
233 sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);
234 return new ShapeSpanIterator(adjust);
235 }
236
237 /*
238 * Return a ShapeSpanIterator ready to iterate the spans of the wide
239 * outline of Shape s using the attributes of the SunGraphics2D
240 * object.
241 *
242 * The ShapeSpanIterator returned will be fully constructed
243 * and filled with the geometry from the Shape widened by the
244 * appropriate BasicStroke and normalization parameters taken
245 * from the SunGraphics2D object and be ready to start returning
246 * spans.
247 *
248 * Note that the caller is responsible for calling dispose()
249 * on the returned ShapeSpanIterator inside a try/finally block.
250 * <pre>
251 * ShapeSpanIterator ssi = LoopPipe.getStrokeSpans(sg2d, s);
252 * try {
253 * // iterate the spans from ssi and operate on them
254 * } finally {
255 * ssi.dispose();
256 * }
257 * </pre>
258 *
259 * REMIND: This should return a SpanIterator interface object
260 * but the caller needs to dispose() the object and that method
261 * is only on ShapeSpanIterator.
262 * TODO: Add a dispose() method to the SpanIterator interface.
263 */
264 public static ShapeSpanIterator getStrokeSpans(SunGraphics2D sg2d,
265 Shape s)
266 {
267 ShapeSpanIterator sr = new ShapeSpanIterator(false);
268
269 try {
270 sr.setOutputArea(sg2d.getCompClip());
271 sr.setRule(PathIterator.WIND_NON_ZERO);
272
273 BasicStroke bs = (BasicStroke) sg2d.stroke;
274 boolean thin = (sg2d.strokeState <= sg2d.STROKE_THINDASHED);
275 boolean normalize =
276 (sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);
277
278 RenderEngine.strokeTo(s,
279 sg2d.transform, bs,
280 thin, normalize, false, sr);
281 } catch (Throwable t) {
282 sr.dispose();
283 sr = null;
284 t.printStackTrace();
285 throw new InternalError("Unable to Stroke shape ("+
286 t.getMessage()+")");
287 }
288 return sr;
289 }
290
291 public void fill(SunGraphics2D sg2d, Shape s) {
292 if (sg2d.strokeState == sg2d.STROKE_THIN) {
293 Path2D.Float p2df;
294 int transX;
295 int transY;
296 if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
297 if (s instanceof Path2D.Float) {
298 p2df = (Path2D.Float)s;
299 } else {
300 p2df = new Path2D.Float(s);
301 }
302 transX = sg2d.transX;
303 transY = sg2d.transY;
304 } else {
305 p2df = new Path2D.Float(s, sg2d.transform);
306 transX = 0;
307 transY = 0;
308 }
309 sg2d.loops.fillPathLoop.FillPath(sg2d, sg2d.getSurfaceData(),
310 transX, transY, p2df);
311 return;
312 }
313
314 ShapeSpanIterator sr = getFillSSI(sg2d);
315 try {
316 sr.setOutputArea(sg2d.getCompClip());
317 AffineTransform at =
318 ((sg2d.transformState == sg2d.TRANSFORM_ISIDENT)
319 ? null
320 : sg2d.transform);
321 sr.appendPath(s.getPathIterator(at));
322 fillSpans(sg2d, sr);
323 } finally {
324 sr.dispose();
325 }
326 }
327
328 private static void fillSpans(SunGraphics2D sg2d, SpanIterator si) {
329 // REMIND: Eventually, the plan is that it will not be possible for
330 // fs to be null since the FillSpans loop will be the fundamental
331 // loop implemented for any destination type...
332 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
333 si = sg2d.clipRegion.filter(si);
334 // REMIND: Region.filter produces a Java-only iterator
335 // with no native counterpart...
336 } else {
337 sun.java2d.loops.FillSpans fs = sg2d.loops.fillSpansLoop;
338 if (fs != null) {
339 fs.FillSpans(sg2d, sg2d.getSurfaceData(), si);
340 return;
341 }
342 }
343 int spanbox[] = new int[4];
344 SurfaceData sd = sg2d.getSurfaceData();
345 while (si.nextSpan(spanbox)) {
346 int x = spanbox[0];
347 int y = spanbox[1];
348 int w = spanbox[2] - x;
349 int h = spanbox[3] - y;
350 sg2d.loops.fillRectLoop.FillRect(sg2d, sd, x, y, w, h);
351 }
352 }
353
354 public void fillParallelogram(SunGraphics2D sg2d,
355 double ux1, double uy1,
356 double ux2, double uy2,
357 double x, double y,
358 double dx1, double dy1,
359 double dx2, double dy2)
360 {
361 FillParallelogram fp = sg2d.loops.fillParallelogramLoop;
362 fp.FillParallelogram(sg2d, sg2d.getSurfaceData(),
363 x, y, dx1, dy1, dx2, dy2);
364 }
365
366 public void drawParallelogram(SunGraphics2D sg2d,
367 double ux1, double uy1,
368 double ux2, double uy2,
369 double x, double y,
370 double dx1, double dy1,
371 double dx2, double dy2,
372 double lw1, double lw2)
373 {
374 DrawParallelogram dp = sg2d.loops.drawParallelogramLoop;
375 dp.DrawParallelogram(sg2d, sg2d.getSurfaceData(),
376 x, y, dx1, dy1, dx2, dy2, lw1, lw2);
377 }
378}
java/pkg/sun/java2d/pipe/NullPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/NullPipe.java+155−0
@@ -0,0 +1,155 @@
1/*
2 * Copyright (c) 1997, 2003, 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
26package sun.java2d.pipe;
27
28import java.awt.Color;
29import java.awt.Image;
30import java.awt.Shape;
31import java.awt.geom.AffineTransform;
32import java.awt.image.BufferedImage;
33import java.awt.image.BufferedImageOp;
34import java.awt.image.ImageObserver;
35import java.awt.font.GlyphVector;
36import sun.java2d.SunGraphics2D;
37
38/**
39 * This is a class that implements all of the basic pixel rendering
40 * methods as NOPs.
41 * This class is useful for installing as the pipeline when the
42 * clip is determined to be empty or when the composite operation is
43 * determined to have no effect (i.e. rule == SRC_OVER, extraAlpha == 0.0).
44 */
45public class NullPipe
46 implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe, TextPipe,
47 DrawImagePipe
48{
49 public void drawLine(SunGraphics2D sg,
50 int x1, int y1, int x2, int y2) {
51 }
52
53 public void drawRect(SunGraphics2D sg,
54 int x, int y, int width, int height) {
55 }
56
57 public void fillRect(SunGraphics2D sg,
58 int x, int y, int width, int height) {
59 }
60
61 public void drawRoundRect(SunGraphics2D sg,
62 int x, int y, int width, int height,
63 int arcWidth, int arcHeight) {
64 }
65
66 public void fillRoundRect(SunGraphics2D sg,
67 int x, int y, int width, int height,
68 int arcWidth, int arcHeight) {
69 }
70
71 public void drawOval(SunGraphics2D sg,
72 int x, int y, int width, int height) {
73 }
74
75 public void fillOval(SunGraphics2D sg,
76 int x, int y, int width, int height) {
77 }
78
79 public void drawArc(SunGraphics2D sg,
80 int x, int y, int width, int height,
81 int startAngle, int arcAngle) {
82 }
83
84 public void fillArc(SunGraphics2D sg,
85 int x, int y, int width, int height,
86 int startAngle, int arcAngle) {
87 }
88
89 public void drawPolyline(SunGraphics2D sg,
90 int xPoints[], int yPoints[],
91 int nPoints) {
92 }
93
94 public void drawPolygon(SunGraphics2D sg,
95 int xPoints[], int yPoints[],
96 int nPoints) {
97 }
98
99 public void fillPolygon(SunGraphics2D sg,
100 int xPoints[], int yPoints[],
101 int nPoints) {
102 }
103
104 public void draw(SunGraphics2D sg, Shape s) {
105 }
106
107 public void fill(SunGraphics2D sg, Shape s) {
108 }
109
110 public void drawString(SunGraphics2D sg, String s, double x, double y) {
111 }
112
113 public void drawGlyphVector(SunGraphics2D sg, GlyphVector g,
114 float x, float y) {
115 }
116
117 public void drawChars(SunGraphics2D sg,
118 char data[], int offset, int length,
119 int x, int y) {
120 }
121
122 public boolean copyImage(SunGraphics2D sg, Image img,
123 int x, int y,
124 Color bgColor,
125 ImageObserver observer) {
126 return false;
127 }
128 public boolean copyImage(SunGraphics2D sg, Image img,
129 int dx, int dy, int sx, int sy, int w, int h,
130 Color bgColor,
131 ImageObserver observer) {
132 return false;
133 }
134 public boolean scaleImage(SunGraphics2D sg, Image img, int x, int y,
135 int w, int h,
136 Color bgColor,
137 ImageObserver observer) {
138 return false;
139 }
140 public boolean scaleImage(SunGraphics2D sg, Image img,
141 int dx1, int dy1, int dx2, int dy2,
142 int sx1, int sy1, int sx2, int sy2,
143 Color bgColor,
144 ImageObserver observer) {
145 return false;
146 }
147 public boolean transformImage(SunGraphics2D sg, Image img,
148 AffineTransform atfm,
149 ImageObserver observer) {
150 return false;
151 }
152 public void transformImage(SunGraphics2D sg, BufferedImage img,
153 BufferedImageOp op, int x, int y) {
154 }
155}
java/pkg/sun/java2d/pipe/OutlineTextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/OutlineTextRenderer.java+145−0
@@ -0,0 +1,145 @@
1/*
2 * Copyright (c) 2000, 2005, 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
26package sun.java2d.pipe;
27
28import java.awt.font.FontRenderContext;
29import java.awt.font.GlyphVector;
30import java.awt.font.TextLayout;
31import sun.java2d.SunGraphics2D;
32import sun.font.GlyphList;
33import sun.awt.SunHints;
34
35import java.awt.Shape;
36import java.awt.geom.AffineTransform;
37import java.awt.font.TextLayout;
38
39/**
40 * A delegate pipe of SG2D for drawing "large" text with
41 * a solid source colour to an opaque destination.
42 * The text is drawn as a filled outline.
43 * Since the developer is not explicitly requesting this way of
44 * rendering, this should not be used if the current paint is not
45 * a solid colour.
46 *
47 * If text anti-aliasing is requested by the application, and
48 * filling path, an anti-aliasing fill pipe needs to
49 * be invoked.
50 * This involves making some of the same decisions as in the
51 * validatePipe call, which may be in a SurfaceData subclass, so
52 * its awkward to always ensure that the correct pipe is used.
53 * The easiest thing, rather than reproducing much of that logic
54 * is to call validatePipe() which works but is expensive, although
55 * probably not compared to the cost of filling the path.
56 * Note if AA hint is ON but text-AA hint is OFF this logic will
57 * produce AA text which perhaps isn't what the user expected.
58 * Note that the glyphvector obeys its FRC, not the G2D.
59 */
60
61public class OutlineTextRenderer implements TextPipe {
62
63 // Text with a height greater than the threshhold will be
64 // drawn via this pipe.
65 public static final int THRESHHOLD = 100;
66
67 public void drawChars(SunGraphics2D g2d,
68 char data[], int offset, int length,
69 int x, int y) {
70
71 String s = new String(data, offset, length);
72 drawString(g2d, s, x, y);
73 }
74
75 public void drawString(SunGraphics2D g2d, String str, double x, double y) {
76
77 if ("".equals(str)) {
78 return; // TextLayout constructor throws IAE on "".
79 }
80 TextLayout tl = new TextLayout(str, g2d.getFont(),
81 g2d.getFontRenderContext());
82 Shape s = tl.getOutline(AffineTransform.getTranslateInstance(x, y));
83
84 int textAAHint = g2d.getFontInfo().aaHint;
85
86 int prevaaHint = - 1;
87 if (textAAHint != SunHints.INTVAL_TEXT_ANTIALIAS_OFF &&
88 g2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
89 prevaaHint = g2d.antialiasHint;
90 g2d.antialiasHint = SunHints.INTVAL_ANTIALIAS_ON;
91 g2d.validatePipe();
92 } else if (textAAHint == SunHints.INTVAL_TEXT_ANTIALIAS_OFF
93 && g2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_OFF) {
94 prevaaHint = g2d.antialiasHint;
95 g2d.antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF;
96 g2d.validatePipe();
97 }
98
99 g2d.fill(s);
100
101 if (prevaaHint != -1) {
102 g2d.antialiasHint = prevaaHint;
103 g2d.validatePipe();
104 }
105 }
106
107 public void drawGlyphVector(SunGraphics2D g2d, GlyphVector gv,
108 float x, float y) {
109
110
111 Shape s = gv.getOutline(x, y);
112 int prevaaHint = - 1;
113 FontRenderContext frc = gv.getFontRenderContext();
114 boolean aa = frc.isAntiAliased();
115
116 /* aa will be true if any AA mode has been specified.
117 * ie for LCD and 'gasp' modes too.
118 * We will check if 'gasp' has resolved AA to be "OFF", and
119 * in all other cases (ie AA ON and all LCD modes) use AA outlines.
120 */
121 if (aa) {
122 if (g2d.getGVFontInfo(gv.getFont(), frc).aaHint ==
123 SunHints.INTVAL_TEXT_ANTIALIAS_OFF) {
124 aa = false;
125 }
126 }
127
128 if (aa && g2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
129 prevaaHint = g2d.antialiasHint;
130 g2d.antialiasHint = SunHints.INTVAL_ANTIALIAS_ON;
131 g2d.validatePipe();
132 } else if (!aa && g2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_OFF) {
133 prevaaHint = g2d.antialiasHint;
134 g2d.antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF;
135 g2d.validatePipe();
136 }
137
138 g2d.fill(s);
139
140 if (prevaaHint != -1) {
141 g2d.antialiasHint = prevaaHint;
142 g2d.validatePipe();
143 }
144 }
145}
java/pkg/sun/java2d/pipe/ParallelogramPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/ParallelogramPipe.java+76−0
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) 2008, 2011 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
26package sun.java2d.pipe;
27
28import sun.java2d.SunGraphics2D;
29
30/**
31 * This interface defines the set of calls that pipeline objects
32 * can use to pass on responsibility for drawing arbitrary
33 * parallelogram shapes.
34 * Six floating point numbers are provided and the parallelogram
35 * is defined as the quadrilateral with the following vertices:
36 * <pre>
37 * origin: (x, y)
38 * => (x+dx1, y+dy1)
39 * => (x+dx1+dx2, y+dy1+dy2)
40 * => (x+dx2, y+dy2)
41 * => origin
42 * </pre>
43 * The four u[xy][12] parameters are the unsorted extreme coordinates
44 * of the primitive in user space. They may have been generated by a
45 * line or a rectangle so they could have u[xy]2 < u[xy]1 in some cases.
46 * They should be sorted before calculating the bounds of the original
47 * primitive (such as for calculating the user space bounds for the
48 * Paint.createContext() method).
49 */
50public interface ParallelogramPipe {
51 public void fillParallelogram(SunGraphics2D sg,
52 double ux1, double uy1,
53 double ux2, double uy2,
54 double x, double y,
55 double dx1, double dy1,
56 double dx2, double dy2);
57
58 /**
59 * Draw a Parallelogram with the indicated line widths
60 * assuming a standard BasicStroke with MITER joins.
61 * lw1 specifies the width of the stroke along the dx1,dy1
62 * vector and lw2 specifies the width of the stroke along
63 * the dx2,dy2 vector.
64 * This is equivalent to outsetting the indicated
65 * parallelogram by lw/2 pixels, then insetting the
66 * same parallelogram by lw/2 pixels and filling the
67 * difference between the outer and inner parallelograms.
68 */
69 public void drawParallelogram(SunGraphics2D sg,
70 double ux1, double uy1,
71 double ux2, double uy2,
72 double x, double y,
73 double dx1, double dy1,
74 double dx2, double dy2,
75 double lw1, double lw2);
76}
java/pkg/sun/java2d/pipe/PixelDrawPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/PixelDrawPipe.java+67−0
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) 1997, 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
26package sun.java2d.pipe;
27
28import sun.java2d.SunGraphics2D;
29
30/**
31 * This interface defines the set of calls that pipeline objects
32 * can use to pass on responsibility for drawing various basic
33 * geometric figures defined by explicit integer coordinates.
34 * Typically this interface will be used for communication when
35 * the coordinates of the rendering have been narrowed down to
36 * actual device pixels, or for communication of untransformed
37 * coordinates when the coordinates were specified using integers.
38 * This interface does not cover all of the rendering calls that
39 * are possible in Graphics since many of the rendering calls can
40 * be transformed into one or more variants of these calls.
41 */
42public interface PixelDrawPipe {
43 public void drawLine(SunGraphics2D sg,
44 int x1, int y1, int x2, int y2);
45
46 public void drawRect(SunGraphics2D sg,
47 int x, int y, int width, int height);
48
49 public void drawRoundRect(SunGraphics2D sg,
50 int x, int y, int width, int height,
51 int arcWidth, int arcHeight);
52
53 public void drawOval(SunGraphics2D sg,
54 int x, int y, int width, int height);
55
56 public void drawArc(SunGraphics2D sg,
57 int x, int y, int width, int height,
58 int startAngle, int arcAngle);
59
60 public void drawPolyline(SunGraphics2D sg,
61 int xPoints[], int yPoints[],
62 int nPoints);
63
64 public void drawPolygon(SunGraphics2D sg,
65 int xPoints[], int yPoints[],
66 int nPoints);
67}
java/pkg/sun/java2d/pipe/PixelFillPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/PixelFillPipe.java+61−0
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 1997, 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
26package sun.java2d.pipe;
27
28import sun.java2d.SunGraphics2D;
29
30/**
31 * This interface defines the set of calls that pipeline objects
32 * can use to pass on responsibility for filling various basic
33 * geometric figures defined by explicit integer coordinates.
34 * Typically this interface will be used for communication when
35 * the coordinates of the rendering have been narrowed down to
36 * actual device pixels, or for communication of untransformed
37 * coordinates when the coordinates were specified using integers.
38 * This interface does not cover all of the rendering calls that
39 * are possible in Graphics since many of the rendering calls can
40 * be transformed into one or more variants of these calls.
41 */
42public interface PixelFillPipe {
43 public void fillRect(SunGraphics2D sg,
44 int x, int y, int width, int height);
45
46
47 public void fillRoundRect(SunGraphics2D sg,
48 int x, int y, int width, int height,
49 int arcWidth, int arcHeight);
50
51 public void fillOval(SunGraphics2D sg,
52 int x, int y, int width, int height);
53
54 public void fillArc(SunGraphics2D sg,
55 int x, int y, int width, int height,
56 int startAngle, int arcAngle);
57
58 public void fillPolygon(SunGraphics2D sg,
59 int xPoints[], int yPoints[],
60 int nPoints);
61}
java/pkg/sun/java2d/pipe/PixelToParallelogramConverter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/PixelToParallelogramConverter.java+429−0
@@ -0,0 +1,429 @@
1/*
2 * Copyright (c) 2008, 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
26package sun.java2d.pipe;
27
28import java.awt.Shape;
29import java.awt.BasicStroke;
30import java.awt.geom.Line2D;
31import java.awt.geom.Rectangle2D;
32import java.awt.geom.AffineTransform;
33import sun.java2d.SunGraphics2D;
34import sun.awt.SunHints;
35
36/**
37 * This class converts calls to the basic pixel rendering methods
38 * into calls to the methods on a ParallelogramPipe.
39 * Most calls are transformed into calls to the fill(Shape) method
40 * by the parent PixelToShapeConverter class, but some calls are
41 * transformed into calls to fill/drawParallelogram().
42 */
43public class PixelToParallelogramConverter extends PixelToShapeConverter
44 implements ShapeDrawPipe
45{
46 ParallelogramPipe outrenderer;
47 double minPenSize;
48 double normPosition;
49 double normRoundingBias;
50 boolean adjustfill;
51
52 /**
53 * @param shapepipe pipeline to forward shape calls to
54 * @param pgrampipe pipeline to forward parallelogram calls to
55 * (and drawLine calls if possible)
56 * @param minPenSize minimum pen size for dropout control
57 * @param normPosition sub-pixel location to normalize endpoints
58 * for STROKE_NORMALIZE cases
59 * @param adjustFill boolean to control whethere normalization
60 * constants are also applied to fill operations
61 * (normally true for non-AA, false for AA)
62 */
63 public PixelToParallelogramConverter(ShapeDrawPipe shapepipe,
64 ParallelogramPipe pgrampipe,
65 double minPenSize,
66 double normPosition,
67 boolean adjustfill)
68 {
69 super(shapepipe);
70 outrenderer = pgrampipe;
71 this.minPenSize = minPenSize;
72 this.normPosition = normPosition;
73 this.normRoundingBias = 0.5 - normPosition;
74 this.adjustfill = adjustfill;
75 }
76
77 public void drawLine(SunGraphics2D sg2d,
78 int x1, int y1, int x2, int y2)
79 {
80 if (!drawGeneralLine(sg2d, x1, y1, x2, y2)) {
81 super.drawLine(sg2d, x1, y1, x2, y2);
82 }
83 }
84
85 public void drawRect(SunGraphics2D sg2d,
86 int x, int y, int w, int h)
87 {
88 if (w >= 0 && h >= 0) {
89 if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) {
90 BasicStroke bs = ((BasicStroke) sg2d.stroke);
91 if (w > 0 && h > 0) {
92 if (bs.getLineJoin() == BasicStroke.JOIN_MITER &&
93 bs.getDashArray() == null)
94 {
95 double lw = bs.getLineWidth();
96 drawRectangle(sg2d, x, y, w, h, lw);
97 return;
98 }
99 } else {
100 // Note: This calls the integer version which
101 // will verify that the local drawLine optimizations
102 // work and call super.drawLine(), if not.
103 drawLine(sg2d, x, y, x+w, y+h);
104 return;
105 }
106 }
107 super.drawRect(sg2d, x, y, w, h);
108 }
109 }
110
111 public void fillRect(SunGraphics2D sg2d,
112 int x, int y, int w, int h)
113 {
114 if (w > 0 && h > 0) {
115 fillRectangle(sg2d, x, y, w, h);
116 }
117 }
118
119 public void draw(SunGraphics2D sg2d, Shape s) {
120 if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) {
121 BasicStroke bs = ((BasicStroke) sg2d.stroke);
122 if (s instanceof Rectangle2D) {
123 if (bs.getLineJoin() == BasicStroke.JOIN_MITER &&
124 bs.getDashArray() == null)
125 {
126 Rectangle2D r2d = (Rectangle2D) s;
127 double w = r2d.getWidth();
128 double h = r2d.getHeight();
129 double x = r2d.getX();
130 double y = r2d.getY();
131 if (w >= 0 && h >= 0) {
132 double lw = bs.getLineWidth();
133 drawRectangle(sg2d, x, y, w, h, lw);
134 }
135 return;
136 }
137 } else if (s instanceof Line2D) {
138 Line2D l2d = (Line2D) s;
139 if (drawGeneralLine(sg2d,
140 l2d.getX1(), l2d.getY1(),
141 l2d.getX2(), l2d.getY2()))
142 {
143 return;
144 }
145 }
146 }
147
148 outpipe.draw(sg2d, s);
149 }
150
151 public void fill(SunGraphics2D sg2d, Shape s) {
152 if (s instanceof Rectangle2D) {
153 Rectangle2D r2d = (Rectangle2D) s;
154 double w = r2d.getWidth();
155 double h = r2d.getHeight();
156 if (w > 0 && h > 0) {
157 double x = r2d.getX();
158 double y = r2d.getY();
159 fillRectangle(sg2d, x, y, w, h);
160 }
161 return;
162 }
163
164 outpipe.fill(sg2d, s);
165 }
166
167 static double len(double x, double y) {
168 return ((x == 0) ? Math.abs(y)
169 : ((y == 0) ? Math.abs(x)
170 : Math.sqrt(x * x + y * y)));
171 }
172
173 double normalize(double v) {
174 return Math.floor(v + normRoundingBias) + normPosition;
175 }
176
177 public boolean drawGeneralLine(SunGraphics2D sg2d,
178 double ux1, double uy1,
179 double ux2, double uy2)
180 {
181 if (sg2d.strokeState == SunGraphics2D.STROKE_CUSTOM ||
182 sg2d.strokeState == SunGraphics2D.STROKE_THINDASHED)
183 {
184 return false;
185 }
186 BasicStroke bs = (BasicStroke) sg2d.stroke;
187 int cap = bs.getEndCap();
188 if (cap == BasicStroke.CAP_ROUND || bs.getDashArray() != null) {
189 // TODO: we could construct the GeneralPath directly
190 // for CAP_ROUND and save a lot of processing in that case...
191 // And again, we would need to deal with dropout control...
192 return false;
193 }
194 double lw = bs.getLineWidth();
195 // Save the original dx, dy in case we need it to transform
196 // the linewidth as a perpendicular vector below
197 double dx = ux2 - ux1;
198 double dy = uy2 - uy1;
199 double x1, y1, x2, y2;
200 switch (sg2d.transformState) {
201 case SunGraphics2D.TRANSFORM_GENERIC:
202 case SunGraphics2D.TRANSFORM_TRANSLATESCALE:
203 {
204 double coords[] = {ux1, uy1, ux2, uy2};
205 sg2d.transform.transform(coords, 0, coords, 0, 2);
206 x1 = coords[0];
207 y1 = coords[1];
208 x2 = coords[2];
209 y2 = coords[3];
210 }
211 break;
212 case SunGraphics2D.TRANSFORM_ANY_TRANSLATE:
213 case SunGraphics2D.TRANSFORM_INT_TRANSLATE:
214 {
215 double tx = sg2d.transform.getTranslateX();
216 double ty = sg2d.transform.getTranslateY();
217 x1 = ux1 + tx;
218 y1 = uy1 + ty;
219 x2 = ux2 + tx;
220 y2 = uy2 + ty;
221 }
222 break;
223 case SunGraphics2D.TRANSFORM_ISIDENT:
224 x1 = ux1;
225 y1 = uy1;
226 x2 = ux2;
227 y2 = uy2;
228 break;
229 default:
230 throw new InternalError("unknown TRANSFORM state...");
231 }
232 if (sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE) {
233 if (sg2d.strokeState == SunGraphics2D.STROKE_THIN &&
234 outrenderer instanceof PixelDrawPipe)
235 {
236 // PixelDrawPipes will add sg2d.transXY so we need to factor
237 // that out...
238 int ix1 = (int) Math.floor(x1 - sg2d.transX);
239 int iy1 = (int) Math.floor(y1 - sg2d.transY);
240 int ix2 = (int) Math.floor(x2 - sg2d.transX);
241 int iy2 = (int) Math.floor(y2 - sg2d.transY);
242 ((PixelDrawPipe)outrenderer).drawLine(sg2d, ix1, iy1, ix2, iy2);
243 return true;
244 }
245 x1 = normalize(x1);
246 y1 = normalize(y1);
247 x2 = normalize(x2);
248 y2 = normalize(y2);
249 }
250 if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
251 // Transform the linewidth...
252 // calculate the scaling factor for a unit vector
253 // perpendicular to the original user space line.
254 double len = len(dx, dy);
255 if (len == 0) {
256 dx = len = 1;
257 // dy = 0; already
258 }
259 // delta transform the transposed (90 degree rotated) unit vector
260 double unitvector[] = {dy/len, -dx/len};
261 sg2d.transform.deltaTransform(unitvector, 0, unitvector, 0, 1);
262 lw *= len(unitvector[0], unitvector[1]);
263 }
264 lw = Math.max(lw, minPenSize);
265 dx = x2 - x1;
266 dy = y2 - y1;
267 double len = len(dx, dy);
268 double udx, udy;
269 if (len == 0) {
270 if (cap == BasicStroke.CAP_BUTT) {
271 return true;
272 }
273 udx = lw;
274 udy = 0;
275 } else {
276 udx = lw * dx / len;
277 udy = lw * dy / len;
278 }
279 double px = x1 + udy / 2.0;
280 double py = y1 - udx / 2.0;
281 if (cap == BasicStroke.CAP_SQUARE) {
282 px -= udx / 2.0;
283 py -= udy / 2.0;
284 dx += udx;
285 dy += udy;
286 }
287 outrenderer.fillParallelogram(sg2d, ux1, uy1, ux2, uy2,
288 px, py, -udy, udx, dx, dy);
289 return true;
290 }
291
292 public void fillRectangle(SunGraphics2D sg2d,
293 double rx, double ry,
294 double rw, double rh)
295 {
296 double px, py;
297 double dx1, dy1, dx2, dy2;
298 AffineTransform txform = sg2d.transform;
299 dx1 = txform.getScaleX();
300 dy1 = txform.getShearY();
301 dx2 = txform.getShearX();
302 dy2 = txform.getScaleY();
303 px = rx * dx1 + ry * dx2 + txform.getTranslateX();
304 py = rx * dy1 + ry * dy2 + txform.getTranslateY();
305 dx1 *= rw;
306 dy1 *= rw;
307 dx2 *= rh;
308 dy2 *= rh;
309 if (adjustfill &&
310 sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM &&
311 sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE)
312 {
313 double newx = normalize(px);
314 double newy = normalize(py);
315 dx1 = normalize(px + dx1) - newx;
316 dy1 = normalize(py + dy1) - newy;
317 dx2 = normalize(px + dx2) - newx;
318 dy2 = normalize(py + dy2) - newy;
319 px = newx;
320 py = newy;
321 }
322 outrenderer.fillParallelogram(sg2d, rx, ry, rx+rw, ry+rh,
323 px, py, dx1, dy1, dx2, dy2);
324 }
325
326 public void drawRectangle(SunGraphics2D sg2d,
327 double rx, double ry,
328 double rw, double rh,
329 double lw)
330 {
331 double px, py;
332 double dx1, dy1, dx2, dy2;
333 double lw1, lw2;
334 AffineTransform txform = sg2d.transform;
335 dx1 = txform.getScaleX();
336 dy1 = txform.getShearY();
337 dx2 = txform.getShearX();
338 dy2 = txform.getScaleY();
339 px = rx * dx1 + ry * dx2 + txform.getTranslateX();
340 py = rx * dy1 + ry * dy2 + txform.getTranslateY();
341 // lw along dx1,dy1 scale by transformed length of dx2,dy2 vectors
342 // and vice versa
343 lw1 = len(dx1, dy1) * lw;
344 lw2 = len(dx2, dy2) * lw;
345 dx1 *= rw;
346 dy1 *= rw;
347 dx2 *= rh;
348 dy2 *= rh;
349 if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM &&
350 sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE)
351 {
352 double newx = normalize(px);
353 double newy = normalize(py);
354 dx1 = normalize(px + dx1) - newx;
355 dy1 = normalize(py + dy1) - newy;
356 dx2 = normalize(px + dx2) - newx;
357 dy2 = normalize(py + dy2) - newy;
358 px = newx;
359 py = newy;
360 }
361 lw1 = Math.max(lw1, minPenSize);
362 lw2 = Math.max(lw2, minPenSize);
363 double len1 = len(dx1, dy1);
364 double len2 = len(dx2, dy2);
365 if (lw1 >= len1 || lw2 >= len2) {
366 // The line widths are large enough to consume the
367 // entire hole in the middle of the parallelogram
368 // so we can just fill the outer parallelogram.
369 fillOuterParallelogram(sg2d,
370 rx, ry, rx+rw, ry+rh,
371 px, py, dx1, dy1, dx2, dy2,
372 len1, len2, lw1, lw2);
373 } else {
374 outrenderer.drawParallelogram(sg2d,
375 rx, ry, rx+rw, ry+rh,
376 px, py, dx1, dy1, dx2, dy2,
377 lw1 / len1, lw2 / len2);
378 }
379 }
380
381 /**
382 * This utility function handles the case where a drawRectangle
383 * operation discovered that the interior hole in the rectangle
384 * or parallelogram has been completely filled in by the stroke
385 * width. It calculates the outer parallelogram of the stroke
386 * and issues a single fillParallelogram request to fill it.
387 */
388 public void fillOuterParallelogram(SunGraphics2D sg2d,
389 double ux1, double uy1,
390 double ux2, double uy2,
391 double px, double py,
392 double dx1, double dy1,
393 double dx2, double dy2,
394 double len1, double len2,
395 double lw1, double lw2)
396 {
397 double udx1 = dx1 / len1;
398 double udy1 = dy1 / len1;
399 double udx2 = dx2 / len2;
400 double udy2 = dy2 / len2;
401 if (len1 == 0) {
402 // len1 is 0, replace udxy1 with perpendicular of udxy2
403 if (len2 == 0) {
404 // both are 0, use a unit Y vector for udxy2
405 udx2 = 0;
406 udy2 = 1;
407 }
408 udx1 = udy2;
409 udy1 = -udx2;
410 } else if (len2 == 0) {
411 // len2 is 0, replace udxy2 with perpendicular of udxy1
412 udx2 = udy1;
413 udy2 = -udx1;
414 }
415 udx1 *= lw1;
416 udy1 *= lw1;
417 udx2 *= lw2;
418 udy2 *= lw2;
419 px -= (udx1 + udx2) / 2;
420 py -= (udy1 + udy2) / 2;
421 dx1 += udx1;
422 dy1 += udy1;
423 dx2 += udx2;
424 dy2 += udy2;
425
426 outrenderer.fillParallelogram(sg2d, ux1, uy1, ux2, uy2,
427 px, py, dx1, dy1, dx2, dy2);
428 }
429}
java/pkg/sun/java2d/pipe/PixelToShapeConverter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/PixelToShapeConverter.java+133−0
@@ -0,0 +1,133 @@
1/*
2 * Copyright (c) 1997, 1998, 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
26package sun.java2d.pipe;
27
28import java.awt.Rectangle;
29import java.awt.Shape;
30import java.awt.geom.Arc2D;
31import java.awt.geom.Ellipse2D;
32import java.awt.geom.Line2D;
33import java.awt.geom.RoundRectangle2D;
34import java.awt.geom.GeneralPath;
35import sun.java2d.SunGraphics2D;
36
37/**
38 * This class converts calls to the basic pixel rendering methods
39 * into calls to a generic Shape rendering pipeline.
40 */
41public class PixelToShapeConverter
42 implements PixelDrawPipe, PixelFillPipe
43{
44 ShapeDrawPipe outpipe;
45
46 public PixelToShapeConverter(ShapeDrawPipe pipe) {
47 outpipe = pipe;
48 }
49
50 public void drawLine(SunGraphics2D sg,
51 int x1, int y1, int x2, int y2) {
52 outpipe.draw(sg, new Line2D.Float(x1, y1, x2, y2));
53 }
54
55 public void drawRect(SunGraphics2D sg,
56 int x, int y, int w, int h) {
57 outpipe.draw(sg, new Rectangle(x, y, w, h));
58 }
59
60 public void fillRect(SunGraphics2D sg,
61 int x, int y, int w, int h) {
62 outpipe.fill(sg, new Rectangle(x, y, w, h));
63 }
64
65 public void drawRoundRect(SunGraphics2D sg,
66 int x, int y, int w, int h,
67 int aW, int aH) {
68 outpipe.draw(sg, new RoundRectangle2D.Float(x, y, w, h, aW, aH));
69 }
70
71 public void fillRoundRect(SunGraphics2D sg,
72 int x, int y, int w, int h,
73 int aW, int aH) {
74 outpipe.fill(sg, new RoundRectangle2D.Float(x, y, w, h, aW, aH));
75 }
76
77 public void drawOval(SunGraphics2D sg,
78 int x, int y, int w, int h) {
79 outpipe.draw(sg, new Ellipse2D.Float(x, y, w, h));
80 }
81
82 public void fillOval(SunGraphics2D sg,
83 int x, int y, int w, int h) {
84 outpipe.fill(sg, new Ellipse2D.Float(x, y, w, h));
85 }
86
87 public void drawArc(SunGraphics2D sg,
88 int x, int y, int w, int h,
89 int start, int extent) {
90 outpipe.draw(sg, new Arc2D.Float(x, y, w, h,
91 start, extent, Arc2D.OPEN));
92 }
93
94 public void fillArc(SunGraphics2D sg,
95 int x, int y, int w, int h,
96 int start, int extent) {
97 outpipe.fill(sg, new Arc2D.Float(x, y, w, h,
98 start, extent, Arc2D.PIE));
99 }
100
101 private Shape makePoly(int xPoints[], int yPoints[],
102 int nPoints, boolean close) {
103 GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
104 if (nPoints > 0) {
105 gp.moveTo(xPoints[0], yPoints[0]);
106 }
107 for (int i = 1; i < nPoints; i++) {
108 gp.lineTo(xPoints[i], yPoints[i]);
109 }
110 if (close) {
111 gp.closePath();
112 }
113 return gp;
114 }
115
116 public void drawPolyline(SunGraphics2D sg,
117 int xPoints[], int yPoints[],
118 int nPoints) {
119 outpipe.draw(sg, makePoly(xPoints, yPoints, nPoints, false));
120 }
121
122 public void drawPolygon(SunGraphics2D sg,
123 int xPoints[], int yPoints[],
124 int nPoints) {
125 outpipe.draw(sg, makePoly(xPoints, yPoints, nPoints, true));
126 }
127
128 public void fillPolygon(SunGraphics2D sg,
129 int xPoints[], int yPoints[],
130 int nPoints) {
131 outpipe.fill(sg, makePoly(xPoints, yPoints, nPoints, true));
132 }
133}
java/pkg/sun/java2d/pipe/Region$ImmutableRegion.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/Region.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/Region.java+1255−0
@@ -0,0 +1,1255 @@
1/*
2 * Copyright (c) 1998, 2006, 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
26package sun.java2d.pipe;
27
28import java.awt.Rectangle;
29import java.awt.Shape;
30import java.awt.geom.AffineTransform;
31import java.awt.geom.RectangularShape;
32
33/**
34 * This class encapsulates a definition of a two dimensional region which
35 * consists of a number of Y ranges each containing multiple X bands.
36 * <p>
37 * A rectangular Region is allowed to have a null band list in which
38 * case the rectangular shape is defined by the bounding box parameters
39 * (lox, loy, hix, hiy).
40 * <p>
41 * The band list, if present, consists of a list of rows in ascending Y
42 * order, ending at endIndex which is the index beyond the end of the
43 * last row. Each row consists of at least 3 + 2n entries (n >= 1)
44 * where the first 3 entries specify the Y range as start, end, and
45 * the number of X ranges in that Y range. These 3 entries are
46 * followed by pairs of X coordinates in ascending order:
47 * <pre>
48 * bands[rowstart+0] = Y0; // starting Y coordinate
49 * bands[rowstart+1] = Y1; // ending Y coordinate - endY > startY
50 * bands[rowstart+2] = N; // number of X bands - N >= 1
51 *
52 * bands[rowstart+3] = X10; // starting X coordinate of first band
53 * bands[rowstart+4] = X11; // ending X coordinate of first band
54 * bands[rowstart+5] = X20; // starting X coordinate of second band
55 * bands[rowstart+6] = X21; // ending X coordinate of second band
56 * ...
57 * bands[rowstart+3+N*2-2] = XN0; // starting X coord of last band
58 * bands[rowstart+3+N*2-1] = XN1; // ending X coord of last band
59 *
60 * bands[rowstart+3+N*2] = ... // start of next Y row
61 * </pre>
62 */
63public class Region {
64 static final int INIT_SIZE = 50;
65 static final int GROW_SIZE = 50;
66
67 /**
68 * Immutable Region.
69 */
70 private static final class ImmutableRegion extends Region {
71 protected ImmutableRegion(int lox, int loy, int hix, int hiy) {
72 super(lox, loy, hix, hiy);
73 }
74
75 // Override all the methods that mutate the object
76 public void appendSpans(sun.java2d.pipe.SpanIterator si) {}
77 public void setOutputArea(java.awt.Rectangle r) {}
78 public void setOutputAreaXYWH(int x, int y, int w, int h) {}
79 public void setOutputArea(int[] box) {}
80 public void setOutputAreaXYXY(int lox, int loy, int hix, int hiy) {}
81 }
82
83 public static final Region EMPTY_REGION = new ImmutableRegion(0, 0, 0, 0);
84 public static final Region WHOLE_REGION = new ImmutableRegion(
85 Integer.MIN_VALUE,
86 Integer.MIN_VALUE,
87 Integer.MAX_VALUE,
88 Integer.MAX_VALUE);
89
90 int lox;
91 int loy;
92 int hix;
93 int hiy;
94
95 int endIndex;
96 int[] bands;
97
98 private static native void initIDs();
99
100 static {
101 initIDs();
102 }
103
104 /**
105 * Adds the dimension <code>dim</code> to the coordinate
106 * <code>start</code> with appropriate clipping. If
107 * <code>dim</code> is non-positive then the method returns
108 * the start coordinate. If the sum overflows an integer
109 * data type then the method returns <code>Integer.MAX_VALUE</code>.
110 */
111 public static int dimAdd(int start, int dim) {
112 if (dim <= 0) return start;
113 if ((dim += start) < start) return Integer.MAX_VALUE;
114 return dim;
115 }
116
117 /**
118 * Adds the delta {@code dv} to the value {@code v} with
119 * appropriate clipping to the bounds of Integer resolution.
120 * If the answer would be greater than {@code Integer.MAX_VALUE}
121 * then {@code Integer.MAX_VALUE} is returned.
122 * If the answer would be less than {@code Integer.MIN_VALUE}
123 * then {@code Integer.MIN_VALUE} is returned.
124 * Otherwise the sum is returned.
125 */
126 public static int clipAdd(int v, int dv) {
127 int newv = v + dv;
128 if ((newv > v) != (dv > 0)) {
129 newv = (dv < 0) ? Integer.MIN_VALUE : Integer.MAX_VALUE;
130 }
131 return newv;
132 }
133
134 protected Region(int lox, int loy, int hix, int hiy) {
135 this.lox = lox;
136 this.loy = loy;
137 this.hix = hix;
138 this.hiy = hiy;
139 }
140
141 /**
142 * Returns a Region object covering the pixels which would be
143 * touched by a fill or clip operation on a Graphics implementation
144 * on the specified Shape object under the optionally specified
145 * AffineTransform object.
146 *
147 * @param s a non-null Shape object specifying the geometry enclosing
148 * the pixels of interest
149 * @param at an optional <code>AffineTransform</code> to be applied to the
150 * coordinates as they are returned in the iteration, or
151 * <code>null</code> if untransformed coordinates are desired
152 */
153 public static Region getInstance(Shape s, AffineTransform at) {
154 return getInstance(WHOLE_REGION, false, s, at);
155 }
156
157 /**
158 * Returns a Region object covering the pixels which would be
159 * touched by a fill or clip operation on a Graphics implementation
160 * on the specified Shape object under the optionally specified
161 * AffineTransform object further restricted by the specified
162 * device bounds.
163 * <p>
164 * Note that only the bounds of the specified Region are used to
165 * restrict the resulting Region.
166 * If devBounds is non-rectangular and clipping to the specific
167 * bands of devBounds is needed, then an intersection of the
168 * resulting Region with devBounds must be performed in a
169 * subsequent step.
170 *
171 * @param devBounds a non-null Region specifying some bounds to
172 * clip the geometry to
173 * @param s a non-null Shape object specifying the geometry enclosing
174 * the pixels of interest
175 * @param at an optional <code>AffineTransform</code> to be applied to the
176 * coordinates as they are returned in the iteration, or
177 * <code>null</code> if untransformed coordinates are desired
178 */
179 public static Region getInstance(Region devBounds,
180 Shape s, AffineTransform at)
181 {
182 return getInstance(devBounds, false, s, at);
183 }
184
185 /**
186 * Returns a Region object covering the pixels which would be
187 * touched by a fill or clip operation on a Graphics implementation
188 * on the specified Shape object under the optionally specified
189 * AffineTransform object further restricted by the specified
190 * device bounds.
191 * If the normalize parameter is true then coordinate normalization
192 * is performed as per the 2D Graphics non-antialiasing implementation
193 * of the VALUE_STROKE_NORMALIZE hint.
194 * <p>
195 * Note that only the bounds of the specified Region are used to
196 * restrict the resulting Region.
197 * If devBounds is non-rectangular and clipping to the specific
198 * bands of devBounds is needed, then an intersection of the
199 * resulting Region with devBounds must be performed in a
200 * subsequent step.
201 *
202 * @param devBounds a non-null Region specifying some bounds to
203 * clip the geometry to
204 * @param normalize a boolean indicating whether or not to apply
205 * normalization
206 * @param s a non-null Shape object specifying the geometry enclosing
207 * the pixels of interest
208 * @param at an optional <code>AffineTransform</code> to be applied to the
209 * coordinates as they are returned in the iteration, or
210 * <code>null</code> if untransformed coordinates are desired
211 */
212 public static Region getInstance(Region devBounds, boolean normalize,
213 Shape s, AffineTransform at)
214 {
215 // Optimize for empty shapes to avoid involving the SpanIterator
216 if (s instanceof RectangularShape &&
217 ((RectangularShape)s).isEmpty())
218 {
219 return EMPTY_REGION;
220 }
221
222 int box[] = new int[4];
223 ShapeSpanIterator sr = new ShapeSpanIterator(normalize);
224 try {
225 sr.setOutputArea(devBounds);
226 sr.appendPath(s.getPathIterator(at));
227 sr.getPathBox(box);
228 Region r = Region.getInstance(box);
229 r.appendSpans(sr);
230 return r;
231 } finally {
232 sr.dispose();
233 }
234 }
235
236 /**
237 * Returns a Region object with a rectangle of interest specified
238 * by the indicated Rectangle object.
239 * <p>
240 * This method can also be used to create a simple rectangular
241 * region.
242 */
243 public static Region getInstance(Rectangle r) {
244 return Region.getInstanceXYWH(r.x, r.y, r.width, r.height);
245 }
246
247 /**
248 * Returns a Region object with a rectangle of interest specified
249 * by the indicated rectangular area in x, y, width, height format.
250 * <p>
251 * This method can also be used to create a simple rectangular
252 * region.
253 */
254 public static Region getInstanceXYWH(int x, int y, int w, int h) {
255 return Region.getInstanceXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
256 }
257
258 /**
259 * Returns a Region object with a rectangle of interest specified
260 * by the indicated span array.
261 * <p>
262 * This method can also be used to create a simple rectangular
263 * region.
264 */
265 public static Region getInstance(int box[]) {
266 return new Region(box[0], box[1], box[2], box[3]);
267 }
268
269 /**
270 * Returns a Region object with a rectangle of interest specified
271 * by the indicated rectangular area in lox, loy, hix, hiy format.
272 * <p>
273 * This method can also be used to create a simple rectangular
274 * region.
275 */
276 public static Region getInstanceXYXY(int lox, int loy, int hix, int hiy) {
277 return new Region(lox, loy, hix, hiy);
278 }
279
280 /**
281 * Sets the rectangle of interest for storing and returning
282 * region bands.
283 * <p>
284 * This method can also be used to initialize a simple rectangular
285 * region.
286 */
287 public void setOutputArea(Rectangle r) {
288 setOutputAreaXYWH(r.x, r.y, r.width, r.height);
289 }
290
291 /**
292 * Sets the rectangle of interest for storing and returning
293 * region bands. The rectangle is specified in x, y, width, height
294 * format and appropriate clipping is performed as per the method
295 * <code>dimAdd</code>.
296 * <p>
297 * This method can also be used to initialize a simple rectangular
298 * region.
299 */
300 public void setOutputAreaXYWH(int x, int y, int w, int h) {
301 setOutputAreaXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
302 }
303
304 /**
305 * Sets the rectangle of interest for storing and returning
306 * region bands. The rectangle is specified as a span array.
307 * <p>
308 * This method can also be used to initialize a simple rectangular
309 * region.
310 */
311 public void setOutputArea(int box[]) {
312 this.lox = box[0];
313 this.loy = box[1];
314 this.hix = box[2];
315 this.hiy = box[3];
316 }
317
318 /**
319 * Sets the rectangle of interest for storing and returning
320 * region bands. The rectangle is specified in lox, loy,
321 * hix, hiy format.
322 * <p>
323 * This method can also be used to initialize a simple rectangular
324 * region.
325 */
326 public void setOutputAreaXYXY(int lox, int loy, int hix, int hiy) {
327 this.lox = lox;
328 this.loy = loy;
329 this.hix = hix;
330 this.hiy = hiy;
331 }
332
333 /**
334 * Appends the list of spans returned from the indicated
335 * SpanIterator. Each span must be at a higher starting
336 * Y coordinate than the previous data or it must have a
337 * Y range equal to the highest Y band in the region and a
338 * higher X coordinate than any of the spans in that band.
339 */
340 public void appendSpans(SpanIterator si) {
341 int[] box = new int[6];
342
343 while (si.nextSpan(box)) {
344 appendSpan(box);
345 }
346
347 endRow(box);
348 calcBBox();
349 }
350
351 /**
352 * Returns a Region object that represents the same list of
353 * rectangles as the current Region object, translated by
354 * the specified dx, dy translation factors.
355 */
356 public Region getTranslatedRegion(int dx, int dy) {
357 if ((dx | dy) == 0) {
358 return this;
359 }
360 int tlox = lox + dx;
361 int tloy = loy + dy;
362 int thix = hix + dx;
363 int thiy = hiy + dy;
364 if ((tlox > lox) != (dx > 0) ||
365 (tloy > loy) != (dy > 0) ||
366 (thix > hix) != (dx > 0) ||
367 (thiy > hiy) != (dy > 0))
368 {
369 return getSafeTranslatedRegion(dx, dy);
370 }
371 Region ret = new Region(tlox, tloy, thix, thiy);
372 int bands[] = this.bands;
373 if (bands != null) {
374 int end = endIndex;
375 ret.endIndex = end;
376 int newbands[] = new int[end];
377 ret.bands = newbands;
378 int i = 0;
379 int ncol;
380 while (i < end) {
381 newbands[i] = bands[i] + dy; i++;
382 newbands[i] = bands[i] + dy; i++;
383 newbands[i] = ncol = bands[i]; i++;
384 while (--ncol >= 0) {
385 newbands[i] = bands[i] + dx; i++;
386 newbands[i] = bands[i] + dx; i++;
387 }
388 }
389 }
390 return ret;
391 }
392
393 private Region getSafeTranslatedRegion(int dx, int dy) {
394 int tlox = clipAdd(lox, dx);
395 int tloy = clipAdd(loy, dy);
396 int thix = clipAdd(hix, dx);
397 int thiy = clipAdd(hiy, dy);
398 Region ret = new Region(tlox, tloy, thix, thiy);
399 int bands[] = this.bands;
400 if (bands != null) {
401 int end = endIndex;
402 int newbands[] = new int[end];
403 int i = 0; // index for source bands
404 int j = 0; // index for translated newbands
405 int ncol;
406 while (i < end) {
407 int y1, y2;
408 newbands[j++] = y1 = clipAdd(bands[i++], dy);
409 newbands[j++] = y2 = clipAdd(bands[i++], dy);
410 newbands[j++] = ncol = bands[i++];
411 int savej = j;
412 if (y1 < y2) {
413 while (--ncol >= 0) {
414 int x1 = clipAdd(bands[i++], dx);
415 int x2 = clipAdd(bands[i++], dx);
416 if (x1 < x2) {
417 newbands[j++] = x1;
418 newbands[j++] = x2;
419 }
420 }
421 } else {
422 i += ncol * 2;
423 }
424 // Did we get any non-empty bands in this row?
425 if (j > savej) {
426 newbands[savej-1] = (j - savej) / 2;
427 } else {
428 j = savej - 3;
429 }
430 }
431 if (j <= 5) {
432 if (j < 5) {
433 // No rows or bands were generated...
434 ret.lox = ret.loy = ret.hix = ret.hiy = 0;
435 } else {
436 // Only generated one single rect in the end...
437 ret.loy = newbands[0];
438 ret.hiy = newbands[1];
439 ret.lox = newbands[3];
440 ret.hix = newbands[4];
441 }
442 // ret.endIndex and ret.bands were never initialized...
443 // ret.endIndex = 0;
444 // ret.newbands = null;
445 } else {
446 // Generated multiple bands and/or multiple rows...
447 ret.endIndex = j;
448 ret.bands = newbands;
449 }
450 }
451 return ret;
452 }
453
454 /**
455 * Returns a Region object that represents the intersection of
456 * this object with the specified Rectangle. The return value
457 * may be this same object if no clipping occurs.
458 */
459 public Region getIntersection(Rectangle r) {
460 return getIntersectionXYWH(r.x, r.y, r.width, r.height);
461 }
462
463 /**
464 * Returns a Region object that represents the intersection of
465 * this object with the specified rectangular area. The return
466 * value may be this same object if no clipping occurs.
467 */
468 public Region getIntersectionXYWH(int x, int y, int w, int h) {
469 return getIntersectionXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
470 }
471
472 /**
473 * Returns a Region object that represents the intersection of
474 * this object with the specified rectangular area. The return
475 * value may be this same object if no clipping occurs.
476 */
477 public Region getIntersectionXYXY(int lox, int loy, int hix, int hiy) {
478 if (isInsideXYXY(lox, loy, hix, hiy)) {
479 return this;
480 }
481 Region ret = new Region((lox < this.lox) ? this.lox : lox,
482 (loy < this.loy) ? this.loy : loy,
483 (hix > this.hix) ? this.hix : hix,
484 (hiy > this.hiy) ? this.hiy : hiy);
485 if (bands != null) {
486 ret.appendSpans(this.getSpanIterator());
487 }
488 return ret;
489 }
490
491 /**
492 * Returns a Region object that represents the intersection of this
493 * object with the specified Region object.
494 * <p>
495 * If {@code A} and {@code B} are both Region Objects and
496 * <code>C = A.getIntersection(B);</code> then a point will
497 * be contained in {@code C} iff it is contained in both
498 * {@code A} and {@code B}.
499 * <p>
500 * The return value may be this same object or the argument
501 * Region object if no clipping occurs.
502 */
503 public Region getIntersection(Region r) {
504 if (this.isInsideQuickCheck(r)) {
505 return this;
506 }
507 if (r.isInsideQuickCheck(this)) {
508 return r;
509 }
510 Region ret = new Region((r.lox < this.lox) ? this.lox : r.lox,
511 (r.loy < this.loy) ? this.loy : r.loy,
512 (r.hix > this.hix) ? this.hix : r.hix,
513 (r.hiy > this.hiy) ? this.hiy : r.hiy);
514 if (!ret.isEmpty()) {
515 ret.filterSpans(this, r, INCLUDE_COMMON);
516 }
517 return ret;
518 }
519
520 /**
521 * Returns a Region object that represents the union of this
522 * object with the specified Region object.
523 * <p>
524 * If {@code A} and {@code B} are both Region Objects and
525 * <code>C = A.getUnion(B);</code> then a point will
526 * be contained in {@code C} iff it is contained in either
527 * {@code A} or {@code B}.
528 * <p>
529 * The return value may be this same object or the argument
530 * Region object if no augmentation occurs.
531 */
532 public Region getUnion(Region r) {
533 if (r.isEmpty() || r.isInsideQuickCheck(this)) {
534 return this;
535 }
536 if (this.isEmpty() || this.isInsideQuickCheck(r)) {
537 return r;
538 }
539 Region ret = new Region((r.lox > this.lox) ? this.lox : r.lox,
540 (r.loy > this.loy) ? this.loy : r.loy,
541 (r.hix < this.hix) ? this.hix : r.hix,
542 (r.hiy < this.hiy) ? this.hiy : r.hiy);
543 ret.filterSpans(this, r, INCLUDE_A | INCLUDE_B | INCLUDE_COMMON);
544 return ret;
545 }
546
547 /**
548 * Returns a Region object that represents the difference of the
549 * specified Region object subtracted from this object.
550 * <p>
551 * If {@code A} and {@code B} are both Region Objects and
552 * <code>C = A.getDifference(B);</code> then a point will
553 * be contained in {@code C} iff it is contained in
554 * {@code A} but not contained in {@code B}.
555 * <p>
556 * The return value may be this same object or the argument
557 * Region object if no clipping occurs.
558 */
559 public Region getDifference(Region r) {
560 if (!r.intersectsQuickCheck(this)) {
561 return this;
562 }
563 if (this.isInsideQuickCheck(r)) {
564 return EMPTY_REGION;
565 }
566 Region ret = new Region(this.lox, this.loy, this.hix, this.hiy);
567 ret.filterSpans(this, r, INCLUDE_A);
568 return ret;
569 }
570
571 /**
572 * Returns a Region object that represents the exclusive or of this
573 * object with the specified Region object.
574 * <p>
575 * If {@code A} and {@code B} are both Region Objects and
576 * <code>C = A.getExclusiveOr(B);</code> then a point will
577 * be contained in {@code C} iff it is contained in either
578 * {@code A} or {@code B}, but not if it is contained in both.
579 * <p>
580 * The return value may be this same object or the argument
581 * Region object if either is empty.
582 */
583 public Region getExclusiveOr(Region r) {
584 if (r.isEmpty()) {
585 return this;
586 }
587 if (this.isEmpty()) {
588 return r;
589 }
590 Region ret = new Region((r.lox > this.lox) ? this.lox : r.lox,
591 (r.loy > this.loy) ? this.loy : r.loy,
592 (r.hix < this.hix) ? this.hix : r.hix,
593 (r.hiy < this.hiy) ? this.hiy : r.hiy);
594 ret.filterSpans(this, r, INCLUDE_A | INCLUDE_B);
595 return ret;
596 }
597
598 static final int INCLUDE_A = 1;
599 static final int INCLUDE_B = 2;
600 static final int INCLUDE_COMMON = 4;
601
602 private void filterSpans(Region ra, Region rb, int flags) {
603 int abands[] = ra.bands;
604 int bbands[] = rb.bands;
605 if (abands == null) {
606 abands = new int[] {ra.loy, ra.hiy, 1, ra.lox, ra.hix};
607 }
608 if (bbands == null) {
609 bbands = new int[] {rb.loy, rb.hiy, 1, rb.lox, rb.hix};
610 }
611 int box[] = new int[6];
612 int acolstart = 0;
613 int ay1 = abands[acolstart++];
614 int ay2 = abands[acolstart++];
615 int acolend = abands[acolstart++];
616 acolend = acolstart + 2 * acolend;
617 int bcolstart = 0;
618 int by1 = bbands[bcolstart++];
619 int by2 = bbands[bcolstart++];
620 int bcolend = bbands[bcolstart++];
621 bcolend = bcolstart + 2 * bcolend;
622 int y = loy;
623 while (y < hiy) {
624 if (y >= ay2) {
625 if (acolend < ra.endIndex) {
626 acolstart = acolend;
627 ay1 = abands[acolstart++];
628 ay2 = abands[acolstart++];
629 acolend = abands[acolstart++];
630 acolend = acolstart + 2 * acolend;
631 } else {
632 if ((flags & INCLUDE_B) == 0) break;
633 ay1 = ay2 = hiy;
634 }
635 continue;
636 }
637 if (y >= by2) {
638 if (bcolend < rb.endIndex) {
639 bcolstart = bcolend;
640 by1 = bbands[bcolstart++];
641 by2 = bbands[bcolstart++];
642 bcolend = bbands[bcolstart++];
643 bcolend = bcolstart + 2 * bcolend;
644 } else {
645 if ((flags & INCLUDE_A) == 0) break;
646 by1 = by2 = hiy;
647 }
648 continue;
649 }
650 int yend;
651 if (y < by1) {
652 if (y < ay1) {
653 y = Math.min(ay1, by1);
654 continue;
655 }
656 // We are in a set of rows that belong only to A
657 yend = Math.min(ay2, by1);
658 if ((flags & INCLUDE_A) != 0) {
659 box[1] = y;
660 box[3] = yend;
661 int acol = acolstart;
662 while (acol < acolend) {
663 box[0] = abands[acol++];
664 box[2] = abands[acol++];
665 appendSpan(box);
666 }
667 }
668 } else if (y < ay1) {
669 // We are in a set of rows that belong only to B
670 yend = Math.min(by2, ay1);
671 if ((flags & INCLUDE_B) != 0) {
672 box[1] = y;
673 box[3] = yend;
674 int bcol = bcolstart;
675 while (bcol < bcolend) {
676 box[0] = bbands[bcol++];
677 box[2] = bbands[bcol++];
678 appendSpan(box);
679 }
680 }
681 } else {
682 // We are in a set of rows that belong to both A and B
683 yend = Math.min(ay2, by2);
684 box[1] = y;
685 box[3] = yend;
686 int acol = acolstart;
687 int bcol = bcolstart;
688 int ax1 = abands[acol++];
689 int ax2 = abands[acol++];
690 int bx1 = bbands[bcol++];
691 int bx2 = bbands[bcol++];
692 int x = Math.min(ax1, bx1);
693 if (x < lox) x = lox;
694 while (x < hix) {
695 if (x >= ax2) {
696 if (acol < acolend) {
697 ax1 = abands[acol++];
698 ax2 = abands[acol++];
699 } else {
700 if ((flags & INCLUDE_B) == 0) break;
701 ax1 = ax2 = hix;
702 }
703 continue;
704 }
705 if (x >= bx2) {
706 if (bcol < bcolend) {
707 bx1 = bbands[bcol++];
708 bx2 = bbands[bcol++];
709 } else {
710 if ((flags & INCLUDE_A) == 0) break;
711 bx1 = bx2 = hix;
712 }
713 continue;
714 }
715 int xend;
716 boolean appendit;
717 if (x < bx1) {
718 if (x < ax1) {
719 xend = Math.min(ax1, bx1);
720 appendit = false;
721 } else {
722 xend = Math.min(ax2, bx1);
723 appendit = ((flags & INCLUDE_A) != 0);
724 }
725 } else if (x < ax1) {
726 xend = Math.min(ax1, bx2);
727 appendit = ((flags & INCLUDE_B) != 0);
728 } else {
729 xend = Math.min(ax2, bx2);
730 appendit = ((flags & INCLUDE_COMMON) != 0);
731 }
732 if (appendit) {
733 box[0] = x;
734 box[2] = xend;
735 appendSpan(box);
736 }
737 x = xend;
738 }
739 }
740 y = yend;
741 }
742 endRow(box);
743 calcBBox();
744 }
745
746 /**
747 * Returns a Region object that represents the bounds of the
748 * intersection of this object with the bounds of the specified
749 * Region object.
750 * <p>
751 * The return value may be this same object if no clipping occurs
752 * and this Region is rectangular.
753 */
754 public Region getBoundsIntersection(Rectangle r) {
755 return getBoundsIntersectionXYWH(r.x, r.y, r.width, r.height);
756 }
757
758 /**
759 * Returns a Region object that represents the bounds of the
760 * intersection of this object with the bounds of the specified
761 * rectangular area in x, y, width, height format.
762 * <p>
763 * The return value may be this same object if no clipping occurs
764 * and this Region is rectangular.
765 */
766 public Region getBoundsIntersectionXYWH(int x, int y, int w, int h) {
767 return getBoundsIntersectionXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
768 }
769
770 /**
771 * Returns a Region object that represents the bounds of the
772 * intersection of this object with the bounds of the specified
773 * rectangular area in lox, loy, hix, hiy format.
774 * <p>
775 * The return value may be this same object if no clipping occurs
776 * and this Region is rectangular.
777 */
778 public Region getBoundsIntersectionXYXY(int lox, int loy,
779 int hix, int hiy)
780 {
781 if (this.bands == null &&
782 this.lox >= lox && this.loy >= loy &&
783 this.hix <= hix && this.hiy <= hiy)
784 {
785 return this;
786 }
787 return new Region((lox < this.lox) ? this.lox : lox,
788 (loy < this.loy) ? this.loy : loy,
789 (hix > this.hix) ? this.hix : hix,
790 (hiy > this.hiy) ? this.hiy : hiy);
791 }
792
793 /**
794 * Returns a Region object that represents the intersection of
795 * this object with the bounds of the specified Region object.
796 * <p>
797 * The return value may be this same object or the argument
798 * Region object if no clipping occurs and the Regions are
799 * rectangular.
800 */
801 public Region getBoundsIntersection(Region r) {
802 if (this.encompasses(r)) {
803 return r;
804 }
805 if (r.encompasses(this)) {
806 return this;
807 }
808 return new Region((r.lox < this.lox) ? this.lox : r.lox,
809 (r.loy < this.loy) ? this.loy : r.loy,
810 (r.hix > this.hix) ? this.hix : r.hix,
811 (r.hiy > this.hiy) ? this.hiy : r.hiy);
812 }
813
814 /**
815 * Appends a single span defined by the 4 parameters
816 * spanlox, spanloy, spanhix, spanhiy.
817 * This span must be at a higher starting Y coordinate than
818 * the previous data or it must have a Y range equal to the
819 * highest Y band in the region and a higher X coordinate
820 * than any of the spans in that band.
821 */
822 private void appendSpan(int box[]) {
823 int spanlox, spanloy, spanhix, spanhiy;
824 if ((spanlox = box[0]) < lox) spanlox = lox;
825 if ((spanloy = box[1]) < loy) spanloy = loy;
826 if ((spanhix = box[2]) > hix) spanhix = hix;
827 if ((spanhiy = box[3]) > hiy) spanhiy = hiy;
828 if (spanhix <= spanlox || spanhiy <= spanloy) {
829 return;
830 }
831
832 int curYrow = box[4];
833 if (endIndex == 0 || spanloy >= bands[curYrow + 1]) {
834 if (bands == null) {
835 bands = new int[INIT_SIZE];
836 } else {
837 needSpace(5);
838 endRow(box);
839 curYrow = box[4];
840 }
841 bands[endIndex++] = spanloy;
842 bands[endIndex++] = spanhiy;
843 bands[endIndex++] = 0;
844 } else if (spanloy == bands[curYrow] &&
845 spanhiy == bands[curYrow + 1] &&
846 spanlox >= bands[endIndex - 1]) {
847 if (spanlox == bands[endIndex - 1]) {
848 bands[endIndex - 1] = spanhix;
849 return;
850 }
851 needSpace(2);
852 } else {
853 throw new InternalError("bad span");
854 }
855 bands[endIndex++] = spanlox;
856 bands[endIndex++] = spanhix;
857 bands[curYrow + 2]++;
858 }
859
860 private void needSpace(int num) {
861 if (endIndex + num >= bands.length) {
862 int[] newbands = new int[bands.length + GROW_SIZE];
863 System.arraycopy(bands, 0, newbands, 0, endIndex);
864 bands = newbands;
865 }
866 }
867
868 private void endRow(int box[]) {
869 int cur = box[4];
870 int prev = box[5];
871 if (cur > prev) {
872 int[] bands = this.bands;
873 if (bands[prev + 1] == bands[cur] &&
874 bands[prev + 2] == bands[cur + 2])
875 {
876 int num = bands[cur + 2] * 2;
877 cur += 3;
878 prev += 3;
879 while (num > 0) {
880 if (bands[cur++] != bands[prev++]) {
881 break;
882 }
883 num--;
884 }
885 if (num == 0) {
886 // prev == box[4]
887 bands[box[5] + 1] = bands[prev + 1];
888 endIndex = prev;
889 return;
890 }
891 }
892 }
893 box[5] = box[4];
894 box[4] = endIndex;
895 }
896
897 private void calcBBox() {
898 int[] bands = this.bands;
899 if (endIndex <= 5) {
900 if (endIndex == 0) {
901 lox = loy = hix = hiy = 0;
902 } else {
903 loy = bands[0];
904 hiy = bands[1];
905 lox = bands[3];
906 hix = bands[4];
907 endIndex = 0;
908 }
909 this.bands = null;
910 return;
911 }
912 int lox = this.hix;
913 int hix = this.lox;
914 int hiyindex = 0;
915
916 int i = 0;
917 while (i < endIndex) {
918 hiyindex = i;
919 int numbands = bands[i + 2];
920 i += 3;
921 if (lox > bands[i]) {
922 lox = bands[i];
923 }
924 i += numbands * 2;
925 if (hix < bands[i - 1]) {
926 hix = bands[i - 1];
927 }
928 }
929
930 this.lox = lox;
931 this.loy = bands[0];
932 this.hix = hix;
933 this.hiy = bands[hiyindex + 1];
934 }
935
936 /**
937 * Returns the lowest X coordinate in the Region.
938 */
939 public final int getLoX() {
940 return lox;
941 }
942
943 /**
944 * Returns the lowest Y coordinate in the Region.
945 */
946 public final int getLoY() {
947 return loy;
948 }
949
950 /**
951 * Returns the highest X coordinate in the Region.
952 */
953 public final int getHiX() {
954 return hix;
955 }
956
957 /**
958 * Returns the highest Y coordinate in the Region.
959 */
960 public final int getHiY() {
961 return hiy;
962 }
963
964 /**
965 * Returns the width of this Region clipped to the range (0 - MAX_INT).
966 */
967 public final int getWidth() {
968 if (hix < lox) return 0;
969 int w;
970 if ((w = hix - lox) < 0) {
971 w = Integer.MAX_VALUE;
972 }
973 return w;
974 }
975
976 /**
977 * Returns the height of this Region clipped to the range (0 - MAX_INT).
978 */
979 public final int getHeight() {
980 if (hiy < loy) return 0;
981 int h;
982 if ((h = hiy - loy) < 0) {
983 h = Integer.MAX_VALUE;
984 }
985 return h;
986 }
987
988 /**
989 * Returns true iff this Region encloses no area.
990 */
991 public boolean isEmpty() {
992 return (hix <= lox || hiy <= loy);
993 }
994
995 /**
996 * Returns true iff this Region represents a single simple
997 * rectangular area.
998 */
999 public boolean isRectangular() {
1000 return (bands == null);
1001 }
1002
1003 /**
1004 * Returns true iff this Region contains the specified coordinate.
1005 */
1006 public boolean contains(int x, int y) {
1007 if (x < lox || x >= hix || y < loy || y >= hiy) return false;
1008 if (bands == null) return true;
1009 int i = 0;
1010 while (i < endIndex) {
1011 if (y < bands[i++]) {
1012 return false;
1013 }
1014 if (y >= bands[i++]) {
1015 int numspans = bands[i++];
1016 i += numspans * 2;
1017 } else {
1018 int end = bands[i++];
1019 end = i + end * 2;
1020 while (i < end) {
1021 if (x < bands[i++]) return false;
1022 if (x < bands[i++]) return true;
1023 }
1024 return false;
1025 }
1026 }
1027 return false;
1028 }
1029
1030 /**
1031 * Returns true iff this Region lies inside the indicated
1032 * rectangular area specified in x, y, width, height format
1033 * with appropriate clipping performed as per the dimAdd method.
1034 */
1035 public boolean isInsideXYWH(int x, int y, int w, int h) {
1036 return isInsideXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
1037 }
1038
1039 /**
1040 * Returns true iff this Region lies inside the indicated
1041 * rectangular area specified in lox, loy, hix, hiy format.
1042 */
1043 public boolean isInsideXYXY(int lox, int loy, int hix, int hiy) {
1044 return (this.lox >= lox && this.loy >= loy &&
1045 this.hix <= hix && this.hiy <= hiy);
1046
1047 }
1048
1049 /**
1050 * Quickly checks if this Region lies inside the specified
1051 * Region object.
1052 * <p>
1053 * This method will return false if the specified Region
1054 * object is not a simple rectangle.
1055 */
1056 public boolean isInsideQuickCheck(Region r) {
1057 return (r.bands == null &&
1058 r.lox <= this.lox && r.loy <= this.loy &&
1059 r.hix >= this.hix && r.hiy >= this.hiy);
1060 }
1061
1062 /**
1063 * Quickly checks if this Region intersects the specified
1064 * rectangular area specified in lox, loy, hix, hiy format.
1065 * <p>
1066 * This method tests only against the bounds of this region
1067 * and does not bother to test if the rectangular region
1068 * actually intersects any bands.
1069 */
1070 public boolean intersectsQuickCheckXYXY(int lox, int loy,
1071 int hix, int hiy)
1072 {
1073 return (hix > this.lox && lox < this.hix &&
1074 hiy > this.loy && loy < this.hiy);
1075 }
1076
1077 /**
1078 * Quickly checks if this Region intersects the specified
1079 * Region object.
1080 * <p>
1081 * This method tests only against the bounds of this region
1082 * and does not bother to test if the rectangular region
1083 * actually intersects any bands.
1084 */
1085 public boolean intersectsQuickCheck(Region r) {
1086 return (r.hix > this.lox && r.lox < this.hix &&
1087 r.hiy > this.loy && r.loy < this.hiy);
1088 }
1089
1090 /**
1091 * Quickly checks if this Region surrounds the specified
1092 * Region object.
1093 * <p>
1094 * This method will return false if this Region object is
1095 * not a simple rectangle.
1096 */
1097 public boolean encompasses(Region r) {
1098 return (this.bands == null &&
1099 this.lox <= r.lox && this.loy <= r.loy &&
1100 this.hix >= r.hix && this.hiy >= r.hiy);
1101 }
1102
1103 /**
1104 * Quickly checks if this Region surrounds the specified
1105 * rectangular area specified in x, y, width, height format.
1106 * <p>
1107 * This method will return false if this Region object is
1108 * not a simple rectangle.
1109 */
1110 public boolean encompassesXYWH(int x, int y, int w, int h) {
1111 return encompassesXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
1112 }
1113
1114 /**
1115 * Quickly checks if this Region surrounds the specified
1116 * rectangular area specified in lox, loy, hix, hiy format.
1117 * <p>
1118 * This method will return false if this Region object is
1119 * not a simple rectangle.
1120 */
1121 public boolean encompassesXYXY(int lox, int loy, int hix, int hiy) {
1122 return (this.bands == null &&
1123 this.lox <= lox && this.loy <= loy &&
1124 this.hix >= hix && this.hiy >= hiy);
1125 }
1126
1127 /**
1128 * Gets the bbox of the available spans, clipped to the OutputArea.
1129 */
1130 public void getBounds(int pathbox[]) {
1131 pathbox[0] = lox;
1132 pathbox[1] = loy;
1133 pathbox[2] = hix;
1134 pathbox[3] = hiy;
1135 }
1136
1137 /**
1138 * Clips the indicated bbox array to the bounds of this Region.
1139 */
1140 public void clipBoxToBounds(int bbox[]) {
1141 if (bbox[0] < lox) bbox[0] = lox;
1142 if (bbox[1] < loy) bbox[1] = loy;
1143 if (bbox[2] > hix) bbox[2] = hix;
1144 if (bbox[3] > hiy) bbox[3] = hiy;
1145 }
1146
1147 /**
1148 * Gets an iterator object to iterate over the spans in this region.
1149 */
1150 public RegionIterator getIterator() {
1151 return new RegionIterator(this);
1152 }
1153
1154 /**
1155 * Gets a span iterator object that iterates over the spans in this region
1156 */
1157 public SpanIterator getSpanIterator() {
1158 return new RegionSpanIterator(this);
1159 }
1160
1161 /**
1162 * Gets a span iterator object that iterates over the spans in this region
1163 * but clipped to the bounds given in the argument (xlo, ylo, xhi, yhi).
1164 */
1165 public SpanIterator getSpanIterator(int bbox[]) {
1166 SpanIterator result = getSpanIterator();
1167 result.intersectClipBox(bbox[0], bbox[1], bbox[2], bbox[3]);
1168 return result;
1169 }
1170
1171 /**
1172 * Returns a SpanIterator that is the argument iterator filtered by
1173 * this region.
1174 */
1175 public SpanIterator filter(SpanIterator si) {
1176 if (bands == null) {
1177 si.intersectClipBox(lox, loy, hix, hiy);
1178 } else {
1179 si = new RegionClipSpanIterator(this, si);
1180 }
1181 return si;
1182 }
1183
1184 public String toString() {
1185 StringBuffer sb = new StringBuffer();
1186 sb.append("Region[[");
1187 sb.append(lox);
1188 sb.append(", ");
1189 sb.append(loy);
1190 sb.append(" => ");
1191 sb.append(hix);
1192 sb.append(", ");
1193 sb.append(hiy);
1194 sb.append("]");
1195 if (bands != null) {
1196 int col = 0;
1197 while (col < endIndex) {
1198 sb.append("y{");
1199 sb.append(bands[col++]);
1200 sb.append(",");
1201 sb.append(bands[col++]);
1202 sb.append("}[");
1203 int end = bands[col++];
1204 end = col + end * 2;
1205 while (col < end) {
1206 sb.append("x(");
1207 sb.append(bands[col++]);
1208 sb.append(", ");
1209 sb.append(bands[col++]);
1210 sb.append(")");
1211 }
1212 sb.append("]");
1213 }
1214 }
1215 sb.append("]");
1216 return sb.toString();
1217 }
1218
1219 public int hashCode() {
1220 return (isEmpty() ? 0 : (lox * 3 + loy * 5 + hix * 7 + hiy * 9));
1221 }
1222
1223 public boolean equals(Object o) {
1224 if (!(o instanceof Region)) {
1225 return false;
1226 }
1227 Region r = (Region) o;
1228 if (this.isEmpty()) {
1229 return r.isEmpty();
1230 } else if (r.isEmpty()) {
1231 return false;
1232 }
1233 if (r.lox != this.lox || r.loy != this.loy ||
1234 r.hix != this.hix || r.hiy != this.hiy)
1235 {
1236 return false;
1237 }
1238 if (this.bands == null) {
1239 return (r.bands == null);
1240 } else if (r.bands == null) {
1241 return false;
1242 }
1243 if (this.endIndex != r.endIndex) {
1244 return false;
1245 }
1246 int abands[] = this.bands;
1247 int bbands[] = r.bands;
1248 for (int i = 0; i < endIndex; i++) {
1249 if (abands[i] != bbands[i]) {
1250 return false;
1251 }
1252 }
1253 return true;
1254 }
1255}
java/pkg/sun/java2d/pipe/RegionClipSpanIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RegionClipSpanIterator.java+392−0
@@ -0,0 +1,392 @@
1/*
2 * Copyright (c) 1999, 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
26package sun.java2d.pipe;
27
28import java.awt.geom.PathIterator;
29import java.awt.Rectangle;
30
31/**
32 * This class clips a SpanIterator to a Region and outputs the
33 * resulting spans as another SpanIterator.
34 *
35 * Spans are output in the usual y/x order, unless the input span
36 * iterator doesn't conform to this order, or the iterator's span
37 * straddle more than one band of the Region used for clipping.
38 *
39 * Principle of operation:
40 *
41 * The iterator maintains a several cursors onto the RegionIterator
42 * in order to avoid having to buffer spans from the SpanIterator.
43 * They are:
44 * resetState The initial state of the RegionIterator
45 * lwm Low Water Mark, a running start point for
46 * processing each band. Usually goes down, but
47 * can be reset to resetState if a span has a lower
48 * start coordinate than the previous one.
49 * row The start of the current band of the RegionIterator
50 * box The current span of the current row
51 *
52 * The main nextSpan() loop implements a coroutine like structure, with
53 * three producers to get the next span, row and box calling each other
54 * to iterate through the span iterator and region.
55 *
56 * REMIND: Needs a native implementation!
57 */
58public class RegionClipSpanIterator implements SpanIterator {
59
60 // The inputs to the filter
61 Region rgn;
62 SpanIterator spanIter;
63
64 // The cursors that track the progress through the region
65 RegionIterator resetState;
66 RegionIterator lwm;
67 RegionIterator row;
68 RegionIterator box;
69
70 // The bounds of the current span iterator span
71 int spanlox, spanhix, spanloy, spanhiy;
72
73 // The extent of the region band marking the low water mark
74 int lwmloy, lwmhiy;
75
76 // The bounds of the current region box
77 int rgnlox, rgnloy, rgnhix, rgnhiy;
78
79 // The bounding box of the input Region. Used for click
80 // rejection of iterator spans
81 int rgnbndslox, rgnbndsloy, rgnbndshix, rgnbndshiy;
82
83 // The array used to hold coordinates from the region iterator
84 int rgnbox[] = new int[4];
85
86 // The array used to hold coordinates from the span iterator
87 int spanbox[] = new int[4];
88
89 // True if the next iterator span should be read on the next
90 // iteration of the main nextSpan() loop
91 boolean doNextSpan;
92
93 // True if the next region box should be read on the next
94 // iteration of the main nextSpan() loop
95 boolean doNextBox;
96
97 // True if there are no more spans or the Region is empty
98 boolean done = false;
99
100 /*
101 * Creates an instance that filters the spans generated by
102 * spanIter through the region described by rgn.
103 */
104 public RegionClipSpanIterator(Region rgn, SpanIterator spanIter) {
105
106 this.spanIter = spanIter;
107
108 resetState = rgn.getIterator();
109 lwm = resetState.createCopy();
110
111 if (!lwm.nextYRange(rgnbox)) {
112 done = true;
113 return;
114 }
115
116 rgnloy = lwmloy = rgnbox[1];
117 rgnhiy = lwmhiy = rgnbox[3];
118
119 rgn.getBounds(rgnbox);
120 rgnbndslox = rgnbox[0];
121 rgnbndsloy = rgnbox[1];
122 rgnbndshix = rgnbox[2];
123 rgnbndshiy = rgnbox[3];
124 if (rgnbndslox >= rgnbndshix ||
125 rgnbndsloy >= rgnbndshiy) {
126 done = true;
127 return;
128 }
129
130 this.rgn = rgn;
131
132
133 row = lwm.createCopy();
134 box = row.createCopy();
135 doNextSpan = true;
136 doNextBox = false;
137 }
138
139 /*
140 * Gets the bbox of the available path segments, clipped to the
141 * Region.
142 */
143 public void getPathBox(int pathbox[]) {
144 int[] rgnbox = new int[4];
145 rgn.getBounds(rgnbox);
146 spanIter.getPathBox(pathbox);
147
148 if (pathbox[0] < rgnbox[0]) {
149 pathbox[0] = rgnbox[0];
150 }
151
152 if (pathbox[1] < rgnbox[1]) {
153 pathbox[1] = rgnbox[1];
154 }
155
156 if (pathbox[2] > rgnbox[2]) {
157 pathbox[2] = rgnbox[2];
158 }
159
160 if (pathbox[3] > rgnbox[3]) {
161 pathbox[3] = rgnbox[3];
162 }
163}
164
165 /*
166 * Intersects the path box with the given bbox.
167 * Returned spans are clipped to this region, or discarded
168 * altogether if they lie outside it.
169 */
170 public void intersectClipBox(int lox, int loy, int hix, int hiy) {
171 spanIter.intersectClipBox(lox, loy, hix, hiy);
172 }
173
174
175 /*
176 * Fetches the next span that needs to be operated on.
177 * If the return value is false then there are no more spans.
178 */
179 public boolean nextSpan(int resultbox[]) {
180 if (done) {
181 return false;
182 }
183
184 int resultlox, resultloy, resulthix, resulthiy;
185 boolean doNextRow = false;
186
187 // REMIND: Cache the coordinate inst vars used in this loop
188 // in locals vars.
189 while (true) {
190 // We've exhausted the current span so get the next one
191 if (doNextSpan) {
192 if (!spanIter.nextSpan(spanbox)) {
193 done = true;
194 return false;
195 } else {
196 spanlox = spanbox[0];
197 // Clip out spans that lie outside of the rgn's bounds
198 if (spanlox >= rgnbndshix) {
199 continue;
200 }
201
202 spanloy = spanbox[1];
203 if (spanloy >= rgnbndshiy) {
204 continue;
205 }
206
207 spanhix = spanbox[2];
208 if (spanhix <= rgnbndslox) {
209 continue;
210 }
211
212 spanhiy = spanbox[3];
213 if (spanhiy <= rgnbndsloy) {
214 continue;
215 }
216 }
217 // If the span starts higher up than the low-water mark,
218 // reset the lwm. This can only happen if spans aren't
219 // returned in strict y/x order, or the first time through.
220 if (lwmloy > spanloy) {
221 lwm.copyStateFrom(resetState);
222 lwm.nextYRange(rgnbox);
223 lwmloy = rgnbox[1];
224 lwmhiy = rgnbox[3];
225 }
226 // Skip to the first rgn row whose bottom edge is
227 // below the top of the current span. This will only
228 // execute >0 times when the current span starts in a
229 // lower region row than the previous one, or possibly the
230 // first time through.
231 while (lwmhiy <= spanloy) {
232 if (!lwm.nextYRange(rgnbox))
233 break;
234 lwmloy = rgnbox[1];
235 lwmhiy = rgnbox[3];
236 }
237 // If the row overlaps the span, process it, otherwise
238 // fetch another span
239 if (lwmhiy > spanloy && lwmloy < spanhiy) {
240 // Update the current row if it's different from the
241 // new lwm
242 if (rgnloy != lwmloy) {
243 row.copyStateFrom(lwm);
244 rgnloy = lwmloy;
245 rgnhiy = lwmhiy;
246 }
247 box.copyStateFrom(row);
248 doNextBox = true;
249 doNextSpan = false;
250 }
251 continue;
252 }
253
254 // The current row's spans are exhausted, do the next one
255 if (doNextRow) {
256 // Next time we either do the next span or the next box
257 doNextRow = false;
258 // Get the next row
259 boolean ok = row.nextYRange(rgnbox);
260 // If there was one, update the bounds
261 if (ok) {
262 rgnloy = rgnbox[1];
263 rgnhiy = rgnbox[3];
264 }
265 if (!ok || rgnloy >= spanhiy) {
266 // If we've exhausted the rows or this one is below the span,
267 // go onto the next span
268 doNextSpan = true;
269 }
270 else {
271 // Otherwise get the first box on this row
272 box.copyStateFrom(row);
273 doNextBox = true;
274 }
275 continue;
276 }
277
278 // Process the next box in the current row
279 if (doNextBox) {
280 boolean ok = box.nextXBand(rgnbox);
281 if (ok) {
282 rgnlox = rgnbox[0];
283 rgnhix = rgnbox[2];
284 }
285 if (!ok || rgnlox >= spanhix) {
286 // If there was no next rgn span or it's beyond the
287 // source span, go onto the next row or span
288 doNextBox = false;
289 if (rgnhiy >= spanhiy) {
290 // If the current row totally overlaps the span,
291 // go onto the next span
292 doNextSpan = true;
293 } else {
294 // otherwise go onto the next rgn row
295 doNextRow = true;
296 }
297 } else {
298 // Otherwise, if the new rgn span overlaps the
299 // spanbox, no need to get another box
300 doNextBox = rgnhix <= spanlox;
301 }
302 continue;
303 }
304
305 // Prepare to do the next box either on this call or
306 // or the subsequent one
307 doNextBox = true;
308
309 // Clip the current span against the current box
310 if (spanlox > rgnlox) {
311 resultlox = spanlox;
312 }
313 else {
314 resultlox = rgnlox;
315 }
316
317 if (spanloy > rgnloy) {
318 resultloy = spanloy;
319 }
320 else {
321 resultloy = rgnloy;
322 }
323
324 if (spanhix < rgnhix) {
325 resulthix = spanhix;
326 }
327 else {
328 resulthix = rgnhix;
329 }
330
331 if (spanhiy < rgnhiy) {
332 resulthiy = spanhiy;
333 }
334 else {
335 resulthiy = rgnhiy;
336 }
337
338 // If the result is empty, try then next box
339 // otherwise return the box.
340 // REMIND: I think by definition it's non-empty
341 // if we're here. Need to think about this some more.
342 if (resultlox >= resulthix ||
343 resultloy >= resulthiy) {
344 continue;
345 }
346 else {
347 break;
348 }
349 }
350
351 resultbox[0] = resultlox;
352 resultbox[1] = resultloy;
353 resultbox[2] = resulthix;
354 resultbox[3] = resulthiy;
355 return true;
356
357 }
358
359
360 /**
361 * This method tells the iterator that it may skip all spans
362 * whose Y range is completely above the indicated Y coordinate.
363 */
364 public void skipDownTo(int y) {
365 spanIter.skipDownTo(y);
366 }
367
368 /**
369 * This method returns a native pointer to a function block that
370 * can be used by a native method to perform the same iteration
371 * cycle that the above methods provide while avoiding upcalls to
372 * the Java object.
373 * The definition of the structure whose pointer is returned by
374 * this method is defined in:
375 * <pre>
376 * src/share/native/sun/java2d/pipe/SpanIterator.h
377 * </pre>
378 */
379 public long getNativeIterator() {
380 return 0;
381 }
382
383 /*
384 * Cleans out all internal data structures.
385 */
386 //public native void dispose();
387
388 protected void finalize() {
389 //dispose();
390 }
391
392}
java/pkg/sun/java2d/pipe/RegionIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RegionIterator.java+101−0
@@ -0,0 +1,101 @@
1/*
2 * Copyright (c) 1998, 2002, 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
26package sun.java2d.pipe;
27
28import java.awt.Rectangle;
29
30/**
31 * This class defines the API for iterating through the bands
32 * of a region object.
33 */
34public class RegionIterator {
35 Region region;
36 int curIndex;
37 int numXbands;
38
39 RegionIterator(Region r) {
40 region = r;
41 }
42
43 /**
44 * Returns a new RegionIterator object representing the same
45 * iteration state as this object to allow multiple iteration
46 * branches from the current position.
47 */
48 public RegionIterator createCopy() {
49 RegionIterator r = new RegionIterator(region);
50 r.curIndex = this.curIndex;
51 r.numXbands = this.numXbands;
52 return r;
53 }
54
55 /**
56 * Copies the iteration state from this RegionIterator object
57 * into another RegionIterator object to allow multiple iteration
58 * branches from the current position.
59 */
60 public void copyStateFrom(RegionIterator ri) {
61 if (this.region != ri.region) {
62 throw new InternalError("region mismatch");
63 }
64 this.curIndex = ri.curIndex;
65 this.numXbands = ri.numXbands;
66 }
67
68 /**
69 * Moves the iteration state to the beginning of the next
70 * Y range in the region returning true if one is found
71 * and recording the low and high Y coordinates of the
72 * range in the array at locations 1 and 3 respectively.
73 */
74 public boolean nextYRange(int range[]) {
75 curIndex += numXbands * 2;
76 numXbands = 0;
77 if (curIndex >= region.endIndex) {
78 return false;
79 }
80 range[1] = region.bands[curIndex++];
81 range[3] = region.bands[curIndex++];
82 numXbands = region.bands[curIndex++];
83 return true;
84 }
85
86 /**
87 * Moves the iteration state to the beginning of the next
88 * X band in the current Y range returning true if one is
89 * found and recording the low and high X coordinates of
90 * the range in the array at locations 0 and 2 respectively.
91 */
92 public boolean nextXBand(int range[]) {
93 if (numXbands <= 0) {
94 return false;
95 }
96 numXbands--;
97 range[0] = region.bands[curIndex++];
98 range[2] = region.bands[curIndex++];
99 return true;
100 }
101}
java/pkg/sun/java2d/pipe/RegionSpanIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RegionSpanIterator.java+210−0
@@ -0,0 +1,210 @@
1/*
2 * Copyright (c) 1999, 2002, 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
26package sun.java2d.pipe;
27
28/**
29 * This class implements the ShapeIterator interface for a Region.
30 * This is useful as the source iterator of a device clip region
31 * (in its native guise), and also as the result of clipping a
32 * Region to a rectangle.
33 */
34public class RegionSpanIterator implements SpanIterator {
35 // The RegionIterator that we use to do the work
36 RegionIterator ri;
37
38 // Clipping bounds
39 int lox, loy, hix, hiy;
40
41 // Current Y band limits
42 int curloy, curhiy;
43
44 // Are we done?
45 boolean done = false;
46
47 // Is the associated Region rectangular?
48 boolean isrect;
49
50/*
51 REMIND: For native implementation
52 long pData; // Private storage of rect info
53
54 static {
55 initIDs();
56 }
57
58 public static native void initIDs();
59*/
60
61 /**
62 * Constructs an instance based on the given Region
63 */
64 public RegionSpanIterator(Region r) {
65 int[] bounds = new int[4];
66
67 r.getBounds(bounds);
68 lox = bounds[0];
69 loy = bounds[1];
70 hix = bounds[2];
71 hiy = bounds[3];
72 isrect = r.isRectangular();
73
74 ri = r.getIterator();
75 }
76
77 /**
78 * Gets the bbox of the available region spans.
79 */
80 public void getPathBox(int pathbox[]) {
81 pathbox[0] = lox;
82 pathbox[1] = loy;
83 pathbox[2] = hix;
84 pathbox[3] = hiy;
85 }
86
87 /**
88 * Intersect the box used for clipping the output spans with the
89 * given box.
90 */
91 public void intersectClipBox(int clox, int cloy, int chix, int chiy) {
92 if (clox > lox) {
93 lox = clox;
94 }
95 if (cloy > loy) {
96 loy = cloy;
97 }
98 if (chix < hix) {
99 hix = chix;
100 }
101 if (chiy < hiy) {
102 hiy = chiy;
103 }
104 done = lox >= hix || loy >= hiy;
105 }
106
107 /**
108 * Fetches the next span that needs to be operated on.
109 * If the return value is false then there are no more spans.
110 */
111 public boolean nextSpan(int spanbox[]) {
112
113 // Quick test for end conditions
114 if (done) {
115 return false;
116 }
117
118 // If the Region is rectangular, we store our bounds (possibly
119 // clipped via intersectClipBox()) in spanbox and return true
120 // so that the caller will process the single span. We set done
121 // to true to ensure that this will be the last span processed.
122 if (isrect) {
123 getPathBox(spanbox);
124 done = true;
125 return true;
126 }
127
128 // Local cache of current span's bounds
129 int curlox, curhix;
130 int curloy = this.curloy;
131 int curhiy = this.curhiy;
132
133 while (true) {
134 if (!ri.nextXBand(spanbox)) {
135 if (!ri.nextYRange(spanbox)) {
136 done = true;
137 return false;
138 }
139 // Update the current y band and clip it
140 curloy = spanbox[1];
141 curhiy = spanbox[3];
142 if (curloy < loy) {
143 curloy = loy;
144 }
145 if (curhiy > hiy) {
146 curhiy = hiy;
147 }
148 // Check for moving below the clip rect
149 if (curloy >= hiy) {
150 done = true;
151 return false;
152 }
153 continue;
154 }
155 // Clip the x box
156 curlox = spanbox[0];
157 curhix = spanbox[2];
158 if (curlox < lox) {
159 curlox = lox;
160 }
161 if (curhix > hix) {
162 curhix = hix;
163 }
164 // If it's non- box, we're done
165 if (curlox < curhix && curloy < curhiy) {
166 break;
167 }
168 }
169
170 // Update the result and the store y range
171 spanbox[0] = curlox;
172 spanbox[1] = this.curloy = curloy;
173 spanbox[2] = curhix;
174 spanbox[3] = this.curhiy = curhiy;
175 return true;
176 }
177
178 /**
179 * This method tells the iterator that it may skip all spans
180 * whose Y range is completely above the indicated Y coordinate.
181 */
182 public void skipDownTo(int y) {
183 loy = y;
184 }
185
186 /**
187 * This method returns a native pointer to a function block that
188 * can be used by a native method to perform the same iteration
189 * cycle that the above methods provide while avoiding upcalls to
190 * the Java object.
191 * The definition of the structure whose pointer is returned by
192 * this method is defined in:
193 * <pre>
194 * src/share/native/sun/java2d/pipe/SpanIterator.h
195 * </pre>
196 */
197 public long getNativeIterator() {
198 return 0;
199 }
200
201 /*
202 * Cleans out all internal data structures.
203 * REMIND: Native implementation
204 public native void dispose();
205
206 protected void finalize() {
207 dispose();
208 }
209 */
210}
java/pkg/sun/java2d/pipe/RenderBuffer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderBuffer.java+294−0
@@ -0,0 +1,294 @@
1/*
2 * Copyright (c) 2005, 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
26package sun.java2d.pipe;
27
28import sun.misc.Unsafe;
29
30/**
31 * The RenderBuffer class is a simplified, high-performance, Unsafe wrapper
32 * used for buffering rendering operations in a single-threaded rendering
33 * environment. It's functionality is similar to the ByteBuffer and related
34 * NIO classes. However, the methods in this class perform little to no
35 * alignment or bounds checks for performance reasons. Therefore, it is
36 * the caller's responsibility to ensure that all put() calls are properly
37 * aligned and within bounds:
38 * - int and float values must be aligned on 4-byte boundaries
39 * - long and double values must be aligned on 8-byte boundaries
40 *
41 * This class only includes the bare minimum of methods to support
42 * single-threaded rendering. For example, there is no put(double[]) method
43 * because we currently have no need for such a method in the STR classes.
44 */
45public class RenderBuffer {
46
47 /**
48 * These constants represent the size of various data types (in bytes).
49 */
50 protected static final long SIZEOF_BYTE = 1L;
51 protected static final long SIZEOF_SHORT = 2L;
52 protected static final long SIZEOF_INT = 4L;
53 protected static final long SIZEOF_FLOAT = 4L;
54 protected static final long SIZEOF_LONG = 8L;
55 protected static final long SIZEOF_DOUBLE = 8L;
56
57 /**
58 * Represents the number of elements at which we have empirically
59 * determined that the average cost of a JNI call exceeds the expense
60 * of an element by element copy. In other words, if the number of
61 * elements in an array to be copied exceeds this value, then we should
62 * use the copyFromArray() method to complete the bulk put operation.
63 * (This value can be adjusted if the cost of JNI downcalls is reduced
64 * in a future release.)
65 */
66 private static final int COPY_FROM_ARRAY_THRESHOLD = 6;
67
68 protected final Unsafe unsafe;
69 protected final long baseAddress;
70 protected final long endAddress;
71 protected long curAddress;
72 protected final int capacity;
73
74 protected RenderBuffer(int numBytes) {
75 unsafe = Unsafe.getUnsafe();
76 curAddress = baseAddress = unsafe.allocateMemory(numBytes);
77 endAddress = baseAddress + numBytes;
78 capacity = numBytes;
79 }
80
81 /**
82 * Allocates a fresh buffer using the machine endianness.
83 */
84 public static RenderBuffer allocate(int numBytes) {
85 return new RenderBuffer(numBytes);
86 }
87
88 /**
89 * Returns the base address of the underlying memory buffer.
90 */
91 public final long getAddress() {
92 return baseAddress;
93 }
94
95 /**
96 * The behavior (and names) of the following methods are nearly
97 * identical to their counterparts in the various NIO Buffer classes.
98 */
99
100 public final int capacity() {
101 return capacity;
102 }
103
104 public final int remaining() {
105 return (int)(endAddress - curAddress);
106 }
107
108 public final int position() {
109 return (int)(curAddress - baseAddress);
110 }
111
112 public final void position(long numBytes) {
113 curAddress = baseAddress + numBytes;
114 }
115
116 public final void clear() {
117 curAddress = baseAddress;
118 }
119
120 public final RenderBuffer skip(long numBytes) {
121 curAddress += numBytes;
122 return this;
123 }
124
125 /**
126 * putByte() methods...
127 */
128
129 public final RenderBuffer putByte(byte x) {
130 unsafe.putByte(curAddress, x);
131 curAddress += SIZEOF_BYTE;
132 return this;
133 }
134
135 public RenderBuffer put(byte[] x) {
136 return put(x, 0, x.length);
137 }
138
139 public RenderBuffer put(byte[] x, int offset, int length) {
140 if (length > COPY_FROM_ARRAY_THRESHOLD) {
141 long offsetInBytes = offset * SIZEOF_BYTE + Unsafe.ARRAY_BYTE_BASE_OFFSET;
142 long lengthInBytes = length * SIZEOF_BYTE;
143 unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
144 position(position() + lengthInBytes);
145 } else {
146 int end = offset + length;
147 for (int i = offset; i < end; i++) {
148 putByte(x[i]);
149 }
150 }
151 return this;
152 }
153
154 /**
155 * putShort() methods...
156 */
157
158 public final RenderBuffer putShort(short x) {
159 // assert (position() % SIZEOF_SHORT == 0);
160 unsafe.putShort(curAddress, x);
161 curAddress += SIZEOF_SHORT;
162 return this;
163 }
164
165 public RenderBuffer put(short[] x) {
166 return put(x, 0, x.length);
167 }
168
169 public RenderBuffer put(short[] x, int offset, int length) {
170 // assert (position() % SIZEOF_SHORT == 0);
171 if (length > COPY_FROM_ARRAY_THRESHOLD) {
172 long offsetInBytes = offset * SIZEOF_SHORT + Unsafe.ARRAY_SHORT_BASE_OFFSET;
173 long lengthInBytes = length * SIZEOF_SHORT;
174 unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
175 position(position() + lengthInBytes);
176 } else {
177 int end = offset + length;
178 for (int i = offset; i < end; i++) {
179 putShort(x[i]);
180 }
181 }
182 return this;
183 }
184
185 /**
186 * putInt() methods...
187 */
188
189 public final RenderBuffer putInt(int pos, int x) {
190 // assert (baseAddress + pos % SIZEOF_INT == 0);
191 unsafe.putInt(baseAddress + pos, x);
192 return this;
193 }
194
195 public final RenderBuffer putInt(int x) {
196 // assert (position() % SIZEOF_INT == 0);
197 unsafe.putInt(curAddress, x);
198 curAddress += SIZEOF_INT;
199 return this;
200 }
201
202 public RenderBuffer put(int[] x) {
203 return put(x, 0, x.length);
204 }
205
206 public RenderBuffer put(int[] x, int offset, int length) {
207 // assert (position() % SIZEOF_INT == 0);
208 if (length > COPY_FROM_ARRAY_THRESHOLD) {
209 long offsetInBytes = offset * SIZEOF_INT + Unsafe.ARRAY_INT_BASE_OFFSET;
210 long lengthInBytes = length * SIZEOF_INT;
211 unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
212 position(position() + lengthInBytes);
213 } else {
214 int end = offset + length;
215 for (int i = offset; i < end; i++) {
216 putInt(x[i]);
217 }
218 }
219 return this;
220 }
221
222 /**
223 * putFloat() methods...
224 */
225
226 public final RenderBuffer putFloat(float x) {
227 // assert (position() % SIZEOF_FLOAT == 0);
228 unsafe.putFloat(curAddress, x);
229 curAddress += SIZEOF_FLOAT;
230 return this;
231 }
232
233 public RenderBuffer put(float[] x) {
234 return put(x, 0, x.length);
235 }
236
237 public RenderBuffer put(float[] x, int offset, int length) {
238 // assert (position() % SIZEOF_FLOAT == 0);
239 if (length > COPY_FROM_ARRAY_THRESHOLD) {
240 long offsetInBytes = offset * SIZEOF_FLOAT + Unsafe.ARRAY_FLOAT_BASE_OFFSET;
241 long lengthInBytes = length * SIZEOF_FLOAT;
242 unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
243 position(position() + lengthInBytes);
244 } else {
245 int end = offset + length;
246 for (int i = offset; i < end; i++) {
247 putFloat(x[i]);
248 }
249 }
250 return this;
251 }
252
253 /**
254 * putLong() methods...
255 */
256
257 public final RenderBuffer putLong(long x) {
258 // assert (position() % SIZEOF_LONG == 0);
259 unsafe.putLong(curAddress, x);
260 curAddress += SIZEOF_LONG;
261 return this;
262 }
263
264 public RenderBuffer put(long[] x) {
265 return put(x, 0, x.length);
266 }
267
268 public RenderBuffer put(long[] x, int offset, int length) {
269 // assert (position() % SIZEOF_LONG == 0);
270 if (length > COPY_FROM_ARRAY_THRESHOLD) {
271 long offsetInBytes = offset * SIZEOF_LONG + Unsafe.ARRAY_LONG_BASE_OFFSET;
272 long lengthInBytes = length * SIZEOF_LONG;
273 unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
274 position(position() + lengthInBytes);
275 } else {
276 int end = offset + length;
277 for (int i = offset; i < end; i++) {
278 putLong(x[i]);
279 }
280 }
281 return this;
282 }
283
284 /**
285 * putDouble() method(s)...
286 */
287
288 public final RenderBuffer putDouble(double x) {
289 // assert (position() % SIZEOF_DOUBLE == 0);
290 unsafe.putDouble(curAddress, x);
291 curAddress += SIZEOF_DOUBLE;
292 return this;
293 }
294}
java/pkg/sun/java2d/pipe/RenderQueue.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderQueue.java+223−0
@@ -0,0 +1,223 @@
1/*
2 * Copyright (c) 2005, 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
26package sun.java2d.pipe;
27
28import java.util.HashSet;
29import java.util.Set;
30import sun.awt.SunToolkit;
31
32/**
33 * The RenderQueue class encapsulates a RenderBuffer on which rendering
34 * operations are enqueued. Note that the RenderQueue lock must be acquired
35 * before performing any operations on the queue (e.g. enqueuing an operation
36 * or flushing the queue). A sample usage scenario follows:
37 *
38 * public void drawSomething(...) {
39 * rq.lock();
40 * try {
41 * ctx.validate(...);
42 * rq.ensureCapacity(4);
43 * rq.getBuffer().putInt(DRAW_SOMETHING);
44 * ...
45 * } finally {
46 * rq.unlock();
47 * }
48 * }
49 *
50 * If you are enqueuing an operation that involves 8-byte parameters (i.e.
51 * long or double values), it is imperative that you ensure proper
52 * alignment of the underlying RenderBuffer. This can be accomplished
53 * simply by providing an offset to the first 8-byte parameter in your
54 * operation to the ensureCapacityAndAlignment() method. For example:
55 *
56 * public void drawStuff(...) {
57 * rq.lock();
58 * try {
59 * RenderBuffer buf = rq.getBuffer();
60 * ctx.validate(...);
61 * // 28 total bytes in the operation, 12 bytes to the first long
62 * rq.ensureCapacityAndAlignment(28, 12);
63 * buf.putInt(DRAW_STUFF);
64 * buf.putInt(x).putInt(y);
65 * buf.putLong(addr1);
66 * buf.putLong(addr2);
67 * } finally {
68 * rq.unlock();
69 * }
70 * }
71 */
72public abstract class RenderQueue {
73
74 /** The size of the underlying buffer, in bytes. */
75 private static final int BUFFER_SIZE = 32000;
76
77 /** The underlying buffer for this queue. */
78 protected RenderBuffer buf;
79
80 /**
81 * A Set containing hard references to Objects that must stay alive until
82 * the queue has been completely flushed.
83 */
84 protected Set refSet;
85
86 protected RenderQueue() {
87 refSet = new HashSet();
88 buf = RenderBuffer.allocate(BUFFER_SIZE);
89 }
90
91 /**
92 * Locks the queue for read/write access.
93 */
94 public final void lock() {
95 /*
96 * Implementation note: In theory we should have two separate locks:
97 * one lock to synchronize access to the RenderQueue, and then a
98 * separate lock (the AWT lock) that only needs to be acquired when
99 * we are about to flush the queue (using native windowing system
100 * operations). In practice it has been difficult to enforce the
101 * correct lock ordering; sometimes AWT will have already acquired
102 * the AWT lock before grabbing the RQ lock (see 6253009), while the
103 * expected order should be RQ lock and then AWT lock. Due to this
104 * issue, using two separate locks is prone to deadlocks. Therefore,
105 * to solve this issue we have decided to eliminate the separate RQ
106 * lock and instead just acquire the AWT lock here. (Someday it might
107 * be nice to go back to the old two-lock system, but that would
108 * require potentially risky changes to AWT to ensure that it never
109 * acquires the AWT lock before calling into 2D code that wants to
110 * acquire the RQ lock.)
111 */
112 SunToolkit.awtLock();
113 }
114
115 /**
116 * Attempts to lock the queue. If successful, this method returns true,
117 * indicating that the caller is responsible for calling
118 * <code>unlock</code>; otherwise this method returns false.
119 */
120 public final boolean tryLock() {
121 return SunToolkit.awtTryLock();
122 }
123
124 /**
125 * Unlocks the queue.
126 */
127 public final void unlock() {
128 SunToolkit.awtUnlock();
129 }
130
131 /**
132 * Adds the given Object to the set of hard references, which will
133 * prevent that Object from being disposed until the queue has been
134 * flushed completely. This is useful in cases where some enqueued
135 * data could become invalid if the reference Object were garbage
136 * collected before the queue could be processed. (For example, keeping
137 * a hard reference to a FontStrike will prevent any enqueued glyph
138 * images associated with that strike from becoming invalid before the
139 * queue is flushed.) The reference set will be cleared immediately
140 * after the queue is flushed each time.
141 */
142 public final void addReference(Object ref) {
143 refSet.add(ref);
144 }
145
146 /**
147 * Returns the encapsulated RenderBuffer object.
148 */
149 public final RenderBuffer getBuffer() {
150 return buf;
151 }
152
153 /**
154 * Ensures that there will be enough room on the underlying buffer
155 * for the following operation. If the operation will not fit given
156 * the remaining space, the buffer will be flushed immediately, leaving
157 * an empty buffer for the impending operation.
158 *
159 * @param opsize size (in bytes) of the following operation
160 */
161 public final void ensureCapacity(int opsize) {
162 if (buf.remaining() < opsize) {
163 flushNow();
164 }
165 }
166
167 /**
168 * Convenience method that is equivalent to calling ensureCapacity()
169 * followed by ensureAlignment(). The ensureCapacity() call allows for an
170 * extra 4 bytes of space in case the ensureAlignment() method needs to
171 * insert a NOOP token on the buffer.
172 *
173 * @param opsize size (in bytes) of the following operation
174 * @param first8ByteValueOffset offset (in bytes) from the current
175 * position to the first 8-byte value used in the following operation
176 */
177 public final void ensureCapacityAndAlignment(int opsize,
178 int first8ByteValueOffset)
179 {
180 ensureCapacity(opsize + 4);
181 ensureAlignment(first8ByteValueOffset);
182 }
183
184 /**
185 * Inserts a 4-byte NOOP token when necessary to ensure that all 8-byte
186 * parameters for the following operation are added to the underlying
187 * buffer with an 8-byte memory alignment.
188 *
189 * @param first8ByteValueOffset offset (in bytes) from the current
190 * position to the first 8-byte value used in the following operation
191 */
192 public final void ensureAlignment(int first8ByteValueOffset) {
193 int first8ByteValuePosition = buf.position() + first8ByteValueOffset;
194 if ((first8ByteValuePosition & 7) != 0) {
195 buf.putInt(BufferedOpCodes.NOOP);
196 }
197 }
198
199 /**
200 * Immediately processes each operation currently pending on the buffer.
201 * This method will block until the entire buffer has been flushed. The
202 * queue lock must be acquired before calling this method.
203 */
204 public abstract void flushNow();
205
206 /**
207 * Immediately processes each operation currently pending on the buffer,
208 * and then invokes the provided task. This method will block until the
209 * entire buffer has been flushed and the provided task has been executed.
210 * The queue lock must be acquired before calling this method.
211 */
212 public abstract void flushAndInvokeNow(Runnable task);
213
214 /**
215 * Updates the current position of the underlying buffer, and then
216 * flushes the queue immediately. This method is useful when native code
217 * has added data to the queue and needs to flush immediately.
218 */
219 public void flushNow(int position) {
220 buf.position(position);
221 flushNow();
222 }
223}
java/pkg/sun/java2d/pipe/RenderingEngine$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderingEngine$Tracer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderingEngine.class+0−0

Binary file not shown.

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
26package sun.java2d.pipe;
27
28import java.awt.Shape;
29import java.awt.BasicStroke;
30import java.awt.geom.PathIterator;
31import java.awt.geom.AffineTransform;
32
33import java.security.PrivilegedAction;
34import java.security.AccessController;
35import java.util.ServiceLoader;
36import sun.security.action.GetPropertyAction;
37
38import 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 */
86public 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}
java/pkg/sun/java2d/pipe/ShapeDrawPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/ShapeDrawPipe.java+40−0
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 1997, 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
26package sun.java2d.pipe;
27
28import java.awt.Shape;
29import sun.java2d.SunGraphics2D;
30
31/**
32 * This interface defines the set of calls that pipeline objects
33 * can use to pass on responsibility for drawing generic Shape
34 * objects.
35 */
36public interface ShapeDrawPipe {
37 public void draw(SunGraphics2D sg, Shape s);
38
39 public void fill(SunGraphics2D sg, Shape s);
40}
java/pkg/sun/java2d/pipe/ShapeSpanIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/ShapeSpanIterator.java+201−0
@@ -0,0 +1,201 @@
1/*
2 * Copyright (c) 1998, 2007, 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
26package sun.java2d.pipe;
27
28import java.awt.geom.PathIterator;
29import java.awt.Rectangle;
30import sun.awt.geom.PathConsumer2D;
31
32/**
33 * This class can iterate individual span elements generated by scan
34 * converting a Shape.
35 * This particular implementation flattens the incoming path and then
36 * performs simple polygon tracing to calculate the spans.
37 *
38 * Note that this class holds pointers to native data which must be
39 * disposed. It is not marked as finalizable since it is intended
40 * to be very lightweight and finalization is a comparitively expensive
41 * procedure. The caller must specifically use try{} finally{} to
42 * manually ensure that the object is disposed after use, otherwise
43 * native data structures might be leaked.
44 *
45 * Here is a code sample for using this class:
46 *
47 * public void fillShape(Shape s, Rectangle clipRect) {
48 * ShapeSpanIterator ssi = new ShapeSpanIterator(false);
49 * try {
50 * ssi.setOutputArea(clipRect);
51 * ssi.appendPath(s.getPathIterator(null));
52 * int spanbox[] = new int[4];
53 * while (ssi.nextSpan(spanbox)) {
54 * int x = spanbox[0];
55 * int y = spanbox[1];
56 * int w = spanbox[2] - x;
57 * int h = spanbox[3] - y;
58 * fillRect(x, y, w, h);
59 * }
60 * } finally {
61 * ssi.dispose();
62 * }
63 * }
64 */
65public final class ShapeSpanIterator
66 implements SpanIterator, PathConsumer2D
67{
68 long pData;
69
70 static {
71 initIDs();
72 }
73
74 public static native void initIDs();
75
76 public ShapeSpanIterator(boolean adjust) {
77 setNormalize(adjust);
78 }
79
80 /*
81 * Appends the geometry and winding rule from the indicated
82 * path iterator.
83 */
84 public void appendPath(PathIterator pi) {
85 float coords[] = new float[6];
86
87 setRule(pi.getWindingRule());
88 while (!pi.isDone()) {
89 addSegment(pi.currentSegment(coords), coords);
90 pi.next();
91 }
92 pathDone();
93 }
94
95 /*
96 * Appends the geometry from the indicated set of polygon points.
97 */
98 public native void appendPoly(int xPoints[], int yPoints[], int nPoints,
99 int xoff, int yoff);
100
101 /*
102 * Sets the normalization flag so that incoming data is
103 * adjusted to nearest (0.25, 0.25) subpixel position.
104 */
105 private native void setNormalize(boolean adjust);
106
107 /*
108 * Sets the rectangle of interest for storing and returning
109 * span segments.
110 */
111 public void setOutputAreaXYWH(int x, int y, int w, int h) {
112 setOutputAreaXYXY(x, y, Region.dimAdd(x, w), Region.dimAdd(y, h));
113 }
114
115 /*
116 * Sets the rectangle of interest for storing and returning
117 * span segments.
118 */
119 public native void setOutputAreaXYXY(int lox, int loy, int hix, int hiy);
120
121 /*
122 * Sets the rectangle of interest for storing and returning
123 * span segments to the specified Rectangle.
124 */
125 public void setOutputArea(Rectangle r) {
126 setOutputAreaXYWH(r.x, r.y, r.width, r.height);
127 }
128
129 /*
130 * Sets the rectangle of interest for storing and returning
131 * span segments to the bounds of the specified Region.
132 */
133 public void setOutputArea(Region r) {
134 setOutputAreaXYXY(r.lox, r.loy, r.hix, r.hiy);
135 }
136
137 /*
138 * Sets the winding rule in the native data structures.
139 */
140 public native void setRule(int rule);
141
142 /*
143 * Adds a single PathIterator segment to the internal list of
144 * path element structures.
145 */
146 public native void addSegment(int type, float coords[]);
147
148 /*
149 * Gets the bbox of the available path segments, clipped to the
150 * OutputArea.
151 */
152 public native void getPathBox(int pathbox[]);
153
154 /*
155 * Intersects the path box with the given bbox.
156 * Returned spans are clipped to this region, or discarded
157 * altogether if they lie outside it.
158 */
159 public native void intersectClipBox(int lox, int loy, int hix, int hiy);
160
161 /*
162 * Fetches the next span that needs to be operated on.
163 * If the return value is false then there are no more spans.
164 */
165 public native boolean nextSpan(int spanbox[]);
166
167 /**
168 * This method tells the iterator that it may skip all spans
169 * whose Y range is completely above the indicated Y coordinate.
170 */
171 public native void skipDownTo(int y);
172
173 /**
174 * This method returns a native pointer to a function block that
175 * can be used by a native method to perform the same iteration
176 * cycle that the above methods provide while avoiding upcalls to
177 * the Java object.
178 * The definition of the structure whose pointer is returned by
179 * this method is defined in:
180 * <pre>
181 * src/share/native/sun/java2d/pipe/SpanIterator.h
182 * </pre>
183 */
184 public native long getNativeIterator();
185
186 /*
187 * Cleans out all internal data structures.
188 */
189 public native void dispose();
190
191 public native void moveTo(float x, float y);
192 public native void lineTo(float x, float y);
193 public native void quadTo(float x1, float y1,
194 float x2, float y2);
195 public native void curveTo(float x1, float y1,
196 float x2, float y2,
197 float x3, float y3);
198 public native void closePath();
199 public native void pathDone();
200 public native long getNativeConsumer();
201}
java/pkg/sun/java2d/pipe/SolidTextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SolidTextRenderer.java+44−0
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2000, 2005, 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
26package sun.java2d.pipe;
27
28import java.awt.font.GlyphVector;
29import sun.awt.SunHints;
30import sun.java2d.SunGraphics2D;
31import sun.font.GlyphList;
32
33/**
34 * A delegate pipe of SG2D for drawing text with
35 * a solid source colour to an opaque destination.
36 */
37
38public class SolidTextRenderer extends GlyphListLoopPipe
39 implements LoopBasedPipe
40{
41 protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
42 sg2d.loops.drawGlyphListLoop.DrawGlyphList(sg2d, sg2d.surfaceData, gl);
43 }
44}
java/pkg/sun/java2d/pipe/SpanClipRenderer$SCRcontext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanClipRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanClipRenderer.java+141−0
@@ -0,0 +1,141 @@
1/*
2 * Copyright (c) 1998, 1999, 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
26package sun.java2d.pipe;
27
28import java.awt.Rectangle;
29import java.awt.Shape;
30import java.awt.geom.PathIterator;
31import sun.java2d.SunGraphics2D;
32
33/**
34 * This class uses a Region iterator to modify the extents of alpha
35 * tiles created during Shape rendering based upon a non-rectangular
36 * clipping path.
37 */
38public class SpanClipRenderer implements CompositePipe
39{
40 CompositePipe outpipe;
41
42 static Class RegionClass = Region.class;
43 static Class RegionIteratorClass = RegionIterator.class;
44
45 static {
46 initIDs(RegionClass, RegionIteratorClass);
47 }
48
49 static native void initIDs(Class rc, Class ric);
50
51 public SpanClipRenderer(CompositePipe pipe) {
52 outpipe = pipe;
53 }
54
55 class SCRcontext {
56 RegionIterator iterator;
57 Object outcontext;
58 int band[];
59 byte tile[];
60
61 public SCRcontext(RegionIterator ri, Object outctx) {
62 iterator = ri;
63 outcontext = outctx;
64 band = new int[4];
65 }
66 }
67
68 public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR,
69 int[] abox) {
70 RegionIterator ri = sg.clipRegion.getIterator();
71
72 return new SCRcontext(ri, outpipe.startSequence(sg, s, devR, abox));
73 }
74
75 public boolean needTile(Object ctx, int x, int y, int w, int h) {
76 SCRcontext context = (SCRcontext) ctx;
77 return (outpipe.needTile(context.outcontext, x, y, w, h));
78 }
79
80 public void renderPathTile(Object ctx,
81 byte[] atile, int offset, int tsize,
82 int x, int y, int w, int h,
83 ShapeSpanIterator sr) {
84 renderPathTile(ctx, atile, offset, tsize, x, y, w, h);
85 }
86
87 public void renderPathTile(Object ctx,
88 byte[] atile, int offset, int tsize,
89 int x, int y, int w, int h) {
90 SCRcontext context = (SCRcontext) ctx;
91 RegionIterator ri = context.iterator.createCopy();
92 int[] band = context.band;
93 band[0] = x;
94 band[1] = y;
95 band[2] = x + w;
96 band[3] = y + h;
97 if (atile == null) {
98 int size = w * h;
99 atile = context.tile;
100 if (atile != null && atile.length < size) {
101 atile = null;
102 }
103 if (atile == null) {
104 atile = new byte[size];
105 context.tile = atile;
106 }
107 offset = 0;
108 tsize = w;
109 fillTile(ri, atile, offset, tsize, band);
110 } else {
111 eraseTile(ri, atile, offset, tsize, band);
112 }
113
114 if (band[2] > band[0] && band[3] > band[1]) {
115 offset += (band[1] - y) * tsize + (band[0] - x);
116 outpipe.renderPathTile(context.outcontext,
117 atile, offset, tsize,
118 band[0], band[1],
119 band[2] - band[0],
120 band[3] - band[1]);
121 }
122 }
123
124 public native void fillTile(RegionIterator ri,
125 byte[] alpha, int offset, int tsize,
126 int[] band);
127
128 public native void eraseTile(RegionIterator ri,
129 byte[] alpha, int offset, int tsize,
130 int[] band);
131
132 public void skipTile(Object ctx, int x, int y) {
133 SCRcontext context = (SCRcontext) ctx;
134 outpipe.skipTile(context.outcontext, x, y);
135 }
136
137 public void endSequence(Object ctx) {
138 SCRcontext context = (SCRcontext) ctx;
139 outpipe.endSequence(context.outcontext);
140 }
141}
java/pkg/sun/java2d/pipe/SpanIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanIterator.java+95−0
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) 1998, 1999, 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
26package sun.java2d.pipe;
27
28/**
29 * This interface defines a general method for iterating through the
30 * rectangular "spans" that represent the interior of a filled path.
31 * <p>
32 * There can be many kinds of span iterators used in the rendering
33 * pipeline, the most basic being an iterator that scan converts a
34 * path defined by any PathIterator, or an nested iterator which
35 * intersects another iterator's spans with a clip region.
36 * Other iterators can be created for scan converting some of the
37 * primitive shapes more explicitly for speed or quality.
38 *
39 * @author Jim Graham
40 */
41public interface SpanIterator {
42 /**
43 * This method returns the bounding box of the spans that the
44 * iterator will be returning.
45 * The array must be of length at least 4 and upon return, it
46 * will be filled with the values:
47 * <pre>
48 * {PathMinX, PathMinY, PathMaxX, PathMaxY}.
49 * </pre>
50 */
51 public void getPathBox(int pathbox[]);
52
53 /**
54 * This method constrains the spans returned by nextSpan() to the
55 * rectangle whose bounds are given.
56 */
57 public void intersectClipBox(int lox, int loy, int hix, int hiy);
58
59 /**
60 * This method returns the next span in the shape being iterated.
61 * The array must be of length at least 4 and upon return, it
62 * will be filled with the values:
63 * <pre>
64 * {SpanMinX, SpanMinY, SpanMaxX, SpanMaxY}.
65 * </pre>
66 */
67 public boolean nextSpan(int spanbox[]);
68
69 /**
70 * This method tells the iterator that it may skip all spans
71 * whose Y range is completely above the indicated Y coordinate.
72 * This method is used to provide feedback from the caller when
73 * clipping prevents the display of any data in a given Y range.
74 * Typically it will only be called when this iterator has returned
75 * a span whose MaxY coordinate is less than the indicated Y and
76 * the calling mechanism wants to avoid unnecessary iteration work.
77 * While this request could technically be ignored (i.e. a NOP),
78 * doing so could potentially cause the caller to make this callback
79 * for each span that is being skipped.
80 */
81 public void skipDownTo(int y);
82
83 /**
84 * This method returns a native pointer to a function block that
85 * can be used by a native method to perform the same iteration
86 * cycle that the above methods provide while avoiding upcalls to
87 * the Java object.
88 * The definition of the structure whose pointer is returned by
89 * this method is defined in:
90 * <pre>
91 * src/share/native/sun/java2d/pipe/SpanIterator.h
92 * </pre>
93 */
94 public long getNativeIterator();
95}
java/pkg/sun/java2d/pipe/SpanShapeRenderer$Composite.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanShapeRenderer$Simple.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanShapeRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanShapeRenderer.java+216−0
@@ -0,0 +1,216 @@
1/*
2 * Copyright (c) 1998, 2007, 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
26package sun.java2d.pipe;
27
28import sun.java2d.SunGraphics2D;
29import sun.java2d.SurfaceData;
30import java.awt.Rectangle;
31import java.awt.Shape;
32import java.awt.BasicStroke;
33import java.awt.geom.PathIterator;
34import java.awt.geom.AffineTransform;
35import java.awt.geom.Rectangle2D;
36import sun.awt.SunHints;
37
38/**
39 * This class is used to convert raw geometry into a span iterator
40 * object using a simple flattening polygon scan converter.
41 * The iterator can be passed on to special SpanFiller loops to
42 * perform the actual rendering.
43 */
44public abstract class SpanShapeRenderer implements ShapeDrawPipe {
45 final static RenderingEngine RenderEngine = RenderingEngine.getInstance();
46
47 public static class Composite extends SpanShapeRenderer {
48 CompositePipe comppipe;
49
50 public Composite(CompositePipe pipe) {
51 comppipe = pipe;
52 }
53
54 public Object startSequence(SunGraphics2D sg, Shape s,
55 Rectangle devR, int[] bbox) {
56 return comppipe.startSequence(sg, s, devR, bbox);
57 }
58
59 public void renderBox(Object ctx, int x, int y, int w, int h) {
60 comppipe.renderPathTile(ctx, null, 0, w, x, y, w, h);
61 }
62
63 public void endSequence(Object ctx) {
64 comppipe.endSequence(ctx);
65 }
66 }
67
68 public static class Simple extends SpanShapeRenderer
69 implements LoopBasedPipe
70 {
71 public Object startSequence(SunGraphics2D sg, Shape s,
72 Rectangle devR, int[] bbox) {
73 return sg;
74 }
75
76 public void renderBox(Object ctx, int x, int y, int w, int h) {
77 SunGraphics2D sg2d = (SunGraphics2D) ctx;
78 SurfaceData sd = sg2d.getSurfaceData();
79 sg2d.loops.fillRectLoop.FillRect(sg2d, sd, x, y, w, h);
80 }
81
82 public void endSequence(Object ctx) {
83 }
84 }
85
86 public void draw(SunGraphics2D sg, Shape s) {
87 if (sg.stroke instanceof BasicStroke) {
88 ShapeSpanIterator sr = LoopPipe.getStrokeSpans(sg, s);
89 try {
90 renderSpans(sg, sg.getCompClip(), s, sr);
91 } finally {
92 sr.dispose();
93 }
94 } else {
95 fill(sg, sg.stroke.createStrokedShape(s));
96 }
97 }
98
99 public static final int NON_RECTILINEAR_TRANSFORM_MASK =
100 (AffineTransform.TYPE_GENERAL_TRANSFORM |
101 AffineTransform.TYPE_GENERAL_ROTATION);
102
103 public void fill(SunGraphics2D sg, Shape s) {
104 if (s instanceof Rectangle2D &&
105 (sg.transform.getType() & NON_RECTILINEAR_TRANSFORM_MASK) == 0)
106 {
107 renderRect(sg, (Rectangle2D) s);
108 return;
109 }
110
111 Region clipRegion = sg.getCompClip();
112 ShapeSpanIterator sr = LoopPipe.getFillSSI(sg);
113 try {
114 sr.setOutputArea(clipRegion);
115 sr.appendPath(s.getPathIterator(sg.transform));
116 renderSpans(sg, clipRegion, s, sr);
117 } finally {
118 sr.dispose();
119 }
120 }
121
122 public abstract Object startSequence(SunGraphics2D sg, Shape s,
123 Rectangle devR, int[] bbox);
124
125 public abstract void renderBox(Object ctx, int x, int y, int w, int h);
126
127 public abstract void endSequence(Object ctx);
128
129 public void renderRect(SunGraphics2D sg, Rectangle2D r) {
130 double corners[] = {
131 r.getX(), r.getY(), r.getWidth(), r.getHeight(),
132 };
133 corners[2] += corners[0];
134 corners[3] += corners[1];
135 if (corners[2] <= corners[0] || corners[3] <= corners[1]) {
136 return;
137 }
138 sg.transform.transform(corners, 0, corners, 0, 2);
139 if (corners[2] < corners[0]) {
140 double t = corners[2];
141 corners[2] = corners[0];
142 corners[0] = t;
143 }
144 if (corners[3] < corners[1]) {
145 double t = corners[3];
146 corners[3] = corners[1];
147 corners[1] = t;
148 }
149 int abox[] = {
150 (int) corners[0],
151 (int) corners[1],
152 (int) corners[2],
153 (int) corners[3],
154 };
155 Rectangle devR = new Rectangle(abox[0], abox[1],
156 abox[2] - abox[0],
157 abox[3] - abox[1]);
158 Region clipRegion = sg.getCompClip();
159 clipRegion.clipBoxToBounds(abox);
160 if (abox[0] >= abox[2] || abox[1] >= abox[3]) {
161 return;
162 }
163 Object context = startSequence(sg, r, devR, abox);
164 if (clipRegion.isRectangular()) {
165 renderBox(context, abox[0], abox[1],
166 abox[2] - abox[0],
167 abox[3] - abox[1]);
168 } else {
169 SpanIterator sr = clipRegion.getSpanIterator(abox);
170 while (sr.nextSpan(abox)) {
171 renderBox(context, abox[0], abox[1],
172 abox[2] - abox[0],
173 abox[3] - abox[1]);
174 }
175 }
176 endSequence(context);
177 }
178
179 public void renderSpans(SunGraphics2D sg, Region clipRegion, Shape s,
180 ShapeSpanIterator sr)
181 {
182 Object context = null;
183 int abox[] = new int[4];
184 try {
185 sr.getPathBox(abox);
186 Rectangle devR = new Rectangle(abox[0], abox[1],
187 abox[2] - abox[0],
188 abox[3] - abox[1]);
189 clipRegion.clipBoxToBounds(abox);
190 if (abox[0] >= abox[2] || abox[1] >= abox[3]) {
191 return;
192 }
193 sr.intersectClipBox(abox[0], abox[1], abox[2], abox[3]);
194 context = startSequence(sg, s, devR, abox);
195
196 spanClipLoop(context, sr, clipRegion, abox);
197
198 } finally {
199 if (context != null) {
200 endSequence(context);
201 }
202 }
203 }
204
205 public void spanClipLoop(Object ctx, SpanIterator sr,
206 Region r, int[] abox) {
207 if (!r.isRectangular()) {
208 sr = r.filter(sr);
209 }
210 while (sr.nextSpan(abox)) {
211 int x = abox[0];
212 int y = abox[1];
213 renderBox(ctx, x, y, abox[2] - x, abox[3] - y);
214 }
215 }
216}
java/pkg/sun/java2d/pipe/TextPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/TextPipe.java+49−0
@@ -0,0 +1,49 @@
1/*
2 * Copyright (c) 1998, 2003, 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/*
27 * @author Charlton Innovations, Inc.
28 */
29
30package sun.java2d.pipe;
31
32import sun.java2d.SunGraphics2D;
33import java.awt.font.GlyphVector;
34import java.awt.font.TextLayout;
35
36/**
37 * This interface defines the set of calls that pipeline objects
38 * can use to pass on responsibility for drawing various text
39 * representations.
40 */
41public interface TextPipe {
42 public void drawString(SunGraphics2D g2d, String s,
43 double x, double y);
44 public void drawGlyphVector(SunGraphics2D g2d, GlyphVector g,
45 float x, float y);
46 public void drawChars(SunGraphics2D g2d,
47 char data[], int offset, int length,
48 int x, int y);
49}
java/pkg/sun/java2d/pipe/TextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/TextRenderer.java+98−0
@@ -0,0 +1,98 @@
1/*
2 * Copyright (c) 2000, 2003, 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
26package sun.java2d.pipe;
27
28import java.awt.Rectangle;
29import java.awt.Shape;
30import java.awt.Font;
31import java.awt.font.GlyphVector;
32import sun.java2d.SunGraphics2D;
33import sun.java2d.loops.FontInfo;
34import sun.font.GlyphList;
35
36/*
37 * This class uses the alpha graybits arrays from a GlyphList object to
38 * drive a CompositePipe in much the same way as the antialiasing renderer.
39 */
40public class TextRenderer extends GlyphListPipe {
41
42 CompositePipe outpipe;
43
44 public TextRenderer(CompositePipe pipe) {
45 outpipe = pipe;
46 }
47
48 protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
49 int num = gl.getNumGlyphs();
50 Region clipRegion = sg2d.getCompClip();
51 int cx1 = clipRegion.getLoX();
52 int cy1 = clipRegion.getLoY();
53 int cx2 = clipRegion.getHiX();
54 int cy2 = clipRegion.getHiY();
55 Object ctx = null;
56 try {
57 int[] bounds = gl.getBounds();
58 Rectangle r = new Rectangle(bounds[0], bounds[1],
59 bounds[2] - bounds[0],
60 bounds[3] - bounds[1]);
61 Shape s = sg2d.untransformShape(r);
62 ctx = outpipe.startSequence(sg2d, s, r, bounds);
63 for (int i = 0; i < num; i++) {
64 gl.setGlyphIndex(i);
65 int metrics[] = gl.getMetrics();
66 int gx1 = metrics[0];
67 int gy1 = metrics[1];
68 int w = metrics[2];
69 int gx2 = gx1 + w;
70 int gy2 = gy1 + metrics[3];
71 int off = 0;
72 if (gx1 < cx1) {
73 off = cx1 - gx1;
74 gx1 = cx1;
75 }
76 if (gy1 < cy1) {
77 off += (cy1 - gy1) * w;
78 gy1 = cy1;
79 }
80 if (gx2 > cx2) gx2 = cx2;
81 if (gy2 > cy2) gy2 = cy2;
82 if (gx2 > gx1 && gy2 > gy1 &&
83 outpipe.needTile(ctx, gx1, gy1, gx2 - gx1, gy2 - gy1))
84 {
85 byte alpha[] = gl.getGrayBits();
86 outpipe.renderPathTile(ctx, alpha, off, w,
87 gx1, gy1, gx2 - gx1, gy2 - gy1);
88 } else {
89 outpipe.skipTile(ctx, gx1, gy1);
90 }
91 }
92 } finally {
93 if (ctx != null) {
94 outpipe.endSequence(ctx);
95 }
96 }
97 }
98}
java/pkg/sun/java2d/pipe/ValidatePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/ValidatePipe.java+241−0
@@ -0,0 +1,241 @@
1/*
2 * Copyright (c) 1997, 2003, 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
26package sun.java2d.pipe;
27
28import java.awt.Color;
29import java.awt.Image;
30import java.awt.Shape;
31import java.awt.geom.AffineTransform;
32import java.awt.image.BufferedImage;
33import java.awt.image.BufferedImageOp;
34import java.awt.image.ImageObserver;
35import sun.java2d.SunGraphics2D;
36import java.awt.font.GlyphVector;
37
38/**
39 * This class is used to force a revalidation of the pipelines of
40 * the indicated SunGraphics2D object before a draw command.
41 * After calling SunGraphics2D.validatePipe() to force the pipeline
42 * to be revalidated, this object redispatches the draw command to
43 * the new valid pipe object.
44 */
45public class ValidatePipe
46 implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe, TextPipe,
47 DrawImagePipe
48{
49 /*
50 * Different subclasses may override this to do various
51 * other forms of validation and return a return code
52 * indicating whether or not the validation was successful.
53 */
54 public boolean validate(SunGraphics2D sg) {
55 sg.validatePipe();
56 return true;
57 }
58
59 public void drawLine(SunGraphics2D sg,
60 int x1, int y1, int x2, int y2) {
61 if (validate(sg)) {
62 sg.drawpipe.drawLine(sg, x1, y1, x2, y2);
63 }
64 }
65
66 public void drawRect(SunGraphics2D sg,
67 int x, int y, int width, int height) {
68 if (validate(sg)) {
69 sg.drawpipe.drawRect(sg, x, y, width, height);
70 }
71 }
72
73 public void fillRect(SunGraphics2D sg,
74 int x, int y, int width, int height) {
75 if (validate(sg)) {
76 sg.fillpipe.fillRect(sg, x, y, width, height);
77 }
78 }
79
80 public void drawRoundRect(SunGraphics2D sg,
81 int x, int y, int width, int height,
82 int arcWidth, int arcHeight) {
83 if (validate(sg)) {
84 sg.drawpipe.drawRoundRect(sg, x, y, width, height,
85 arcWidth, arcHeight);
86 }
87 }
88
89 public void fillRoundRect(SunGraphics2D sg,
90 int x, int y, int width, int height,
91 int arcWidth, int arcHeight) {
92 if (validate(sg)) {
93 sg.fillpipe.fillRoundRect(sg, x, y, width, height,
94 arcWidth, arcHeight);
95 }
96 }
97
98 public void drawOval(SunGraphics2D sg,
99 int x, int y, int width, int height) {
100 if (validate(sg)) {
101 sg.drawpipe.drawOval(sg, x, y, width, height);
102 }
103 }
104
105 public void fillOval(SunGraphics2D sg,
106 int x, int y, int width, int height) {
107 if (validate(sg)) {
108 sg.fillpipe.fillOval(sg, x, y, width, height);
109 }
110 }
111
112 public void drawArc(SunGraphics2D sg,
113 int x, int y, int width, int height,
114 int startAngle, int arcAngle) {
115 if (validate(sg)) {
116 sg.drawpipe.drawArc(sg, x, y, width, height, startAngle, arcAngle);
117 }
118 }
119
120 public void fillArc(SunGraphics2D sg,
121 int x, int y, int width, int height,
122 int startAngle, int arcAngle) {
123 if (validate(sg)) {
124 sg.fillpipe.fillArc(sg, x, y, width, height, startAngle, arcAngle);
125 }
126 }
127
128 public void drawPolyline(SunGraphics2D sg,
129 int xPoints[], int yPoints[],
130 int nPoints) {
131 if (validate(sg)) {
132 sg.drawpipe.drawPolyline(sg, xPoints, yPoints, nPoints);
133 }
134 }
135
136 public void drawPolygon(SunGraphics2D sg,
137 int xPoints[], int yPoints[],
138 int nPoints) {
139 if (validate(sg)) {
140 sg.drawpipe.drawPolygon(sg, xPoints, yPoints, nPoints);
141 }
142 }
143
144 public void fillPolygon(SunGraphics2D sg,
145 int xPoints[], int yPoints[],
146 int nPoints) {
147 if (validate(sg)) {
148 sg.fillpipe.fillPolygon(sg, xPoints, yPoints, nPoints);
149 }
150 }
151
152 public void draw(SunGraphics2D sg, Shape s) {
153 if (validate(sg)) {
154 sg.shapepipe.draw(sg, s);
155 }
156 }
157
158 public void fill(SunGraphics2D sg, Shape s) {
159 if (validate(sg)) {
160 sg.shapepipe.fill(sg, s);
161 }
162 }
163 public void drawString(SunGraphics2D sg, String s, double x, double y) {
164 if (validate(sg)) {
165 sg.textpipe.drawString(sg, s, x, y);
166 }
167 }
168 public void drawGlyphVector(SunGraphics2D sg, GlyphVector g,
169 float x, float y) {
170 if (validate(sg)) {
171 sg.textpipe.drawGlyphVector(sg, g, x, y);
172 }
173 }
174 public void drawChars(SunGraphics2D sg,
175 char data[], int offset, int length,
176 int x, int y) {
177 if (validate(sg)) {
178 sg.textpipe.drawChars(sg, data, offset, length, x, y);
179 }
180 }
181 public boolean copyImage(SunGraphics2D sg, Image img,
182 int x, int y,
183 Color bgColor,
184 ImageObserver observer) {
185 if (validate(sg)) {
186 return sg.imagepipe.copyImage(sg, img, x, y, bgColor, observer);
187 } else {
188 return false;
189 }
190 }
191 public boolean copyImage(SunGraphics2D sg, Image img,
192 int dx, int dy, int sx, int sy, int w, int h,
193 Color bgColor,
194 ImageObserver observer) {
195 if (validate(sg)) {
196 return sg.imagepipe.copyImage(sg, img, dx, dy, sx, sy, w, h,
197 bgColor, observer);
198 } else {
199 return false;
200 }
201 }
202 public boolean scaleImage(SunGraphics2D sg, Image img, int x, int y,
203 int w, int h,
204 Color bgColor,
205 ImageObserver observer) {
206 if (validate(sg)) {
207 return sg.imagepipe.scaleImage(sg, img, x, y, w, h, bgColor,
208 observer);
209 } else {
210 return false;
211 }
212 }
213 public boolean scaleImage(SunGraphics2D sg, Image img,
214 int dx1, int dy1, int dx2, int dy2,
215 int sx1, int sy1, int sx2, int sy2,
216 Color bgColor,
217 ImageObserver observer) {
218 if (validate(sg)) {
219 return sg.imagepipe.scaleImage(sg, img, dx1, dy1, dx2, dy2,
220 sx1, sy1, sx2, sy2, bgColor,
221 observer);
222 } else {
223 return false;
224 }
225 }
226 public boolean transformImage(SunGraphics2D sg, Image img,
227 AffineTransform atfm,
228 ImageObserver observer) {
229 if (validate(sg)) {
230 return sg.imagepipe.transformImage(sg, img, atfm, observer);
231 } else {
232 return false;
233 }
234 }
235 public void transformImage(SunGraphics2D sg, BufferedImage img,
236 BufferedImageOp op, int x, int y) {
237 if (validate(sg)) {
238 sg.imagepipe.transformImage(sg, img, op, x, y);
239 }
240 }
241}
java/pkg/sun/java2d/pipe/hw/AccelDeviceEventListener.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/AccelDeviceEventListener.java+59−0
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 2007, 2008, 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
26package sun.java2d.pipe.hw;
27
28/**
29 * An interface for receiving notifications about imminent accelerated device's
30 * events. Upon receiving such event appropriate actions can be taken (for
31 * example, resources associated with the device can be freed).
32 */
33public interface AccelDeviceEventListener {
34 /**
35 * Called when the device is about to be reset.
36 *
37 * One must release all native resources associated with the device which
38 * prevent the device from being reset (such as Default Pool resources for
39 * the D3D pipeline).
40 *
41 * It is safe to remove the listener while in the call back.
42 *
43 * Note: this method is called on the rendering thread,
44 * do not call into user code, do not take RQ lock!
45 */
46 public void onDeviceReset();
47
48 /**
49 * Called when the device is about to be disposed of.
50 *
51 * One must release all native resources associated with the device.
52 *
53 * It is safe to remove the listener while in the call back.
54 *
55 * Note: this method is called on the rendering thread,
56 * do not call into user code, do not take RQ lock!
57 */
58 public void onDeviceDispose();
59}
java/pkg/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java+167−0
@@ -0,0 +1,167 @@
1/*
2 * Copyright (c) 2007, 2008, 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
26package sun.java2d.pipe.hw;
27
28import java.util.Collections;
29import java.util.HashMap;
30import java.util.Iterator;
31import java.util.Map;
32import java.util.Set;
33
34/**
35 * This class is used to notify listeners about accelerated device's
36 * events such as device reset or dispose that are about to occur.
37 */
38public class AccelDeviceEventNotifier {
39
40 private static AccelDeviceEventNotifier theInstance;
41
42 /**
43 * A device is about to be reset. The listeners have to release all
44 * resources associated with the device which are required for the device
45 * to be reset.
46 */
47 public static final int DEVICE_RESET = 0;
48
49 /**
50 * A device is about to be disposed. The listeners have to release all
51 * resources associated with the device.
52 */
53 public static final int DEVICE_DISPOSED = 1;
54
55 private final Map<AccelDeviceEventListener, Integer> listeners;
56
57 private AccelDeviceEventNotifier() {
58 listeners = Collections.synchronizedMap(
59 new HashMap<AccelDeviceEventListener, Integer>(1));
60 }
61
62 /**
63 * Returns a singleton of AccelDeviceEventNotifier if it exists. If the
64 * passed boolean is false and singleton doesn't exist yet, null is
65 * returned. If the passed boolean is {@code true} and singleton doesn't
66 * exist it will be created and returned.
67 *
68 * @param create whether to create a singleton instance if doesn't yet
69 * exist
70 * @return a singleton instance or null
71 */
72 private static synchronized
73 AccelDeviceEventNotifier getInstance(boolean create)
74 {
75 if (theInstance == null && create) {
76 theInstance = new AccelDeviceEventNotifier();
77 }
78 return theInstance;
79 }
80
81 /**
82 * Called to indicate that a device event had occured.
83 * If a singleton exists, the listeners (those associated with
84 * the device) will be notified.
85 *
86 * @param screen a screen number of the device which is a source of
87 * the event
88 * @param eventType a type of the event
89 * @see #DEVICE_DISPOSED
90 * @see #DEVICE_RESET
91 */
92 public static final void eventOccured(int screen, int eventType) {
93 AccelDeviceEventNotifier notifier = getInstance(false);
94 if (notifier != null) {
95 notifier.notifyListeners(eventType, screen);
96 }
97 }
98
99 /**
100 * Adds the listener associated with a device on particular screen.
101 *
102 * Note: the listener must be removed as otherwise it will forever
103 * be referenced by the notifier.
104 *
105 * @param l the listener
106 * @param screen the screen number indicating which device the listener is
107 * interested in.
108 */
109 public static final void addListener(AccelDeviceEventListener l,int screen){
110 getInstance(true).add(l, screen);
111 }
112
113 /**
114 * Removes the listener.
115 *
116 * @param l the listener
117 */
118 public static final void removeListener(AccelDeviceEventListener l) {
119 getInstance(true).remove(l);
120 }
121
122 private final void add(AccelDeviceEventListener theListener, int screen) {
123 listeners.put(theListener, screen);
124 }
125 private final void remove(AccelDeviceEventListener theListener) {
126 listeners.remove(theListener);
127 }
128
129 /**
130 * Notifies the listeners associated with the screen's device about the
131 * event.
132 *
133 * Implementation note: the current list of listeners is first duplicated
134 * which allows the listeners to remove themselves during the iteration.
135 *
136 * @param screen a screen number with which the device which is a source of
137 * the event is associated with
138 * @param eventType a type of the event
139 * @see #DEVICE_DISPOSED
140 * @see #DEVICE_RESET
141 */
142 private final void notifyListeners(int deviceEventType, int screen) {
143 HashMap<AccelDeviceEventListener, Integer> listClone;
144 Set<AccelDeviceEventListener> cloneSet;
145
146 synchronized(listeners) {
147 listClone =
148 new HashMap<AccelDeviceEventListener, Integer>(listeners);
149 }
150
151 cloneSet = listClone.keySet();
152 Iterator<AccelDeviceEventListener> itr = cloneSet.iterator();
153 while (itr.hasNext()) {
154 AccelDeviceEventListener current = itr.next();
155 Integer i = listClone.get(current);
156 // only notify listeners which are interested in this device
157 if (i != null && i.intValue() != screen) {
158 continue;
159 }
160 if (deviceEventType == DEVICE_RESET) {
161 current.onDeviceReset();
162 } else if (deviceEventType == DEVICE_DISPOSED) {
163 current.onDeviceDispose();
164 }
165 }
166 }
167}
java/pkg/sun/java2d/pipe/hw/AccelGraphicsConfig.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/AccelGraphicsConfig.java+95−0
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) 2007, 2008, 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
26package sun.java2d.pipe.hw;
27
28import java.awt.image.VolatileImage;
29
30/**
31 * Implementors of this interface provida a way to create a
32 * {@code VolatileImage} whose destination surface is an
33 * {@link AccelSurface} of specified type.
34 *
35 * @see AccelSurface
36 */
37public interface AccelGraphicsConfig extends BufferedContextProvider {
38 /**
39 * Returns a VolatileImage with specified width, height, transparency
40 * and guaranteed accelerated surface type. If such image can not be created
41 * (out of vram error, specific surface type is not supported) null
42 * is returned.
43 *
44 * Note: if {@link AccelSurface#TEXTURE} type is requested, rendering
45 * to the image will be denied by throwing
46 * {@code UnsupportedOperationException }
47 * from {@link java.awt.image.VolatileImage#getGraphics} and
48 * {@link java.awt.image.VolatileImage#createGraphics}
49 *
50 * @param width the width of the returned {@code VolatileImage}
51 * @param height the height of the returned {@code VolatileImage}
52 * @param transparency the specified transparency mode
53 * @param type requested accelerated surface type as specified by constants
54 * in AccelSurface interface
55 * @return a {@code VolatileImage} backed up by requested accelerated
56 * surface type or null
57 * @throws IllegalArgumentException if the transparency is not a valid value
58 * @see AccelSurface#TEXTURE
59 * @see AccelSurface#RT_PLAIN
60 * @see AccelSurface#RT_TEXTURE
61 */
62 public VolatileImage createCompatibleVolatileImage(int width, int height,
63 int transparency,
64 int type);
65 /**
66 * Returns object representing capabilities of the context associated
67 * with this {@code AccelGraphicsConfig}.
68 *
69 * @return ContextCapabilities object representing caps
70 * @see ContextCapabilities
71 */
72 public ContextCapabilities getContextCapabilities();
73
74 /**
75 * Adds an {@code AccelDeviceEventListener} to listen to accelerated
76 * device's (which is associated with this {@code AccelGraphicsConfig})
77 * events.
78 *
79 * Note: a hard link to the listener may be kept so it must be explicitly
80 * removed via {@link #removeDeviceEventListener()}.
81 *
82 * @param l the listener
83 * @see AccelDeviceEventListener
84 */
85 public void addDeviceEventListener(AccelDeviceEventListener l);
86
87 /**
88 * Removes an {@code AccelDeviceEventListener} from the list of listeners
89 * for this device's events.
90 *
91 * @param l the listener
92 * @see AccelDeviceEventListener
93 */
94 public void removeDeviceEventListener(AccelDeviceEventListener l);
95}
java/pkg/sun/java2d/pipe/hw/AccelSurface.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/AccelSurface.java+136−0
@@ -0,0 +1,136 @@
1/*
2 * Copyright (c) 2007, 2008, 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
26package sun.java2d.pipe.hw;
27
28import java.awt.Rectangle;
29import sun.java2d.Surface;
30
31/**
32 * Abstraction for a hardware accelerated surface.
33 */
34public interface AccelSurface extends BufferedContextProvider, Surface {
35 /**
36 * Undefined
37 */
38 public static final int UNDEFINED = 0;
39 /**
40 * Window (or window substitute) surface
41 */
42 public static final int WINDOW = 1;
43 /**
44 * Render-To Plain surface (pbuffer for OpenGL, Render Target surface
45 * for Direct3D)
46 */
47 public static final int RT_PLAIN = 2;
48 /**
49 * Texture surface
50 */
51 public static final int TEXTURE = 3;
52 /**
53 * A back-buffer surface (SwapChain surface for Direct3D, backbuffer for
54 * OpenGL)
55 */
56 public static final int FLIP_BACKBUFFER = 4;
57 /**
58 * Render-To Texture surface (fbobject for OpenGL, texture with render-to
59 * attribute for Direct3D)
60 */
61 public static final int RT_TEXTURE = 5;
62
63 /**
64 * Returns {@code int} representing surface's type as defined by constants
65 * in this interface.
66 *
67 * @return an integer representing this surface's type
68 * @see AccelSurface#UNDEFINED
69 * @see AccelSurface#WINDOW
70 * @see AccelSurface#RT_PLAIN
71 * @see AccelSurface#TEXTURE
72 * @see AccelSurface#FLIP_BACKBUFFER
73 * @see AccelSurface#RT_TEXTURE
74 */
75 public int getType();
76
77 /**
78 * Returns a pointer to the native surface data associated with this
79 * surface.
80 * Note: this pointer is only valid on the rendering thread.
81 *
82 * @return pointer to the native surface's data
83 */
84 public long getNativeOps();
85
86 /**
87 * Returns a pointer to the real native resource
88 * of the specified type associated with this AccelSurface.
89 * Note: this pointer is only valid on the rendering thread.
90 *
91 * @param resType the type of the requested resource
92 * @return a long containing a pointer to the native resource of the
93 * specified type or 0L if such resource doesn't exist for this surface
94 */
95 public long getNativeResource(int resType);
96
97 /**
98 * Marks this surface dirty.
99 */
100 public void markDirty();
101
102 /**
103 * Returns whether the pipeline considers this surface valid. A surface
104 * may become invalid if it is disposed of, or resized.
105 *
106 * @return true if valid, false otherwise
107 */
108 public boolean isValid();
109
110 /**
111 * Returns whether this surface is lost. The return value is only valid
112 * on the render thread, meaning that even if this method returns
113 * {@code true} it could be lost in the next moment unless it is called
114 * on the rendering thread.
115 *
116 * @return true if the surface is known to be lost, false otherwise
117 */
118 public boolean isSurfaceLost();
119
120 /**
121 * Returns the requested bounds of the destination surface. The real bounds
122 * of the native accelerated surface may differ. Use
123 * {@link #getNativeBounds} to get the bounds of the native surface.
124 *
125 * @return Rectangle representing java surface's bounds
126 */
127 public Rectangle getBounds();
128
129 /**
130 * Returns real bounds of the native surface, which may differ from those
131 * returned by {@link #getBounds}.
132 *
133 * @return Rectangle representing native surface's bounds
134 */
135 public Rectangle getNativeBounds();
136}
java/pkg/sun/java2d/pipe/hw/AccelTypedVolatileImage.java+74−0
@@ -0,0 +1,74 @@
1/*
2 * Copyright (c) 2007, 2008, 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
26package sun.java2d.pipe.hw;
27
28import java.awt.Graphics;
29import java.awt.Graphics2D;
30import java.awt.GraphicsConfiguration;
31import sun.awt.image.SunVolatileImage;
32import static sun.java2d.pipe.hw.AccelSurface.*;
33
34/**
35 * This is an image with forced type of the accelerated surface.
36 */
37public class AccelTypedVolatileImage extends SunVolatileImage {
38
39 /**
40 * Creates a volatile image with specified type of accelerated surface.
41 *
42 * @param graphicsConfig a GraphicsConfiguration for which this image should
43 * be created.
44 * @param width width
45 * @param height width
46 * @param transparency type of {@link java.awt.Transparency transparency}
47 * requested for the image
48 * @param accType type of the desired accelerated surface as defined in
49 * AccelSurface interface
50 * @see sun.java2d.pipe.hw.AccelSurface
51 */
52 public AccelTypedVolatileImage(GraphicsConfiguration graphicsConfig,
53 int width, int height, int transparency,
54 int accType)
55 {
56 super(null, graphicsConfig, width, height, null, transparency,
57 null, accType);
58 }
59
60 /**
61 * {@inheritDoc}
62 *
63 * This method will throw {@code UnsupportedOperationException} if it this
64 * image's destination surface can not be rendered to.
65 */
66 @Override
67 public Graphics2D createGraphics() {
68 if (getForcedAccelSurfaceType() == TEXTURE) {
69 throw new UnsupportedOperationException("Can't render " +
70 "to a non-RT Texture");
71 }
72 return super.createGraphics();
73 }
74}
java/pkg/sun/java2d/pipe/hw/BufferedContextProvider.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/BufferedContextProvider.java+45−0
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2007, 2008, 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
26package sun.java2d.pipe.hw;
27
28import sun.java2d.pipe.BufferedContext;
29
30/**
31 * Classes implementing this interface can provide the {@code BufferedContext}
32 * associated with or used by them.
33 *
34 * @see sun.java2d.pipe.BufferedContext
35 */
36public interface BufferedContextProvider {
37 /**
38 * Retrieves a context associated with object implementing this
39 * interface.
40 *
41 * @return associated context
42 * @see sun.java2d.pipe.BufferedContext
43 */
44 public BufferedContext getContext();
45}
java/pkg/sun/java2d/pipe/hw/ContextCapabilities.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/ContextCapabilities.java+128−0
@@ -0,0 +1,128 @@
1/*
2 * Copyright (c) 2007, 2008, 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
26package sun.java2d.pipe.hw;
27
28/**
29 * Represents a set of capabilities of a BufferedContext and associated
30 * AccelGraphicsConfig.
31 *
32 * @see AccelGraphicsConfig
33 */
34public class ContextCapabilities {
35 /** Indicates that the context has no capabilities. */
36 public static final int CAPS_EMPTY = (0 << 0);
37 /** Indicates that the context supports RT surfaces with alpha channel. */
38 public static final int CAPS_RT_PLAIN_ALPHA = (1 << 1);
39 /** Indicates that the context supports RT textures with alpha channel. */
40 public static final int CAPS_RT_TEXTURE_ALPHA = (1 << 2);
41 /** Indicates that the context supports opaque RT textures. */
42 public static final int CAPS_RT_TEXTURE_OPAQUE = (1 << 3);
43 /** Indicates that the context supports multitexturing. */
44 public static final int CAPS_MULTITEXTURE = (1 << 4);
45 /** Indicates that the context supports non-pow2 texture dimensions. */
46 public static final int CAPS_TEXNONPOW2 = (1 << 5);
47 /** Indicates that the context supports non-square textures. */
48 public static final int CAPS_TEXNONSQUARE = (1 << 6);
49 /** Indicates that the context supports pixel shader 2.0 or better. */
50 public static final int CAPS_PS20 = (1 << 7);
51 /** Indicates that the context supports pixel shader 3.0 or better. */
52 public static final int CAPS_PS30 = (1 << 8);
53 /*
54 * Pipeline contexts should use this for defining pipeline-specific
55 * capabilities, for example:
56 * int CAPS_D3D_1 = (FIRST_PRIVATE_CAP << 0);
57 * int CAPS_D3D_2 = (FIRST_PRIVATE_CAP << 1);
58 */
59 protected static final int FIRST_PRIVATE_CAP = (1 << 16);
60
61 protected final int caps;
62 protected final String adapterId;
63
64 /**
65 * Constructs a {@code ContextCapabilities} object.
66 * @param caps an {@code int} representing the capabilities
67 * @param a {@code String} representing the name of the adapter, or null,
68 * in which case the adapterId will be set to "unknown adapter".
69 */
70 protected ContextCapabilities(int caps, String adapterId) {
71 this.caps = caps;
72 this.adapterId = adapterId != null ? adapterId : "unknown adapter";
73 }
74
75 /**
76 * Returns a string representing the name of the graphics adapter if such
77 * could be determined. It is guaranteed to never return {@code null}.
78 * @return string representing adapter id
79 */
80 public String getAdapterId() {
81 return adapterId;
82 }
83
84 /**
85 * Returns an {@code int} with capabilities (OR-ed constants defined in
86 * this class and its pipeline-specific subclasses).
87 * @return capabilities as {@code int}
88 */
89 public int getCaps() {
90 return caps;
91 }
92
93 @Override
94 public String toString() {
95 StringBuffer buf =
96 new StringBuffer("ContextCapabilities: adapter=" +
97 adapterId+", caps=");
98 if (caps == CAPS_EMPTY) {
99 buf.append("CAPS_EMPTY");
100 } else {
101 if ((caps & CAPS_RT_PLAIN_ALPHA) != 0) {
102 buf.append("CAPS_RT_PLAIN_ALPHA|");
103 }
104 if ((caps & CAPS_RT_TEXTURE_ALPHA) != 0) {
105 buf.append("CAPS_RT_TEXTURE_ALPHA|");
106 }
107 if ((caps & CAPS_RT_TEXTURE_OPAQUE) != 0) {
108 buf.append("CAPS_RT_TEXTURE_OPAQUE|");
109 }
110 if ((caps & CAPS_MULTITEXTURE) != 0) {
111 buf.append("CAPS_MULTITEXTURE|");
112 }
113 if ((caps & CAPS_TEXNONPOW2) != 0) {
114 buf.append("CAPS_TEXNONPOW2|");
115 }
116 if ((caps & CAPS_TEXNONSQUARE) != 0) {
117 buf.append("CAPS_TEXNONSQUARE|");
118 }
119 if ((caps & CAPS_PS20) != 0) {
120 buf.append("CAPS_PS20|");
121 }
122 if ((caps & CAPS_PS30) != 0) {
123 buf.append("CAPS_PS30|");
124 }
125 }
126 return buf.toString();
127 }
128}
java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities$VSyncType.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java+154−0
@@ -0,0 +1,154 @@
1/*
2 * Copyright (c) 2007, 2008, 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
26package sun.java2d.pipe.hw;
27
28import java.awt.BufferCapabilities;
29import java.awt.ImageCapabilities;
30
31/**
32 * Provides extended BufferStrategy capabilities, allowing to specify
33 * the type of vertical refresh synchronization for a buffer strategy.
34 *
35 * This BS capability is always page flipping because v-sync is only relevant
36 * to flipping buffer strategies.
37 *
38 * Note that asking for a v-synced BS doesn't necessarily guarantee that it will
39 * be v-synced since the vsync capability may be disabled in the driver, or
40 * there may be other restriction (like a number of v-synced buffer strategies
41 * allowed per vm). Because of this {@code createBufferStrategy} doesn't
42 * throw {@code AWTException} when a v-synced BS could not be created when
43 * requested.
44 *
45 * @see java.awt.Canvas#createBufferStrategy(int, BufferCapabilities)
46 * @see java.awt.Window#createBufferStrategy(int, BufferCapabilities)
47 */
48public class ExtendedBufferCapabilities extends BufferCapabilities {
49
50 /**
51 * Type of synchronization on vertical retrace.
52 */
53 public static enum VSyncType {
54 /**
55 * Use the default v-sync mode appropriate for given BufferStrategy
56 * and situation.
57 */
58 VSYNC_DEFAULT(0),
59
60 /**
61 * Synchronize flip on vertical retrace.
62 */
63 VSYNC_ON(1),
64
65 /**
66 * Do not synchronize flip on vertical retrace.
67 */
68 VSYNC_OFF(2);
69
70 /**
71 * Used to identify the v-sync type (independent of the constants
72 * order as opposed to {@code ordinal()}).
73 */
74 public int id() {
75 return id;
76 }
77
78 private VSyncType(int id) {
79 this.id = id;
80 }
81 private int id;
82 }
83
84 private VSyncType vsync;
85
86 /**
87 * Creates an ExtendedBufferCapabilities object with front/back/flip caps
88 * from the passed cap, and VSYNC_DEFAULT v-sync mode.
89 */
90 public ExtendedBufferCapabilities(BufferCapabilities caps) {
91 super(caps.getFrontBufferCapabilities(),
92 caps.getBackBufferCapabilities(),
93 caps.getFlipContents());
94
95 this.vsync = VSyncType.VSYNC_DEFAULT;
96 }
97
98 /**
99 * Creates an ExtendedBufferCapabilities instance with front/back/flip caps
100 * from the passed caps, and VSYNC_DEFAULT v-sync mode.
101 */
102 public ExtendedBufferCapabilities(ImageCapabilities front,
103 ImageCapabilities back, FlipContents flip)
104 {
105 super(front, back, flip);
106
107 this.vsync = VSyncType.VSYNC_DEFAULT;
108 }
109
110 /**
111 * Creates an ExtendedBufferCapabilities instance with front/back/flip caps
112 * from the passed image/flip caps, and the v-sync type.
113 */
114 public ExtendedBufferCapabilities(ImageCapabilities front,
115 ImageCapabilities back, FlipContents flip,
116 VSyncType t)
117 {
118 super(front, back, flip);
119
120 this.vsync = t;
121 }
122
123 /**
124 * Creates an ExtendedBufferCapabilities instance with front/back/flip caps
125 * from the passed cap, and the passed v-sync mode.
126 */
127 public ExtendedBufferCapabilities(BufferCapabilities caps, VSyncType t) {
128 super(caps.getFrontBufferCapabilities(),
129 caps.getBackBufferCapabilities(),
130 caps.getFlipContents());
131
132 this.vsync = t;
133 }
134
135 /**
136 * Creates an ExtendedBufferCapabilities instance with front/back/flip caps
137 * from the object, and passed v-sync mode.
138 */
139 public ExtendedBufferCapabilities derive(VSyncType t) {
140 return new ExtendedBufferCapabilities(this, t);
141 }
142
143 /**
144 * Returns the type of v-sync requested by this capabilities instance.
145 */
146 public VSyncType getVSync() {
147 return vsync;
148 }
149
150 @Override
151 public final boolean isPageFlipping() {
152 return true;
153 }
154}
java/pkg/sun/java2d/pipe/hw/mkfile+15−0
@@ -0,0 +1,15 @@
1<../../../../../../mkconfig
2
3TARG=\
4 AccelDeviceEventListener.dis\
5 AccelDeviceEventNotifier.dis\
6 AccelGraphicsConfig.dis\
7 AccelSurface.dis\
8 AccelTypedVolatileImage.dis\
9 BufferedContextProvider.dis\
10 ContextCapabilities.dis\
11 ExtendedBufferCapabilities.dis\
12
13DISBIN=$ROOT/java/dis/java/java/sun/java2d/pipe/hw
14
15<$ROOT/mkfiles/mkjava
java/pkg/sun/java2d/pipe/mkfile+56−0
@@ -0,0 +1,56 @@
1<../../../../../mkconfig
2
3DIRS=\
4 hw\
5
6TARG=\
7 AAShapePipe.dis\
8 AATextRenderer.dis\
9 AATileGenerator.dis\
10 AlphaColorPipe.dis\
11 AlphaPaintPipe.dis\
12 BufferedBufImgOps.dis\
13 BufferedContext.dis\
14 BufferedMaskBlit.dis\
15 BufferedMaskFill.dis\
16 BufferedOpCodes.dis\
17 BufferedPaints.dis\
18 BufferedRenderPipe.dis\
19 BufferedTextPipe.dis\
20 CompositePipe.dis\
21 DrawImage.dis\
22 DrawImagePipe.dis\
23 GeneralCompositePipe.dis\
24 GlyphListLoopPipe.dis\
25 GlyphListPipe.dis\
26 LCDTextRenderer.dis\
27 LoopBasedPipe.dis\
28 LoopPipe.dis\
29 NullPipe.dis\
30 OutlineTextRenderer.dis\
31 ParallelogramPipe.dis\
32 PixelDrawPipe.dis\
33 PixelFillPipe.dis\
34 PixelToParallelogramConverter.dis\
35 PixelToShapeConverter.dis\
36 Region.dis\
37 RegionClipSpanIterator.dis\
38 RegionIterator.dis\
39 RegionSpanIterator.dis\
40 RenderBuffer.dis\
41 RenderingEngine.dis\
42 RenderQueue.dis\
43 ShapeDrawPipe.dis\
44 ShapeSpanIterator.dis\
45 SolidTextRenderer.dis\
46 SpanClipRenderer.dis\
47 SpanIterator.dis\
48 SpanShapeRenderer.dis\
49 TextPipe.dis\
50 TextRenderer.dis\
51 ValidatePipe.dis\
52
53DISBIN=$ROOT/java/dis/java/java/sun/java2d/pipe
54
55<$ROOT/mkfiles/mkjava
56<$ROOT/mkfiles/mksubdirs