use of java.awt.geom.Rectangle2D in project jdk8u_jdk by JetBrains.
the class PSPathGraphics method drawImageToPlatform.
/**
* 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 transform 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
*/
protected boolean drawImageToPlatform(Image image, AffineTransform xform, Color bgcolor, int srcX, int srcY, int srcWidth, int srcHeight, boolean handlingTransparency) {
BufferedImage img = getBufferedImage(image);
if (img == null) {
return true;
}
PSPrinterJob psPrinterJob = (PSPrinterJob) getPrinterJob();
/* 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.
*/
AffineTransform fullTransform = getTransform();
if (xform == null) {
xform = new AffineTransform();
}
fullTransform.concatenate(xform);
/* 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];
fullTransform.getMatrix(fullMatrix);
/* 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.
*/
Point2D.Float unitVectorX = new Point2D.Float(1, 0);
Point2D.Float unitVectorY = new Point2D.Float(0, 1);
fullTransform.deltaTransform(unitVectorX, unitVectorX);
fullTransform.deltaTransform(unitVectorY, unitVectorY);
Point2D.Float origin = new Point2D.Float(0, 0);
double scaleX = unitVectorX.distance(origin);
double scaleY = unitVectorY.distance(origin);
double devResX = psPrinterJob.getXRes();
double devResY = psPrinterJob.getYRes();
double devScaleX = devResX / DEFAULT_USER_RES;
double devScaleY = devResY / DEFAULT_USER_RES;
/* check if rotated or sheared */
int transformType = fullTransform.getType();
boolean clampScale = ((transformType & (AffineTransform.TYPE_GENERAL_ROTATION | AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
if (clampScale) {
if (scaleX > devScaleX)
scaleX = devScaleX;
if (scaleY > devScaleY)
scaleY = devScaleY;
}
/* We do not need to draw anything if either scaling
* factor is zero.
*/
if (scaleX != 0 && scaleY != 0) {
/* Here's the transformation we will do with Java2D,
*/
AffineTransform rotTransform = new AffineTransform(//m00
fullMatrix[0] / scaleX, //m10
fullMatrix[1] / scaleY, //m01
fullMatrix[2] / scaleX, //m11
fullMatrix[3] / scaleY, //m02
fullMatrix[4] / scaleX, //m12
fullMatrix[5] / scaleY);
/* 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.
*/
Rectangle2D.Float srcRect = new Rectangle2D.Float(srcX, srcY, srcWidth, srcHeight);
Shape rotShape = rotTransform.createTransformedShape(srcRect);
Rectangle2D rotBounds = rotShape.getBounds2D();
/* add a fudge factor as some fp precision problems have
* been observed which caused pixels to be rounded down and
* out of the image.
*/
rotBounds.setRect(rotBounds.getX(), rotBounds.getY(), rotBounds.getWidth() + 0.001, rotBounds.getHeight() + 0.001);
int boundsWidth = (int) rotBounds.getWidth();
int boundsHeight = (int) rotBounds.getHeight();
if (boundsWidth > 0 && boundsHeight > 0) {
/* 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;
if (!handlingTransparency && hasTransparentPixels(img)) {
drawOpaque = false;
if (isBitmaskTransparency(img)) {
if (bgcolor == null) {
if (drawBitmaskImage(img, xform, bgcolor, srcX, srcY, srcWidth, srcHeight)) {
// 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.
bgcolor = null;
}
// may blit b/g colour (including white) where it shoudn't.
if ((srcX + srcWidth > img.getWidth(null) || srcY + srcHeight > img.getHeight(null)) && canDoRedraws()) {
drawOpaque = false;
}
if (drawOpaque == false) {
fullTransform.getMatrix(fullMatrix);
AffineTransform tx = new AffineTransform(//m00
fullMatrix[0] / devScaleX, //m10
fullMatrix[1] / devScaleY, //m01
fullMatrix[2] / devScaleX, //m11
fullMatrix[3] / devScaleY, //m02
fullMatrix[4] / devScaleX, //m12
fullMatrix[5] / devScaleY);
Rectangle2D.Float rect = new Rectangle2D.Float(srcX, srcY, srcWidth, srcHeight);
Shape shape = fullTransform.createTransformedShape(rect);
// Region isn't user space because its potentially
// been rotated for landscape.
Rectangle2D region = shape.getBounds2D();
region.setRect(region.getX(), region.getY(), region.getWidth() + 0.001, region.getHeight() + 0.001);
// 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 w = (int) region.getWidth();
int h = (int) region.getHeight();
int nbytes = w * h * 3;
int maxBytes = 8 * 1024 * 1024;
double origDpi = (devResX < devResY) ? devResX : devResY;
int dpi = (int) origDpi;
double scaleFactor = 1;
double maxSFX = w / (double) boundsWidth;
double maxSFY = h / (double) boundsHeight;
double maxSF = (maxSFX > maxSFY) ? maxSFY : maxSFX;
int minDpi = (int) (dpi / maxSF);
if (minDpi < DEFAULT_USER_RES)
minDpi = DEFAULT_USER_RES;
while (nbytes > maxBytes && dpi > minDpi) {
scaleFactor *= 2;
dpi /= 2;
nbytes /= 4;
}
if (dpi < minDpi) {
scaleFactor = (origDpi / minDpi);
}
region.setRect(region.getX() / scaleFactor, region.getY() / scaleFactor, region.getWidth() / scaleFactor, region.getHeight() / scaleFactor);
/*
* 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.
*/
psPrinterJob.saveState(getTransform(), getClip(), region, scaleFactor, scaleFactor);
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.
*/
BufferedImage deepImage = new BufferedImage((int) rotBounds.getWidth(), (int) rotBounds.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
/* Setup a Graphics2D on to the BufferedImage so that the
* source image when copied, lands within the image buffer.
*/
Graphics2D imageGraphics = deepImage.createGraphics();
imageGraphics.clipRect(0, 0, deepImage.getWidth(), deepImage.getHeight());
imageGraphics.translate(-rotBounds.getX(), -rotBounds.getY());
imageGraphics.transform(rotTransform);
/* Fill the BufferedImage either with the caller supplied
* color, 'bgColor' or, if null, with white.
*/
if (bgcolor == null) {
bgcolor = Color.white;
}
/* REMIND: no need to use scaling here. */
imageGraphics.drawImage(img, srcX, srcY, srcX + srcWidth, srcY + srcHeight, srcX, srcY, srcX + srcWidth, srcY + srcHeight, bgcolor, null);
/* 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.
*/
Shape holdClip = getClip();
Shape oldClip = getTransform().createTransformedShape(holdClip);
AffineTransform sat = AffineTransform.getScaleInstance(scaleX, scaleY);
Shape imgClip = sat.createTransformedShape(rotShape);
Area imgArea = new Area(imgClip);
Area oldArea = new Area(oldClip);
imgArea.intersect(oldArea);
psPrinterJob.setClip(imgArea);
/* 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.
*/
Rectangle2D.Float scaledBounds = new Rectangle2D.Float((float) (rotBounds.getX() * scaleX), (float) (rotBounds.getY() * scaleY), (float) (rotBounds.getWidth() * scaleX), (float) (rotBounds.getHeight() * scaleY));
/* Pull the raster data from the buffered image
* and pass it along to PS.
*/
ByteComponentRaster tile = (ByteComponentRaster) deepImage.getRaster();
psPrinterJob.drawImageBGR(tile.getDataStorage(), scaledBounds.x, scaledBounds.y, (float) Math.rint(scaledBounds.width + 0.5), (float) Math.rint(scaledBounds.height + 0.5), 0f, 0f, deepImage.getWidth(), deepImage.getHeight(), deepImage.getWidth(), deepImage.getHeight());
/* Reset the device clip to match user clip */
psPrinterJob.setClip(getTransform().createTransformedShape(holdClip));
imageGraphics.dispose();
}
}
}
return true;
}
use of java.awt.geom.Rectangle2D in project jdk8u_jdk by JetBrains.
the class PSPrinterJob method textOut.
protected boolean textOut(Graphics g, String str, float x, float y, Font mLastFont, FontRenderContext frc, float width) {
boolean didText = true;
if (mFontProps == null) {
return false;
} else {
prepDrawing();
/* On-screen drawString renders most control chars as the missing
* glyph and have the non-zero advance of that glyph.
* Exceptions are \t, \n and \r which are considered zero-width.
* Postscript handles control chars mostly as a missing glyph.
* But we use 'ashow' specifying a width for the string which
* assumes zero-width for those three exceptions, and Postscript
* tries to squeeze the extra char in, with the result that the
* glyphs look compressed or even overlap.
* So exclude those control chars from the string sent to PS.
*/
str = removeControlChars(str);
if (str.length() == 0) {
return true;
}
CharsetString[] acs = ((PlatformFont) (mLastFont.getPeer())).makeMultiCharsetString(str, false);
if (acs == null) {
/* AWT can't convert all chars so use 2D path */
return false;
}
/* Get an array of indices into our PostScript name
* table. If all of the runs can not be converted
* to PostScript fonts then null is returned and
* we'll want to fall back to printing the text
* as shapes.
*/
int[] psFonts = getPSFontIndexArray(mLastFont, acs);
if (psFonts != null) {
for (int i = 0; i < acs.length; i++) {
CharsetString cs = acs[i];
CharsetEncoder fontCS = cs.fontDescriptor.encoder;
StringBuffer nativeStr = new StringBuffer();
byte[] strSeg = new byte[cs.length * 2];
int len = 0;
try {
ByteBuffer bb = ByteBuffer.wrap(strSeg);
fontCS.encode(CharBuffer.wrap(cs.charsetChars, cs.offset, cs.length), bb, true);
bb.flip();
len = bb.limit();
} catch (IllegalStateException xx) {
continue;
} catch (CoderMalfunctionError xx) {
continue;
}
/* The width to fit to may either be specified,
* or calculated. Specifying by the caller is only
* valid if the text does not need to be decomposed
* into multiple calls.
*/
float desiredWidth;
if (acs.length == 1 && width != 0f) {
desiredWidth = width;
} else {
Rectangle2D r2d = mLastFont.getStringBounds(cs.charsetChars, cs.offset, cs.offset + cs.length, frc);
desiredWidth = (float) r2d.getWidth();
}
/* unprintable chars had width of 0, causing a PS error
*/
if (desiredWidth == 0) {
return didText;
}
nativeStr.append('<');
for (int j = 0; j < len; j++) {
byte b = strSeg[j];
// to avoid encoding conversion with println()
String hexS = Integer.toHexString(b);
int length = hexS.length();
if (length > 2) {
hexS = hexS.substring(length - 2, length);
} else if (length == 1) {
hexS = "0" + hexS;
} else if (length == 0) {
hexS = "00";
}
nativeStr.append(hexS);
}
nativeStr.append('>');
/* This comment costs too much in output file size */
// mPSStream.println("% Font[" + mLastFont.getName() + ", " +
// FontConfiguration.getStyleString(mLastFont.getStyle()) + ", "
// + mLastFont.getSize2D() + "]");
getGState().emitPSFont(psFonts[i], mLastFont.getSize2D());
// out String
mPSStream.println(nativeStr.toString() + " " + desiredWidth + " " + x + " " + y + " " + DrawStringName);
x += desiredWidth;
}
} else {
didText = false;
}
}
return didText;
}
use of java.awt.geom.Rectangle2D in project jdk8u_jdk by JetBrains.
the class PeekGraphics method drawString.
/**
* Draws a string of text.
* The rendering attributes applied include the clip, transform,
* paint or color, font and composite attributes.
* @param s The string to be drawn.
* @param x,y The coordinates where the string should be drawn.
* @see #setPaint
* @see java.awt.Graphics#setColor
* @see java.awt.Graphics#setFont
* @see #transform
* @see #setTransform
* @see #setComposite
* @see #clip
* @see #setClip
*/
public void drawString(String str, float x, float y) {
if (str.length() == 0) {
return;
}
/* Logical bounds close enough and is used for GlyphVector */
FontRenderContext frc = getFontRenderContext();
Rectangle2D bbox = getFont().getStringBounds(str, frc);
addDrawingRect(bbox, x, y);
mPrintMetrics.drawText(this);
}
use of java.awt.geom.Rectangle2D in project jdk8u_jdk by JetBrains.
the class RasterPrinterJob method printPage.
/**
* Print a page from the provided document.
* @return int Printable.PAGE_EXISTS if the page existed and was drawn and
* Printable.NO_SUCH_PAGE if the page did not exist.
* @see java.awt.print.Printable
*/
protected int printPage(Pageable document, int pageIndex) throws PrinterException {
PageFormat page;
PageFormat origPage;
Printable painter;
try {
origPage = document.getPageFormat(pageIndex);
page = (PageFormat) origPage.clone();
painter = document.getPrintable(pageIndex);
} catch (Exception e) {
PrinterException pe = new PrinterException("Error getting page or printable.[ " + e + " ]");
pe.initCause(e);
throw pe;
}
/* Get the imageable area from Paper instead of PageFormat
* because we do not want it adjusted by the page orientation.
*/
Paper paper = page.getPaper();
// if non-portrait and 270 degree landscape rotation
if (page.getOrientation() != PageFormat.PORTRAIT && landscapeRotates270) {
double left = paper.getImageableX();
double top = paper.getImageableY();
double width = paper.getImageableWidth();
double height = paper.getImageableHeight();
paper.setImageableArea(paper.getWidth() - left - width, paper.getHeight() - top - height, width, height);
page.setPaper(paper);
if (page.getOrientation() == PageFormat.LANDSCAPE) {
page.setOrientation(PageFormat.REVERSE_LANDSCAPE);
} else {
page.setOrientation(PageFormat.LANDSCAPE);
}
}
double xScale = getXRes() / 72.0;
double yScale = getYRes() / 72.0;
/* The deviceArea is the imageable area in the printer's
* resolution.
*/
Rectangle2D deviceArea = new Rectangle2D.Double(paper.getImageableX() * xScale, paper.getImageableY() * yScale, paper.getImageableWidth() * xScale, paper.getImageableHeight() * yScale);
/* Build and hold on to a uniform transform so that
* we can get back to device space at the beginning
* of each band.
*/
AffineTransform uniformTransform = new AffineTransform();
/* The scale transform is used to switch from the
* device space to the user's 72 dpi space.
*/
AffineTransform scaleTransform = new AffineTransform();
scaleTransform.scale(xScale, yScale);
/* bandwidth is multiple of 4 as the data is used in a win32 DIB and
* some drivers behave badly if scanlines aren't multiples of 4 bytes.
*/
int bandWidth = (int) deviceArea.getWidth();
if (bandWidth % 4 != 0) {
bandWidth += (4 - (bandWidth % 4));
}
if (bandWidth <= 0) {
throw new PrinterException("Paper's imageable width is too small.");
}
int deviceAreaHeight = (int) deviceArea.getHeight();
if (deviceAreaHeight <= 0) {
throw new PrinterException("Paper's imageable height is too small.");
}
/* Figure out the number of lines that will fit into
* our maximum band size. The hard coded 3 reflects the
* fact that we can only create 24 bit per pixel 3 byte BGR
* BufferedImages. FIX.
*/
int bandHeight = (int) (MAX_BAND_SIZE / bandWidth / 3);
int deviceLeft = (int) Math.rint(paper.getImageableX() * xScale);
int deviceTop = (int) Math.rint(paper.getImageableY() * yScale);
/* The device transform is used to move the band down
* the page using translates. Normally this is all it
* would do, but since, when printing, the Window's
* DIB format wants the last line to be first (lowest) in
* memory, the deviceTransform moves the origin to the
* bottom of the band and flips the origin. This way the
* app prints upside down into the band which is the DIB
* format.
*/
AffineTransform deviceTransform = new AffineTransform();
deviceTransform.translate(-deviceLeft, deviceTop);
deviceTransform.translate(0, bandHeight);
deviceTransform.scale(1, -1);
/* Create a BufferedImage to hold the band. We set the clip
* of the band to be tight around the bits so that the
* application can use it to figure what part of the
* page needs to be drawn. The clip is never altered in
* this method, but we do translate the band's coordinate
* system so that the app will see the clip moving down the
* page though it s always around the same set of pixels.
*/
BufferedImage pBand = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR);
/* Have the app draw into a PeekGraphics object so we can
* learn something about the needs of the print job.
*/
PeekGraphics peekGraphics = createPeekGraphics(pBand.createGraphics(), this);
Rectangle2D.Double pageFormatArea = new Rectangle2D.Double(page.getImageableX(), page.getImageableY(), page.getImageableWidth(), page.getImageableHeight());
peekGraphics.transform(scaleTransform);
peekGraphics.translate(-getPhysicalPrintableX(paper) / xScale, -getPhysicalPrintableY(paper) / yScale);
peekGraphics.transform(new AffineTransform(page.getMatrix()));
initPrinterGraphics(peekGraphics, pageFormatArea);
AffineTransform pgAt = peekGraphics.getTransform();
/* Update the information used to return a GraphicsConfiguration
* for this printer device. It needs to be updated per page as
* not all pages in a job may be the same size (different bounds)
* The transform is the scaling transform as this corresponds to
* the default transform for the device. The width and height are
* those of the paper, not the page format, as we want to describe
* the bounds of the device in its natural coordinate system of
* device coordinate whereas a page format may be in a rotated context.
*/
setGraphicsConfigInfo(scaleTransform, paper.getWidth(), paper.getHeight());
int pageResult = painter.print(peekGraphics, origPage, pageIndex);
debug_println("pageResult " + pageResult);
if (pageResult == Printable.PAGE_EXISTS) {
debug_println("startPage " + pageIndex);
/* We need to check if the paper size is changed.
* Note that it is not sufficient to ask for the pageformat
* of "pageIndex-1", since PageRanges mean that pages can be
* skipped. So we have to look at the actual last paper size used.
*/
Paper thisPaper = page.getPaper();
boolean paperChanged = previousPaper == null || thisPaper.getWidth() != previousPaper.getWidth() || thisPaper.getHeight() != previousPaper.getHeight();
previousPaper = thisPaper;
startPage(page, painter, pageIndex, paperChanged);
Graphics2D pathGraphics = createPathGraphics(peekGraphics, this, painter, page, pageIndex);
/* If we can convert the page directly to the
* underlying graphics system then we do not
* need to rasterize. We also may not need to
* create the 'band' if all the pages can take
* this path.
*/
if (pathGraphics != null) {
pathGraphics.transform(scaleTransform);
// user (0,0) should be origin of page, not imageable area
pathGraphics.translate(-getPhysicalPrintableX(paper) / xScale, -getPhysicalPrintableY(paper) / yScale);
pathGraphics.transform(new AffineTransform(page.getMatrix()));
initPrinterGraphics(pathGraphics, pageFormatArea);
redrawList.clear();
AffineTransform initialTx = pathGraphics.getTransform();
painter.print(pathGraphics, origPage, pageIndex);
for (int i = 0; i < redrawList.size(); i++) {
GraphicsState gstate = (GraphicsState) redrawList.get(i);
pathGraphics.setTransform(initialTx);
((PathGraphics) pathGraphics).redrawRegion(gstate.region, gstate.sx, gstate.sy, gstate.theClip, gstate.theTransform);
}
/* This is the banded-raster printing loop.
* It should be moved into its own method.
*/
} else {
BufferedImage band = cachedBand;
if (cachedBand == null || bandWidth != cachedBandWidth || bandHeight != cachedBandHeight) {
band = new BufferedImage(bandWidth, bandHeight, BufferedImage.TYPE_3BYTE_BGR);
cachedBand = band;
cachedBandWidth = bandWidth;
cachedBandHeight = bandHeight;
}
Graphics2D bandGraphics = band.createGraphics();
Rectangle2D.Double clipArea = new Rectangle2D.Double(0, 0, bandWidth, bandHeight);
initPrinterGraphics(bandGraphics, clipArea);
ProxyGraphics2D painterGraphics = new ProxyGraphics2D(bandGraphics, this);
Graphics2D clearGraphics = band.createGraphics();
clearGraphics.setColor(Color.white);
/* We need the actual bits of the BufferedImage to send to
* the native Window's code. 'data' points to the actual
* pixels. Right now these are in ARGB format with 8 bits
* per component. We need to use a monochrome BufferedImage
* for monochrome printers when this is supported by
* BufferedImage. FIX
*/
ByteInterleavedRaster tile = (ByteInterleavedRaster) band.getRaster();
byte[] data = tile.getDataStorage();
/* Loop over the page moving our band down the page,
* calling the app to render the band, and then send the band
* to the printer.
*/
int deviceBottom = deviceTop + deviceAreaHeight;
/* device's printable x,y is really addressable origin
* we address relative to media origin so when we print a
* band we need to adjust for the different methods of
* addressing it.
*/
int deviceAddressableX = (int) getPhysicalPrintableX(paper);
int deviceAddressableY = (int) getPhysicalPrintableY(paper);
for (int bandTop = 0; bandTop <= deviceAreaHeight; bandTop += bandHeight) {
/* Put the band back into device space and
* erase the contents of the band.
*/
clearGraphics.fillRect(0, 0, bandWidth, bandHeight);
/* Put the band into the correct location on the
* page. Once the band is moved we translate the
* device transform so that the band will move down
* the page on the next iteration of the loop.
*/
bandGraphics.setTransform(uniformTransform);
bandGraphics.transform(deviceTransform);
deviceTransform.translate(0, -bandHeight);
/* Switch the band from device space to user,
* 72 dpi, space.
*/
bandGraphics.transform(scaleTransform);
bandGraphics.transform(new AffineTransform(page.getMatrix()));
Rectangle clip = bandGraphics.getClipBounds();
clip = pgAt.createTransformedShape(clip).getBounds();
if ((clip == null) || peekGraphics.hitsDrawingArea(clip) && (bandWidth > 0 && bandHeight > 0)) {
/* if the client has specified an imageable X or Y
* which is off than the physically addressable
* area of the page, then we need to adjust for that
* here so that we pass only non -ve band coordinates
* We also need to translate by the adjusted amount
* so that printing appears in the correct place.
*/
int bandX = deviceLeft - deviceAddressableX;
if (bandX < 0) {
bandGraphics.translate(bandX / xScale, 0);
bandX = 0;
}
int bandY = deviceTop + bandTop - deviceAddressableY;
if (bandY < 0) {
bandGraphics.translate(0, bandY / yScale);
bandY = 0;
}
/* Have the app's painter image into the band
* and then send the band to the printer.
*/
painterGraphics.setDelegate((Graphics2D) bandGraphics.create());
painter.print(painterGraphics, origPage, pageIndex);
painterGraphics.dispose();
printBand(data, bandX, bandY, bandWidth, bandHeight);
}
}
clearGraphics.dispose();
bandGraphics.dispose();
}
debug_println("calling endPage " + pageIndex);
endPage(page, painter, pageIndex);
}
return pageResult;
}
use of java.awt.geom.Rectangle2D in project jdk8u_jdk by JetBrains.
the class ExtendedTextSourceLabel method createItalicBounds.
public Rectangle2D createItalicBounds() {
float ia = cm.italicAngle;
Rectangle2D lb = getLogicalBounds();
float l = (float) lb.getMinX();
float t = -cm.ascent;
float r = (float) lb.getMaxX();
float b = cm.descent;
if (ia != 0) {
if (ia > 0) {
l -= ia * (b - cm.ssOffset);
r -= ia * (t - cm.ssOffset);
} else {
l -= ia * (t - cm.ssOffset);
r -= ia * (b - cm.ssOffset);
}
}
return new Rectangle2D.Float(l, t, r - l, b - t);
}
Aggregations