1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.g2d.image;
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;
28 * Image Provider Utilities offers methods for constructing chains of
29 * provider {@link Image} providers.
31 * The nature of IProvider<Image> 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")
35 * (b) method of acquiring the image from its source
36 * e.g. Image i = provider.get();
38 * IProviders are equals-comparable and can be used as keys in a map.
41 * map.put( at("https://www.simantics.org/simantics/simantics/logo.jpg"), obj1 );
43 * Object obj2 = map.get( at("https://www.simantics.org/simantics/simantics/logo.jpg") );
46 * The difference between IProvider<Image> and IFactory<Image> is Factory
47 * always constructs a new instance and provider may either instantiate new instance
48 * or return cached result.
50 * In typical scenario the result of IFactory<Image> 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.
56 * IFactory<Image> prov = reference(weakCache(rasterize(asynchronize(at("https://www.simantics.org/simantics/simantics/logo.jpg")))));
58 * Image handle = prov.get();
59 * handle.addImageListener();
64 * handle instance would be a composition of the following instances:
69 * java.awt.image.BufferedImage
72 * @See {@link ImageUtils}
73 * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
75 public class ProviderUtils {
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.
85 public static IFactory<Image> at(URL url)
87 return new ImageURLFactory(url);
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).
95 * @param filename bundle address
96 * @return bundle image constructor
98 public static IFactory<Image> bundle(String filename)
100 return new ImageBundleFactory(filename);
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() ).
110 public static IProvider<Image> cache(IProvider<Image> provider)
112 return WeakCachedProvider.cache(provider);
116 * Creates a memory buffer backed raster of provided vector based image.
117 * For non-vector images this provider changes nothing.
119 * @param prov image provider
120 * @return provider that rasterizes the image
122 public static IFactory<Image> rasterize(IProvider<Image> prov) {
123 return new RasterizingProvider(prov);
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.
132 * @param prov original provider
133 * @return asynchronous provider (constructs new image every time)
135 public static IFactory<Image> asynchronize(IProvider<Image> prov) {
136 return new ProviderAsyncronizer(prov);
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.
144 * @param prov original provider (cache provider)
145 * @return asynchronous provider (constructs new image every time)
147 public static IFactory<Image> reference(IProvider<Image> prov) {
148 return new ProviderProxier(prov);
152 * Caches the constructed image weakly. Use proxy provider to create
153 * strong references to the cached image.
156 * @return caching provider
158 public static IProvider<Image> cache(IFactory<Image> prov) {
159 return new CacheProvider(prov);
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
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
175 * IFactory<Image> i = convenience( at("https://www.simantics.org/simantics/simantics/logo.jpg") );
179 * @param originalFactory
180 * @return factory that instantiates disposable (nullable) handles
182 public static IFactory<Image> convenience(IFactory<Image> originalFactory) {
183 return reference(cache(rasterize(asynchronize(originalFactory))));
185 public static IFactory<Image> convenience(URL url) {
186 return reference(cache(rasterize(asynchronize(at(url)))));
188 public static IFactory<Image> convenience(String bundleAddress) {
189 return reference(cache(rasterize(asynchronize(bundle(bundleAddress)))));