/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* This class converts paths into PostScript
* by breaking all graphics into fills and
* clips of paths.
*/
/**
* For a drawing application the initial user space
* resolution is 72dpi.
*/
boolean canRedraw) {
}
/**
* Creates a new <code>Graphics</code> object that is
* a copy of this <code>Graphics</code> object.
* @return a new graphics context that is a copy of
* this graphics context.
* @since JDK1.0
*/
getPrintable(),
getPageIndex(),
canDoRedraws());
}
/**
* Override the inherited implementation of fill
* so that we can generate PostScript in user space
* rather than device space.
*/
}
/**
* Draws the text given by the specified string, using this
* graphics context's current font and color. The baseline of the
* first character is at position (<i>x</i>, <i>y</i>) in this
* graphics context's coordinate system.
* @param str the string to be drawn.
* @param x the <i>x</i> coordinate.
* @param y the <i>y</i> coordinate.
* @see java.awt.Graphics#drawBytes
* @see java.awt.Graphics#drawChars
* @since JDK1.0
*/
drawString(str, (float) x, (float) y);
}
/**
* Renders the text specified by the specified <code>String</code>,
* using the current <code>Font</code> and <code>Paint</code> attributes
* in the <code>Graphics2D</code> context.
* The baseline of the first character is at position
* (<i>x</i>, <i>y</i>) in the User Space.
* The rendering attributes applied include the <code>Clip</code>,
* <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
* <code>Composite</code> attributes. For characters in script systems
* such as Hebrew and Arabic, the glyphs can be rendered from right to
* left, in which case the coordinate supplied is the location of the
* leftmost character on the baseline.
* @param s the <code>String</code> to be rendered
* @param x, y the coordinates where the <code>String</code>
* should be rendered
* @see #setPaint
* @see java.awt.Graphics#setColor
* @see java.awt.Graphics#setFont
* @see #setTransform
* @see #setComposite
* @see #setClip
*/
}
protected boolean canDrawStringToWidth() {
return true;
}
}
return;
}
/* If the Font has layout attributes we need to delegate to TextLayout.
* TextLayout renders text as GlyphVectors. We try to print those
* using printer fonts - ie using Postscript text operators so
* we may be reinvoked. In that case the "!printingGlyphVector" test
* prevents us recursing and instead sends us into the body of the
* method where we can safely ignore layout attributes as those
* are already handled by TextLayout.
*/
return;
}
} else {
}
boolean drawnWithPS = false;
if (fontisTransformed) {
/* TYPE_TRANSLATION is a flag bit but we can do "==" here
* because we want to detect when its just that bit set and
*
*/
fontisTransformed = false;
}
}
boolean directToPS = !fontisTransformed;
/* Set the text color.
* We should not be in this shape printing path
* if the application is drawing with non-solid
* colors. We should be in the raster path. Because
* we are here in the shape path, the cast of the
* paint to a Color should be fine.
*/
try {
} catch (ClassCastException e) {
}
throw new IllegalArgumentException(
"Expected a Color instance");
}
x+translateX, y+translateY,
}
}
/* The text could not be converted directly to PS text
* calls so decompose the text into a shape.
*/
if (drawnWithPS == false) {
}
}
}
}
/**
* The various <code>drawImage()</code> methods for
* <code>WPathGraphics</code> are all decomposed
* into an invocation of <code>drawImageToPlatform</code>.
* The portion of the passed in image defined by
* <code>srcX, srcY, srcWidth, and srcHeight</code>
* is transformed by the supplied AffineTransform and
* drawn using PS to the printer context.
*
* @param img The image to be drawn.
* This method does nothing if <code>img</code> is null.
* @param xform Used to tranform the image before drawing.
* This can be null.
* @param bgcolor This color is drawn where the image has transparent
* pixels. If this parameter is null then the
* pixels already in the destination should show
* through.
* @param srcX With srcY this defines the upper-left corner
* of the portion of the image to be drawn.
*
* @param srcY With srcX this defines the upper-left corner
* of the portion of the image to be drawn.
* @param srcWidth The width of the portion of the image to
* be drawn.
* @param srcHeight The height of the portion of the image to
* be drawn.
* @param handlingTransparency if being recursively called to
* print opaque region of transparent image
*/
boolean handlingTransparency) {
return true;
}
/* The full transform to be applied to the image is the
* caller's transform concatenated on to the transform
* from user space to device space. If the caller didn't
* supply a transform then we just act as if they passed
* in the identify transform.
*/
xform = new AffineTransform();
}
/* Split the full transform into a pair of
* transforms. The first transform holds effects
* such as rotation and shearing. The second transform
* is setup to hold only the scaling effects.
* These transforms are created such that a point,
* p, in user space, when transformed by 'fullTransform'
* lands in the same place as when it is transformed
* by 'rotTransform' and then 'scaleTransform'.
*
* The entire image transformation is not in Java in order
* to minimize the amount of memory needed in the VM. By
* dividing the transform in two, we rotate and shear
* the source image in its own space and only go to
* the, usually, larger, device space when we ask
* PostScript to perform the final scaling.
*/
double[] fullMatrix = new double[6];
/* Calculate the amount of scaling in the x
* and y directions. This scaling is computed by
* transforming a unit vector along each axis
* and computing the resulting magnitude.
* The computed values 'scaleX' and 'scaleY'
* represent the amount of scaling PS will be asked
* to perform.
* Clamp this to the device scale for better quality printing.
*/
/* check if rotated or sheared */
boolean clampScale = ((transformType &
if (clampScale) {
}
/* We do not need to draw anything if either scaling
* factor is zero.
*/
/* Here's the transformation we will do with Java2D,
*/
/* The scale transform is not used directly: we instead
* directly multiply by scaleX and scaleY.
*
* Conceptually here is what the scaleTransform is:
*
* AffineTransform scaleTransform = new AffineTransform(
* scaleX, //m00
* 0, //m10
* 0, //m01
* scaleY, //m11
* 0, //m02
* 0); //m12
*/
/* Convert the image source's rectangle into the rotated
* and sheared space. Once there, we calculate a rectangle
* that encloses the resulting shape. It is this rectangle
* which defines the size of the BufferedImage we need to
* create to hold the transformed image.
*/
/* add a fudge factor as some fp precision problems have
* been observed which caused pixels to be rounded down and
* out of the image.
*/
/* If the image has transparent or semi-transparent
* pixels then we'll have the application re-render
* the portion of the page covered by the image.
* This will be done in a later call to print using the
* saved graphics state.
* However several special cases can be handled otherwise:
* - bitmask transparency with a solid background colour
* - images which have transparency color models but no
* transparent pixels
* - images with bitmask transparency and an IndexColorModel
* (the common transparent GIF case) can be handled by
* rendering just the opaque pixels.
*/
boolean drawOpaque = true;
drawOpaque = false;
if (isBitmaskTransparency(img)) {
// image drawn, just return.
return true;
}
} else if (bgcolor.getTransparency()
== Transparency.OPAQUE) {
drawOpaque = true;
}
}
if (!canDoRedraws()) {
drawOpaque = true;
}
} else {
// if there's no transparent pixels there's no need
// for a background colour. This can avoid edge artifacts
// in rotation cases.
}
// if src region extends beyond the image, the "opaque" path
// may blit b/g colour (including white) where it shoudn't.
&& canDoRedraws()) {
drawOpaque = false;
}
if (drawOpaque == false) {
new AffineTransform(
// Region isn't user space because its potentially
// been rotated for landscape.
// Try to limit the amount of memory used to 8Mb, so
// if at device resolution this exceeds a certain
// image size then scale down the region to fit in
// that memory, but never to less than 72 dpi.
int nbytes = w * h * 3;
double scaleFactor = 1;
double maxSFX = w/(double)boundsWidth;
double maxSFY = h/(double)boundsHeight;
scaleFactor *= 2;
dpi /= 2;
nbytes /= 4;
}
}
/*
* We need to have the clip as part of the saved state,
* either directly, or all the components that are
* needed to reconstitute it (image source area,
* image transform and current graphics transform).
* The clip is described in user space, so we need to
* save the current graphics transform anyway so just
* save these two.
*/
return true;
/* The image can be rendered directly by PS so we
* copy it into a BufferedImage (this takes care of
* ColorSpace and BufferedImageOp issues) and then
* send that to PS.
*/
} else {
/* Create a buffered image big enough to hold the portion
* of the source image being printed.
*/
/* Setup a Graphics2D on to the BufferedImage so that the
* source image when copied, lands within the image buffer.
*/
/* Fill the BufferedImage either with the caller supplied
* color, 'bgColor' or, if null, with white.
*/
}
/* REMIND: no need to use scaling here. */
/* In PSPrinterJob images are printed in device space
* and therefore we need to set a device space clip.
* FIX: this is an overly tight coupling of these
* two classes.
* The temporary clip set needs to be an intersection
* with the previous user clip.
* REMIND: two xfms may lose accuracy in clip path.
*/
/* Scale the bounding rectangle by the scale transform.
* Because the scaling transform has only x and y
* scaling components it is equivalent to multiply
* the x components of the bounding rectangle by
* the x scaling factor and to multiply the y components
* by the y scaling factor.
*/
= new Rectangle2D.Float(
/* Pull the raster data from the buffered image
* and pass it along to PS.
*/
scaledBounds.x, scaledBounds.y,
0f, 0f,
/* Reset the device clip to match user clip */
}
}
}
return true;
}
/** Redraw a rectanglular area using a proxy graphics
* To do this we need to know the rectangular area to redraw and
* the transform & clip in effect at the time of the original drawImage
*
*/
throws PrinterException {
int pageIndex = getPageIndex();
/* Create a buffered image big enough to hold the portion
* of the source image being printed.
*/
/* Get a graphics for the application to render into.
* We initialize the buffer to white in order to
* match the paper and then we shift the BufferedImage
* so that it covers the area on the page where the
* caller's Image will be drawn.
*/
/* Calculate the resolution of the source image.
*/
/* The application expects to see user space at 72 dpi.
* so change user space from image source resolution to
* 72 dpi.
*/
/* NB User space now has to be at 72 dpi for this calc to be correct */
g.dispose();
/* In PSPrinterJob images are printed in device space
* and therefore we need to set a device space clip.
*/
/* Scale the bounding rectangle by the scale transform.
* Because the scaling transform has only x and y
* scaling components it is equivalent to multiply
* the x components of the bounding rectangle by
* the x scaling factor and to multiply the y components
* by the y scaling factor.
*/
= new Rectangle2D.Float(
/* Pull the raster data from the buffered image
* and pass it along to PS.
*/
scaledBounds.x, scaledBounds.y,
0f, 0f,
}
/*
* Fill the path defined by <code>pathIter</code>
* with the specified color.
* The path is provided in current user space.
*/
}
/*
* Draw the bounding rectangle using path by calling draw()
* function and passing a rectangle shape.
*/
}
/*
* Draw a line using path by calling draw() function and passing
* a line shape.
*/
}
/*
* Fill the rectangle with the specified color by calling fill().
*/
}
/*
* This method should not be invoked by PSPathGraphics.
* FIX: Rework PathGraphics so that this method is
* not an abstract method there.
*/
}
}