160
161 Paint paint = getPaint();
162
163 try {
164 AffineTransform deviceTransform = getTransform();
165 if (getClip() != null) {
166 deviceClip(getClip().getPathIterator(deviceTransform));
167 }
168
169 deviceDrawLine(x1, y1, x2, y2, (Color) paint);
170
171 } catch (ClassCastException e) {
172 throw new IllegalArgumentException("Expected a Color instance");
173 }
174 }
175
176
177 /**
178 * Draws the outline of the specified rectangle.
179 * The left and right edges of the rectangle are at
180 * <code>x</code> and <code>x + width</code>.
181 * The top and bottom edges are at
182 * <code>y</code> and <code>y + height</code>.
183 * The rectangle is drawn using the graphics context's current color.
184 * @param x the <i>x</i> coordinate
185 * of the rectangle to be drawn.
186 * @param y the <i>y</i> coordinate
187 * of the rectangle to be drawn.
188 * @param width the width of the rectangle to be drawn.
189 * @param height the height of the rectangle to be drawn.
190 * @see java.awt.Graphics#fillRect
191 * @see java.awt.Graphics#clearRect
192 */
193 public void drawRect(int x, int y, int width, int height) {
194
195 Paint paint = getPaint();
196
197 try {
198 AffineTransform deviceTransform = getTransform();
199 if (getClip() != null) {
200 deviceClip(getClip().getPathIterator(deviceTransform));
201 }
202
203 deviceFrameRect(x, y, width, height, (Color) paint);
204
205 } catch (ClassCastException e) {
206 throw new IllegalArgumentException("Expected a Color instance");
207 }
208
209 }
210
211 /**
212 * Fills the specified rectangle.
213 * The left and right edges of the rectangle are at
214 * <code>x</code> and <code>x + width - 1</code>.
215 * The top and bottom edges are at
216 * <code>y</code> and <code>y + height - 1</code>.
217 * The resulting rectangle covers an area
218 * <code>width</code> pixels wide by
219 * <code>height</code> pixels tall.
220 * The rectangle is filled using the graphics context's current color.
221 * @param x the <i>x</i> coordinate
222 * of the rectangle to be filled.
223 * @param y the <i>y</i> coordinate
224 * of the rectangle to be filled.
225 * @param width the width of the rectangle to be filled.
226 * @param height the height of the rectangle to be filled.
227 * @see java.awt.Graphics#clearRect
228 * @see java.awt.Graphics#drawRect
229 */
230 public void fillRect(int x, int y, int width, int height){
231
232 Paint paint = getPaint();
233
234 try {
235 AffineTransform deviceTransform = getTransform();
236 if (getClip() != null) {
237 deviceClip(getClip().getPathIterator(deviceTransform));
238 }
239
240 deviceFillRect(x, y, width, height, (Color) paint);
241
242 } catch (ClassCastException e) {
243 throw new IllegalArgumentException("Expected a Color instance");
244 }
245 }
246
247 /**
248 * Clears the specified rectangle by filling it with the background
249 * color of the current drawing surface. This operation does not
250 * use the current paint mode.
251 * <p>
252 * Beginning with Java 1.1, the background color
253 * of offscreen images may be system dependent. Applications should
254 * use <code>setColor</code> followed by <code>fillRect</code> to
255 * ensure that an offscreen image is cleared to a specific color.
256 * @param x the <i>x</i> coordinate of the rectangle to clear.
257 * @param y the <i>y</i> coordinate of the rectangle to clear.
258 * @param width the width of the rectangle to clear.
259 * @param height the height of the rectangle to clear.
260 * @see java.awt.Graphics#fillRect(int, int, int, int)
261 * @see java.awt.Graphics#drawRect
262 * @see java.awt.Graphics#setColor(java.awt.Color)
263 * @see java.awt.Graphics#setPaintMode
264 * @see java.awt.Graphics#setXORMode(java.awt.Color)
265 */
266 public void clearRect(int x, int y, int width, int height) {
267
268 fill(new Rectangle2D.Float(x, y, width, height), getBackground());
269 }
270
271 /**
272 * Draws an outlined round-cornered rectangle using this graphics
273 * context's current color. The left and right edges of the rectangle
274 * are at <code>x</code> and <code>x + width</code>,
275 * respectively. The top and bottom edges of the rectangle are at
276 * <code>y</code> and <code>y + height</code>.
277 * @param x the <i>x</i> coordinate of the rectangle to be drawn.
278 * @param y the <i>y</i> coordinate of the rectangle to be drawn.
279 * @param width the width of the rectangle to be drawn.
280 * @param height the height of the rectangle to be drawn.
281 * @param arcWidth the horizontal diameter of the arc
282 * at the four corners.
283 * @param arcHeight the vertical diameter of the arc
284 * at the four corners.
285 * @see java.awt.Graphics#fillRoundRect
286 */
287 public void drawRoundRect(int x, int y, int width, int height,
288 int arcWidth, int arcHeight) {
289
290 draw(new RoundRectangle2D.Float(x, y,
291 width, height,
292 arcWidth, arcHeight));
293 }
294
295
296 /**
297 * Fills the specified rounded corner rectangle with the current color.
298 * The left and right edges of the rectangle
299 * are at <code>x</code> and <code>x + width - 1</code>,
300 * respectively. The top and bottom edges of the rectangle are at
301 * <code>y</code> and <code>y + height - 1</code>.
302 * @param x the <i>x</i> coordinate of the rectangle to be filled.
303 * @param y the <i>y</i> coordinate of the rectangle to be filled.
304 * @param width the width of the rectangle to be filled.
305 * @param height the height of the rectangle to be filled.
306 * @param arcWidth the horizontal diameter
307 * of the arc at the four corners.
308 * @param arcHeight the vertical diameter
309 * of the arc at the four corners.
310 * @see java.awt.Graphics#drawRoundRect
311 */
312 public void fillRoundRect(int x, int y, int width, int height,
313 int arcWidth, int arcHeight) {
314
315 fill(new RoundRectangle2D.Float(x, y,
316 width, height,
317 arcWidth, arcHeight));
318 }
319
320 /**
321 * Draws the outline of an oval.
322 * The result is a circle or ellipse that fits within the
323 * rectangle specified by the <code>x</code>, <code>y</code>,
324 * <code>width</code>, and <code>height</code> arguments.
325 * <p>
326 * The oval covers an area that is
327 * <code>width + 1</code> pixels wide
328 * and <code>height + 1</code> pixels tall.
329 * @param x the <i>x</i> coordinate of the upper left
330 * corner of the oval to be drawn.
331 * @param y the <i>y</i> coordinate of the upper left
332 * corner of the oval to be drawn.
333 * @param width the width of the oval to be drawn.
334 * @param height the height of the oval to be drawn.
335 * @see java.awt.Graphics#fillOval
336 * @since 1.0
337 */
338 public void drawOval(int x, int y, int width, int height) {
339 draw(new Ellipse2D.Float(x, y, width, height));
340 }
341
342 /**
343 * Fills an oval bounded by the specified rectangle with the
344 * current color.
345 * @param x the <i>x</i> coordinate of the upper left corner
346 * of the oval to be filled.
347 * @param y the <i>y</i> coordinate of the upper left corner
348 * of the oval to be filled.
349 * @param width the width of the oval to be filled.
350 * @param height the height of the oval to be filled.
351 * @see java.awt.Graphics#drawOval
352 */
353 public void fillOval(int x, int y, int width, int height){
354
355 fill(new Ellipse2D.Float(x, y, width, height));
356 }
357
358 /**
359 * Draws the outline of a circular or elliptical arc
360 * covering the specified rectangle.
361 * <p>
362 * The resulting arc begins at <code>startAngle</code> and extends
363 * for <code>arcAngle</code> degrees, using the current color.
364 * Angles are interpreted such that 0 degrees
365 * is at the 3 o'clock position.
366 * A positive value indicates a counter-clockwise rotation
367 * while a negative value indicates a clockwise rotation.
368 * <p>
369 * The center of the arc is the center of the rectangle whose origin
370 * is (<i>x</i>, <i>y</i>) and whose size is specified by the
371 * <code>width</code> and <code>height</code> arguments.
372 * <p>
373 * The resulting arc covers an area
374 * <code>width + 1</code> pixels wide
375 * by <code>height + 1</code> pixels tall.
376 * <p>
377 * The angles are specified relative to the non-square extents of
378 * the bounding rectangle such that 45 degrees always falls on the
379 * line from the center of the ellipse to the upper right corner of
380 * the bounding rectangle. As a result, if the bounding rectangle is
381 * noticeably longer in one axis than the other, the angles to the
382 * start and end of the arc segment will be skewed farther along the
383 * longer axis of the bounds.
384 * @param x the <i>x</i> coordinate of the
385 * upper-left corner of the arc to be drawn.
386 * @param y the <i>y</i> coordinate of the
387 * upper-left corner of the arc to be drawn.
388 * @param width the width of the arc to be drawn.
389 * @param height the height of the arc to be drawn.
390 * @param startAngle the beginning angle.
391 * @param arcAngle the angular extent of the arc,
392 * relative to the start angle.
393 * @see java.awt.Graphics#fillArc
394 */
395 public void drawArc(int x, int y, int width, int height,
396 int startAngle, int arcAngle) {
397 draw(new Arc2D.Float(x, y, width, height,
398 startAngle, arcAngle,
399 Arc2D.OPEN));
400 }
401
402
403 /**
404 * Fills a circular or elliptical arc covering the specified rectangle.
405 * <p>
406 * The resulting arc begins at <code>startAngle</code> and extends
407 * for <code>arcAngle</code> degrees.
408 * Angles are interpreted such that 0 degrees
409 * is at the 3 o'clock position.
410 * A positive value indicates a counter-clockwise rotation
411 * while a negative value indicates a clockwise rotation.
412 * <p>
413 * The center of the arc is the center of the rectangle whose origin
414 * is (<i>x</i>, <i>y</i>) and whose size is specified by the
415 * <code>width</code> and <code>height</code> arguments.
416 * <p>
417 * The resulting arc covers an area
418 * <code>width + 1</code> pixels wide
419 * by <code>height + 1</code> pixels tall.
420 * <p>
421 * The angles are specified relative to the non-square extents of
422 * the bounding rectangle such that 45 degrees always falls on the
423 * line from the center of the ellipse to the upper right corner of
424 * the bounding rectangle. As a result, if the bounding rectangle is
425 * noticeably longer in one axis than the other, the angles to the
426 * start and end of the arc segment will be skewed farther along the
427 * longer axis of the bounds.
428 * @param x the <i>x</i> coordinate of the
429 * upper-left corner of the arc to be filled.
430 * @param y the <i>y</i> coordinate of the
431 * upper-left corner of the arc to be filled.
432 * @param width the width of the arc to be filled.
433 * @param height the height of the arc to be filled.
434 * @param startAngle the beginning angle.
435 * @param arcAngle the angular extent of the arc,
461
462 if (nPoints == 2) {
463 draw(new Line2D.Float(xPoints[0], yPoints[0],
464 xPoints[1], yPoints[1]));
465 } else if (nPoints > 2) {
466 Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD, nPoints);
467 path.moveTo(xPoints[0], yPoints[0]);
468 for(int i = 1; i < nPoints; i++) {
469 path.lineTo(xPoints[i], yPoints[i]);
470 }
471 draw(path);
472 }
473 }
474
475
476 /**
477 * Draws a closed polygon defined by
478 * arrays of <i>x</i> and <i>y</i> coordinates.
479 * Each pair of (<i>x</i>, <i>y</i>) coordinates defines a point.
480 * <p>
481 * This method draws the polygon defined by <code>nPoint</code> line
482 * segments, where the first <code>nPoint - 1</code>
483 * line segments are line segments from
484 * <code>(xPoints[i - 1], yPoints[i - 1])</code>
485 * to <code>(xPoints[i], yPoints[i])</code>, for
486 * 1 ≤ <i>i</i> ≤ <code>nPoints</code>.
487 * The figure is automatically closed by drawing a line connecting
488 * the final point to the first point, if those points are different.
489 * @param xPoints a an array of <code>x</code> coordinates.
490 * @param yPoints a an array of <code>y</code> coordinates.
491 * @param nPoints a the total number of points.
492 * @see java.awt.Graphics#fillPolygon
493 * @see java.awt.Graphics#drawPolyline
494 */
495 public void drawPolygon(int xPoints[], int yPoints[],
496 int nPoints) {
497
498 draw(new Polygon(xPoints, yPoints, nPoints));
499 }
500
501 /**
502 * Draws the outline of a polygon defined by the specified
503 * <code>Polygon</code> object.
504 * @param p the polygon to draw.
505 * @see java.awt.Graphics#fillPolygon
506 * @see java.awt.Graphics#drawPolyline
507 */
508 public void drawPolygon(Polygon p) {
509 draw(p);
510 }
511
512 /**
513 * Fills a closed polygon defined by
514 * arrays of <i>x</i> and <i>y</i> coordinates.
515 * <p>
516 * This method draws the polygon defined by <code>nPoint</code> line
517 * segments, where the first <code>nPoint - 1</code>
518 * line segments are line segments from
519 * <code>(xPoints[i - 1], yPoints[i - 1])</code>
520 * to <code>(xPoints[i], yPoints[i])</code>, for
521 * 1 ≤ <i>i</i> ≤ <code>nPoints</code>.
522 * The figure is automatically closed by drawing a line connecting
523 * the final point to the first point, if those points are different.
524 * <p>
525 * The area inside the polygon is defined using an
526 * even-odd fill rule, also known as the alternating rule.
527 * @param xPoints a an array of <code>x</code> coordinates.
528 * @param yPoints a an array of <code>y</code> coordinates.
529 * @param nPoints a the total number of points.
530 * @see java.awt.Graphics#drawPolygon(int[], int[], int)
531 */
532 public void fillPolygon(int xPoints[], int yPoints[],
533 int nPoints) {
534
535 fill(new Polygon(xPoints, yPoints, nPoints));
536 }
537
538
539 /**
540 * Fills the polygon defined by the specified Polygon object with
541 * the graphics context's current color.
542 * <p>
543 * The area inside the polygon is defined using an
544 * even-odd fill rule, also known as the alternating rule.
545 * @param p the polygon to fill.
546 * @see java.awt.Graphics#drawPolygon(int[], int[], int)
547 */
548 public void fillPolygon(Polygon p) {
1072 * solid colors and so we do not expect the cast of Paint
1073 * to Color to fail. If it does fail then something went
1074 * wrong, like the app draw a page with a solid color but
1075 * then redrew it with a Gradient.
1076 */
1077 } catch (ClassCastException e) {
1078 throw new IllegalArgumentException("Expected a Color instance");
1079 }
1080 }
1081
1082 public void fill(Shape s, Color color) {
1083 AffineTransform deviceTransform = getTransform();
1084
1085 if (getClip() != null) {
1086 deviceClip(getClip().getPathIterator(deviceTransform));
1087 }
1088 deviceFill(s.getPathIterator(deviceTransform), color);
1089 }
1090
1091 /**
1092 * Fill the path defined by <code>pathIter</code>
1093 * with the specified color.
1094 * The path is provided in device coordinates.
1095 */
1096 protected abstract void deviceFill(PathIterator pathIter, Color color);
1097
1098 /*
1099 * Set the clipping path to that defined by
1100 * the passed in <code>PathIterator</code>.
1101 */
1102 protected abstract void deviceClip(PathIterator pathIter);
1103
1104 /*
1105 * Draw the outline of the rectangle without using path
1106 * if supported by platform.
1107 */
1108 protected abstract void deviceFrameRect(int x, int y,
1109 int width, int height,
1110 Color color);
1111
1112 /*
1113 * Draw a line without using path if supported by platform.
1114 */
1115 protected abstract void deviceDrawLine(int xBegin, int yBegin,
1116 int xEnd, int yEnd, Color color);
1117
1118 /*
1119 * Fill a rectangle using specified color.
1120 */
1309 }
1310 } else if (startx < 0) {
1311 startx = i;
1312 }
1313 }
1314 if (startx >= 0) {
1315 subImage = bufferedImage.getSubimage(startx, j,
1316 right - startx, 1);
1317 xform.translate(startx, j);
1318 drawImageToPlatform(subImage, xform, bgcolor,
1319 0, 0, right - startx, 1, true);
1320 xform.translate(-startx, -j);
1321 }
1322 }
1323 return true;
1324 }
1325
1326
1327
1328 /**
1329 * The various <code>drawImage()</code> methods for
1330 * <code>PathGraphics</code> are all decomposed
1331 * into an invocation of <code>drawImageToPlatform</code>.
1332 * The portion of the passed in image defined by
1333 * <code>srcX, srcY, srcWidth, and srcHeight</code>
1334 * is transformed by the supplied AffineTransform and
1335 * drawn using PS to the printer context.
1336 *
1337 * @param img The image to be drawn.
1338 * This method does nothing if <code>img</code> is null.
1339 * @param xform Used to transform the image before drawing.
1340 * This can be null.
1341 * @param bgcolor This color is drawn where the image has transparent
1342 * pixels. If this parameter is null then the
1343 * pixels already in the destination should show
1344 * through.
1345 * @param srcX With srcY this defines the upper-left corner
1346 * of the portion of the image to be drawn.
1347 *
1348 * @param srcY With srcX this defines the upper-left corner
1349 * of the portion of the image to be drawn.
1350 * @param srcWidth The width of the portion of the image to
1351 * be drawn.
1352 * @param srcHeight The height of the portion of the image to
1353 * be drawn.
1354 * @param handlingTransparency if being recursively called to
1355 * print opaque region of transparent image
1356 */
1357 protected abstract boolean
1358 drawImageToPlatform(Image img, AffineTransform xform,
1359 Color bgcolor,
1360 int srcX, int srcY,
1361 int srcWidth, int srcHeight,
1362 boolean handlingTransparency);
1363
1364 /**
1365 * Draws as much of the specified image as is currently available.
1366 * The image is drawn with its top-left corner at
1367 * (<i>x</i>, <i>y</i>) in this graphics context's coordinate
1368 * space. Transparent pixels in the image do not affect whatever
1369 * pixels are already there.
1370 * <p>
1371 * This method returns immediately in all cases, even if the
1372 * complete image has not yet been loaded, and it has not been dithered
1373 * and converted for the current output device.
1374 * <p>
1375 * If the image has not yet been completely loaded, then
1376 * <code>drawImage</code> returns <code>false</code>. As more of
1377 * the image becomes available, the process that draws the image notifies
1378 * the specified image observer.
1379 * @param img the specified image to be drawn.
1380 * @param x the <i>x</i> coordinate.
1381 * @param y the <i>y</i> coordinate.
1382 * @param observer object to be notified as more of
1383 * the image is converted.
1384 * @see java.awt.Image
1385 * @see java.awt.image.ImageObserver
1386 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1387 * @since 1.0
1388 */
1389 public boolean drawImage(Image img, int x, int y,
1390 ImageObserver observer) {
1391
1392 return drawImage(img, x, y, null, observer);
1393 }
1394
1395 /**
1396 * Draws as much of the specified image as has already been scaled
1397 * to fit inside the specified rectangle.
1398 * <p>
1399 * The image is drawn inside the specified rectangle of this
1400 * graphics context's coordinate space, and is scaled if
1401 * necessary. Transparent pixels do not affect whatever pixels
1402 * are already there.
1403 * <p>
1404 * This method returns immediately in all cases, even if the
1405 * entire image has not yet been scaled, dithered, and converted
1406 * for the current output device.
1407 * If the current output representation is not yet complete, then
1408 * <code>drawImage</code> returns <code>false</code>. As more of
1409 * the image becomes available, the process that draws the image notifies
1410 * the image observer by calling its <code>imageUpdate</code> method.
1411 * <p>
1412 * A scaled version of an image will not necessarily be
1413 * available immediately just because an unscaled version of the
1414 * image has been constructed for this output device. Each size of
1415 * the image may be cached separately and generated from the original
1416 * data in a separate image production sequence.
1417 * @param img the specified image to be drawn.
1418 * @param x the <i>x</i> coordinate.
1419 * @param y the <i>y</i> coordinate.
1420 * @param width the width of the rectangle.
1421 * @param height the height of the rectangle.
1422 * @param observer object to be notified as more of
1423 * the image is converted.
1424 * @see java.awt.Image
1425 * @see java.awt.image.ImageObserver
1426 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1427 * @since 1.0
1428 */
1429 public boolean drawImage(Image img, int x, int y,
1430 int width, int height,
1433 return drawImage(img, x, y, width, height, null, observer);
1434
1435 }
1436
1437 /*
1438 * Draws as much of the specified image as is currently available.
1439 * The image is drawn with its top-left corner at
1440 * (<i>x</i>, <i>y</i>) in this graphics context's coordinate
1441 * space. Transparent pixels are drawn in the specified
1442 * background color.
1443 * <p>
1444 * This operation is equivalent to filling a rectangle of the
1445 * width and height of the specified image with the given color and then
1446 * drawing the image on top of it, but possibly more efficient.
1447 * <p>
1448 * This method returns immediately in all cases, even if the
1449 * complete image has not yet been loaded, and it has not been dithered
1450 * and converted for the current output device.
1451 * <p>
1452 * If the image has not yet been completely loaded, then
1453 * <code>drawImage</code> returns <code>false</code>. As more of
1454 * the image becomes available, the process that draws the image notifies
1455 * the specified image observer.
1456 * @param img the specified image to be drawn.
1457 * This method does nothing if <code>img</code> is null.
1458 * @param x the <i>x</i> coordinate.
1459 * @param y the <i>y</i> coordinate.
1460 * @param bgcolor the background color to paint under the
1461 * non-opaque portions of the image.
1462 * In this WPathGraphics implementation,
1463 * this parameter can be null in which
1464 * case that background is made a transparent
1465 * white.
1466 * @param observer object to be notified as more of
1467 * the image is converted.
1468 * @see java.awt.Image
1469 * @see java.awt.image.ImageObserver
1470 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1471 * @since 1.0
1472 */
1473 public boolean drawImage(Image img, int x, int y,
1474 Color bgcolor,
1475 ImageObserver observer) {
1476
1477 if (img == null) {
1490
1491 return result;
1492 }
1493
1494 /**
1495 * Draws as much of the specified image as has already been scaled
1496 * to fit inside the specified rectangle.
1497 * <p>
1498 * The image is drawn inside the specified rectangle of this
1499 * graphics context's coordinate space, and is scaled if
1500 * necessary. Transparent pixels are drawn in the specified
1501 * background color.
1502 * This operation is equivalent to filling a rectangle of the
1503 * width and height of the specified image with the given color and then
1504 * drawing the image on top of it, but possibly more efficient.
1505 * <p>
1506 * This method returns immediately in all cases, even if the
1507 * entire image has not yet been scaled, dithered, and converted
1508 * for the current output device.
1509 * If the current output representation is not yet complete then
1510 * <code>drawImage</code> returns <code>false</code>. As more of
1511 * the image becomes available, the process that draws the image notifies
1512 * the specified image observer.
1513 * <p>
1514 * A scaled version of an image will not necessarily be
1515 * available immediately just because an unscaled version of the
1516 * image has been constructed for this output device. Each size of
1517 * the image may be cached separately and generated from the original
1518 * data in a separate image production sequence.
1519 * @param img the specified image to be drawn.
1520 * This method does nothing if <code>img</code> is null.
1521 * @param x the <i>x</i> coordinate.
1522 * @param y the <i>y</i> coordinate.
1523 * @param width the width of the rectangle.
1524 * @param height the height of the rectangle.
1525 * @param bgcolor the background color to paint under the
1526 * non-opaque portions of the image.
1527 * @param observer object to be notified as more of
1528 * the image is converted.
1529 * @see java.awt.Image
1530 * @see java.awt.image.ImageObserver
1531 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1532 * @since 1.0
1533 */
1534 public boolean drawImage(Image img, int x, int y,
1535 int width, int height,
1536 Color bgcolor,
1537 ImageObserver observer) {
1538
1539 if (img == null) {
1540 return true;
1549 } else {
1550 result = drawImage(img,
1551 x, y, x + width, y + height,
1552 0, 0, srcWidth, srcHeight,
1553 observer);
1554 }
1555
1556 return result;
1557 }
1558
1559 /**
1560 * Draws as much of the specified area of the specified image as is
1561 * currently available, scaling it on the fly to fit inside the
1562 * specified area of the destination drawable surface. Transparent pixels
1563 * do not affect whatever pixels are already there.
1564 * <p>
1565 * This method returns immediately in all cases, even if the
1566 * image area to be drawn has not yet been scaled, dithered, and converted
1567 * for the current output device.
1568 * If the current output representation is not yet complete then
1569 * <code>drawImage</code> returns <code>false</code>. As more of
1570 * the image becomes available, the process that draws the image notifies
1571 * the specified image observer.
1572 * <p>
1573 * This method always uses the unscaled version of the image
1574 * to render the scaled rectangle and performs the required
1575 * scaling on the fly. It does not use a cached, scaled version
1576 * of the image for this operation. Scaling of the image from source
1577 * to destination is performed such that the first coordinate
1578 * of the source rectangle is mapped to the first coordinate of
1579 * the destination rectangle, and the second source coordinate is
1580 * mapped to the second destination coordinate. The subimage is
1581 * scaled and flipped as needed to preserve those mappings.
1582 * @param img the specified image to be drawn
1583 * @param dx1 the <i>x</i> coordinate of the first corner of the
1584 * destination rectangle.
1585 * @param dy1 the <i>y</i> coordinate of the first corner of the
1586 * destination rectangle.
1587 * @param dx2 the <i>x</i> coordinate of the second corner of the
1588 * destination rectangle.
1589 * @param dy2 the <i>y</i> coordinate of the second corner of the
1611 return drawImage(img,
1612 dx1, dy1, dx2, dy2,
1613 sx1, sy1, sx2, sy2,
1614 null, observer);
1615 }
1616
1617 /**
1618 * Draws as much of the specified area of the specified image as is
1619 * currently available, scaling it on the fly to fit inside the
1620 * specified area of the destination drawable surface.
1621 * <p>
1622 * Transparent pixels are drawn in the specified background color.
1623 * This operation is equivalent to filling a rectangle of the
1624 * width and height of the specified image with the given color and then
1625 * drawing the image on top of it, but possibly more efficient.
1626 * <p>
1627 * This method returns immediately in all cases, even if the
1628 * image area to be drawn has not yet been scaled, dithered, and converted
1629 * for the current output device.
1630 * If the current output representation is not yet complete then
1631 * <code>drawImage</code> returns <code>false</code>. As more of
1632 * the image becomes available, the process that draws the image notifies
1633 * the specified image observer.
1634 * <p>
1635 * This method always uses the unscaled version of the image
1636 * to render the scaled rectangle and performs the required
1637 * scaling on the fly. It does not use a cached, scaled version
1638 * of the image for this operation. Scaling of the image from source
1639 * to destination is performed such that the first coordinate
1640 * of the source rectangle is mapped to the first coordinate of
1641 * the destination rectangle, and the second source coordinate is
1642 * mapped to the second destination coordinate. The subimage is
1643 * scaled and flipped as needed to preserve those mappings.
1644 * @param img the specified image to be drawn
1645 * This method does nothing if <code>img</code> is null.
1646 * @param dx1 the <i>x</i> coordinate of the first corner of the
1647 * destination rectangle.
1648 * @param dy1 the <i>y</i> coordinate of the first corner of the
1649 * destination rectangle.
1650 * @param dx2 the <i>x</i> coordinate of the second corner of the
1651 * destination rectangle.
1652 * @param dy2 the <i>y</i> coordinate of the second corner of the
1653 * destination rectangle.
1654 * @param sx1 the <i>x</i> coordinate of the first corner of the
1655 * source rectangle.
1656 * @param sy1 the <i>y</i> coordinate of the first corner of the
1657 * source rectangle.
1658 * @param sx2 the <i>x</i> coordinate of the second corner of the
1659 * source rectangle.
1660 * @param sy2 the <i>y</i> coordinate of the second corner of the
1661 * source rectangle.
1662 * @param bgcolor the background color to paint under the
1663 * non-opaque portions of the image.
1664 * @param observer object to be notified as more of the image is
1665 * scaled and converted.
1750 return true;
1751 }
1752
1753 return drawImageToPlatform(img, xForm, bgcolor,
1754 sx1, sy1, srcWidth, srcHeight, false);
1755
1756
1757 }
1758
1759 /**
1760 * Draws an image, applying a transform from image space into user space
1761 * before drawing.
1762 * The transformation from user space into device space is done with
1763 * the current transform in the Graphics2D.
1764 * The given transformation is applied to the image before the
1765 * transform attribute in the Graphics2D state is applied.
1766 * The rendering attributes applied include the clip, transform,
1767 * and composite attributes. Note that the result is
1768 * undefined, if the given transform is noninvertible.
1769 * @param img The image to be drawn.
1770 * This method does nothing if <code>img</code> is null.
1771 * @param xform The transformation from image space into user space.
1772 * @param obs The image observer to be notified as more of the image
1773 * is converted.
1774 * @see #transform
1775 * @see #setTransform
1776 * @see #setComposite
1777 * @see #clip
1778 * @see #setClip
1779 */
1780 public boolean drawImage(Image img,
1781 AffineTransform xform,
1782 ImageObserver obs) {
1783
1784 if (img == null) {
1785 return true;
1786 }
1787
1788 boolean result;
1789 int srcWidth = img.getWidth(null);
1790 int srcHeight = img.getHeight(null);
1792 if (srcWidth < 0 || srcHeight < 0) {
1793 result = false;
1794 } else {
1795 result = drawImageToPlatform(img, xform, null,
1796 0, 0, srcWidth, srcHeight, false);
1797 }
1798
1799 return result;
1800 }
1801
1802 /**
1803 * Draws a BufferedImage that is filtered with a BufferedImageOp.
1804 * The rendering attributes applied include the clip, transform
1805 * and composite attributes. This is equivalent to:
1806 * <pre>
1807 * img1 = op.filter(img, null);
1808 * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
1809 * </pre>
1810 * @param op The filter to be applied to the image before drawing.
1811 * @param img The BufferedImage to be drawn.
1812 * This method does nothing if <code>img</code> is null.
1813 * @param x,y The location in user space where the image should be drawn.
1814 * @see #transform
1815 * @see #setTransform
1816 * @see #setComposite
1817 * @see #clip
1818 * @see #setClip
1819 */
1820 public void drawImage(BufferedImage img,
1821 BufferedImageOp op,
1822 int x,
1823 int y) {
1824
1825 if (img == null) {
1826 return;
1827 }
1828
1829 int srcWidth = img.getWidth(null);
1830 int srcHeight = img.getHeight(null);
1831
1832 if (op != null) {
1836 return;
1837 } else {
1838 AffineTransform xform = new AffineTransform(1f,0f,0f,1f,x,y);
1839 drawImageToPlatform(img, xform, null,
1840 0, 0, srcWidth, srcHeight, false);
1841 }
1842
1843 }
1844
1845 /**
1846 * Draws an image, applying a transform from image space into user space
1847 * before drawing.
1848 * The transformation from user space into device space is done with
1849 * the current transform in the Graphics2D.
1850 * The given transformation is applied to the image before the
1851 * transform attribute in the Graphics2D state is applied.
1852 * The rendering attributes applied include the clip, transform,
1853 * and composite attributes. Note that the result is
1854 * undefined, if the given transform is noninvertible.
1855 * @param img The image to be drawn.
1856 * This method does nothing if <code>img</code> is null.
1857 * @param xform The transformation from image space into user space.
1858 * @see #transform
1859 * @see #setTransform
1860 * @see #setComposite
1861 * @see #clip
1862 * @see #setClip
1863 */
1864 public void drawRenderedImage(RenderedImage img,
1865 AffineTransform xform) {
1866
1867 if (img == null) {
1868 return;
1869 }
1870
1871 BufferedImage bufferedImage = null;
1872 int srcWidth = img.getWidth();
1873 int srcHeight = img.getHeight();
1874
1875 if (srcWidth <= 0 || srcHeight <= 0) {
1876 return;
|
160
161 Paint paint = getPaint();
162
163 try {
164 AffineTransform deviceTransform = getTransform();
165 if (getClip() != null) {
166 deviceClip(getClip().getPathIterator(deviceTransform));
167 }
168
169 deviceDrawLine(x1, y1, x2, y2, (Color) paint);
170
171 } catch (ClassCastException e) {
172 throw new IllegalArgumentException("Expected a Color instance");
173 }
174 }
175
176
177 /**
178 * Draws the outline of the specified rectangle.
179 * The left and right edges of the rectangle are at
180 * {@code x} and <code>x + width</code>.
181 * The top and bottom edges are at
182 * {@code y} and <code>y + height</code>.
183 * The rectangle is drawn using the graphics context's current color.
184 * @param x the <i>x</i> coordinate
185 * of the rectangle to be drawn.
186 * @param y the <i>y</i> coordinate
187 * of the rectangle to be drawn.
188 * @param width the width of the rectangle to be drawn.
189 * @param height the height of the rectangle to be drawn.
190 * @see java.awt.Graphics#fillRect
191 * @see java.awt.Graphics#clearRect
192 */
193 public void drawRect(int x, int y, int width, int height) {
194
195 Paint paint = getPaint();
196
197 try {
198 AffineTransform deviceTransform = getTransform();
199 if (getClip() != null) {
200 deviceClip(getClip().getPathIterator(deviceTransform));
201 }
202
203 deviceFrameRect(x, y, width, height, (Color) paint);
204
205 } catch (ClassCastException e) {
206 throw new IllegalArgumentException("Expected a Color instance");
207 }
208
209 }
210
211 /**
212 * Fills the specified rectangle.
213 * The left and right edges of the rectangle are at
214 * {@code x} and <code>x + width - 1</code>.
215 * The top and bottom edges are at
216 * {@code y} and <code>y + height - 1</code>.
217 * The resulting rectangle covers an area
218 * {@code width} pixels wide by
219 * {@code height} pixels tall.
220 * The rectangle is filled using the graphics context's current color.
221 * @param x the <i>x</i> coordinate
222 * of the rectangle to be filled.
223 * @param y the <i>y</i> coordinate
224 * of the rectangle to be filled.
225 * @param width the width of the rectangle to be filled.
226 * @param height the height of the rectangle to be filled.
227 * @see java.awt.Graphics#clearRect
228 * @see java.awt.Graphics#drawRect
229 */
230 public void fillRect(int x, int y, int width, int height){
231
232 Paint paint = getPaint();
233
234 try {
235 AffineTransform deviceTransform = getTransform();
236 if (getClip() != null) {
237 deviceClip(getClip().getPathIterator(deviceTransform));
238 }
239
240 deviceFillRect(x, y, width, height, (Color) paint);
241
242 } catch (ClassCastException e) {
243 throw new IllegalArgumentException("Expected a Color instance");
244 }
245 }
246
247 /**
248 * Clears the specified rectangle by filling it with the background
249 * color of the current drawing surface. This operation does not
250 * use the current paint mode.
251 * <p>
252 * Beginning with Java 1.1, the background color
253 * of offscreen images may be system dependent. Applications should
254 * use {@code setColor} followed by {@code fillRect} to
255 * ensure that an offscreen image is cleared to a specific color.
256 * @param x the <i>x</i> coordinate of the rectangle to clear.
257 * @param y the <i>y</i> coordinate of the rectangle to clear.
258 * @param width the width of the rectangle to clear.
259 * @param height the height of the rectangle to clear.
260 * @see java.awt.Graphics#fillRect(int, int, int, int)
261 * @see java.awt.Graphics#drawRect
262 * @see java.awt.Graphics#setColor(java.awt.Color)
263 * @see java.awt.Graphics#setPaintMode
264 * @see java.awt.Graphics#setXORMode(java.awt.Color)
265 */
266 public void clearRect(int x, int y, int width, int height) {
267
268 fill(new Rectangle2D.Float(x, y, width, height), getBackground());
269 }
270
271 /**
272 * Draws an outlined round-cornered rectangle using this graphics
273 * context's current color. The left and right edges of the rectangle
274 * are at {@code x} and <code>x + width</code>,
275 * respectively. The top and bottom edges of the rectangle are at
276 * {@code y} and <code>y + height</code>.
277 * @param x the <i>x</i> coordinate of the rectangle to be drawn.
278 * @param y the <i>y</i> coordinate of the rectangle to be drawn.
279 * @param width the width of the rectangle to be drawn.
280 * @param height the height of the rectangle to be drawn.
281 * @param arcWidth the horizontal diameter of the arc
282 * at the four corners.
283 * @param arcHeight the vertical diameter of the arc
284 * at the four corners.
285 * @see java.awt.Graphics#fillRoundRect
286 */
287 public void drawRoundRect(int x, int y, int width, int height,
288 int arcWidth, int arcHeight) {
289
290 draw(new RoundRectangle2D.Float(x, y,
291 width, height,
292 arcWidth, arcHeight));
293 }
294
295
296 /**
297 * Fills the specified rounded corner rectangle with the current color.
298 * The left and right edges of the rectangle
299 * are at {@code x} and <code>x + width - 1</code>,
300 * respectively. The top and bottom edges of the rectangle are at
301 * {@code y} and <code>y + height - 1</code>.
302 * @param x the <i>x</i> coordinate of the rectangle to be filled.
303 * @param y the <i>y</i> coordinate of the rectangle to be filled.
304 * @param width the width of the rectangle to be filled.
305 * @param height the height of the rectangle to be filled.
306 * @param arcWidth the horizontal diameter
307 * of the arc at the four corners.
308 * @param arcHeight the vertical diameter
309 * of the arc at the four corners.
310 * @see java.awt.Graphics#drawRoundRect
311 */
312 public void fillRoundRect(int x, int y, int width, int height,
313 int arcWidth, int arcHeight) {
314
315 fill(new RoundRectangle2D.Float(x, y,
316 width, height,
317 arcWidth, arcHeight));
318 }
319
320 /**
321 * Draws the outline of an oval.
322 * The result is a circle or ellipse that fits within the
323 * rectangle specified by the {@code x}, {@code y},
324 * {@code width}, and {@code height} arguments.
325 * <p>
326 * The oval covers an area that is
327 * <code>width + 1</code> pixels wide
328 * and <code>height + 1</code> pixels tall.
329 * @param x the <i>x</i> coordinate of the upper left
330 * corner of the oval to be drawn.
331 * @param y the <i>y</i> coordinate of the upper left
332 * corner of the oval to be drawn.
333 * @param width the width of the oval to be drawn.
334 * @param height the height of the oval to be drawn.
335 * @see java.awt.Graphics#fillOval
336 * @since 1.0
337 */
338 public void drawOval(int x, int y, int width, int height) {
339 draw(new Ellipse2D.Float(x, y, width, height));
340 }
341
342 /**
343 * Fills an oval bounded by the specified rectangle with the
344 * current color.
345 * @param x the <i>x</i> coordinate of the upper left corner
346 * of the oval to be filled.
347 * @param y the <i>y</i> coordinate of the upper left corner
348 * of the oval to be filled.
349 * @param width the width of the oval to be filled.
350 * @param height the height of the oval to be filled.
351 * @see java.awt.Graphics#drawOval
352 */
353 public void fillOval(int x, int y, int width, int height){
354
355 fill(new Ellipse2D.Float(x, y, width, height));
356 }
357
358 /**
359 * Draws the outline of a circular or elliptical arc
360 * covering the specified rectangle.
361 * <p>
362 * The resulting arc begins at {@code startAngle} and extends
363 * for {@code arcAngle} degrees, using the current color.
364 * Angles are interpreted such that 0 degrees
365 * is at the 3 o'clock position.
366 * A positive value indicates a counter-clockwise rotation
367 * while a negative value indicates a clockwise rotation.
368 * <p>
369 * The center of the arc is the center of the rectangle whose origin
370 * is (<i>x</i>, <i>y</i>) and whose size is specified by the
371 * {@code width} and {@code height} arguments.
372 * <p>
373 * The resulting arc covers an area
374 * <code>width + 1</code> pixels wide
375 * by <code>height + 1</code> pixels tall.
376 * <p>
377 * The angles are specified relative to the non-square extents of
378 * the bounding rectangle such that 45 degrees always falls on the
379 * line from the center of the ellipse to the upper right corner of
380 * the bounding rectangle. As a result, if the bounding rectangle is
381 * noticeably longer in one axis than the other, the angles to the
382 * start and end of the arc segment will be skewed farther along the
383 * longer axis of the bounds.
384 * @param x the <i>x</i> coordinate of the
385 * upper-left corner of the arc to be drawn.
386 * @param y the <i>y</i> coordinate of the
387 * upper-left corner of the arc to be drawn.
388 * @param width the width of the arc to be drawn.
389 * @param height the height of the arc to be drawn.
390 * @param startAngle the beginning angle.
391 * @param arcAngle the angular extent of the arc,
392 * relative to the start angle.
393 * @see java.awt.Graphics#fillArc
394 */
395 public void drawArc(int x, int y, int width, int height,
396 int startAngle, int arcAngle) {
397 draw(new Arc2D.Float(x, y, width, height,
398 startAngle, arcAngle,
399 Arc2D.OPEN));
400 }
401
402
403 /**
404 * Fills a circular or elliptical arc covering the specified rectangle.
405 * <p>
406 * The resulting arc begins at {@code startAngle} and extends
407 * for {@code arcAngle} degrees.
408 * Angles are interpreted such that 0 degrees
409 * is at the 3 o'clock position.
410 * A positive value indicates a counter-clockwise rotation
411 * while a negative value indicates a clockwise rotation.
412 * <p>
413 * The center of the arc is the center of the rectangle whose origin
414 * is (<i>x</i>, <i>y</i>) and whose size is specified by the
415 * {@code width} and {@code height} arguments.
416 * <p>
417 * The resulting arc covers an area
418 * <code>width + 1</code> pixels wide
419 * by <code>height + 1</code> pixels tall.
420 * <p>
421 * The angles are specified relative to the non-square extents of
422 * the bounding rectangle such that 45 degrees always falls on the
423 * line from the center of the ellipse to the upper right corner of
424 * the bounding rectangle. As a result, if the bounding rectangle is
425 * noticeably longer in one axis than the other, the angles to the
426 * start and end of the arc segment will be skewed farther along the
427 * longer axis of the bounds.
428 * @param x the <i>x</i> coordinate of the
429 * upper-left corner of the arc to be filled.
430 * @param y the <i>y</i> coordinate of the
431 * upper-left corner of the arc to be filled.
432 * @param width the width of the arc to be filled.
433 * @param height the height of the arc to be filled.
434 * @param startAngle the beginning angle.
435 * @param arcAngle the angular extent of the arc,
461
462 if (nPoints == 2) {
463 draw(new Line2D.Float(xPoints[0], yPoints[0],
464 xPoints[1], yPoints[1]));
465 } else if (nPoints > 2) {
466 Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD, nPoints);
467 path.moveTo(xPoints[0], yPoints[0]);
468 for(int i = 1; i < nPoints; i++) {
469 path.lineTo(xPoints[i], yPoints[i]);
470 }
471 draw(path);
472 }
473 }
474
475
476 /**
477 * Draws a closed polygon defined by
478 * arrays of <i>x</i> and <i>y</i> coordinates.
479 * Each pair of (<i>x</i>, <i>y</i>) coordinates defines a point.
480 * <p>
481 * This method draws the polygon defined by {@code nPoint} line
482 * segments, where the first <code>nPoint - 1</code>
483 * line segments are line segments from
484 * <code>(xPoints[i - 1], yPoints[i - 1])</code>
485 * to <code>(xPoints[i], yPoints[i])</code>, for
486 * 1 ≤ <i>i</i> ≤ {@code nPoints}.
487 * The figure is automatically closed by drawing a line connecting
488 * the final point to the first point, if those points are different.
489 * @param xPoints a an array of {@code x} coordinates.
490 * @param yPoints a an array of {@code y} coordinates.
491 * @param nPoints a the total number of points.
492 * @see java.awt.Graphics#fillPolygon
493 * @see java.awt.Graphics#drawPolyline
494 */
495 public void drawPolygon(int xPoints[], int yPoints[],
496 int nPoints) {
497
498 draw(new Polygon(xPoints, yPoints, nPoints));
499 }
500
501 /**
502 * Draws the outline of a polygon defined by the specified
503 * {@code Polygon} object.
504 * @param p the polygon to draw.
505 * @see java.awt.Graphics#fillPolygon
506 * @see java.awt.Graphics#drawPolyline
507 */
508 public void drawPolygon(Polygon p) {
509 draw(p);
510 }
511
512 /**
513 * Fills a closed polygon defined by
514 * arrays of <i>x</i> and <i>y</i> coordinates.
515 * <p>
516 * This method draws the polygon defined by {@code nPoint} line
517 * segments, where the first <code>nPoint - 1</code>
518 * line segments are line segments from
519 * <code>(xPoints[i - 1], yPoints[i - 1])</code>
520 * to <code>(xPoints[i], yPoints[i])</code>, for
521 * 1 ≤ <i>i</i> ≤ {@code nPoints}.
522 * The figure is automatically closed by drawing a line connecting
523 * the final point to the first point, if those points are different.
524 * <p>
525 * The area inside the polygon is defined using an
526 * even-odd fill rule, also known as the alternating rule.
527 * @param xPoints a an array of {@code x} coordinates.
528 * @param yPoints a an array of {@code y} coordinates.
529 * @param nPoints a the total number of points.
530 * @see java.awt.Graphics#drawPolygon(int[], int[], int)
531 */
532 public void fillPolygon(int xPoints[], int yPoints[],
533 int nPoints) {
534
535 fill(new Polygon(xPoints, yPoints, nPoints));
536 }
537
538
539 /**
540 * Fills the polygon defined by the specified Polygon object with
541 * the graphics context's current color.
542 * <p>
543 * The area inside the polygon is defined using an
544 * even-odd fill rule, also known as the alternating rule.
545 * @param p the polygon to fill.
546 * @see java.awt.Graphics#drawPolygon(int[], int[], int)
547 */
548 public void fillPolygon(Polygon p) {
1072 * solid colors and so we do not expect the cast of Paint
1073 * to Color to fail. If it does fail then something went
1074 * wrong, like the app draw a page with a solid color but
1075 * then redrew it with a Gradient.
1076 */
1077 } catch (ClassCastException e) {
1078 throw new IllegalArgumentException("Expected a Color instance");
1079 }
1080 }
1081
1082 public void fill(Shape s, Color color) {
1083 AffineTransform deviceTransform = getTransform();
1084
1085 if (getClip() != null) {
1086 deviceClip(getClip().getPathIterator(deviceTransform));
1087 }
1088 deviceFill(s.getPathIterator(deviceTransform), color);
1089 }
1090
1091 /**
1092 * Fill the path defined by {@code pathIter}
1093 * with the specified color.
1094 * The path is provided in device coordinates.
1095 */
1096 protected abstract void deviceFill(PathIterator pathIter, Color color);
1097
1098 /*
1099 * Set the clipping path to that defined by
1100 * the passed in {@code PathIterator}.
1101 */
1102 protected abstract void deviceClip(PathIterator pathIter);
1103
1104 /*
1105 * Draw the outline of the rectangle without using path
1106 * if supported by platform.
1107 */
1108 protected abstract void deviceFrameRect(int x, int y,
1109 int width, int height,
1110 Color color);
1111
1112 /*
1113 * Draw a line without using path if supported by platform.
1114 */
1115 protected abstract void deviceDrawLine(int xBegin, int yBegin,
1116 int xEnd, int yEnd, Color color);
1117
1118 /*
1119 * Fill a rectangle using specified color.
1120 */
1309 }
1310 } else if (startx < 0) {
1311 startx = i;
1312 }
1313 }
1314 if (startx >= 0) {
1315 subImage = bufferedImage.getSubimage(startx, j,
1316 right - startx, 1);
1317 xform.translate(startx, j);
1318 drawImageToPlatform(subImage, xform, bgcolor,
1319 0, 0, right - startx, 1, true);
1320 xform.translate(-startx, -j);
1321 }
1322 }
1323 return true;
1324 }
1325
1326
1327
1328 /**
1329 * The various {@code drawImage()} methods for
1330 * {@code PathGraphics} are all decomposed
1331 * into an invocation of {@code drawImageToPlatform}.
1332 * The portion of the passed in image defined by
1333 * {@code srcX, srcY, srcWidth, and srcHeight}
1334 * is transformed by the supplied AffineTransform and
1335 * drawn using PS to the printer context.
1336 *
1337 * @param img The image to be drawn.
1338 * This method does nothing if {@code img} is null.
1339 * @param xform Used to transform the image before drawing.
1340 * This can be null.
1341 * @param bgcolor This color is drawn where the image has transparent
1342 * pixels. If this parameter is null then the
1343 * pixels already in the destination should show
1344 * through.
1345 * @param srcX With srcY this defines the upper-left corner
1346 * of the portion of the image to be drawn.
1347 *
1348 * @param srcY With srcX this defines the upper-left corner
1349 * of the portion of the image to be drawn.
1350 * @param srcWidth The width of the portion of the image to
1351 * be drawn.
1352 * @param srcHeight The height of the portion of the image to
1353 * be drawn.
1354 * @param handlingTransparency if being recursively called to
1355 * print opaque region of transparent image
1356 */
1357 protected abstract boolean
1358 drawImageToPlatform(Image img, AffineTransform xform,
1359 Color bgcolor,
1360 int srcX, int srcY,
1361 int srcWidth, int srcHeight,
1362 boolean handlingTransparency);
1363
1364 /**
1365 * Draws as much of the specified image as is currently available.
1366 * The image is drawn with its top-left corner at
1367 * (<i>x</i>, <i>y</i>) in this graphics context's coordinate
1368 * space. Transparent pixels in the image do not affect whatever
1369 * pixels are already there.
1370 * <p>
1371 * This method returns immediately in all cases, even if the
1372 * complete image has not yet been loaded, and it has not been dithered
1373 * and converted for the current output device.
1374 * <p>
1375 * If the image has not yet been completely loaded, then
1376 * {@code drawImage} returns {@code false}. As more of
1377 * the image becomes available, the process that draws the image notifies
1378 * the specified image observer.
1379 * @param img the specified image to be drawn.
1380 * @param x the <i>x</i> coordinate.
1381 * @param y the <i>y</i> coordinate.
1382 * @param observer object to be notified as more of
1383 * the image is converted.
1384 * @see java.awt.Image
1385 * @see java.awt.image.ImageObserver
1386 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1387 * @since 1.0
1388 */
1389 public boolean drawImage(Image img, int x, int y,
1390 ImageObserver observer) {
1391
1392 return drawImage(img, x, y, null, observer);
1393 }
1394
1395 /**
1396 * Draws as much of the specified image as has already been scaled
1397 * to fit inside the specified rectangle.
1398 * <p>
1399 * The image is drawn inside the specified rectangle of this
1400 * graphics context's coordinate space, and is scaled if
1401 * necessary. Transparent pixels do not affect whatever pixels
1402 * are already there.
1403 * <p>
1404 * This method returns immediately in all cases, even if the
1405 * entire image has not yet been scaled, dithered, and converted
1406 * for the current output device.
1407 * If the current output representation is not yet complete, then
1408 * {@code drawImage} returns {@code false}. As more of
1409 * the image becomes available, the process that draws the image notifies
1410 * the image observer by calling its {@code imageUpdate} method.
1411 * <p>
1412 * A scaled version of an image will not necessarily be
1413 * available immediately just because an unscaled version of the
1414 * image has been constructed for this output device. Each size of
1415 * the image may be cached separately and generated from the original
1416 * data in a separate image production sequence.
1417 * @param img the specified image to be drawn.
1418 * @param x the <i>x</i> coordinate.
1419 * @param y the <i>y</i> coordinate.
1420 * @param width the width of the rectangle.
1421 * @param height the height of the rectangle.
1422 * @param observer object to be notified as more of
1423 * the image is converted.
1424 * @see java.awt.Image
1425 * @see java.awt.image.ImageObserver
1426 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1427 * @since 1.0
1428 */
1429 public boolean drawImage(Image img, int x, int y,
1430 int width, int height,
1433 return drawImage(img, x, y, width, height, null, observer);
1434
1435 }
1436
1437 /*
1438 * Draws as much of the specified image as is currently available.
1439 * The image is drawn with its top-left corner at
1440 * (<i>x</i>, <i>y</i>) in this graphics context's coordinate
1441 * space. Transparent pixels are drawn in the specified
1442 * background color.
1443 * <p>
1444 * This operation is equivalent to filling a rectangle of the
1445 * width and height of the specified image with the given color and then
1446 * drawing the image on top of it, but possibly more efficient.
1447 * <p>
1448 * This method returns immediately in all cases, even if the
1449 * complete image has not yet been loaded, and it has not been dithered
1450 * and converted for the current output device.
1451 * <p>
1452 * If the image has not yet been completely loaded, then
1453 * {@code drawImage} returns {@code false}. As more of
1454 * the image becomes available, the process that draws the image notifies
1455 * the specified image observer.
1456 * @param img the specified image to be drawn.
1457 * This method does nothing if {@code img} is null.
1458 * @param x the <i>x</i> coordinate.
1459 * @param y the <i>y</i> coordinate.
1460 * @param bgcolor the background color to paint under the
1461 * non-opaque portions of the image.
1462 * In this WPathGraphics implementation,
1463 * this parameter can be null in which
1464 * case that background is made a transparent
1465 * white.
1466 * @param observer object to be notified as more of
1467 * the image is converted.
1468 * @see java.awt.Image
1469 * @see java.awt.image.ImageObserver
1470 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1471 * @since 1.0
1472 */
1473 public boolean drawImage(Image img, int x, int y,
1474 Color bgcolor,
1475 ImageObserver observer) {
1476
1477 if (img == null) {
1490
1491 return result;
1492 }
1493
1494 /**
1495 * Draws as much of the specified image as has already been scaled
1496 * to fit inside the specified rectangle.
1497 * <p>
1498 * The image is drawn inside the specified rectangle of this
1499 * graphics context's coordinate space, and is scaled if
1500 * necessary. Transparent pixels are drawn in the specified
1501 * background color.
1502 * This operation is equivalent to filling a rectangle of the
1503 * width and height of the specified image with the given color and then
1504 * drawing the image on top of it, but possibly more efficient.
1505 * <p>
1506 * This method returns immediately in all cases, even if the
1507 * entire image has not yet been scaled, dithered, and converted
1508 * for the current output device.
1509 * If the current output representation is not yet complete then
1510 * {@code drawImage} returns {@code false}. As more of
1511 * the image becomes available, the process that draws the image notifies
1512 * the specified image observer.
1513 * <p>
1514 * A scaled version of an image will not necessarily be
1515 * available immediately just because an unscaled version of the
1516 * image has been constructed for this output device. Each size of
1517 * the image may be cached separately and generated from the original
1518 * data in a separate image production sequence.
1519 * @param img the specified image to be drawn.
1520 * This method does nothing if {@code img} is null.
1521 * @param x the <i>x</i> coordinate.
1522 * @param y the <i>y</i> coordinate.
1523 * @param width the width of the rectangle.
1524 * @param height the height of the rectangle.
1525 * @param bgcolor the background color to paint under the
1526 * non-opaque portions of the image.
1527 * @param observer object to be notified as more of
1528 * the image is converted.
1529 * @see java.awt.Image
1530 * @see java.awt.image.ImageObserver
1531 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1532 * @since 1.0
1533 */
1534 public boolean drawImage(Image img, int x, int y,
1535 int width, int height,
1536 Color bgcolor,
1537 ImageObserver observer) {
1538
1539 if (img == null) {
1540 return true;
1549 } else {
1550 result = drawImage(img,
1551 x, y, x + width, y + height,
1552 0, 0, srcWidth, srcHeight,
1553 observer);
1554 }
1555
1556 return result;
1557 }
1558
1559 /**
1560 * Draws as much of the specified area of the specified image as is
1561 * currently available, scaling it on the fly to fit inside the
1562 * specified area of the destination drawable surface. Transparent pixels
1563 * do not affect whatever pixels are already there.
1564 * <p>
1565 * This method returns immediately in all cases, even if the
1566 * image area to be drawn has not yet been scaled, dithered, and converted
1567 * for the current output device.
1568 * If the current output representation is not yet complete then
1569 * {@code drawImage} returns {@code false}. As more of
1570 * the image becomes available, the process that draws the image notifies
1571 * the specified image observer.
1572 * <p>
1573 * This method always uses the unscaled version of the image
1574 * to render the scaled rectangle and performs the required
1575 * scaling on the fly. It does not use a cached, scaled version
1576 * of the image for this operation. Scaling of the image from source
1577 * to destination is performed such that the first coordinate
1578 * of the source rectangle is mapped to the first coordinate of
1579 * the destination rectangle, and the second source coordinate is
1580 * mapped to the second destination coordinate. The subimage is
1581 * scaled and flipped as needed to preserve those mappings.
1582 * @param img the specified image to be drawn
1583 * @param dx1 the <i>x</i> coordinate of the first corner of the
1584 * destination rectangle.
1585 * @param dy1 the <i>y</i> coordinate of the first corner of the
1586 * destination rectangle.
1587 * @param dx2 the <i>x</i> coordinate of the second corner of the
1588 * destination rectangle.
1589 * @param dy2 the <i>y</i> coordinate of the second corner of the
1611 return drawImage(img,
1612 dx1, dy1, dx2, dy2,
1613 sx1, sy1, sx2, sy2,
1614 null, observer);
1615 }
1616
1617 /**
1618 * Draws as much of the specified area of the specified image as is
1619 * currently available, scaling it on the fly to fit inside the
1620 * specified area of the destination drawable surface.
1621 * <p>
1622 * Transparent pixels are drawn in the specified background color.
1623 * This operation is equivalent to filling a rectangle of the
1624 * width and height of the specified image with the given color and then
1625 * drawing the image on top of it, but possibly more efficient.
1626 * <p>
1627 * This method returns immediately in all cases, even if the
1628 * image area to be drawn has not yet been scaled, dithered, and converted
1629 * for the current output device.
1630 * If the current output representation is not yet complete then
1631 * {@code drawImage} returns {@code false}. As more of
1632 * the image becomes available, the process that draws the image notifies
1633 * the specified image observer.
1634 * <p>
1635 * This method always uses the unscaled version of the image
1636 * to render the scaled rectangle and performs the required
1637 * scaling on the fly. It does not use a cached, scaled version
1638 * of the image for this operation. Scaling of the image from source
1639 * to destination is performed such that the first coordinate
1640 * of the source rectangle is mapped to the first coordinate of
1641 * the destination rectangle, and the second source coordinate is
1642 * mapped to the second destination coordinate. The subimage is
1643 * scaled and flipped as needed to preserve those mappings.
1644 * @param img the specified image to be drawn
1645 * This method does nothing if {@code img} is null.
1646 * @param dx1 the <i>x</i> coordinate of the first corner of the
1647 * destination rectangle.
1648 * @param dy1 the <i>y</i> coordinate of the first corner of the
1649 * destination rectangle.
1650 * @param dx2 the <i>x</i> coordinate of the second corner of the
1651 * destination rectangle.
1652 * @param dy2 the <i>y</i> coordinate of the second corner of the
1653 * destination rectangle.
1654 * @param sx1 the <i>x</i> coordinate of the first corner of the
1655 * source rectangle.
1656 * @param sy1 the <i>y</i> coordinate of the first corner of the
1657 * source rectangle.
1658 * @param sx2 the <i>x</i> coordinate of the second corner of the
1659 * source rectangle.
1660 * @param sy2 the <i>y</i> coordinate of the second corner of the
1661 * source rectangle.
1662 * @param bgcolor the background color to paint under the
1663 * non-opaque portions of the image.
1664 * @param observer object to be notified as more of the image is
1665 * scaled and converted.
1750 return true;
1751 }
1752
1753 return drawImageToPlatform(img, xForm, bgcolor,
1754 sx1, sy1, srcWidth, srcHeight, false);
1755
1756
1757 }
1758
1759 /**
1760 * Draws an image, applying a transform from image space into user space
1761 * before drawing.
1762 * The transformation from user space into device space is done with
1763 * the current transform in the Graphics2D.
1764 * The given transformation is applied to the image before the
1765 * transform attribute in the Graphics2D state is applied.
1766 * The rendering attributes applied include the clip, transform,
1767 * and composite attributes. Note that the result is
1768 * undefined, if the given transform is noninvertible.
1769 * @param img The image to be drawn.
1770 * This method does nothing if {@code img} is null.
1771 * @param xform The transformation from image space into user space.
1772 * @param obs The image observer to be notified as more of the image
1773 * is converted.
1774 * @see #transform
1775 * @see #setTransform
1776 * @see #setComposite
1777 * @see #clip
1778 * @see #setClip
1779 */
1780 public boolean drawImage(Image img,
1781 AffineTransform xform,
1782 ImageObserver obs) {
1783
1784 if (img == null) {
1785 return true;
1786 }
1787
1788 boolean result;
1789 int srcWidth = img.getWidth(null);
1790 int srcHeight = img.getHeight(null);
1792 if (srcWidth < 0 || srcHeight < 0) {
1793 result = false;
1794 } else {
1795 result = drawImageToPlatform(img, xform, null,
1796 0, 0, srcWidth, srcHeight, false);
1797 }
1798
1799 return result;
1800 }
1801
1802 /**
1803 * Draws a BufferedImage that is filtered with a BufferedImageOp.
1804 * The rendering attributes applied include the clip, transform
1805 * and composite attributes. This is equivalent to:
1806 * <pre>
1807 * img1 = op.filter(img, null);
1808 * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
1809 * </pre>
1810 * @param op The filter to be applied to the image before drawing.
1811 * @param img The BufferedImage to be drawn.
1812 * This method does nothing if {@code img} is null.
1813 * @param x,y The location in user space where the image should be drawn.
1814 * @see #transform
1815 * @see #setTransform
1816 * @see #setComposite
1817 * @see #clip
1818 * @see #setClip
1819 */
1820 public void drawImage(BufferedImage img,
1821 BufferedImageOp op,
1822 int x,
1823 int y) {
1824
1825 if (img == null) {
1826 return;
1827 }
1828
1829 int srcWidth = img.getWidth(null);
1830 int srcHeight = img.getHeight(null);
1831
1832 if (op != null) {
1836 return;
1837 } else {
1838 AffineTransform xform = new AffineTransform(1f,0f,0f,1f,x,y);
1839 drawImageToPlatform(img, xform, null,
1840 0, 0, srcWidth, srcHeight, false);
1841 }
1842
1843 }
1844
1845 /**
1846 * Draws an image, applying a transform from image space into user space
1847 * before drawing.
1848 * The transformation from user space into device space is done with
1849 * the current transform in the Graphics2D.
1850 * The given transformation is applied to the image before the
1851 * transform attribute in the Graphics2D state is applied.
1852 * The rendering attributes applied include the clip, transform,
1853 * and composite attributes. Note that the result is
1854 * undefined, if the given transform is noninvertible.
1855 * @param img The image to be drawn.
1856 * This method does nothing if {@code img} is null.
1857 * @param xform The transformation from image space into user space.
1858 * @see #transform
1859 * @see #setTransform
1860 * @see #setComposite
1861 * @see #clip
1862 * @see #setClip
1863 */
1864 public void drawRenderedImage(RenderedImage img,
1865 AffineTransform xform) {
1866
1867 if (img == null) {
1868 return;
1869 }
1870
1871 BufferedImage bufferedImage = null;
1872 int srcWidth = img.getWidth();
1873 int srcHeight = img.getHeight();
1874
1875 if (srcWidth <= 0 || srcHeight <= 0) {
1876 return;
|