CaRMtl/de/erichseifert/vectorgraphics2d/VectorGraphics2D.java
2018-09-04 22:51:42 -04:00

958 lines
25 KiB
Java

/*
* VectorGraphics2D: Vector export for Java(R) Graphics2D
*
* (C) Copyright 2010 Erich Seifert <dev[at]erichseifert.de>
*
* This file is part of VectorGraphics2D.
*
* VectorGraphics2D is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VectorGraphics2D is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with VectorGraphics2D. If not, see <http://www.gnu.org/licenses/>.
*/
package de.erichseifert.vectorgraphics2d;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.MultipleGradientPaint;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.io.UnsupportedEncodingException;
import java.text.AttributedCharacterIterator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* Base for classed that want to implement vector export.
* @author Erich Seifert
*/
public abstract class VectorGraphics2D extends Graphics2D {
/** Constants to define how fonts are rendered. */
public static enum FontRendering {
/** Constant indicating that fonts should be rendered as
text objects. */
TEXT,
/** Constant indicating that fonts should be converted to vectors. */
VECTORS
}
/** Maximal resolution for image rastering. */
private static final int DEFAULT_PAINT_IMAGE_SIZE_MAXIMUM = 128;
/** Document contents. */
private final StringBuffer document;
/** Rectangular bounds of the documents. */
private final Rectangle2D bounds;
/** Resolution in dots per inch that is used to raster paints. */
private double resolution;
/** Maximal size of images that are used to raster paints. */
private int rasteredImageSizeMaximum;
/** Font rendering mode. */
private FontRendering fontRendering;
/** Flag that stores whether affine transformations have been applied. */
private boolean transformed;
/** Rendering hints. */
private final RenderingHints hints;
/** Current background color. */
private Color background;
/** Current foreground color. */
private Color color;
/** Shape used for clipping paint operations. */
private Shape clip;
/** Method used for compositing. */
private Composite composite;
/** Device configuration settings. */
private final GraphicsConfiguration deviceConfig;
/** Current font. */
private Font font;
/** Context settings used to render fonts. */
private final FontRenderContext fontRenderContext;
/** Paint used to fill shapes. */
private Paint paint;
/** Stroke used for drawing shapes. */
private Stroke stroke;
/** Current transformation matrix. */
private final AffineTransform transform;
/** XOR mode used for rendering. */
private Color xorMode;
/**
* Constructor to initialize a new {@code VectorGraphics2D} document.
* The dimensions of the document must be passed.
* @param x Horizontal position of document origin.
* @param y Vertical position of document origin.
* @param width Width of document.
* @param height Height of document.
*/
public VectorGraphics2D(double x, double y, double width, double height) {
hints = new RenderingHints(new HashMap<RenderingHints.Key, Object>());
document = new StringBuffer();
bounds = new Rectangle2D.Double(x, y, width, height);
fontRendering = FontRendering.TEXT;
resolution = 72.0;
rasteredImageSizeMaximum = DEFAULT_PAINT_IMAGE_SIZE_MAXIMUM;
background = Color.WHITE;
color = Color.BLACK;
composite = AlphaComposite.getInstance(AlphaComposite.CLEAR);
deviceConfig = null;
font = Font.decode(null);
fontRenderContext = new FontRenderContext(null, false, true);
paint = color;
stroke = new BasicStroke(1f);
transform = new AffineTransform();
transformed = false;
xorMode = Color.BLACK;
}
@Override
public void addRenderingHints(Map<?,?> hints) {
this.hints.putAll(hints);
}
@Override
public void clip(Shape s) {
if ((getClip() != null) && (s != null)) {
Area clipAreaOld = new Area(getClip());
Area clipAreaNew = new Area(s);
clipAreaNew.intersect(clipAreaOld);
s = clipAreaNew;
}
setClip(s);
}
@Override
public void draw(Shape s) {
writeShape(s);
writeClosingDraw(s);
}
@Override
public void drawGlyphVector(GlyphVector g, float x, float y) {
draw(g.getOutline(x, y));
}
@Override
public boolean drawImage(Image img, AffineTransform xform,
ImageObserver obs) {
BufferedImage bimg = getTransformedImage(img, xform);
drawImage(bimg, null, bimg.getMinX(), bimg.getMinY());
return true;
}
@Override
public void drawImage(BufferedImage img, BufferedImageOp op,
int x, int y) {
if (op != null) {
img = op.filter(img, null);
}
drawImage(img, x, y, img.getWidth(), img.getHeight(), null);
}
@Override
public void drawRenderableImage(RenderableImage img,
AffineTransform xform) {
drawRenderedImage(img.createDefaultRendering(), xform);
}
@Override
public void drawRenderedImage(RenderedImage img,
AffineTransform xform) {
// TODO Implement
//throw new UnsupportedOperationException("Rendered images aren't supported.");
}
@Override
public void drawString(String str, int x, int y) {
drawString(str, (float) x, (float) y);
}
@Override
public void drawString(String str, float x, float y) {
if (str != null && str.trim().isEmpty()) {
return;
}
switch (getFontRendering()) {
case VECTORS:
TextLayout layout = new TextLayout(str, getFont(),
getFontRenderContext());
Shape s = layout.getOutline(
AffineTransform.getTranslateInstance(x, y));
fill(s);
break;
case TEXT:
writeString(str, x, y);
break;
default:
throw new IllegalStateException("Unknown font rendering mode.");
}
}
@Override
public void drawString(AttributedCharacterIterator iterator,
int x, int y) {
drawString(iterator, (float) x, (float) y);
}
@Override
public void drawString(AttributedCharacterIterator iterator,
float x, float y) {
// TODO Take text formatting into account
StringBuffer buf = new StringBuffer();
for (char c = iterator.first(); c != AttributedCharacterIterator.DONE;
c = iterator.next()) {
buf.append(c);
}
drawString(buf.toString(), x, y);
}
@Override
public void fill(Shape s) {
writeShape(s);
writeClosingFill(s);
}
@Override
public Color getBackground() {
return background;
}
@Override
public Composite getComposite() {
return composite;
}
@Override
public GraphicsConfiguration getDeviceConfiguration() {
return deviceConfig;
}
@Override
public FontRenderContext getFontRenderContext() {
return fontRenderContext;
}
@Override
public Paint getPaint() {
return paint;
}
@Override
public Object getRenderingHint(RenderingHints.Key hintKey) {
if (RenderingHints.KEY_ANTIALIASING.equals(hintKey)) {
return RenderingHints.VALUE_ANTIALIAS_OFF;
} else if (RenderingHints.KEY_TEXT_ANTIALIASING.equals(hintKey)) {
return RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
} else if (RenderingHints.KEY_FRACTIONALMETRICS.equals(hintKey)) {
return RenderingHints.VALUE_FRACTIONALMETRICS_ON;
}
return hints.get(hintKey);
}
@Override
public RenderingHints getRenderingHints() {
return hints;
}
@Override
public Stroke getStroke() {
return stroke;
}
@Override
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
if (onStroke) {
Shape sStroke = getStroke().createStrokedShape(s);
return sStroke.intersects(rect);
} else {
return s.intersects(rect);
}
}
@Override
public void setBackground(Color color) {
background = color;
}
@Override
public void setComposite(Composite comp) {
composite = comp;
}
@Override
public void setPaint(Paint paint) {
if (paint != null) {
this.paint = paint;
if (paint instanceof Color) {
setColor((Color) paint);
} else if (paint instanceof MultipleGradientPaint) {
// Set brightest or least opaque color for gradients
Color[] colors = ((MultipleGradientPaint) paint).getColors();
if (colors.length == 1) {
setColor(colors[0]);
} else if (colors.length > 1) {
Color colLight = colors[0];
float brightness = getBrightness(colLight);
int alpha = colLight.getAlpha();
for (int i = 1; i < colors.length; i++) {
Color c = colors[i];
float b = getBrightness(c);
int a = c.getAlpha();
if (b < brightness || a < alpha) {
colLight = c;
brightness = b;
}
}
setColor(colLight);
}
}
}
}
/**
* Utility method to get the brightness of a specified color.
* @param c Color.
* @return Brightness value between 0f (black) and 1f (white).
*/
private static float getBrightness(Color c) {
return Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null)[2];
}
@Override
public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) {
hints.put(hintKey, hintValue);
}
@Override
public void setRenderingHints(Map<?, ?> hints) {
this.hints.putAll(hints);
}
@Override
public void setStroke(Stroke s) {
stroke = s;
}
@Override
public AffineTransform getTransform() {
return new AffineTransform(transform);
}
@Override
public void setTransform(AffineTransform tx) {
setAffineTransform(tx);
}
/**
* Sets the current transformation.
* @param tx Current transformation
*/
protected void setAffineTransform(AffineTransform tx) {
if (!transform.equals(tx)) {
transform.setTransform(tx);
transformed = true;
}
}
@Override
public void shear(double shx, double shy) {
AffineTransform transform = getTransform();
transform.shear(shx, shy);
setAffineTransform(transform);
}
@Override
public void transform(AffineTransform tx) {
AffineTransform transform = getTransform();
transform.concatenate(tx);
setAffineTransform(transform);
}
@Override
public void translate(int x, int y) {
translate((double) x, (double) y);
}
@Override
public void translate(double tx, double ty) {
AffineTransform transform = getTransform();
transform.translate(tx, ty);
setAffineTransform(transform);
}
@Override
public void rotate(double theta) {
AffineTransform transform = getTransform();
transform.rotate(theta);
setAffineTransform(transform);
}
@Override
public void rotate(double theta, double x, double y) {
AffineTransform transform = getTransform();
transform.rotate(theta, x, y);
setAffineTransform(transform);
}
@Override
public void scale(double sx, double sy) {
AffineTransform transform = getTransform();
transform.scale(sx, sy);
setAffineTransform(transform);
}
@Override
public void clearRect(int x, int y, int width, int height) {
// TODO Implement
//throw new UnsupportedOperationException("clearRect() isn't supported by VectorGraphics2D.");
}
@Override
public void clipRect(int x, int y, int width, int height) {
clip(new Rectangle(x, y, width, height));
}
@Override
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
// TODO Implement
//throw new UnsupportedOperationException("copyArea() isn't supported by VectorGraphics2D.");
}
@Override
public Graphics create() {
// TODO Implement
return this;
}
@Override
public void dispose() {
// TODO Implement
}
@Override
public void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle) {
draw(new Arc2D.Double(x, y, width, height,
startAngle, arcAngle, Arc2D.OPEN));
}
@Override
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
return drawImage(img, x, y,
img.getWidth(observer), img.getHeight(observer), observer);
}
@Override
public boolean drawImage(Image img, int x, int y, Color bgcolor,
ImageObserver observer) {
return drawImage(img, x, y,
img.getWidth(observer), img.getHeight(observer), observer);
}
@Override
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer) {
int imgWidth = img.getWidth(observer);
int imgHeight = img.getHeight(observer);
writeImage(img, imgWidth, imgHeight, x, y, width, height);
return true; // TODO Return only true if image data was complete
}
@Override
public boolean drawImage(Image img, int x, int y, int width, int height,
Color bgcolor, ImageObserver observer) {
return drawImage(img, x, y, width, height, observer);
}
@Override
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2, ImageObserver observer) {
if (img == null) {
return true;
}
int sx = Math.min(sx1, sx2);
int sy = Math.min(sy1, sy2);
int sw = Math.abs(sx2 - sx1);
int sh = Math.abs(sy2 - sy1);
int dx = Math.min(dx1, dx2);
int dy = Math.min(dy1, dy2);
int dw = Math.abs(dx2 - dx1);
int dh = Math.abs(dy2 - dy1);
// Draw image
BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img);
Image cropped = bufferedImg.getSubimage(sx, sy, sw, sh);
return drawImage(cropped, dx, dy, dw, dh, observer);
}
@Override
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2, Color bgcolor,
ImageObserver observer) {
if (img == null) {
return true;
}
int sx = Math.min(sx1, sx2);
int sy = Math.min(sy1, sy2);
int sw = Math.abs(sx2 - sx1);
int sh = Math.abs(sy2 - sy1);
int dx = Math.min(dx1, dx2);
int dy = Math.min(dy1, dy2);
int dw = Math.abs(dx2 - dx1);
int dh = Math.abs(dy2 - dy1);
// Fill Rectangle with bgcolor
Color bgcolorOld = getColor();
setColor(bgcolor);
fill(new Rectangle(dx, dy, dw, dh));
setColor(bgcolorOld);
// Draw image on rectangle
BufferedImage bufferedImg = GraphicsUtils.toBufferedImage(img);
Image cropped = bufferedImg.getSubimage(sx, sy, sw, sh);
return drawImage(cropped, dx, dy, dw, dh, observer);
}
@Override
public void drawLine(int x1, int y1, int x2, int y2) {
draw(new Line2D.Double(x1, y1, x2, y2));
}
@Override
public void drawOval(int x, int y, int width, int height) {
draw(new Ellipse2D.Double(x, y, width, height));
}
@Override
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
Path2D p = new Path2D.Float();
for (int i = 0; i < nPoints; i++) {
if (i > 0) {
p.lineTo(xPoints[i], yPoints[i]);
} else {
p.moveTo(xPoints[i], yPoints[i]);
}
}
p.closePath();
draw(p);
}
@Override
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) {
Path2D p = new Path2D.Float();
for (int i = 0; i < nPoints; i++) {
if (i > 0) {
p.lineTo(xPoints[i], yPoints[i]);
} else {
p.moveTo(xPoints[i], yPoints[i]);
}
}
draw(p);
}
@Override
public void drawRect(int x, int y, int width, int height) {
draw(new Rectangle2D.Double(x, y, width, height));
}
@Override
public void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight) {
draw(new RoundRectangle2D.Double(x, y, width, height,
arcWidth, arcHeight));
}
@Override
public void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle) {
fill(new Arc2D.Double(x, y, width, height,
startAngle, arcAngle, Arc2D.PIE));
}
@Override
public void fillOval(int x, int y, int width, int height) {
fill(new Ellipse2D.Double(x, y, width, height));
}
@Override
public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) {
Path2D p = new Path2D.Float();
for (int i = 0; i < nPoints; i++) {
if (i > 0) {
p.lineTo(xPoints[i], yPoints[i]);
} else {
p.moveTo(xPoints[i], yPoints[i]);
}
}
p.closePath();
fill(p);
}
@Override
public void fillRect(int x, int y, int width, int height) {
fill(new Rectangle2D.Double(x, y, width, height));
}
@Override
public void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight) {
fill(new RoundRectangle2D.Double(x, y, width, height,
arcWidth, arcHeight));
}
@Override
public Shape getClip() {
return clip;
}
@Override
public Rectangle getClipBounds() {
if (clip == null) {
return null;
}
return clip.getBounds();
}
@Override
public Color getColor() {
return color;
}
@Override
public Font getFont() {
return font;
}
@Override
public FontMetrics getFontMetrics(Font f) {
// TODO Find a better way for creating a new FontMetrics instance
BufferedImage bi =
new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = bi.getGraphics();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.dispose();
bi = null;
return fontMetrics;
}
@Override
public void setClip(Shape clip) {
this.clip = clip;
}
@Override
public void setClip(int x, int y, int width, int height) {
setClip(new Rectangle(x, y, width, height));
}
@Override
public void setColor(Color c) {
color = c;
}
@Override
public void setFont(Font font) {
if (!this.font.equals(font)) {
this.font = font;
}
}
@Override
public void setPaintMode() {
// TODO Implement
//throw new UnsupportedOperationException("setPaintMode() isn't supported.");
}
@Override
public void setXORMode(Color c1) {
xorMode = c1;
}
/**
* Utility method for writing multiple objects to the SVG document.
* @param strs Objects to be written
*/
protected void write(Object... strs) {
for (Object o : strs) {
String str = o.toString();
if ((o instanceof Double) || (o instanceof Float)) {
str = String.format(Locale.ENGLISH, "%.7f", o)
.replaceAll("\\.?0+$", "");
}
document.append(str);
}
}
/**
* Utility method for writing a line of multiple objects to the
* SVG document.
* @param strs Objects to be written
*/
protected void writeln(Object... strs) {
write(strs);
write("\n");
}
/**
* Write the specified shape to the document. This does not necessarily
* contain the actual command to paint the shape.
* @param s Shape to be written.
*/
protected abstract void writeShape(Shape s);
/**
* Write the specified image to the document. A number of dimensions will
* specify how the image will be placed in the document.
* @param img Image to be rendered.
* @param imgWidth Number of pixels in horizontal direction.
* @param imgHeight Number of pixels in vertical direction
* @param x Horizontal position in document units where the
* upper left corner of the image should be placed.
* @param y Vertical position in document units where the
* upper left corner of the image should be placed.
* @param width Width of the image in document units.
* @param height Height of the image in document units.
*/
protected abstract void writeImage(Image img, int imgWidth, int imgHeight,
double x, double y, double width, double height);
/**
* Write a text string to the document at a specified position.
* @param str Text to be rendered.
* @param x Horizontal position in document units.
* @param y Vertical position in document units.
*/
protected abstract void writeString(String str, double x, double y);
/**
* Write a command to draw the outline of a previously inserted shape.
* @param s Shape that should be drawn.
*/
protected abstract void writeClosingDraw(Shape s);
/**
* Write a command to fill the outline of a previously inserted shape.
* @param s Shape that should be filled.
*/
protected void writeClosingFill(Shape s) {
Rectangle2D shapeBounds = s.getBounds2D();
// Calculate dimensions of shape with current transformations
int wImage = (int) Math.ceil(shapeBounds.getWidth()*getResolution());
int hImage = (int) Math.ceil(shapeBounds.getHeight()*getResolution());
// Limit the size of images
wImage = Math.min(wImage, rasteredImageSizeMaximum);
hImage = Math.min(hImage, rasteredImageSizeMaximum);
// Create image to paint draw gradient with current transformations
BufferedImage paintImage = new BufferedImage(
wImage, hImage, BufferedImage.TYPE_INT_ARGB);
// Paint shape
Graphics2D g = (Graphics2D) paintImage.getGraphics();
g.scale(wImage/shapeBounds.getWidth(), hImage/shapeBounds.getHeight());
g.translate(-shapeBounds.getX(), -shapeBounds.getY());
g.setPaint(getPaint());
g.fill(s);
// Free resources
g.dispose();
// Output image of gradient
writeImage(paintImage, wImage, hImage,
shapeBounds.getX(), shapeBounds.getY(),
shapeBounds.getWidth(), shapeBounds.getHeight());
}
/**
* Write the header to start a new document.
*/
protected abstract void writeHeader();
/**
* Returns a string of the footer to end a document.
*/
protected abstract String getFooter();
/**
* Returns a transformed version of an image.
* @param image Image to be transformed
* @param xform Affine transform to be applied
* @return Image with transformed content
*/
private BufferedImage getTransformedImage(Image image,
AffineTransform xform) {
Integer interpolationType =
(Integer) hints.get(RenderingHints.KEY_INTERPOLATION);
if (RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR
.equals(interpolationType)) {
interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
} else if (RenderingHints.VALUE_INTERPOLATION_BILINEAR
.equals(interpolationType)) {
interpolationType = AffineTransformOp.TYPE_BILINEAR;
} else {
interpolationType = AffineTransformOp.TYPE_BICUBIC;
}
AffineTransformOp op = new AffineTransformOp(xform, interpolationType);
BufferedImage bufferedImage = GraphicsUtils.toBufferedImage(image);
return op.filter(bufferedImage, null);
}
/**
* Returns whether a distorting transformation has been applied to the
* document.
* @return <code>true</code> if the document is distorted,
* otherwise <code>false</code>.
*/
protected boolean isDistorted() {
if (!isTransformed()) {
return false;
}
int type = transform.getType();
int otherButTranslatedOrScaled = ~(AffineTransform.TYPE_TRANSLATION
| AffineTransform.TYPE_MASK_SCALE);
return (type & otherButTranslatedOrScaled) != 0;
}
@Override
public String toString() {
return document.toString() + getFooter();
}
/**
* Encodes the painted data into a sequence of bytes.
* @return A byte array containing the data in the current file format.
*/
public byte[] getBytes() {
try {
return toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
return toString().getBytes();
}
}
/**
* Returns the dimensions of the document.
* @return dimensions of the document.
*/
public Rectangle2D getBounds() {
Rectangle2D b = new Rectangle2D.Double();
b.setFrame(bounds);
return b;
}
/**
* Returns the number of bytes of the document.
* @return size of the document in bytes.
*/
protected int size() {
return document.length();
}
/**
* Returns how fonts should be rendered.
* @return Font rendering mode.
*/
public FontRendering getFontRendering() {
return fontRendering;
}
/**
* Sets how fonts should be rendered. For example, they can be converted
* to vector shapes.
* @param mode New font rendering mode.
*/
public void setFontRendering(FontRendering mode) {
fontRendering = mode;
}
/**
* Returns whether an affine transformation like translation, scaling,
* rotation or shearing has been applied to this graphics instance.
* @return <code>true</code> if the instance has been transformed,
* <code>false</code> otherwise
*/
protected boolean isTransformed() {
return transformed;
}
/**
* Returns the resolution in pixels per inch.
* @return Resolution in pixels per inch.
*/
public double getResolution() {
return resolution;
}
/**
* Sets the resolution in pixels per inch.
* @param resolution New resolution in pixels per inch.
*/
public void setResolution(double resolution) {
if (resolution <= 0.0) {
throw new IllegalArgumentException(
"Only positive non-zero values allowed");
}
this.resolution = resolution;
}
/**
* Returns the maximal size of images which are used to raster paints
* like e.g. gradients, or patterns. The default value is 128.
* @return Current maximal image size in pixels.
*/
public int getRasteredImageSizeMaximum() {
return rasteredImageSizeMaximum;
}
/**
* Sets the maximal size of images which are used to raster paints
* like e.g. gradients, or patterns.
* @param paintImageSizeMaximum New maximal image size in pixels.
*/
public void setRasteredImageSizeMaximum(int paintImageSizeMaximum) {
this.rasteredImageSizeMaximum = paintImageSizeMaximum;
}
}