/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package org.apache.batik.gvt;

import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.Raster;

import org.apache.batik.ext.awt.image.PadMode;
import org.apache.batik.ext.awt.image.renderable.Filter;
import org.apache.batik.ext.awt.image.renderable.PadRable8Bit;

The PatternPaint class provides a way to fill a Shape with a a pattern defined as a GVT Tree.
Author:Vincent Hardy
Version:$Id: PatternPaint.java 1733416 2016-03-03 07:07:13Z gadams $
/** * The PatternPaint class provides a way to fill a Shape with a a pattern * defined as a GVT Tree. * * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a> * @version $Id: PatternPaint.java 1733416 2016-03-03 07:07:13Z gadams $ */
public class PatternPaint implements Paint {
The GraphicsNode that this Paint uses to produce the pixel pattern
/** * The <code>GraphicsNode</code> that this <code>Paint</code> uses to * produce the pixel pattern */
private GraphicsNode node;
The region to which this paint is constrained
/** * The region to which this paint is constrained */
private Rectangle2D patternRegion;
Additional pattern transform, added on top of the user space to device space transform (i.e., before the tiling space
/** * Additional pattern transform, added on top of the * user space to device space transform (i.e., before * the tiling space */
private AffineTransform patternTransform; /* * The basic tile to fill the region with. * we replicate this out in the Context. */ private Filter tile;
Controls whether or not the pattern overflows the pattern tile
/** * Controls whether or not the pattern overflows * the pattern tile */
private boolean overflow; private PatternPaintContext lastContext;
Constructs a new PatternPaint.
Params:
  • node – Used to generate the paint pixel pattern
  • patternRegion – Region to which this paint is constrained
  • overflow – controls whether or not the node can overflow the patternRegion.
  • patternTransform – additional transform added on top of the user space to device space transform.
/** * Constructs a new <code>PatternPaint</code>. * * @param node Used to generate the paint pixel pattern * @param patternRegion Region to which this paint is constrained * @param overflow controls whether or not the node can overflow * the patternRegion. * @param patternTransform additional transform added on * top of the user space to device space transform. */
public PatternPaint(GraphicsNode node, Rectangle2D patternRegion, boolean overflow, AffineTransform patternTransform){ if (node == null) { throw new IllegalArgumentException(); } if (patternRegion == null) { throw new IllegalArgumentException(); } this.node = node; this.patternRegion = patternRegion; this.overflow = overflow; this.patternTransform = patternTransform; // Wrap the input node so that the primitivePaint // in GraphicsNodeRable takes the filter, clip.... // into account. CompositeGraphicsNode comp = new CompositeGraphicsNode(); comp.getChildren().add(node); Filter gnr = comp.getGraphicsNodeRable(true); Rectangle2D padBounds = (Rectangle2D)patternRegion.clone(); // When there is overflow, make sure we take the full node bounds into // account. if (overflow) { Rectangle2D nodeBounds = comp.getBounds(); // System.out.println("Comp Bounds : " + nodeBounds); // System.out.println("Node Bounds : " + node.getBounds(gnrc)); padBounds.add(nodeBounds); } // System.out.println("Pattern region : " + patternRegion); // System.out.println("Node txf : " + node.getTransform()); tile = new PadRable8Bit(gnr, padBounds, PadMode.ZERO_PAD); }
Returns the graphics node that define the pattern.
/** * Returns the graphics node that define the pattern. */
public GraphicsNode getGraphicsNode(){ return node; }
Returns the pattern region.
/** * Returns the pattern region. */
public Rectangle2D getPatternRect(){ return (Rectangle2D)patternRegion.clone(); }
Returns the additional transform of the pattern paint.
/** * Returns the additional transform of the pattern paint. */
public AffineTransform getPatternTransform(){ return patternTransform; } public boolean getOverflow() { return overflow; }
Creates and returns a context used to generate the pattern.
/** * Creates and returns a context used to generate the pattern. */
public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) { // Concatenate the patternTransform to xform if (patternTransform != null) { xform = new AffineTransform(xform); xform.concatenate(patternTransform); } if ((lastContext!= null) && lastContext.getColorModel().equals(cm)) { double[] p = new double[6]; double[] q = new double[6]; xform.getMatrix(p); lastContext.getUsr2Dev().getMatrix(q); if ((p[0] == q[0]) && (p[1] == q[1]) && (p[2] == q[2]) && (p[3] == q[3])) { if ((p[4] == q[4]) && (p[5] == q[5])) return lastContext; else return new PatternPaintContextWrapper (lastContext, (int)(q[4]-p[4]+0.5), (int)(q[5]-p[5]+0.5)); } } // System.out.println("CreateContext Called: " + this); // System.out.println("CM : " + cm); // System.out.println("xForm : " + xform); lastContext = new PatternPaintContext(cm, xform, hints, tile, patternRegion, overflow); return lastContext; }
Returns the transparency mode for this pattern paint.
/** * Returns the transparency mode for this pattern paint. */
public int getTransparency(){ return TRANSLUCENT; } static class PatternPaintContextWrapper implements PaintContext { PatternPaintContext ppc; int xShift, yShift; PatternPaintContextWrapper(PatternPaintContext ppc, int xShift, int yShift) { this.ppc = ppc; this.xShift = xShift; this.yShift = yShift; } public void dispose(){ } public ColorModel getColorModel(){ return ppc.getColorModel(); } public Raster getRaster(int x, int y, int width, int height){ return ppc.getRaster(x+xShift, y+yShift, width, height); } } }