1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.modeling.ui.pdf;
\r
14 import java.util.concurrent.Semaphore;
\r
15 import java.util.concurrent.atomic.AtomicReference;
\r
17 import org.simantics.db.ReadGraph;
\r
18 import org.simantics.db.Resource;
\r
19 import org.simantics.db.common.request.PossibleIndexRoot;
\r
20 import org.simantics.db.common.request.UniqueRead;
\r
21 import org.simantics.db.common.utils.NameUtils;
\r
22 import org.simantics.db.exception.DatabaseException;
\r
23 import org.simantics.db.exception.ValidationException;
\r
24 import org.simantics.db.layer0.variable.Variable;
\r
25 import org.simantics.db.layer0.variable.Variables;
\r
26 import org.simantics.db.management.ISessionContext;
\r
27 import org.simantics.diagram.elements.DiagramNodeUtil;
\r
28 import org.simantics.diagram.stubs.DiagramResource;
\r
29 import org.simantics.g2d.canvas.Hints;
\r
30 import org.simantics.g2d.canvas.impl.CanvasContext;
\r
31 import org.simantics.g2d.scenegraph.ICanvasSceneGraphProvider;
\r
32 import org.simantics.modeling.requests.Node;
\r
33 import org.simantics.structural.stubs.StructuralResource2;
\r
34 import org.simantics.utils.DataContainer;
\r
35 import org.simantics.utils.datastructures.Pair;
\r
36 import org.simantics.utils.page.PageDesc;
\r
37 import org.simantics.utils.threads.IThreadWorkQueue;
\r
38 import org.simantics.utils.threads.ThreadUtils;
\r
40 import com.lowagie.text.Rectangle;
\r
41 import com.lowagie.text.pdf.FontMapper;
\r
42 import com.lowagie.text.pdf.PdfWriter;
\r
45 * Rasterizes diagram into a PDF document using the com.lowagie.text plug-in.
\r
47 * @author Tuukka Lehtonen
\r
49 public class PDFPainter {
\r
51 public static boolean render(
\r
52 final IThreadWorkQueue thread,
\r
53 final ISessionContext sessionContext,
\r
54 PDFExportPlan exportModel,
\r
56 final PdfWriter writer,
\r
57 final FontMapper mapper,
\r
58 final Rectangle pageSize,
\r
59 final PageDesc pageDesc,
\r
60 final boolean fitDiagramContentsToPageMargins,
\r
62 throws InterruptedException, DatabaseException
\r
64 final DataContainer<Boolean> result = new DataContainer<Boolean>(false);
\r
65 final DataContainer<DatabaseException> exception = new DataContainer<DatabaseException>();
\r
67 final CanvasContext ctx = new CanvasContext(thread);
\r
68 final AtomicReference<ICanvasSceneGraphProvider> sgProvider = new AtomicReference<ICanvasSceneGraphProvider>();
\r
71 final Semaphore done = new Semaphore(0);
\r
72 // IMPORTANT: Load diagram in a different thread than the canvas context thread!
\r
73 ThreadUtils.getBlockingWorkExecutor().execute(new Runnable() {
\r
77 Pair<Resource, String> modelAndRVI = sessionContext.getSession().syncRequest(new UniqueRead<Pair<Resource, String>>() {
\r
79 public Pair<Resource, String> perform(ReadGraph graph) throws DatabaseException {
\r
80 return new Pair<Resource, String>( resolveModel(graph, node), resolveRVI(graph, node) );
\r
84 final Boolean isSymbol = sessionContext.getSession().syncRequest(new UniqueRead<Boolean>() {
\r
86 public Boolean perform(ReadGraph graph) throws DatabaseException {
\r
87 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
88 DiagramResource DIA = DiagramResource.getInstance(graph);
\r
89 Resource possibleSymbol = graph.getPossibleObject(node.getDiagramResource(), STR.Defines);
\r
90 return possibleSymbol != null && graph.isInstanceOf(possibleSymbol, DIA.ElementClass);
\r
94 ICanvasSceneGraphProvider provider = DiagramNodeUtil.loadSceneGraphProvider(ctx, modelAndRVI.first, node.getDiagramResource(), modelAndRVI.second, 5000);
\r
95 sgProvider.set( provider );
\r
96 ctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);
\r
98 // StringBuilder b = new StringBuilder();
\r
99 // NodeUtil.printTreeNodes(ctx.getCanvasNode(), b);
\r
100 // System.err.println(b.toString());
\r
102 ThreadUtils.asyncExec(thread, new Runnable() {
\r
104 public void run() {
\r
106 PDFBuilder chassis = new PDFBuilder(writer, mapper, pageSize, pageDesc, fitDiagramContentsToPageMargins || isSymbol);
\r
108 chassis.paint(ctx, true);
\r
114 } catch (DatabaseException e) {
\r
117 } catch (Throwable e) {
\r
119 exception.set(new DatabaseException(e));
\r
127 if (exception.get() != null)
\r
128 throw exception.get();
\r
129 return result.get();
\r
131 if (sgProvider.get() != null)
\r
132 sgProvider.get().dispose();
\r
137 private static Resource resolveModel(ReadGraph graph, Node node) throws DatabaseException {
\r
138 Resource composite = node.getDefiningResources().head();
\r
139 Resource model = graph.syncRequest(new PossibleIndexRoot(composite));
\r
140 // Resource model = StructuralVariables.getModel(graph, composite);
\r
142 throw new ValidationException("no model found for composite " + NameUtils.getSafeName(graph, composite));
\r
146 // private static String resolveModelURI(ReadGraph graph, final Node node) throws DatabaseException {
\r
147 // return graph.getURI(resolveModel(graph, node));
\r
150 private static String resolveRVI(ReadGraph graph, final Node node) throws DatabaseException {
\r
151 String RVI = node.getRVI();
\r
152 if(RVI != null) return RVI;
\r
153 Resource composite = node.getDefiningResources().head();
\r
154 Variable var = Variables.getVariable(graph, composite);
\r
155 org.simantics.db.layer0.variable.RVI rvi = var.getPossibleRVI(graph);
\r
156 if(rvi == null) return null;
\r
157 return rvi.toString();
\r
158 // final ResourceArray compositePath = StructuralVariables.getCompositeArray(graph, composite);
\r
159 // final ResourceArray variablePath = compositePath.removeFromBeginning(1);
\r
160 // return StructuralVariables.getRVI(graph, variablePath);
\r