1 /* 2 * Copyright (c) 1999, 2014, 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 { 49 native void doDrawLine(GDIWindowSurfaceData sData, 50 Region clip, Composite comp, int color, 51 int x1, int y1, int x2, int y2); 52 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 67 native void doDrawRect(GDIWindowSurfaceData sData, 68 Region clip, Composite comp, int color, 69 int x, int y, int w, int h); 70 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 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 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 102 native void doDrawOval(GDIWindowSurfaceData sData, 103 Region clip, Composite comp, int color, 104 int x, int y, int w, int h); 105 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 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 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 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 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 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 169 native void doFillRect(GDIWindowSurfaceData sData, 170 Region clip, Composite comp, int color, 171 int x, int y, int w, int h); 172 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 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 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 204 native void doFillOval(GDIWindowSurfaceData sData, 205 Region clip, Composite comp, int color, 206 int x, int y, int w, int h); 207 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 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 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 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 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 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 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. 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 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 325 public void fill(SunGraphics2D sg2d, Shape s) { 326 doShape(sg2d, s, true); 327 } 328 329 public native void devCopyArea(GDIWindowSurfaceData sData, 330 int srcx, int srcy, 331 int dx, int dy, 332 int w, int h); 333 334 public GDIRenderer traceWrap() { 335 return new Tracer(); 336 } 337 338 public static class Tracer extends GDIRenderer { 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 }