]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFPainter.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / pdf / PDFPainter.java
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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.ui.pdf;\r
13 \r
14 import java.util.concurrent.Semaphore;\r
15 import java.util.concurrent.atomic.AtomicReference;\r
16 \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
39 \r
40 import com.lowagie.text.Rectangle;\r
41 import com.lowagie.text.pdf.FontMapper;\r
42 import com.lowagie.text.pdf.PdfWriter;\r
43 \r
44 /**\r
45  * Rasterizes diagram into a PDF document using the com.lowagie.text plug-in.\r
46  * \r
47  * @author Tuukka Lehtonen\r
48  */\r
49 public class PDFPainter {\r
50 \r
51     public static boolean render(\r
52             final IThreadWorkQueue thread,\r
53             final ISessionContext sessionContext,\r
54             PDFExportPlan exportModel,\r
55             final Node node,\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
61             long timeout)\r
62     throws InterruptedException, DatabaseException\r
63     {\r
64         final DataContainer<Boolean> result = new DataContainer<Boolean>(false);\r
65         final DataContainer<DatabaseException> exception = new DataContainer<DatabaseException>();\r
66 \r
67         final CanvasContext ctx = new CanvasContext(thread);\r
68         final AtomicReference<ICanvasSceneGraphProvider> sgProvider = new AtomicReference<ICanvasSceneGraphProvider>();\r
69 \r
70         try {\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
74                 @Override\r
75                 public void run() {\r
76                     try {\r
77                         Pair<Resource, String> modelAndRVI = sessionContext.getSession().syncRequest(new UniqueRead<Pair<Resource, String>>() {\r
78                             @Override\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
81                             }\r
82                         });\r
83                         \r
84                         final Boolean isSymbol = sessionContext.getSession().syncRequest(new UniqueRead<Boolean>() {\r
85                             @Override\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
91                             }\r
92                         }); \r
93                         \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
97 \r
98 //                        StringBuilder b = new StringBuilder();\r
99 //                        NodeUtil.printTreeNodes(ctx.getCanvasNode(), b);\r
100 //                        System.err.println(b.toString());\r
101 \r
102                         ThreadUtils.asyncExec(thread, new Runnable() {\r
103                             @Override\r
104                             public void run() {\r
105                                 try {\r
106                                     PDFBuilder chassis = new PDFBuilder(writer, mapper, pageSize, pageDesc, fitDiagramContentsToPageMargins || isSymbol);\r
107                                     \r
108                                     chassis.paint(ctx, true);\r
109                                 } finally {\r
110                                     done.release();\r
111                                 }\r
112                             }\r
113                         });\r
114                     } catch (DatabaseException e) {\r
115                         done.release();\r
116                         exception.set(e);\r
117                     } catch (Throwable e) {\r
118                         done.release();\r
119                         exception.set(new DatabaseException(e));\r
120                     } finally {\r
121                         done.release();\r
122                     }\r
123                 }\r
124             });\r
125 \r
126             done.acquire(2);\r
127             if (exception.get() != null)\r
128                 throw exception.get();\r
129             return result.get();\r
130         } finally {\r
131             if (sgProvider.get() != null)\r
132                 sgProvider.get().dispose();\r
133             ctx.dispose();\r
134         }\r
135     }\r
136 \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
141         if (model == null)\r
142             throw new ValidationException("no model found for composite " + NameUtils.getSafeName(graph, composite));\r
143         return model;\r
144     }\r
145 \r
146 //    private static String resolveModelURI(ReadGraph graph, final Node node) throws DatabaseException {\r
147 //        return graph.getURI(resolveModel(graph, node));\r
148 //    }\r
149 \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
161     }\r
162 \r
163 }\r