X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Fpdf%2FPDFBuilder.java;h=55f2d034b088fab267e05c3de2f62861e827f0ac;hb=95144e3b879f0a10715927027bb9a7aa8e05bdeb;hp=a6d62e6bb8fc69f875a66f64cd7d03f3f52b402e;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFBuilder.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFBuilder.java index a6d62e6bb..55f2d034b 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFBuilder.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFBuilder.java @@ -1,214 +1,214 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.modeling.ui.pdf; - -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; - -import org.simantics.g2d.canvas.ICanvasContext; -import org.simantics.g2d.diagram.DiagramHints; -import org.simantics.g2d.diagram.DiagramUtils; -import org.simantics.g2d.diagram.IDiagram; -import org.simantics.g2d.participant.TransformUtil; -import org.simantics.scenegraph.g2d.G2DPDFRenderingHints; -import org.simantics.scenegraph.g2d.G2DRenderingHints; -import org.simantics.scenegraph.utils.QualityHints; -import org.simantics.utils.page.MarginUtils; -import org.simantics.utils.page.MarginUtils.Margins; -import org.simantics.utils.page.PageDesc; - -import com.lowagie.text.Rectangle; -import com.lowagie.text.pdf.FontMapper; -import com.lowagie.text.pdf.PdfContentByte; -import com.lowagie.text.pdf.PdfTemplate; -import com.lowagie.text.pdf.PdfWriter; - -/** - * Renders ICanvasContext instances into PDF documents. - * - * @author Tuukka Lehtonen - */ -public class PDFBuilder { - - private final PdfWriter writer; - - private final FontMapper mapper; - - private final Rectangle pageSize; - - private final PageDesc pageDesc; - - private final boolean fitDiagramContentsToPageMargins; - - /** - * @param writer - * @param mapper - * @param pageSize - * @param pageDesc - * @param fitDiagramContentsToPageMargins see - * {@link PDFExportPlan#fitContentToPageMargins} for a description - * of this parameter - */ - public PDFBuilder(PdfWriter writer, FontMapper mapper, Rectangle pageSize, PageDesc pageDesc, boolean fitDiagramContentsToPageMargins) { - assert writer != null; - assert mapper != null; - assert pageSize != null; - assert pageDesc != null; - - this.writer = writer; - this.mapper = mapper; - this.pageSize = pageSize; - this.pageDesc = pageDesc; - this.fitDiagramContentsToPageMargins = fitDiagramContentsToPageMargins; - } - - /** - * @param canvasContext the canvas context to paint - * @param writeResults true to actually write the resulting PDF - * content into the {@link PdfWriter} used to construct this - * PDFBuilder - */ - public void paint(ICanvasContext canvasContext, boolean writeResults) { - // Specify rendering template size in points. - float pw = pageSize.getWidth(); - float ph = pageSize.getHeight(); - PdfContentByte cb = writer.getDirectContent(); - PdfTemplate tp = cb.createTemplate(pw, ph); - Graphics2D g2 = tp.createGraphics(pw, ph, mapper); - g2.setRenderingHint(G2DPDFRenderingHints.KEY_PDF_WRITER, tp.getPdfWriter()); - g2.setRenderingHint(G2DPDFRenderingHints.KEY_PDF_BYTECONTENT, tp); - g2.setRenderingHint(G2DPDFRenderingHints.KEY_PDF_FONTMAPPER, mapper); - - double w = pageDesc.getOrientedWidth(); - double h = pageDesc.getOrientedHeight(); - - //System.out.println("PDFBuilder.paint: page in millimeters " + w + " x " + h + ", page in points " + pw + " x " + ph); - - try { - QualityHints.HIGH_QUALITY_HINTS.setQuality(g2); - g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); - - // Make sure the transformation is reset. - AffineTransform tr = new AffineTransform(); - - Margins m = pageDesc.getMargins(); - double mw = pageDesc.getOrientedWidth() - m.left.diagramAbsolute - m.right.diagramAbsolute; - double mh = pageDesc.getOrientedHeight() - m.top.diagramAbsolute - m.bottom.diagramAbsolute; - - Rectangle2D controlArea = new Rectangle2D.Double(m.left.diagramAbsolute, m.top.diagramAbsolute, mw, mh); - - if (fitDiagramContentsToPageMargins) { - IDiagram diagram = canvasContext.getDefaultHintContext().getHint(DiagramHints.KEY_DIAGRAM); - final Rectangle2D diagramRect = DiagramUtils.getContentRect(diagram); - if (diagramRect != null) { - canvasContext.getSingleItem(TransformUtil.class).fitArea(controlArea, diagramRect, MarginUtils.NO_MARGINS); - } - } - - // We render in millimeters, but iText expects coordinates in points. - // So we scale everything to point space. - //System.out.println("PDFBuilder.paint: input transform " + tr); - tr.scale(pw / w, ph / h); - //System.out.println("PDFBuilder.paint: point space scaled transform " + tr); - - g2.setTransform(tr); - //g2.setClip(new Rectangle2D.Double(0, 0, w, h)); - -// if (paintMargin) { -// g2.setStroke(new BasicStroke()); -// g2.setColor(Color.DARK_GRAY); -// g2.draw(new Rectangle2D.Double(pageSize.getBorderWidthLeft(), pageSize.getBorderWidthTop(), ww, hh)); -// } - - // DEBUG: Paint page edges -// g2.setStroke(new BasicStroke(2)); -// g2.setColor(Color.MAGENTA); -// g2.draw(new Rectangle2D.Double(pageDesc.getLeftEdgePos(), pageDesc.getTopEdgePos(), pageDesc.getOrientedWidth(), pageDesc.getOrientedHeight())); - - // DEBUG: paint content area, i.e. the bounds that were fitted to - // meet the printed page margins. -// g2.setColor(new Color(255, 255, 0, 128)); -// g2.draw(controlArea); - - // TODO: test that this doesn't break anything. - g2.setRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS, new Rectangle2D.Double(0, 0, w, h)); - - if (canvasContext.isLocked()) - throw new IllegalStateException("cannot render PDF, canvas context is locked: " + canvasContext); - - canvasContext.getSceneGraph().render(g2); - - // Code from iText examples: -// double ew = w/2; -// double eh = h/2; -// Ellipse2D.Double circle, oval, leaf, stem; -// Area circ, ov, leaf1, leaf2, st1, st2; -// circle = new Ellipse2D.Double(); -// oval = new Ellipse2D.Double(); -// leaf = new Ellipse2D.Double(); -// stem = new Ellipse2D.Double(); -// circ = new Area(circle); -// ov = new Area(oval); -// leaf1 = new Area(leaf); -// leaf2 = new Area(leaf); -// st1 = new Area(stem); -// st2 = new Area(stem); -// g2.setColor(Color.green); -// -// // Creates the first leaf by filling the intersection of two Area objects created from an ellipse. -// leaf.setFrame(ew-16, eh-29, 15.0, 15.0); -// leaf1 = new Area(leaf); -// leaf.setFrame(ew-14, eh-47, 30.0, 30.0); -// leaf2 = new Area(leaf); -// leaf1.intersect(leaf2); -// g2.fill(leaf1); -// -// // Creates the second leaf. -// leaf.setFrame(ew+1, eh-29, 15.0, 15.0); -// leaf1 = new Area(leaf); -// leaf2.intersect(leaf1); -// g2.fill(leaf2); -// -// g2.setColor(Color.black); -// -// // Creates the stem by filling the Area resulting from the subtraction of two Area objects created from an ellipse. -// stem.setFrame(ew, eh-42, 40.0, 40.0); -// st1 = new Area(stem); -// stem.setFrame(ew+3, eh-47, 50.0, 50.0); -// st2 = new Area(stem); -// st1.subtract(st2); -// g2.fill(st1); -// -// g2.setColor(Color.yellow); -// -// // Creates the pear itself by filling the Area resulting from the union of two Area objects created by two different ellipses. -// circle.setFrame(ew-25, eh, 50.0, 50.0); -// oval.setFrame(ew-19, eh-20, 40.0, 70.0); -// circ = new Area(circle); -// ov = new Area(oval); -// circ.add(ov); -// g2.fill(circ); - } finally { - g2.dispose(); - - if (writeResults) { - //System.out.println("Storing PDF template"); - float x = (float) pageDesc.getLeftEdgePos(); - float y = (float) pageDesc.getTopEdgePos(); - cb.addTemplate(tp, x, y); - } - } - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modeling.ui.pdf; + +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.DiagramUtils; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.participant.TransformUtil; +import org.simantics.scenegraph.g2d.G2DPDFRenderingHints; +import org.simantics.scenegraph.g2d.G2DRenderingHints; +import org.simantics.scenegraph.utils.QualityHints; +import org.simantics.utils.page.MarginUtils; +import org.simantics.utils.page.MarginUtils.Margins; +import org.simantics.utils.page.PageDesc; + +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.FontMapper; +import com.lowagie.text.pdf.PdfContentByte; +import com.lowagie.text.pdf.PdfTemplate; +import com.lowagie.text.pdf.PdfWriter; + +/** + * Renders ICanvasContext instances into PDF documents. + * + * @author Tuukka Lehtonen + */ +public class PDFBuilder { + + private final PdfWriter writer; + + private final FontMapper mapper; + + private final Rectangle pageSize; + + private final PageDesc pageDesc; + + private final boolean fitDiagramContentsToPageMargins; + + /** + * @param writer + * @param mapper + * @param pageSize + * @param pageDesc + * @param fitDiagramContentsToPageMargins see + * {@link PDFExportPlan#fitContentToPageMargins} for a description + * of this parameter + */ + public PDFBuilder(PdfWriter writer, FontMapper mapper, Rectangle pageSize, PageDesc pageDesc, boolean fitDiagramContentsToPageMargins) { + assert writer != null; + assert mapper != null; + assert pageSize != null; + assert pageDesc != null; + + this.writer = writer; + this.mapper = mapper; + this.pageSize = pageSize; + this.pageDesc = pageDesc; + this.fitDiagramContentsToPageMargins = fitDiagramContentsToPageMargins; + } + + /** + * @param canvasContext the canvas context to paint + * @param writeResults true to actually write the resulting PDF + * content into the {@link PdfWriter} used to construct this + * PDFBuilder + */ + public void paint(ICanvasContext canvasContext, boolean writeResults) { + // Specify rendering template size in points. + float pw = pageSize.getWidth(); + float ph = pageSize.getHeight(); + PdfContentByte cb = writer.getDirectContent(); + PdfTemplate tp = cb.createTemplate(pw, ph); + Graphics2D g2 = tp.createGraphics(pw, ph, mapper); + g2.setRenderingHint(G2DPDFRenderingHints.KEY_PDF_WRITER, tp.getPdfWriter()); + g2.setRenderingHint(G2DPDFRenderingHints.KEY_PDF_BYTECONTENT, tp); + g2.setRenderingHint(G2DPDFRenderingHints.KEY_PDF_FONTMAPPER, mapper); + + double w = pageDesc.getOrientedWidth(); + double h = pageDesc.getOrientedHeight(); + + //System.out.println("PDFBuilder.paint: page in millimeters " + w + " x " + h + ", page in points " + pw + " x " + ph); + + try { + QualityHints.HIGH_QUALITY_HINTS.setQuality(g2); + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); + + // Make sure the transformation is reset. + AffineTransform tr = new AffineTransform(); + + Margins m = pageDesc.getMargins(); + double mw = pageDesc.getOrientedWidth() - m.left.diagramAbsolute - m.right.diagramAbsolute; + double mh = pageDesc.getOrientedHeight() - m.top.diagramAbsolute - m.bottom.diagramAbsolute; + + Rectangle2D controlArea = new Rectangle2D.Double(m.left.diagramAbsolute, m.top.diagramAbsolute, mw, mh); + + if (fitDiagramContentsToPageMargins) { + IDiagram diagram = canvasContext.getDefaultHintContext().getHint(DiagramHints.KEY_DIAGRAM); + final Rectangle2D diagramRect = DiagramUtils.getContentRect(diagram); + if (diagramRect != null) { + canvasContext.getSingleItem(TransformUtil.class).fitArea(controlArea, diagramRect, MarginUtils.NO_MARGINS); + } + } + + // We render in millimeters, but iText expects coordinates in points. + // So we scale everything to point space. + //System.out.println("PDFBuilder.paint: input transform " + tr); + tr.scale(pw / w, ph / h); + //System.out.println("PDFBuilder.paint: point space scaled transform " + tr); + + g2.setTransform(tr); + //g2.setClip(new Rectangle2D.Double(0, 0, w, h)); + +// if (paintMargin) { +// g2.setStroke(new BasicStroke()); +// g2.setColor(Color.DARK_GRAY); +// g2.draw(new Rectangle2D.Double(pageSize.getBorderWidthLeft(), pageSize.getBorderWidthTop(), ww, hh)); +// } + + // DEBUG: Paint page edges +// g2.setStroke(new BasicStroke(2)); +// g2.setColor(Color.MAGENTA); +// g2.draw(new Rectangle2D.Double(pageDesc.getLeftEdgePos(), pageDesc.getTopEdgePos(), pageDesc.getOrientedWidth(), pageDesc.getOrientedHeight())); + + // DEBUG: paint content area, i.e. the bounds that were fitted to + // meet the printed page margins. +// g2.setColor(new Color(255, 255, 0, 128)); +// g2.draw(controlArea); + + // TODO: test that this doesn't break anything. + g2.setRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS, new Rectangle2D.Double(0, 0, w, h)); + + if (canvasContext.isLocked()) + throw new IllegalStateException("cannot render PDF, canvas context is locked: " + canvasContext); + + canvasContext.getSceneGraph().render(g2); + + // Code from iText examples: +// double ew = w/2; +// double eh = h/2; +// Ellipse2D.Double circle, oval, leaf, stem; +// Area circ, ov, leaf1, leaf2, st1, st2; +// circle = new Ellipse2D.Double(); +// oval = new Ellipse2D.Double(); +// leaf = new Ellipse2D.Double(); +// stem = new Ellipse2D.Double(); +// circ = new Area(circle); +// ov = new Area(oval); +// leaf1 = new Area(leaf); +// leaf2 = new Area(leaf); +// st1 = new Area(stem); +// st2 = new Area(stem); +// g2.setColor(Color.green); +// +// // Creates the first leaf by filling the intersection of two Area objects created from an ellipse. +// leaf.setFrame(ew-16, eh-29, 15.0, 15.0); +// leaf1 = new Area(leaf); +// leaf.setFrame(ew-14, eh-47, 30.0, 30.0); +// leaf2 = new Area(leaf); +// leaf1.intersect(leaf2); +// g2.fill(leaf1); +// +// // Creates the second leaf. +// leaf.setFrame(ew+1, eh-29, 15.0, 15.0); +// leaf1 = new Area(leaf); +// leaf2.intersect(leaf1); +// g2.fill(leaf2); +// +// g2.setColor(Color.black); +// +// // Creates the stem by filling the Area resulting from the subtraction of two Area objects created from an ellipse. +// stem.setFrame(ew, eh-42, 40.0, 40.0); +// st1 = new Area(stem); +// stem.setFrame(ew+3, eh-47, 50.0, 50.0); +// st2 = new Area(stem); +// st1.subtract(st2); +// g2.fill(st1); +// +// g2.setColor(Color.yellow); +// +// // Creates the pear itself by filling the Area resulting from the union of two Area objects created by two different ellipses. +// circle.setFrame(ew-25, eh, 50.0, 50.0); +// oval.setFrame(ew-19, eh-20, 40.0, 70.0); +// circ = new Area(circle); +// ov = new Area(oval); +// circ.add(ov); +// g2.fill(circ); + } finally { + g2.dispose(); + + if (writeResults) { + //System.out.println("Storing PDF template"); + float x = (float) pageDesc.getLeftEdgePos(); + float y = (float) pageDesc.getTopEdgePos(); + cb.addTemplate(tp, x, y); + } + } + } + +}