3909N/A * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * For a drawing application the initial user space 0N/A * resolution is 72dpi. 0N/A /* Note that preferGDITextLayout implies useGDITextLayout. 0N/A * "prefer" is used to override cases where would otherwise 0N/A * choose not to use it. Note that non-layout factors may 0N/A * still mean that GDI cannot be used. 0N/A * Creates a new <code>Graphics</code> object that is 0N/A * a copy of this <code>Graphics</code> object. 0N/A * @return a new graphics context that is a copy of 0N/A * this graphics context. 0N/A * Strokes the outline of a Shape using the settings of the current 0N/A * graphics state. The rendering attributes applied include the 0N/A * clip, transform, paint or color, composite and stroke attributes. 0N/A * @param s The shape to be drawn. 0N/A * @see java.awt.Graphics#setColor 0N/A * @see #setTransform 0N/A * @see #setComposite 0N/A /* If the line being drawn is thinner than can be 0N/A * rendered, then change the line width, stroke 0N/A * the shape, and then set the line width back. 0N/A * We can only do this for BasicStroke's. 0N/A /* Get the requested line width in user space. 0N/A /* Compute the line width in device coordinates. 0N/A * Work on a point in case there is asymetric scaling 0N/A * between user and device space. 0N/A * Take the absolute value in case there is negative 0N/A * scaling in effect. 0N/A /* If the requested line is too thin then map our 0N/A * minimum line width back to user space and set 0N/A * a new BasicStroke. 0N/A /* Convert the minimum line width from device 0N/A * space to user space. 0N/A /* Use all of the parameters from the current 0N/A * stroke but change the line width to our 0N/A * calculated minimum. 0N/A /* If we can't invert the matrix there is something 0N/A * very wrong so don't worry about the minor matter 0N/A * of a minimum line width. 0N/A /* If we changed the stroke, put back the old 0N/A * stroke in order to maintain a minimum line 0N/A /* The stroke in effect was not a BasicStroke so we 0N/A * will not try to enforce a minimum line width. 0N/A * Draws the text given by the specified string, using this 0N/A * graphics context's current font and color. The baseline of the 0N/A * first character is at position (<i>x</i>, <i>y</i>) in this 0N/A * graphics context's coordinate system. 0N/A * @param str the string to be drawn. 0N/A * @param x the <i>x</i> coordinate. 0N/A * @param y the <i>y</i> coordinate. 0N/A * @see java.awt.Graphics#drawBytes 0N/A * @see java.awt.Graphics#drawChars 0N/A /* A return value of 0 would mean font not available to GDI, or the 0N/A * it can't be used for this string. 0N/A * A return of 1 means it is suitable, including for composites. 0N/A * We check that the transform in effect is doable with GDI, and that 0N/A * this is a composite font AWT can handle, or a physical font GDI 0N/A * can handle directly. Its possible that some strings may ultimately 0N/A * fail the more stringent tests in drawString but this is rare and 0N/A * also that method will always succeed, as if the font isn't available 0N/A * it will use outlines via a superclass call. Also it is only called for 0N/A * the default render context (as canDrawStringToWidth() will return 0N/A * false. That is why it ignores the frc and width arguments. 0N/A /* Test if GDI can handle the transform */ 0N/A /* Since all windows fonts are available, and the JRE fonts 0N/A * are also registered. Only the Font.createFont() case is presently 0N/A * unknown to GDI. Those can be registered too, although that 0N/A * code does not exist yet, it can be added too, so we should not 0N/A * fail that case. Just do a quick check whether its a TrueTypeFont 0N/A * - ie not a Type1 font etc, and let drawString() resolve the rest. 0N/A /* In case GDI doesn't handle shaping or BIDI consistently with 0N/A * 2D's TextLayout, we can detect these cases and redelegate up to 0N/A * be drawn via TextLayout, which in is rendered as runs of 0N/A * GlyphVectors, to which we can assign positions for each glyph. 0N/A /* Get the rotation in 1/10'ths degree (as needed by Windows) 0N/A * so that GDI can draw the text rotated. 0N/A * This calculation is only valid for a uniform scale, no shearing. 0N/A /* Windows specifies the rotation anti-clockwise from the x-axis 0N/A * of the device, 2D specifies +ve rotation towards the y-axis 0N/A * Since the 2D y-axis runs from top-to-bottom, windows angle of 0N/A * rotation here is opposite than 2D's, so the rotation needed 0N/A * needs to be recalculated in the opposite direction. 0N/A /* don't let rounding errors be interpreted as non-uniform scale */ 0N/A * Renders the text specified by the specified <code>String</code>, 0N/A * using the current <code>Font</code> and <code>Paint</code> attributes 0N/A * in the <code>Graphics2D</code> context. 0N/A * The baseline of the first character is at position 0N/A * (<i>x</i>, <i>y</i>) in the User Space. 0N/A * The rendering attributes applied include the <code>Clip</code>, 0N/A * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and 0N/A * <code>Composite</code> attributes. For characters in script systems 0N/A * such as Hebrew and Arabic, the glyphs can be rendered from right to 0N/A * left, in which case the coordinate supplied is the location of the 0N/A * leftmost character on the baseline. 0N/A * @param s the <code>String</code> to be rendered 0N/A * @param x, y the coordinates where the <code>String</code> 0N/A * should be rendered 0N/A * @see java.awt.Graphics#setColor 0N/A * @see java.awt.Graphics#setFont 0N/A * @see #setTransform 0N/A * @see #setComposite 0N/A /* If the Font has layout attributes we need to delegate to TextLayout. 0N/A * TextLayout renders text as GlyphVectors. We try to print those 0N/A * using printer fonts - ie using Postscript text operators so 0N/A * we may be reinvoked. In that case the "!printingGlyphVector" test 0N/A * prevents us recursing and instead sends us into the body of the 0N/A * method where we can safely ignore layout attributes as those 0N/A * are already handled by TextLayout. 0N/A * Similarly if layout is needed based on the text, then we 0N/A * delegate to TextLayout if possible, or failing that we delegate 0N/A * upwards to filled shapes. 0N/A /* Use GDI for the text if the graphics transform is something 0N/A * for which we can obtain a suitable GDI font. 0N/A * A flip or shearing transform on the graphics or a transform 0N/A * on the font force us to decompose the text into a shape. 0N/A /* Now we have checked everything is OK to go through GDI as text 0N/A * with the exception of testing GDI can find and use the font. That 0N/A * is handled in the textOut() call. 0N/A /* Compute the starting position of the string in 0N/A /* Already have the translate from the deviceTransform, 0N/A * but the font may have a translation component too. 0N/A /* Get the font size in device coordinates. 0N/A * The size needed is the font height scaled to device space. 0N/A * Although we have already tested that there is no shear, 0N/A * there may be a non-uniform scale, so the width of the font 0N/A * does not scale equally with the height. That is handled 0N/A * by specifying an 'average width' scale to GDI. 0N/A /* Composite fonts are made up of multiple fonts and each 0N/A * substring that uses a particular component font needs to 0N/A * be separately sent to GDI. 0N/A * This works for standard composite fonts, alternate ones, 0N/A * Fonts that are a physical font backed by a standard composite, 0N/A * and with fallback fonts. 0N/A /** return true if the Graphics instance can directly print 0N/A /* We don't want to try to handle per-glyph transforms. GDI can't 0N/A * handle per-glyph rotations, etc. There's no way to express it 0N/A * in a single call, so just bail for this uncommon case. 0N/A /* Use GDI for the text if the graphics transform is something 0N/A * for which we can obtain a suitable GDI font. 0N/A * A flip or shearing transform on the graphics or a transform 0N/A * on the font force us to decompose the text into a shape. 0N/A /* Compute the starting position of the string in 0N/A /* Already have the translate from the deviceTransform, 0N/A * but the font may have a translation component too. 0N/A /* Get the font size in device coordinates. 0N/A * The size needed is the font height scaled to device space. 0N/A * Although we have already tested that there is no shear, 0N/A * there may be a non-uniform scale, so the width of the font 0N/A * does not scale equally with the height. That is handled 0N/A * by specifying an 'average width' scale to GDI. 0N/A /* layout replaces glyphs which have been combined away 0N/A * with 0xfffe or 0xffff. These are supposed to be invisible 0N/A * and we need to handle this here as GDI will interpret it 0N/A * as a missing glyph. We'll do it here by compacting the 0N/A * glyph codes array, but we have to do it in conjunction with 0N/A * the number of glyphs .. 0N/A * Note that since the slot number for composites is in the 0N/A * significant byte we need to mask out that for comparison of 0N/A * the invisible glyph. 0N/A /* To get GDI to rotate glyphs we need to specify the angle 0N/A * of rotation to GDI when creating the HFONT. This implicitly 0N/A * also rotates the baseline, and this adjusts the X & Y advances 0N/A * of the glyphs accordingly. 0N/A * When we specify the advances, they are in device space, so 0N/A * we don't want any further interpretation applied by GDI, but 0N/A * since as noted the advances are interpreted in the HFONT's 0N/A * coordinate space, our advances would be rotated again. 0N/A * We don't have any way to tell GDI to rotate only the glyphs and 0N/A * not the advances, so we need to account for this in the advances 0N/A * we supply, by supplying unrotated advances. 0N/A * Note that "iangle" is in the opposite direction to 2D's normal 0N/A * direction of rotation, so this rotation inverts the 0N/A * rotation element of the deviceTransform. 0N/A /* Composite fonts are made up of multiple fonts and each 0N/A * substring that uses a particular component font needs to 0N/A * be separately sent to GDI. 0N/A * This works for standard composite fonts, alternate ones, 0N/A * Fonts that are a physical font backed by a standard composite, 0N/A * and with fallback fonts. 0N/A /* If we can't get the font, bail to outlines. 0N/A * But we should always be able to get all fonts for 0N/A * Composites, so this is unlikely, so any overstriking 0N/A * if only one slot is unavailable is not worth worrying 0N/A /* If there is a 1:1 char->glyph mapping then char positions 0N/A * are the same as glyph positions and we can tell GDI 0N/A * where to place the glyphs. 0N/A * On drawing we remove control chars so these need to be 0N/A * removed now so the string and positions are the same length. 0N/A * For other cases we need to pass glyph codes to GDI. 0N/A /* GDI advances must not include device space rotation. 0N/A * See earlier comment in printGlyphVector() for details. 0N/A /* If 2D and GDI agree on the advance of the string we do not 0N/A * need to explicitly assign glyph positions. 0N/A * If we are to use the GDI advance, require it to agree with 0N/A * JDK to a precision of <= 0.2% - ie 1 pixel in 500 0N/A * discrepancy after rounding the 2D advance to the 0N/A * nearest pixel and is greater than one pixel in total. 0N/A * ie strings < 500 pixels in length will be OK so long 0N/A * as they differ by only 1 pixel even though that is > 0.02% 0N/A * The bounds from 2D are in user space so need to 0N/A * be scaled to device space for comparison with GDI. 0N/A * scaleX is the scale from user space to device space needed for this. 0N/A * The various <code>drawImage()</code> methods for 0N/A * <code>WPathGraphics</code> are all decomposed 0N/A * into an invocation of <code>drawImageToPlatform</code>. 0N/A * The portion of the passed in image defined by 0N/A * <code>srcX, srcY, srcWidth, and srcHeight</code> 0N/A * is transformed by the supplied AffineTransform and 0N/A * drawn using GDI to the printer context. 0N/A * @param img The image to be drawn. 0N/A * @param xform Used to tranform the image before drawing. 0N/A * @param bgcolor This color is drawn where the image has transparent 0N/A * pixels. If this parameter is null then the 0N/A * pixels already in the destination should show 0N/A * @param srcX With srcY this defines the upper-left corner 0N/A * of the portion of the image to be drawn. 0N/A * @param srcY With srcX this defines the upper-left corner 0N/A * of the portion of the image to be drawn. 0N/A * @param srcWidth The width of the portion of the image to 0N/A * @param srcHeight The height of the portion of the image to 0N/A * @param handlingTransparency if being recursively called to 0N/A * print opaque region of transparent image 0N/A /* The full transform to be applied to the image is the 0N/A * caller's transform concatenated on to the transform 0N/A * from user space to device space. If the caller didn't 0N/A * supply a transform then we just act as if they passed 0N/A * in the identify transform. 0N/A /* Split the full transform into a pair of 0N/A * transforms. The first transform holds effects 0N/A * that GDI (under Win95) can not perform such 0N/A * as rotation and shearing. The second transform 0N/A * is setup to hold only the scaling effects. 0N/A * These transforms are created such that a point, 0N/A * p, in user space, when transformed by 'fullTransform' 0N/A * lands in the same place as when it is transformed 0N/A * by 'rotTransform' and then 'scaleTransform'. 0N/A * The entire image transformation is not in Java in order 0N/A * to minimize the amount of memory needed in the VM. By 0N/A * dividing the transform in two, we rotate and shear 0N/A * the source image in its own space and only go to 0N/A * the, usually, larger, device space when we ask 0N/A * GDI to perform the final scaling. 0N/A * Clamp this to the device scale for better quality printing. 0N/A /* Calculate the amount of scaling in the x 0N/A * and y directions. This scaling is computed by 0N/A * transforming a unit vector along each axis 0N/A * and computing the resulting magnitude. 0N/A * The computed values 'scaleX' and 'scaleY' 0N/A * represent the amount of scaling GDI will be asked 304N/A /* check if rotated or sheared */ 0N/A /* We do not need to draw anything if either scaling 0N/A /* Here's the transformation we will do with Java2D, 0N/A /* The scale transform is not used directly: we instead 0N/A * directly multiply by scaleX and scaleY. 0N/A * Conceptually here is what the scaleTransform is: 0N/A * AffineTransform scaleTransform = new AffineTransform( 0N/A /* Convert the image source's rectangle into the rotated 0N/A * and sheared space. Once there, we calculate a rectangle 0N/A * that encloses the resulting shape. It is this rectangle 0N/A * which defines the size of the BufferedImage we need to 0N/A * create to hold the transformed image. 0N/A /* add a fudge factor as some fp precision problems have 0N/A * been observed which caused pixels to be rounded down and 0N/A /* If the image has transparent or semi-transparent 0N/A * pixels then we'll have the application re-render 0N/A * the portion of the page covered by the image. 0N/A * The BufferedImage will be at the image's resolution 0N/A * to avoid wasting memory. By re-rendering this portion 0N/A * of a page all compositing is done by Java2D into 0N/A * the BufferedImage and then that image is copied to 0N/A * However several special cases can be handled otherwise: 0N/A * - bitmask transparency with a solid background colour 0N/A * - images which have transparency color models but no 0N/A * transparent pixels 0N/A * - images with bitmask transparency and an IndexColorModel 0N/A * (the common transparent GIF case) can be handled by 0N/A * rendering just the opaque pixels. 0N/A // image drawn, just return. 0N/A // if there's no transparent pixels there's no need 0N/A // for a background colour. This can avoid edge artifacts 0N/A // in rotation cases. 0N/A // if src region extends beyond the image, the "opaque" path 0N/A // may blit b/g colour (including white) where it shoudn't. 0N/A // Region isn't user space because its potentially 0N/A // been rotated for landscape. 0N/A // Try to limit the amount of memory used to 8Mb, so 0N/A // if at device resolution this exceeds a certain 0N/A // image size then scale down the region to fit in 0N/A // that memory, but never to less than 72 dpi. 0N/A * We need to have the clip as part of the saved state, 0N/A * either directly, or all the components that are 0N/A * needed to reconstitute it (image source area, 0N/A * image transform and current graphics transform). 0N/A * The clip is described in user space, so we need to 0N/A * save the current graphics transform anyway so just 0N/A /* The image can be rendered directly by GDI so we 0N/A * copy it into a BufferedImage (this takes care of 0N/A * ColorSpace and BufferedImageOp issues) and then 0N/A /* Create a buffered image big enough to hold the portion 0N/A * of the source image being printed. 0N/A * The image format will be 3BYTE_BGR for most cases 0N/A * except where we can represent the image as a 1, 4 or 8 0N/A * bits-per-pixel DIB. 0N/A /* BYTE_BINARY may be 2 bpp which DIB can't handle. 0N/A * Convert this to 4bpp. 0N/A /* If there is no special transform needed (this is a 0N/A * simple BLIT) and dibType == img.getType() and we 0N/A * didn't create a new IndexColorModel AND the whole of 0N/A * the source image is being drawn (GDI can't handle a 0N/A * portion of the original source image) then we 0N/A * don't need to create this intermediate image - GDI 0N/A * can access the data from the original image. 0N/A * Since a subimage can be created by calling 0N/A * BufferedImage.getSubImage() that condition needs to 0N/A * be accounted for too. This implies inspecting the 0N/A * data buffer. In the end too many cases are not able 0N/A * to take advantage of this option until we can teach 0N/A * the native code to properly navigate the data buffer. 0N/A * There was a concern that since in native code since we 0N/A * need to DWORD align and flip to a bottom up DIB that 0N/A * the "original" image may get perturbed by this. 0N/A * But in fact we always malloc new memory for the aligned 0N/A * copy so this isn't a problem. 0N/A * This points out that we allocate two temporaries copies 0N/A * of the image : one in Java and one in native. If 0N/A * we can be smarter about not allocating this one when 0N/A * not needed, that would seem like a good thing to do, 0N/A * even if in many cases the ColorModels don't match and 0N/A * Until all of this is resolved newImage is always true. 0N/A /* Setup a Graphics2D on to the BufferedImage so that 0N/A * the source image when copied, lands within the 0N/A /* Fill the BufferedImage either with the caller 0N/A * supplied color, 'bgColor' or, if null, with white. 0N/A /* Scale the bounding rectangle by the scale transform. 0N/A * Because the scaling transform has only x and y 0N/A * scaling components it is equivalent to multiply 0N/A * the x components of the bounding rectangle by 0N/A * the x scaling factor and to multiply the y components 0N/A * by the y scaling factor. 0N/A /* Pull the raster data from the buffered image 0N/A * and pass it along to GDI. 0N/A /* Because the caller's image has been rotated 0N/A * and sheared into our BufferedImage and because 0N/A * we will be handing that BufferedImage directly to 0N/A * GDI, we need to set an additional clip. This clip 0N/A * makes sure that only parts of the BufferedImage 0N/A * that are also part of the caller's image are drawn. 0N/A * Have the printing application redraw everything that falls 0N/A * within the page bounds defined by <code>region</code>. 0N/A /* Create a buffered image big enough to hold the portion 0N/A * of the source image being printed. 0N/A /* Get a graphics for the application to render into. 0N/A * We initialize the buffer to white in order to 0N/A * match the paper and then we shift the BufferedImage 0N/A * so that it covers the area on the page where the 0N/A * caller's Image will be drawn. 0N/A /* Calculate the resolution of the source image. 0N/A /* The application expects to see user space at 72 dpi. 0N/A * so change user space from image source resolution to 0N/A /* NB User space now has to be at 72 dpi for this calc to be correct */ 0N/A /* We need to set the device clip using saved information. 0N/A * savedClip intersects the user clip with a clip that restricts 0N/A * the GDI rendered area of our BufferedImage to that which 0N/A * may correspond to a rotate or shear. 0N/A * The saved device transform is needed as the current transform 0N/A * is not likely to be the same. 0N/A /* Scale the bounding rectangle by the scale transform. 0N/A * Because the scaling transform has only x and y 0N/A * scaling components it is equivalent to multiplying 0N/A * the x components of the bounding rectangle by 0N/A * the x scaling factor and to multiplying the y components 0N/A * by the y scaling factor. 0N/A /* Pull the raster data from the buffered image 0N/A * and pass it along to GDI. 0N/A * Fill the path defined by <code>pathIter</code> 0N/A * with the specified color. 0N/A * The path is provided in device coordinates. 0N/A * Set the printer device's clip to be the 0N/A * path defined by <code>pathIter</code> 0N/A * The path is provided in device coordinates. 0N/A * Draw the bounding rectangle using transformed coordinates. 0N/A /* check if rotated or sheared */ 0N/A /* check for default style and try to optimize it by 0N/A * calling the frameRect native function instead of using paths. 0N/A /* transform upper left coordinate */ 0N/A /* transform lower right coordinate */ 0N/A /* use selectStylePen, if supported */ 0N/A /* not supported, must be a Win 9x */ 0N/A /* use the default pen styles for thin pens. */ 0N/A * Fill the rectangle with specified color and using Windows' 0N/A * GDI fillRect function. 0N/A * Boundaries are determined by the given coordinates. 0N/A * Transform to device coordinates 0N/A /* check if rotated or sheared */ 0N/A * Draw a line using a pen created using the specified color 0N/A * and current stroke properties. 0N/A /* check if it's a one-pixel line */ 0N/A /* endCap other than Round will not print! 0N/A * due to Windows GDI limitation, force it to CAP_ROUND 0N/A /* call native function that creates pen with style */ 0N/A /* selectStylePen is not supported, must be Win 9X */ 0N/A /* let's see if we can use a a default pen 0N/A * if it's round end (Windows' default style) 0N/A * or stroke is too thin. 0N/A * Given a Java2D <code>PathIterator</code> instance, 0N/A * this method translates that into a Window's path 0N/A * in the printer device context. 0N/A /* Map the PathIterator's fill rule into the Window's 0N/A * polygon fill rule. 0N/A /* Convert the quad path to a bezier.