Skip to content

Commit

Permalink
Added GraphicsObject.renderToBuffer()
Browse files Browse the repository at this point in the history
  • Loading branch information
pcantrell committed Sep 15, 2024
1 parent 279fb24 commit a43ddfb
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 18 deletions.
14 changes: 14 additions & 0 deletions src/edu/macalester/graphics/GraphicsObject.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package edu.macalester.graphics;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -39,6 +41,18 @@ final void draw(Graphics2D gc) {
*/
protected abstract void drawInLocalCoordinates(Graphics2D gc);

/**
* Renders this graphics object to an offscreen pixel buffer.
* @param image The destination buffer.
*/
public void renderToBuffer(BufferedImage image) {
var gc = image.createGraphics();
gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gc.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
gc.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
draw(gc);
}

/**
* Gets the position of the object on the canvas. The “position” is typically the upper left,
* but this can vary. With text, for example, the y component of the position is the baseline,
Expand Down
24 changes: 6 additions & 18 deletions test/edu/macalester/graphics/testsupport/RenderingTestMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,27 +137,12 @@ public void render(BufferedImage image, GraphicsObject gobj) {
public abstract void render(BufferedImage image, GraphicsObject gobj);

private static void renderWithBounds(BufferedImage image, GraphicsObject gobj) {
var gc = image.createGraphics();
gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gc.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
gc.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

// This messy reflection code is secretly just `gobj.draw(gc)`. We could make
// GraphicsObject.draw() a public method, but it would confuse students by showing up in
// autocomplete. We could move this class into the same package as GraphicsObject, but
// that makes the tests harder to navigate. The mess thus lives here.
try {
var drawMethod = GraphicsObject.class.getDeclaredMethod("draw", new Class[] { Graphics2D.class });
drawMethod.setAccessible(true);
drawMethod.invoke(gobj, gc);
} catch (Exception e) {
throw new RuntimeException("Unable to draw " + gobj, e);
}
visualizeBounds(gc, gobj);
gobj.renderToBuffer(image);
visualizeBounds(image, gobj);
}

/// Draws printer-style crop marks around the bounding box of the graphics object.
private static void visualizeBounds(Graphics2D g, GraphicsObject gobj) {
private static void visualizeBounds(BufferedImage image, GraphicsObject gobj) {
var bounds = gobj.getBoundsInParent();
var cropMarks = new Path2D.Double(GeneralPath.WIND_EVEN_ODD);
for(int side = 0; side < 2; side++) {
Expand All @@ -172,6 +157,9 @@ private static void visualizeBounds(Graphics2D g, GraphicsObject gobj) {
cropMarks.lineTo(x, y + (side * 2 - 1) * 4);
}
}

var g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(0.5f));
g.setPaint(new Color(0, 0, 0, 128));
g.draw(cropMarks);
Expand Down

0 comments on commit a43ddfb

Please sign in to comment.