X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Fpdf%2FPDFPainter.java;fp=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Fpdf%2FPDFPainter.java;h=6e725c693b7a2364c83614ba4d585b11c3057353;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFPainter.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFPainter.java new file mode 100644 index 000000000..6e725c693 --- /dev/null +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFPainter.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * 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.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicReference; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ValidationException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.management.ISessionContext; +import org.simantics.diagram.elements.DiagramNodeUtil; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.impl.CanvasContext; +import org.simantics.g2d.scenegraph.ICanvasSceneGraphProvider; +import org.simantics.modeling.requests.Node; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.utils.DataContainer; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.page.PageDesc; +import org.simantics.utils.threads.IThreadWorkQueue; +import org.simantics.utils.threads.ThreadUtils; + +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.FontMapper; +import com.lowagie.text.pdf.PdfWriter; + +/** + * Rasterizes diagram into a PDF document using the com.lowagie.text plug-in. + * + * @author Tuukka Lehtonen + */ +public class PDFPainter { + + public static boolean render( + final IThreadWorkQueue thread, + final ISessionContext sessionContext, + PDFExportPlan exportModel, + final Node node, + final PdfWriter writer, + final FontMapper mapper, + final Rectangle pageSize, + final PageDesc pageDesc, + final boolean fitDiagramContentsToPageMargins, + long timeout) + throws InterruptedException, DatabaseException + { + final DataContainer result = new DataContainer(false); + final DataContainer exception = new DataContainer(); + + final CanvasContext ctx = new CanvasContext(thread); + final AtomicReference sgProvider = new AtomicReference(); + + try { + final Semaphore done = new Semaphore(0); + // IMPORTANT: Load diagram in a different thread than the canvas context thread! + ThreadUtils.getBlockingWorkExecutor().execute(new Runnable() { + @Override + public void run() { + try { + Pair modelAndRVI = sessionContext.getSession().syncRequest(new UniqueRead>() { + @Override + public Pair perform(ReadGraph graph) throws DatabaseException { + return new Pair( resolveModel(graph, node), resolveRVI(graph, node) ); + } + }); + + final Boolean isSymbol = sessionContext.getSession().syncRequest(new UniqueRead() { + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + DiagramResource DIA = DiagramResource.getInstance(graph); + Resource possibleSymbol = graph.getPossibleObject(node.getDiagramResource(), STR.Defines); + return possibleSymbol != null && graph.isInstanceOf(possibleSymbol, DIA.ElementClass); + } + }); + + ICanvasSceneGraphProvider provider = DiagramNodeUtil.loadSceneGraphProvider(ctx, modelAndRVI.first, node.getDiagramResource(), modelAndRVI.second, 5000); + sgProvider.set( provider ); + ctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc); + +// StringBuilder b = new StringBuilder(); +// NodeUtil.printTreeNodes(ctx.getCanvasNode(), b); +// System.err.println(b.toString()); + + ThreadUtils.asyncExec(thread, new Runnable() { + @Override + public void run() { + try { + PDFBuilder chassis = new PDFBuilder(writer, mapper, pageSize, pageDesc, fitDiagramContentsToPageMargins || isSymbol); + + chassis.paint(ctx, true); + } finally { + done.release(); + } + } + }); + } catch (DatabaseException e) { + done.release(); + exception.set(e); + } catch (Throwable e) { + done.release(); + exception.set(new DatabaseException(e)); + } finally { + done.release(); + } + } + }); + + done.acquire(2); + if (exception.get() != null) + throw exception.get(); + return result.get(); + } finally { + if (sgProvider.get() != null) + sgProvider.get().dispose(); + ctx.dispose(); + } + } + + private static Resource resolveModel(ReadGraph graph, Node node) throws DatabaseException { + Resource composite = node.getDefiningResources().head(); + Resource model = graph.syncRequest(new PossibleIndexRoot(composite)); +// Resource model = StructuralVariables.getModel(graph, composite); + if (model == null) + throw new ValidationException("no model found for composite " + NameUtils.getSafeName(graph, composite)); + return model; + } + +// private static String resolveModelURI(ReadGraph graph, final Node node) throws DatabaseException { +// return graph.getURI(resolveModel(graph, node)); +// } + + private static String resolveRVI(ReadGraph graph, final Node node) throws DatabaseException { + String RVI = node.getRVI(); + if(RVI != null) return RVI; + Resource composite = node.getDefiningResources().head(); + Variable var = Variables.getVariable(graph, composite); + org.simantics.db.layer0.variable.RVI rvi = var.getPossibleRVI(graph); + if(rvi == null) return null; + return rvi.toString(); +// final ResourceArray compositePath = StructuralVariables.getCompositeArray(graph, composite); +// final ResourceArray variablePath = compositePath.removeFromBeginning(1); +// return StructuralVariables.getRVI(graph, variablePath); + } + +}