1 /* 2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.windows; 27 28 import java.awt.Composite; 29 import java.awt.Shape; 30 import java.awt.geom.Path2D; 31 import java.awt.geom.PathIterator; 32 import sun.java2d.InvalidPipeException; 33 import sun.java2d.SunGraphics2D; 34 import sun.java2d.SurfaceData; 35 import sun.java2d.pipe.Region; 36 import sun.java2d.pipe.PixelDrawPipe; 37 import sun.java2d.pipe.PixelFillPipe; 38 import sun.java2d.pipe.ShapeDrawPipe; 39 import sun.java2d.pipe.SpanIterator; 40 import sun.java2d.pipe.ShapeSpanIterator; 41 import sun.java2d.pipe.LoopPipe; 42 import sun.java2d.loops.GraphicsPrimitive; 43 44 public class GDIRenderer implements 45 PixelDrawPipe, 46 PixelFillPipe, 47 ShapeDrawPipe 48 { doDrawLine(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x1, int y1, int x2, int y2)49 native void doDrawLine(GDIWindowSurfaceData sData, 50 Region clip, Composite comp, int color, 51 int x1, int y1, int x2, int y2); 52 drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2)53 public void drawLine(SunGraphics2D sg2d, 54 int x1, int y1, int x2, int y2) 55 { 56 int transx = sg2d.transX; 57 int transy = sg2d.transY; 58 try { 59 doDrawLine((GDIWindowSurfaceData)sg2d.surfaceData, 60 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 61 x1+transx, y1+transy, x2+transx, y2+transy); 62 } catch (ClassCastException e) { 63 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 64 } 65 } 66 doDrawRect(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h)67 native void doDrawRect(GDIWindowSurfaceData sData, 68 Region clip, Composite comp, int color, 69 int x, int y, int w, int h); 70 drawRect(SunGraphics2D sg2d, int x, int y, int width, int height)71 public void drawRect(SunGraphics2D sg2d, 72 int x, int y, int width, int height) 73 { 74 try { 75 doDrawRect((GDIWindowSurfaceData)sg2d.surfaceData, 76 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 77 x+sg2d.transX, y+sg2d.transY, width, height); 78 } catch (ClassCastException e) { 79 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 80 } 81 } 82 doDrawRoundRect(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h, int arcW, int arcH)83 native void doDrawRoundRect(GDIWindowSurfaceData sData, 84 Region clip, Composite comp, int color, 85 int x, int y, int w, int h, 86 int arcW, int arcH); 87 drawRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight)88 public void drawRoundRect(SunGraphics2D sg2d, 89 int x, int y, int width, int height, 90 int arcWidth, int arcHeight) 91 { 92 try { 93 doDrawRoundRect((GDIWindowSurfaceData)sg2d.surfaceData, 94 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 95 x+sg2d.transX, y+sg2d.transY, width, height, 96 arcWidth, arcHeight); 97 } catch (ClassCastException e) { 98 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 99 } 100 } 101 doDrawOval(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h)102 native void doDrawOval(GDIWindowSurfaceData sData, 103 Region clip, Composite comp, int color, 104 int x, int y, int w, int h); 105 drawOval(SunGraphics2D sg2d, int x, int y, int width, int height)106 public void drawOval(SunGraphics2D sg2d, 107 int x, int y, int width, int height) 108 { 109 try { 110 doDrawOval((GDIWindowSurfaceData)sg2d.surfaceData, 111 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 112 x+sg2d.transX, y+sg2d.transY, width, height); 113 } catch (ClassCastException e) { 114 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 115 } 116 } 117 doDrawArc(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h, int angleStart, int angleExtent)118 native void doDrawArc(GDIWindowSurfaceData sData, 119 Region clip, Composite comp, int color, 120 int x, int y, int w, int h, 121 int angleStart, int angleExtent); 122 drawArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle)123 public void drawArc(SunGraphics2D sg2d, 124 int x, int y, int width, int height, 125 int startAngle, int arcAngle) 126 { 127 try { 128 doDrawArc((GDIWindowSurfaceData)sg2d.surfaceData, 129 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 130 x+sg2d.transX, y+sg2d.transY, width, height, 131 startAngle, arcAngle); 132 } catch (ClassCastException e) { 133 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 134 } 135 } 136 doDrawPoly(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int transx, int transy, int[] xpoints, int[] ypoints, int npoints, boolean isclosed)137 native void doDrawPoly(GDIWindowSurfaceData sData, 138 Region clip, Composite comp, int color, 139 int transx, int transy, 140 int[] xpoints, int[] ypoints, 141 int npoints, boolean isclosed); 142 drawPolyline(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints)143 public void drawPolyline(SunGraphics2D sg2d, 144 int[] xpoints, int[] ypoints, 145 int npoints) 146 { 147 try { 148 doDrawPoly((GDIWindowSurfaceData)sg2d.surfaceData, 149 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 150 sg2d.transX, sg2d.transY, xpoints, ypoints, npoints, false); 151 } catch (ClassCastException e) { 152 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 153 } 154 } 155 drawPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints)156 public void drawPolygon(SunGraphics2D sg2d, 157 int[] xpoints, int[] ypoints, 158 int npoints) 159 { 160 try { 161 doDrawPoly((GDIWindowSurfaceData)sg2d.surfaceData, 162 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 163 sg2d.transX, sg2d.transY, xpoints, ypoints, npoints, true); 164 } catch (ClassCastException e) { 165 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 166 } 167 } 168 doFillRect(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h)169 native void doFillRect(GDIWindowSurfaceData sData, 170 Region clip, Composite comp, int color, 171 int x, int y, int w, int h); 172 fillRect(SunGraphics2D sg2d, int x, int y, int width, int height)173 public void fillRect(SunGraphics2D sg2d, 174 int x, int y, int width, int height) 175 { 176 try { 177 doFillRect((GDIWindowSurfaceData)sg2d.surfaceData, 178 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 179 x+sg2d.transX, y+sg2d.transY, width, height); 180 } catch (ClassCastException e) { 181 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 182 } 183 } 184 doFillRoundRect(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h, int arcW, int arcH)185 native void doFillRoundRect(GDIWindowSurfaceData sData, 186 Region clip, Composite comp, int color, 187 int x, int y, int w, int h, 188 int arcW, int arcH); 189 fillRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight)190 public void fillRoundRect(SunGraphics2D sg2d, 191 int x, int y, int width, int height, 192 int arcWidth, int arcHeight) 193 { 194 try { 195 doFillRoundRect((GDIWindowSurfaceData)sg2d.surfaceData, 196 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 197 x+sg2d.transX, y+sg2d.transY, width, height, 198 arcWidth, arcHeight); 199 } catch (ClassCastException e) { 200 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 201 } 202 } 203 doFillOval(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h)204 native void doFillOval(GDIWindowSurfaceData sData, 205 Region clip, Composite comp, int color, 206 int x, int y, int w, int h); 207 fillOval(SunGraphics2D sg2d, int x, int y, int width, int height)208 public void fillOval(SunGraphics2D sg2d, 209 int x, int y, int width, int height) 210 { 211 try { 212 doFillOval((GDIWindowSurfaceData)sg2d.surfaceData, 213 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 214 x+sg2d.transX, y+sg2d.transY, width, height); 215 } catch (ClassCastException e) { 216 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 217 } 218 } 219 doFillArc(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h, int angleStart, int angleExtent)220 native void doFillArc(GDIWindowSurfaceData sData, 221 Region clip, Composite comp, int color, 222 int x, int y, int w, int h, 223 int angleStart, int angleExtent); 224 fillArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle)225 public void fillArc(SunGraphics2D sg2d, 226 int x, int y, int width, int height, 227 int startAngle, int arcAngle) 228 { 229 try { 230 doFillArc((GDIWindowSurfaceData)sg2d.surfaceData, 231 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 232 x+sg2d.transX, y+sg2d.transY, width, height, 233 startAngle, arcAngle); 234 } catch (ClassCastException e) { 235 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 236 } 237 } 238 doFillPoly(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int transx, int transy, int[] xpoints, int[] ypoints, int npoints)239 native void doFillPoly(GDIWindowSurfaceData sData, 240 Region clip, Composite comp, int color, 241 int transx, int transy, 242 int[] xpoints, int[] ypoints, 243 int npoints); 244 fillPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints)245 public void fillPolygon(SunGraphics2D sg2d, 246 int[] xpoints, int[] ypoints, 247 int npoints) 248 { 249 try { 250 doFillPoly((GDIWindowSurfaceData)sg2d.surfaceData, 251 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 252 sg2d.transX, sg2d.transY, xpoints, ypoints, npoints); 253 } catch (ClassCastException e) { 254 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 255 } 256 } 257 doShape(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int transX, int transY, Path2D.Float p2df, boolean isfill)258 native void doShape(GDIWindowSurfaceData sData, 259 Region clip, Composite comp, int color, 260 int transX, int transY, 261 Path2D.Float p2df, boolean isfill); 262 doShape(SunGraphics2D sg2d, Shape s, boolean isfill)263 void doShape(SunGraphics2D sg2d, Shape s, boolean isfill) { 264 Path2D.Float p2df; 265 int transX; 266 int transY; 267 if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) { 268 if (s instanceof Path2D.Float) { 269 p2df = (Path2D.Float)s; 270 } else { 271 p2df = new Path2D.Float(s); 272 } 273 transX = sg2d.transX; 274 transY = sg2d.transY; 275 } else { 276 p2df = new Path2D.Float(s, sg2d.transform); 277 transX = 0; 278 transY = 0; 279 } 280 try { 281 doShape((GDIWindowSurfaceData)sg2d.surfaceData, 282 sg2d.getCompClip(), sg2d.composite, sg2d.eargb, 283 transX, transY, p2df, isfill); 284 } catch (ClassCastException e) { 285 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 286 } 287 } 288 289 // REMIND: This is just a hack to get WIDE lines to honor the 290 // necessary hinted pixelization rules. This should be replaced 291 // by a native FillSpans method or a getHintedStrokeGeneralPath() 292 // method that could be filled by the doShape method more quickly. doFillSpans(SunGraphics2D sg2d, SpanIterator si)293 public void doFillSpans(SunGraphics2D sg2d, SpanIterator si) { 294 int[] box = new int[4]; 295 GDIWindowSurfaceData sd; 296 try { 297 sd = (GDIWindowSurfaceData)sg2d.surfaceData; 298 } catch (ClassCastException e) { 299 throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); 300 } 301 Region clip = sg2d.getCompClip(); 302 Composite comp = sg2d.composite; 303 int eargb = sg2d.eargb; 304 while (si.nextSpan(box)) { 305 doFillRect(sd, clip, comp, eargb, 306 box[0], box[1], box[2]-box[0], box[3]-box[1]); 307 } 308 } 309 draw(SunGraphics2D sg2d, Shape s)310 public void draw(SunGraphics2D sg2d, Shape s) { 311 if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) { 312 doShape(sg2d, s, false); 313 } else if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) { 314 ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s); 315 try { 316 doFillSpans(sg2d, si); 317 } finally { 318 si.dispose(); 319 } 320 } else { 321 doShape(sg2d, sg2d.stroke.createStrokedShape(s), true); 322 } 323 } 324 fill(SunGraphics2D sg2d, Shape s)325 public void fill(SunGraphics2D sg2d, Shape s) { 326 doShape(sg2d, s, true); 327 } 328 devCopyArea(GDIWindowSurfaceData sData, int srcx, int srcy, int dx, int dy, int w, int h)329 public native void devCopyArea(GDIWindowSurfaceData sData, 330 int srcx, int srcy, 331 int dx, int dy, 332 int w, int h); 333 traceWrap()334 public GDIRenderer traceWrap() { 335 return new Tracer(); 336 } 337 338 public static class Tracer extends GDIRenderer { doDrawLine(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x1, int y1, int x2, int y2)339 void doDrawLine(GDIWindowSurfaceData sData, 340 Region clip, Composite comp, int color, 341 int x1, int y1, int x2, int y2) 342 { 343 GraphicsPrimitive.tracePrimitive("GDIDrawLine"); 344 super.doDrawLine(sData, clip, comp, color, x1, y1, x2, y2); 345 } doDrawRect(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h)346 void doDrawRect(GDIWindowSurfaceData sData, 347 Region clip, Composite comp, int color, 348 int x, int y, int w, int h) 349 { 350 GraphicsPrimitive.tracePrimitive("GDIDrawRect"); 351 super.doDrawRect(sData, clip, comp, color, x, y, w, h); 352 } doDrawRoundRect(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h, int arcW, int arcH)353 void doDrawRoundRect(GDIWindowSurfaceData sData, 354 Region clip, Composite comp, int color, 355 int x, int y, int w, int h, 356 int arcW, int arcH) 357 { 358 GraphicsPrimitive.tracePrimitive("GDIDrawRoundRect"); 359 super.doDrawRoundRect(sData, clip, comp, color, 360 x, y, w, h, arcW, arcH); 361 } doDrawOval(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h)362 void doDrawOval(GDIWindowSurfaceData sData, 363 Region clip, Composite comp, int color, 364 int x, int y, int w, int h) 365 { 366 GraphicsPrimitive.tracePrimitive("GDIDrawOval"); 367 super.doDrawOval(sData, clip, comp, color, x, y, w, h); 368 } doDrawArc(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h, int angleStart, int angleExtent)369 void doDrawArc(GDIWindowSurfaceData sData, 370 Region clip, Composite comp, int color, 371 int x, int y, int w, int h, 372 int angleStart, int angleExtent) 373 { 374 GraphicsPrimitive.tracePrimitive("GDIDrawArc"); 375 super.doDrawArc(sData, clip, comp, color, x, y, w, h, 376 angleStart, angleExtent); 377 } doDrawPoly(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int transx, int transy, int[] xpoints, int[] ypoints, int npoints, boolean isclosed)378 void doDrawPoly(GDIWindowSurfaceData sData, 379 Region clip, Composite comp, int color, 380 int transx, int transy, 381 int[] xpoints, int[] ypoints, 382 int npoints, boolean isclosed) 383 { 384 GraphicsPrimitive.tracePrimitive("GDIDrawPoly"); 385 super.doDrawPoly(sData, clip, comp, color, transx, transy, 386 xpoints, ypoints, npoints, isclosed); 387 } doFillRect(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h)388 void doFillRect(GDIWindowSurfaceData sData, 389 Region clip, Composite comp, int color, 390 int x, int y, int w, int h) 391 { 392 GraphicsPrimitive.tracePrimitive("GDIFillRect"); 393 super.doFillRect(sData, clip, comp, color, x, y, w, h); 394 } doFillRoundRect(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h, int arcW, int arcH)395 void doFillRoundRect(GDIWindowSurfaceData sData, 396 Region clip, Composite comp, int color, 397 int x, int y, int w, int h, 398 int arcW, int arcH) 399 { 400 GraphicsPrimitive.tracePrimitive("GDIFillRoundRect"); 401 super.doFillRoundRect(sData, clip, comp, color, 402 x, y, w, h, arcW, arcH); 403 } doFillOval(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h)404 void doFillOval(GDIWindowSurfaceData sData, 405 Region clip, Composite comp, int color, 406 int x, int y, int w, int h) 407 { 408 GraphicsPrimitive.tracePrimitive("GDIFillOval"); 409 super.doFillOval(sData, clip, comp, color, x, y, w, h); 410 } doFillArc(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int x, int y, int w, int h, int angleStart, int angleExtent)411 void doFillArc(GDIWindowSurfaceData sData, 412 Region clip, Composite comp, int color, 413 int x, int y, int w, int h, 414 int angleStart, int angleExtent) 415 { 416 GraphicsPrimitive.tracePrimitive("GDIFillArc"); 417 super.doFillArc(sData, clip, comp, color, x, y, w, h, 418 angleStart, angleExtent); 419 } doFillPoly(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int transx, int transy, int[] xpoints, int[] ypoints, int npoints)420 void doFillPoly(GDIWindowSurfaceData sData, 421 Region clip, Composite comp, int color, 422 int transx, int transy, 423 int[] xpoints, int[] ypoints, 424 int npoints) 425 { 426 GraphicsPrimitive.tracePrimitive("GDIFillPoly"); 427 super.doFillPoly(sData, clip, comp, color, transx, transy, 428 xpoints, ypoints, npoints); 429 } doShape(GDIWindowSurfaceData sData, Region clip, Composite comp, int color, int transX, int transY, Path2D.Float p2df, boolean isfill)430 void doShape(GDIWindowSurfaceData sData, 431 Region clip, Composite comp, int color, 432 int transX, int transY, 433 Path2D.Float p2df, boolean isfill) 434 { 435 GraphicsPrimitive.tracePrimitive(isfill 436 ? "GDIFillShape" 437 : "GDIDrawShape"); 438 super.doShape(sData, clip, comp, color, 439 transX, transY, p2df, isfill); 440 } devCopyArea(GDIWindowSurfaceData sData, int srcx, int srcy, int dx, int dy, int w, int h)441 public void devCopyArea(GDIWindowSurfaceData sData, 442 int srcx, int srcy, 443 int dx, int dy, 444 int w, int h) 445 { 446 GraphicsPrimitive.tracePrimitive("GDICopyArea"); 447 super.devCopyArea(sData, srcx, srcy, dx, dy, w, h); 448 } 449 } 450 } 451