]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/image/ProviderUtils.java
G2DParentNode handles "undefined" child bounds separately
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / image / ProviderUtils.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g2d.image;
13
14 import java.net.URL;
15
16 import org.simantics.g2d.image.impl.CacheProvider;
17 import org.simantics.g2d.image.impl.ImageBundleFactory;
18 import org.simantics.g2d.image.impl.ImageProxy;
19 import org.simantics.g2d.image.impl.ImageURLFactory;
20 import org.simantics.g2d.image.impl.ProviderAsyncronizer;
21 import org.simantics.g2d.image.impl.ProviderProxier;
22 import org.simantics.g2d.image.impl.RasterizingProvider;
23 import org.simantics.utils.datastructures.cache.IFactory;
24 import org.simantics.utils.datastructures.cache.IProvider;
25 import org.simantics.utils.datastructures.cache.WeakCachedProvider;
26
27 /**
28  * Image Provider Utilities offers methods for constructing chains of 
29  * provider {@link Image} providers. 
30  * <p>
31  * The nature of IProvider&lt;Image&gt; is at the same time 
32  *    (a) description of the source of an image
33  *        e.g. at("https://www.simantics.org/simantics/simantics/logo.jpg") 
34  *     
35  *    (b) method of acquiring the image from its source
36  *        e.g. Image i = provider.get();
37  * <p>
38  * IProviders are equals-comparable and can be used as keys in a map.
39  * eg.
40  * <pre>
41  *   map.put( at("https://www.simantics.org/simantics/simantics/logo.jpg"), obj1 );
42  *   ...
43  *   Object obj2 = map.get( at("https://www.simantics.org/simantics/simantics/logo.jpg") );
44  * </pre>
45  * <p>
46  * The difference between IProvider&lt;Image&gt; and IFactory&lt;Image&gt; is Factory
47  * always constructs a new instance and provider may either instantiate new instance
48  * or return cached result. 
49  * 
50  * In typical scenario the result of IFactory&lt;Image&gt; is cached using cacheResult().
51  * The cached result is stored weakly and therefore strong references are required.
52  * proxy() adds strong reference ({@link ImageProxy}) factory.   
53  * <p>
54  * Example:
55  * <pre>
56  *  IFactory&lt;Image&gt; prov = reference(weakCache(rasterize(asynchronize(at("https://www.simantics.org/simantics/simantics/logo.jpg")))));
57  * 
58  *  Image handle = prov.get();
59  *  handle.addImageListener();
60  *  handle.paint();
61  *  handle = null;
62  * </pre>
63  * 
64  *  handle instance would be a composition of the following instances:
65  *  <pre>
66  *    ImageProxy
67  *      AsyncImage
68  *        AWTImage
69  *          java.awt.image.BufferedImage
70  *  </pre>
71  *
72  * @See {@link ImageUtils}
73  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
74  */
75 public class ProviderUtils {
76
77         /**
78          * Create provider that retrieves symbol from URL. 
79          * Bitmap and SVG symbols are supported. The format of the image is determined
80          * by the suffix of the url. 
81          * 
82          * @param url
83          * @return
84          */
85         public static IFactory<Image> at(URL url)
86         {
87                 return new ImageURLFactory(url);
88         }
89         
90         /**
91          * Create image from bundle address. The bundle address is in format: 
92          * "<bundleId/location/file.ext>" 
93          * Image type is determined from the suffix (.svg .png .jpg etc supported).
94          * 
95          * @param filename bundle address
96          * @return bundle image constructor
97          */
98         public static IFactory<Image> bundle(String filename)
99         {
100                 return new ImageBundleFactory(filename);
101         }       
102         
103         /**
104          * Caches the result of the provided image with a weak reference.
105          * The cached result will be garbage collected with out strong reference
106          * (See reference() ).
107          *  
108          * @return cache
109          */
110         public static IProvider<Image> cache(IProvider<Image> provider)
111         {
112                 return WeakCachedProvider.cache(provider);
113         }
114
115         /**
116          * Creates a memory buffer backed raster of provided vector based image. 
117          * For non-vector images this provider changes nothing.
118          * 
119          * @param prov image provider
120          * @return provider that rasterizes the image
121          */
122         public static IFactory<Image> rasterize(IProvider<Image> prov) {
123                 return new RasterizingProvider(prov); 
124         }
125         
126         /**
127          * Converts provider into asynchronized provider. It returns non-blocking result
128          * while at the same time acquires the actual image of the source provider 
129          * in a thread. Once the image is complete the content of the result will be changed.
130          * Due to this model, the result is Volatile.   
131          * 
132          * @param prov original provider
133          * @return asynchronous provider (constructs new image every time)
134          */
135         public static IFactory<Image> asynchronize(IProvider<Image> prov) {
136                 return new ProviderAsyncronizer(prov); 
137         }
138
139         /**
140          * Adds a strong reference (proxy instance) to the provider chain. 
141          * Proxy handles are used with cache to ensure strong references to the
142          * weakly cached result.   
143          * 
144          * @param prov original provider (cache provider)
145          * @return asynchronous provider (constructs new image every time)
146          */
147         public static IFactory<Image> reference(IProvider<Image> prov) {
148                 return new ProviderProxier(prov); 
149         }
150         
151         /**
152          * Caches the constructed image weakly. Use proxy provider to create
153          * strong references to the cached image.
154          * 
155          * @param prov 
156          * @return caching provider
157          */
158         public static IProvider<Image> cache(IFactory<Image> prov) {
159                 return new CacheProvider(prov);
160         }
161
162         /**
163          * Convenience method that 
164          *  1. acquires image asynchronously in a thread
165          *  2. rasterizes the image to memory buffer, if necessary (it is vector format)
166          *  3. caches the resulted image
167          *  4. creates a strong reference for the cached image
168          *  
169          * The result of the factory instantiates proxy handles.
170          * Proxy handle returns constructed or cached image. 
171          * The underlying image will be remain in memory until all handles are 
172          * released (nulled).  
173          * 
174          * Usage example:
175          *   IFactory<Image> i = convenience( at("https://www.simantics.org/simantics/simantics/logo.jpg") ); 
176          *   i.paint();
177          *   i = null;
178          * 
179          * @param originalFactory
180          * @return factory that instantiates disposable (nullable) handles 
181          */
182         public static IFactory<Image> convenience(IFactory<Image> originalFactory) {
183                 return reference(cache(rasterize(asynchronize(originalFactory))));
184         }
185         public static IFactory<Image> convenience(URL url) {
186                 return reference(cache(rasterize(asynchronize(at(url)))));
187         }
188         public static IFactory<Image> convenience(String bundleAddress) {
189                 return reference(cache(rasterize(asynchronize(bundle(bundleAddress)))));
190         }
191         
192 }
193