Example usage for java.awt.geom AffineTransform AffineTransform

List of usage examples for java.awt.geom AffineTransform AffineTransform

Introduction

In this page you can find the example usage for java.awt.geom AffineTransform AffineTransform.

Prototype

public AffineTransform() 

Source Link

Document

Constructs a new AffineTransform representing the Identity transformation.

Usage

From source file:org.esa.snap.core.gpf.common.BandMathsOpTest.java

@Test
public void testTwoExpressionWithMultiSize() throws Exception {
    Product sourceProduct1 = createTestProduct(4, 4);
    AffineTransform imageToMap = new AffineTransform();
    final GeoCoding geoCoding = new CrsGeoCoding(CRS.decode("EPSG:32632"), new Rectangle(4, 4), imageToMap);
    sourceProduct1.setSceneGeoCoding(geoCoding);

    Product sourceProduct2 = createTestProduct(12, 12);
    AffineTransform imageToMap2 = new AffineTransform();
    final GeoCoding geoCoding2 = new CrsGeoCoding(CRS.decode("EPSG:32632"), new Rectangle(12, 12), imageToMap2);
    sourceProduct2.setSceneGeoCoding(geoCoding2);

    Map<String, Object> parameters = new HashMap<>();
    BandMathsOp.BandDescriptor[] bandDescriptors = new BandMathsOp.BandDescriptor[2];
    bandDescriptors[0] = createBandDescription("aBandName1", "$sourceProduct.1.band1 + $sourceProduct.1.band2",
            ProductData.TYPESTRING_UINT16, "simpleUnits");
    bandDescriptors[1] = createBandDescription("aBandName2", "$sourceProduct.2.band1 + $sourceProduct.2.band2",
            ProductData.TYPESTRING_UINT16, "simpleUnits");
    parameters.put("targetBands", bandDescriptors);

    Product targetProduct = GPF.createProduct("BandMaths", parameters, sourceProduct1, sourceProduct2);

    assertNotNull(targetProduct);/*from   ww w  .  java2s. co  m*/
    assertNotNull(targetProduct.getSceneGeoCoding());
    assertFalse(targetProduct.isUsingSingleGeoCoding());

    final GeoCoding targetGC1 = targetProduct.getBand("aBandName1").getGeoCoding();
    final GeoCoding targetGC2 = targetProduct.getBand("aBandName2").getGeoCoding();
    assertNotSame(targetGC1, targetGC2);
}

From source file:org.zkoss.poi.ss.util.SheetUtil.java

/**
 * Compute width of a single cell/*from ww w  .  jav  a  2  s . c  o  m*/
 *
 * @param cell the cell whose width is to be calculated
 * @param defaultCharWidth the width of a single character
 * @param formatter formatter used to prepare the text to be measured
 * @param useMergedCells    whether to use merged cells
 * @return  the width in pixels
 */
public static double getCellWidth(Cell cell, int defaultCharWidth, DataFormatter formatter,
        boolean useMergedCells) {

    Sheet sheet = cell.getSheet();
    Workbook wb = sheet.getWorkbook();
    Row row = cell.getRow();
    int column = cell.getColumnIndex();

    int colspan = 1;
    for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
        CellRangeAddress region = sheet.getMergedRegion(i);
        if (containsCell(region, row.getRowNum(), column)) {
            if (!useMergedCells) {
                // If we're not using merged cells, skip this one and move on to the next.
                return -1;
            }
            cell = row.getCell(region.getFirstColumn());
            colspan = 1 + region.getLastColumn() - region.getFirstColumn();
        }
    }

    CellStyle style = cell.getCellStyle();
    int cellType = cell.getCellType();

    // for formula cells we compute the cell width for the cached formula result
    if (cellType == Cell.CELL_TYPE_FORMULA)
        cellType = cell.getCachedFormulaResultType();

    Font font = wb.getFontAt(style.getFontIndex());

    AttributedString str;
    TextLayout layout;

    double width = -1;
    if (cellType == Cell.CELL_TYPE_STRING) {
        RichTextString rt = cell.getRichStringCellValue();
        String[] lines = rt.getString().split("\\n");
        for (int i = 0; i < lines.length; i++) {
            String txt = lines[i] + defaultChar;

            str = new AttributedString(txt);
            copyAttributes(font, str, 0, txt.length());

            if (rt.numFormattingRuns() > 0) {
                // TODO: support rich text fragments
            }

            layout = new TextLayout(str.getIterator(), fontRenderContext);
            if (style.getRotation() != 0) {
                /*
                 * Transform the text using a scale so that it's height is increased by a multiple of the leading,
                 * and then rotate the text before computing the bounds. The scale results in some whitespace around
                 * the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
                 * is added by the standard Excel autosize.
                 */
                AffineTransform trans = new AffineTransform();
                trans.concatenate(
                        AffineTransform.getRotateInstance(style.getRotation() * 2.0 * Math.PI / 360.0));
                trans.concatenate(AffineTransform.getScaleInstance(1, fontHeightMultiple));
                width = Math.max(width,
                        ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth)
                                + cell.getCellStyle().getIndention());
            } else {
                width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth)
                        + cell.getCellStyle().getIndention());
            }
        }
    } else {
        String sval = null;
        if (cellType == Cell.CELL_TYPE_NUMERIC) {
            // Try to get it formatted to look the same as excel
            try {
                sval = formatter.formatCellValue(cell, dummyEvaluator);
            } catch (Exception e) {
                sval = String.valueOf(cell.getNumericCellValue());
            }
        } else if (cellType == Cell.CELL_TYPE_BOOLEAN) {
            sval = String.valueOf(cell.getBooleanCellValue()).toUpperCase();
        }
        if (sval != null) {
            String txt = sval + defaultChar;
            str = new AttributedString(txt);
            copyAttributes(font, str, 0, txt.length());

            layout = new TextLayout(str.getIterator(), fontRenderContext);
            if (style.getRotation() != 0) {
                /*
                 * Transform the text using a scale so that it's height is increased by a multiple of the leading,
                 * and then rotate the text before computing the bounds. The scale results in some whitespace around
                 * the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
                 * is added by the standard Excel autosize.
                 */
                AffineTransform trans = new AffineTransform();
                trans.concatenate(
                        AffineTransform.getRotateInstance(style.getRotation() * 2.0 * Math.PI / 360.0));
                trans.concatenate(AffineTransform.getScaleInstance(1, fontHeightMultiple));
                width = Math.max(width,
                        ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth)
                                + cell.getCellStyle().getIndention());
            } else {
                width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth)
                        + cell.getCellStyle().getIndention());
            }
        }
    }
    return width;
}

From source file:net.sf.ginp.util.GinpUtil.java

/**
 * Take a jpeg from an input stream and write it to an output.
 * stream with a scaled width and height
 * @param sos output stream for image/*from   w w  w  .  j a v  a  2 s . co m*/
 * @param is input stream for image
 * @param width width
 * @param height height
 * @throws IOException if there is an error writing or reading
 */
public static void writeScaledImageToStream(final OutputStream sos, final InputStream is, final int width,
        final int height) throws IOException {
    JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(is);
    BufferedImage origImage = decoder.decodeAsBufferedImage();
    int origHeight = origImage.getHeight(null);
    int origWidth = origImage.getWidth(null);
    int scaledW = 0;
    int scaledH = 0;
    double scaleW = 1.0;
    double scaleH = 1.0;

    // close input stream
    is.close();

    // Calculate scale factors
    if (width == 0) {
        scaleW = (double) height / (double) origHeight;
        scaleH = (double) height / (double) origHeight;
    } else if (height == 0) {
        scaleW = (double) width / (double) origWidth;
        scaleH = (double) width / (double) origWidth;
    } else {
        scaleW = (double) width / (double) origWidth;
        scaleH = (double) height / (double) origHeight;
    }

    scaledW = (int) (scaleW * origWidth);
    scaledH = (int) (scaleH * origHeight);

    BufferedImage outImage = new BufferedImage(scaledW, scaledH, BufferedImage.TYPE_INT_RGB);
    AffineTransform tx = new AffineTransform();

    tx.scale(scaleW, scaleH);

    AffineTransformOp af = new AffineTransformOp(tx, null);

    af.filter(origImage, outImage);

    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(sos);

    encoder.encode(outImage);
}

From source file:org.encuestame.business.images.ImageThumbnailGeneratorImpl.java

/**
 * Create a thumbnail image and save it to disk.
 *
 * This algorithm is based on://from ww  w .  j  av a  2 s  .c  o m
 *      http://www.philreeve.com/java_high_quality_thumbnails.php
 *
 * @param imageIn           The image you want to scale.
 * @param fileOut           The output file.
 * @param largestDimension  The largest dimension, so that neither the width nor height
 *                          will exceed this value.
 *
 * @return the image that was created, null if imageIn or fileOut is null.
 * @throws java.io.IOException if something goes wrong when saving as jpeg
 */
public BufferedImage createThumbnailImage(Image imageIn, File fileOut, int largestDimension)
        throws IOException {
    if ((imageIn == null) || (fileOut == null)) {
        return null;
    }
    //it seems to not return the right size until the methods get called for the first time
    imageIn.getWidth(null);
    imageIn.getHeight(null);

    // Find biggest dimension
    int nImageWidth = imageIn.getWidth(null);
    int nImageHeight = imageIn.getHeight(null);
    int nImageLargestDim = Math.max(nImageWidth, nImageHeight);
    double scale = (double) largestDimension / (double) nImageLargestDim;
    int sizeDifference = nImageLargestDim - largestDimension;

    //create an image buffer to draw to
    BufferedImage imageOut = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); // 8-bit RGB
    Graphics2D g2d;
    AffineTransform tx;

    // Use a few steps if the sizes are drastically different, and only scale
    // if the desired size is smaller than the original.
    int numSteps = 0;
    if (scale < 1.0d) {
        // Make sure we have at least 1 step
        numSteps = Math.max(1, (sizeDifference / 100));
    }

    if (numSteps > 0) {
        int stepSize = sizeDifference / numSteps;
        int stepWeight = stepSize / 2;
        int heavierStepSize = stepSize + stepWeight;
        int lighterStepSize = stepSize - stepWeight;
        int currentStepSize, centerStep;
        double scaledW = imageIn.getWidth(null);
        double scaledH = imageIn.getHeight(null);

        if ((numSteps % 2) == 1) //if there's an odd number of steps
            centerStep = (int) Math.ceil((double) numSteps / 2d); //find the center step
        else
            centerStep = -1; //set it to -1 so it's ignored later

        Integer intermediateSize;
        Integer previousIntermediateSize = nImageLargestDim;

        for (Integer i = 0; i < numSteps; i++) {
            if (i + 1 != centerStep) {
                //if this isn't the center step

                if (i == numSteps - 1) {
                    //if this is the last step
                    //fix the stepsize to account for decimal place errors previously
                    currentStepSize = previousIntermediateSize - largestDimension;
                } else {
                    if (numSteps - i > numSteps / 2) //if we're in the first half of the reductions
                        currentStepSize = heavierStepSize;
                    else
                        currentStepSize = lighterStepSize;
                }
            } else {
                //center step, use natural step size
                currentStepSize = stepSize;
            }

            intermediateSize = previousIntermediateSize - currentStepSize;
            scale = intermediateSize / (double) previousIntermediateSize;
            scaledW = Math.max((int) (scaledW * scale), 1);
            scaledH = Math.max((int) (scaledH * scale), 1);

            log.info("step " + i + ": scaling to " + scaledW + " x " + scaledH);
            imageOut = new BufferedImage((int) scaledW, (int) scaledH, BufferedImage.TYPE_INT_RGB); // 8 bit RGB
            g2d = imageOut.createGraphics();
            g2d.setBackground(Color.WHITE);
            g2d.clearRect(0, 0, imageOut.getWidth(), imageOut.getHeight());
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            tx = new AffineTransform();
            tx.scale(scale, scale);
            g2d.drawImage(imageIn, tx, null);
            g2d.dispose();
            imageIn = new ImageIcon(imageOut).getImage();
            previousIntermediateSize = intermediateSize;
        }
    } else {
        // This enforces a rule that we always have an 8-bit image with white background for the thumbnail.  Plus, for large
        // images, this makes subsequent downscaling really fast because we are working on a large 8-bit image
        // instead of a large 12 or 24 bit image, so the downstream effect is very noticable.
        imageOut = new BufferedImage(imageIn.getWidth(null), imageIn.getHeight(null),
                BufferedImage.TYPE_INT_RGB);
        g2d = imageOut.createGraphics();
        g2d.setBackground(Color.WHITE);
        g2d.clearRect(0, 0, imageOut.getWidth(), imageOut.getHeight());
        tx = new AffineTransform();
        tx.setToIdentity(); //use identity matrix so image is copied exactly
        g2d.drawImage(imageIn, tx, null);
        g2d.dispose();
    }
    //saveImageAsJPEG(imageOut, fileOut);
    ImageIO.write(imageOut, "jpg", fileOut);
    return imageOut;
}

From source file:org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.internal.PdfGraphics2D.java

/**
 * Constructor for PDFGraphics2D.//from  w w w  .  ja  v a2s .co m
 */
public PdfGraphics2D(final PdfContentByte cb, final float width, final float height,
        final PdfOutputProcessorMetaData metaData) {
    this.metaData = metaData;
    dg2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

    this.transform = new AffineTransform();

    paint = Color.black;
    background = Color.white;
    setFont(new Font("sanserif", Font.PLAIN, 12));
    this.cb = cb;
    cb.saveState();
    this.width = width;
    this.height = height;
    clip = new Area(new Rectangle2D.Float(0, 0, width, height));
    clip(clip);
    oldStroke = strokeOne;
    stroke = strokeOne;
    originalStroke = strokeOne;
    setStrokeDiff(stroke, null);
    cb.saveState();
}

From source file:org.apache.jetspeed.security.mfa.impl.CaptchaImageResource.java

public void init() {
    boolean emptyBackground = true;
    if (config.isUseImageBackground() && background != null) {
        ByteArrayInputStream is = new ByteArrayInputStream(background);
        JPEGImgDecoder decoder = new DefaultJPEGImgDecoder();
        try {//from www  .ja v a 2  s.  c om
            this.image = decoder.decodeAsBufferedImage(is);
            this.width = image.getWidth();
            this.height = image.getHeight();
            emptyBackground = false;
        } catch (Exception e) {
            emptyBackground = true;
        }
    }
    if (emptyBackground) {
        this.width = config.getTextMarginLeft() * 2;
        this.height = config.getTextMarginBottom() * 6;
    }
    char[] chars = challengeId.toCharArray();
    charAttsList = new ArrayList();
    TextLayout text = null;
    AffineTransform textAt = null;
    String[] fontNames = config.getFontNames();
    for (int i = 0; i < chars.length; i++) {
        // font name
        String fontName = (fontNames.length == 1) ? fontNames[0] : fontNames[randomInt(0, fontNames.length)];

        // rise
        int rise = config.getTextRiseRange();
        if (rise > 0) {
            rise = randomInt(config.getTextMarginBottom(),
                    config.getTextMarginBottom() + config.getTextRiseRange());
        }

        if (config.getTextShear() > 0.0 || config.getTextRotation() > 0) {
            // rotation
            double dRotation = 0.0;
            if (config.getTextRotation() > 0) {
                dRotation = Math.toRadians(randomInt(-(config.getTextRotation()), config.getTextRotation()));
            }

            // shear
            double shearX = 0.0;
            double shearY = 0.0;
            if (config.getTextShear() > 0.0) {
                Random ran = new Random();
                shearX = ran.nextDouble() * config.getTextShear();
                shearY = ran.nextDouble() * config.getTextShear();
            }
            CharAttributes cf = new CharAttributes(chars[i], fontName, dRotation, rise, shearX, shearY);
            charAttsList.add(cf);
            text = new TextLayout(chars[i] + "", getFont(fontName),
                    new FontRenderContext(null, config.isFontAntialiasing(), false));
            textAt = new AffineTransform();
            if (config.getTextRotation() > 0)
                textAt.rotate(dRotation);
            if (config.getTextShear() > 0.0)
                textAt.shear(shearX, shearY);
        } else {
            CharAttributes cf = new CharAttributes(chars[i], fontName, 0, rise, 0.0, 0.0);
            charAttsList.add(cf);
        }
        if (emptyBackground) {
            Shape shape = text.getOutline(textAt);
            //                this.width += text.getBounds().getWidth();
            this.width += (int) shape.getBounds2D().getWidth();
            this.width += config.getTextSpacing() + 1;
            if (this.height < (int) shape.getBounds2D().getHeight() + rise) {
                this.height = (int) shape.getBounds2D().getHeight() + rise;
            }
        }
    }
    if (emptyBackground) {
        this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D gfx = (Graphics2D) this.image.getGraphics();
        gfx.setBackground(Color.WHITE);
        gfx.clearRect(0, 0, width, height);
    }
}

From source file:org.fhaes.fhrecorder.view.GraphSummaryOverlay.java

/**
 * @return the approximate width of the label in pixels corresponding to the largest value of the overlay graph's y axis.
 *///from  www  .  ja  v  a 2 s . c o m
public int getMaximumRangeLabelWidth() {

    String maxRangeString = Integer.toString(maxRange);
    FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
    Font font = new Font("SansSerif", Font.PLAIN, 10);
    return (int) (font.getStringBounds(maxRangeString, frc).getWidth() + 6);
}

From source file:org.esa.snap.core.gpf.common.BandMathsOpTest.java

@Test
public void testOneExpressionWithMultiSize() throws Exception {
    Product sourceProduct = createTestProduct(4, 4);
    Band band4 = new Band("band4", ProductData.TYPE_INT16, 10, 10);
    sourceProduct.addBand(band4);/*from  ww  w  . j ava  2s  . c o  m*/
    short[] shortValues = new short[10 * 10];
    Arrays.fill(shortValues, (short) 12);
    band4.setData(ProductData.createInstance(shortValues));

    CoordinateReferenceSystem decode = CRS.decode("EPSG:32632");
    Rectangle imageBounds = new Rectangle(4, 4);
    AffineTransform imageToMap = new AffineTransform();
    final GeoCoding geoCoding = new CrsGeoCoding(decode, imageBounds, imageToMap);

    sourceProduct.setSceneGeoCoding(geoCoding);

    Map<String, Object> parameters = new HashMap<>();
    BandMathsOp.BandDescriptor[] bandDescriptors = new BandMathsOp.BandDescriptor[1];
    bandDescriptors[0] = createBandDescription("aBandName", "band1 * band4", ProductData.TYPESTRING_UINT8,
            "simpleUnits");
    parameters.put("targetBands", bandDescriptors);
    try {
        GPF.createProduct("BandMaths", parameters, sourceProduct);
        fail("Should fail, because bands have different size");
    } catch (OperatorException e) {
        //expected
    }

}

From source file:org.jcurl.core.model.CurveManager.java

public void setCurrentTime(final double currentTime) {
    // log.info(Double.toString(currentTime));
    if (!dirty) {
        if (this.currentTime == currentTime)
            return;
    } else//from   w ww.j a  v  a2s .  c  om
        doInit();
    {
        // TUNE thread safety at the cost of two instanciations per call:
        final double[] tmp = { 0, 0, 0 };
        final AffineTransform m = new AffineTransform();
        // NaN-safe time range check (are we navigating known ground?):
        while (currentTime > doGetNextHit().t) {
            final Tupel nh = doGetNextHit();
            doUpdatePosAndSpeed(nh.t, tmp);
            // compute collission(s);
            final int mask = collider.compute(currentPos, currentSpeed, m);
            if (mask == 0)
                break;
            doRecomputeCurvesAndCollissionTimes(mask, nh.t);
        }
        doUpdatePosAndSpeed(currentTime, tmp);
    }
    {
        final double ot = this.currentTime;
        this.currentTime = currentTime;
        currentPos.notifyChange();
        currentSpeed.notifyChange();
        propChange.firePropertyChange("currentTime", ot, currentTime);
        propChange.firePropertyChange("currentPos", currentPos, currentPos);
        propChange.firePropertyChange("currentSpeed", currentSpeed, currentSpeed);
    }
}

From source file:org.apache.fop.render.ps.PSSVGHandler.java

/**
 * Render the svg document.// ww  w. j  a  v a2s.c om
 * @param context the renderer context
 * @param doc the svg document
 */
protected void renderSVGDocument(RendererContext context, Document doc) {
    PSInfo psInfo = getPSInfo(context);
    int xOffset = psInfo.currentXPosition;
    int yOffset = psInfo.currentYPosition;
    PSGenerator gen = psInfo.psGenerator;

    boolean paintAsBitmap = false;
    if (context != null) {
        Map foreign = (Map) context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES);
        paintAsBitmap = ImageHandlerUtil.isConversionModeBitmap(foreign);
    }
    if (paintAsBitmap) {
        try {
            super.renderSVGDocument(context, doc);
        } catch (IOException ioe) {
            SVGEventProducer eventProducer = SVGEventProducer.Provider
                    .get(context.getUserAgent().getEventBroadcaster());
            eventProducer.svgRenderingError(this, ioe, getDocumentURI(doc));
        }
        return;
    }

    //Controls whether text painted by Batik is generated using text or path operations
    boolean strokeText = false;
    Configuration cfg = psInfo.getHandlerConfiguration();
    if (cfg != null) {
        strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText);
    }

    SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform());

    PSGraphics2D graphics = new PSGraphics2D(strokeText, gen);
    graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());

    BridgeContext ctx = new PSBridgeContext(ua, (strokeText ? null : psInfo.fontInfo),
            context.getUserAgent().getFactory().getImageManager(),
            context.getUserAgent().getImageSessionContext());

    //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine)
    //to it.
    Document clonedDoc = BatikUtil.cloneSVGDocument(doc);

    GraphicsNode root;
    try {
        GVTBuilder builder = new GVTBuilder();
        root = builder.build(ctx, clonedDoc);
    } catch (Exception e) {
        SVGEventProducer eventProducer = SVGEventProducer.Provider
                .get(context.getUserAgent().getEventBroadcaster());
        eventProducer.svgNotBuilt(this, e, getDocumentURI(doc));
        return;
    }
    // get the 'width' and 'height' attributes of the SVG document
    float w = (float) ctx.getDocumentSize().getWidth() * 1000f;
    float h = (float) ctx.getDocumentSize().getHeight() * 1000f;

    float sx = psInfo.getWidth() / w;
    float sy = psInfo.getHeight() / h;

    ctx = null;

    try {
        gen.commentln("%FOPBeginSVG");
        gen.saveGraphicsState();
        /*
         * Clip to the svg area.
         * Note: To have the svg overlay (under) a text area then use
         * an fo:block-container
         */
        gen.writeln("newpath");
        gen.defineRect(xOffset / 1000f, yOffset / 1000f, psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f);
        gen.writeln("clip");

        // transform so that the coordinates (0,0) is from the top left
        // and positive is down and to the right. (0,0) is where the
        // viewBox puts it.
        gen.concatMatrix(sx, 0, 0, sy, xOffset / 1000f, yOffset / 1000f);

        /*
        SVGSVGElement svg = ((SVGDocument)doc).getRootElement();
        AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg,
            psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f, ctx);
        if (!at.isIdentity()) {
        double[] vals = new double[6];
        at.getMatrix(vals);
        gen.concatMatrix(vals);
        }*/

        AffineTransform transform = new AffineTransform();
        // scale to viewbox
        transform.translate(xOffset, yOffset);
        gen.getCurrentState().concatMatrix(transform);
        try {
            root.paint(graphics);
        } catch (Exception e) {
            SVGEventProducer eventProducer = SVGEventProducer.Provider
                    .get(context.getUserAgent().getEventBroadcaster());
            eventProducer.svgRenderingError(this, e, getDocumentURI(doc));
        }

        gen.restoreGraphicsState();
        gen.commentln("%FOPEndSVG");
    } catch (IOException ioe) {
        SVGEventProducer eventProducer = SVGEventProducer.Provider
                .get(context.getUserAgent().getEventBroadcaster());
        eventProducer.svgRenderingError(this, ioe, getDocumentURI(doc));
    }
}