Xamarin Public Jenkins (auto-signing) 536cd135cc Imported Upstream version 5.4.0.167
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
2017-08-21 15:34:15 +00:00

422 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//-------------------------------------------------------------
// <copyright company=Microsoft Corporation>
// Copyright © Microsoft Corporation. All Rights Reserved.
// </copyright>
//-------------------------------------------------------------
// @owner=alexgor, deliant
//=================================================================
// File: ImageLoader.cs
//
// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Utilities
//
// Classes: ImageLoader
//
// Purpose: ImageLoader utility class loads specified image and
// caches it in the memory for the future use.
//
// Images can be loaded from different places including
// Files, URIs, WebRequests and Control Resources.
//
// Reviewed: AG - August 7, 2002
// AG - Microsoft 5, 2007
//
//===================================================================
#region Used Namespaces
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Reflection;
using System.Net;
using System.IO;
using System.Security;
using System.Resources;
#if Microsoft_CONTROL
using System.Windows.Forms.DataVisualization.Charting;
#else
using System.Web;
using System.Web.UI.DataVisualization.Charting;
#endif
#endregion
#if Microsoft_CONTROL
namespace System.Windows.Forms.DataVisualization.Charting.Utilities
#else
namespace System.Web.UI.DataVisualization.Charting.Utilities
#endif
{
/// <summary>
/// ImageLoader utility class loads and returns specified image
/// form the File, URI, Web Request or Chart Resources.
/// Loaded images are stored in the internal hashtable which
/// allows to improve performance if image need to be used
/// several times.
/// </summary>
internal class ImageLoader : IDisposable, IServiceProvider
{
#region Fields
// Image storage
private Hashtable _imageData = null;
// Reference to the service container
private IServiceContainer _serviceContainer = null;
#endregion
#region Constructors and Initialization
/// <summary>
/// Default constructor is not accessible.
/// </summary>
private ImageLoader()
{
}
/// <summary>
/// Default public constructor.
/// </summary>
/// <param name="container">Service container.</param>
public ImageLoader(IServiceContainer container)
{
if(container == null)
{
throw(new ArgumentNullException(SR.ExceptionImageLoaderInvalidServiceContainer));
}
_serviceContainer = container;
}
/// <summary>
/// Returns Image Loader service object
/// </summary>
/// <param name="serviceType">Requested service type.</param>
/// <returns>Image Loader service object.</returns>
[EditorBrowsableAttribute(EditorBrowsableState.Never)]
object IServiceProvider.GetService(Type serviceType)
{
if(serviceType == typeof(ImageLoader))
{
return this;
}
throw (new ArgumentException( SR.ExceptionImageLoaderUnsupportedType( serviceType.ToString())));
}
/// <summary>
/// Dispose images in the hashtable
/// </summary>
public void Dispose()
{
if (_imageData != null)
{
foreach (DictionaryEntry entry in _imageData)
{
if (entry.Value is IDisposable)
{
((IDisposable)entry.Value).Dispose();
}
}
_imageData = null;
GC.SuppressFinalize(this);
}
}
#endregion
#region Methods
/// <summary>
/// Loads image from URL. Checks if image already loaded (cached).
/// </summary>
/// <param name="imageURL">Image name (FileName, URL, Resource).</param>
/// <returns>Image object.</returns>
public System.Drawing.Image LoadImage(string imageURL)
{
return LoadImage(imageURL, true);
}
/// <summary>
/// Loads image from URL. Checks if image already loaded (cached).
/// </summary>
/// <param name="imageURL">Image name (FileName, URL, Resource).</param>
/// <param name="saveImage">True if loaded image should be saved in cache.</param>
/// <returns>Image object</returns>
public System.Drawing.Image LoadImage(string imageURL, bool saveImage)
{
System.Drawing.Image image = null;
// Check if image is defined in the chart image collection
if (_serviceContainer != null)
{
Chart chart = (Chart)_serviceContainer.GetService(typeof(Chart));
if(chart != null)
{
foreach(NamedImage namedImage in chart.Images)
{
if(namedImage.Name == imageURL)
{
return namedImage.Image;
}
}
}
}
// Create new hashtable
if (_imageData == null)
{
_imageData = new Hashtable(StringComparer.OrdinalIgnoreCase);
}
// First check if image with this name already loaded
if (_imageData.Contains(imageURL))
{
image = (System.Drawing.Image)_imageData[imageURL];
}
#if ! Microsoft_CONTROL
// Try to load as relative URL using the Control object
if(image == null)
{
Chart control = (Chart)_serviceContainer.GetService(typeof(Chart));
if (control != null && control.Page != null)
{
if (!control.IsDesignMode())
{
image = LoadFromFile(control.Page.MapPath(imageURL));
}
else if (control.IsDesignMode() && !String.IsNullOrEmpty(control.webFormDocumentURL))
{
// Find current web page path and fileName
Uri pageUri = new Uri(control.webFormDocumentURL);
string path = pageUri.LocalPath;
string pageFile = pageUri.Segments[pageUri.Segments.Length-1];
// Find full image fileName
string imageFileRelative = control.ResolveClientUrl(imageURL);
string imageFile = path.Replace(pageFile, imageFileRelative);
// Load image
image = LoadFromFile(imageFile);
}
}
else if ( HttpContext.Current != null )
{
image = LoadFromFile(HttpContext.Current.Request.MapPath(imageURL));
}
}
#endif
// Try to load image from resource
if(image == null)
{
try
{
// Check if resource class type was specified
int columnIndex = imageURL.IndexOf("::", StringComparison.Ordinal);
if (columnIndex > 0)
{
string resourceRootName = imageURL.Substring(0, columnIndex);
string resourceName = imageURL.Substring(columnIndex + 2);
System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(resourceRootName, Assembly.GetExecutingAssembly());
image = (System.Drawing.Image)(resourceManager.GetObject(resourceName));
}
#if Microsoft_CONTROL
else if (Assembly.GetEntryAssembly() != null)
{
// Check if resource class type was specified
columnIndex = imageURL.IndexOf(':');
if (columnIndex > 0)
{
string resourceRootName = imageURL.Substring(0, columnIndex);
string resourceName = imageURL.Substring(columnIndex + 1);
System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(resourceRootName, Assembly.GetEntryAssembly());
image = (Image)(resourceManager.GetObject(resourceName));
}
else
{
// Try to load resource from every type defined in entry assembly
Assembly entryAssembly = Assembly.GetEntryAssembly();
if (entryAssembly != null)
{
foreach (Type type in entryAssembly.GetTypes())
{
System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(type);
try
{
image = (Image)(resourceManager.GetObject(imageURL));
}
catch (ArgumentNullException)
{
}
catch (MissingManifestResourceException)
{
}
// Check if image was loaded
if (image != null)
{
break;
}
}
}
}
}
#endif
}
catch (MissingManifestResourceException)
{
}
}
// Try to load image using the Web Request
if(image == null)
{
Uri imageUri = null;
try
{
// Try to create URI directly from image URL (will work in case of absolute URL)
imageUri = new Uri(imageURL);
}
catch(UriFormatException)
{}
// Load image from file or web resource
if(imageUri != null)
{
try
{
WebRequest request = WebRequest.Create(imageUri);
image = System.Drawing.Image.FromStream(request.GetResponse().GetResponseStream());
}
catch (ArgumentException)
{
}
catch (NotSupportedException)
{
}
catch (SecurityException)
{
}
}
}
#if Microsoft_CONTROL
// absolute uri(without Server.MapPath)in web is not allowed. Loading from replative uri Server[Page].MapPath is done above.
// Try to load as file
if(image == null)
{
image = LoadFromFile(imageURL);
}
#endif
// Error loading image
if(image == null)
{
#if ! Microsoft_CONTROL
throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageUrl( imageURL ) ) );
#else
throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageLocation( imageURL ) ) );
#endif
}
// Save new image in cache
if(saveImage)
{
_imageData[imageURL] = image;
}
return image;
}
/// <summary>
/// Helper function which loads image from file.
/// </summary>
/// <param name="fileName">File name.</param>
/// <returns>Loaded image or null.</returns>
private System.Drawing.Image LoadFromFile(string fileName)
{
// Try to load image from file
try
{
return System.Drawing.Image.FromFile(fileName);
}
catch(FileNotFoundException)
{
return null;
}
}
/// <summary>
/// Returns the image size taking the image DPI into consideration.
/// </summary>
/// <param name="name">Image name (FileName, URL, Resource).</param>
/// <param name="graphics">Graphics used to calculate the image size.</param>
/// <param name="size">Calculated size.</param>
/// <returns>false if it fails to calculate the size, otherwise true.</returns>
internal bool GetAdjustedImageSize(string name, Graphics graphics, ref SizeF size)
{
Image image = LoadImage(name);
if (image == null)
return false;
GetAdjustedImageSize(image, graphics, ref size);
return true;
}
/// <summary>
/// Returns the image size taking the image DPI into consideration.
/// </summary>
/// <param name="image">Image for whcih to calculate the size.</param>
/// <param name="graphics">Graphics used to calculate the image size.</param>
/// <param name="size">Calculated size.</param>
internal static void GetAdjustedImageSize(Image image, Graphics graphics, ref SizeF size)
{
if (graphics != null)
{
//this will work in case the image DPI is specified, otherwise the image DPI will be assumed to be same as the screen DPI
size.Width = image.Width * graphics.DpiX / image.HorizontalResolution;
size.Height = image.Height * graphics.DpiY / image.VerticalResolution;
}
else
{
size.Width = image.Width;
size.Height = image.Height;
}
}
/// <summary>
/// Checks if the image has the same DPI as the graphics object.
/// </summary>
/// <param name="image">Image to be checked.</param>
/// <param name="graphics">Graphics object to be used.</param>
/// <returns>true if they match, otherwise false.</returns>
internal static bool DoDpisMatch(Image image, Graphics graphics)
{
return graphics.DpiX == image.HorizontalResolution && graphics.DpiY == image.VerticalResolution;
}
internal static Image GetScaledImage(Image image, Graphics graphics)
{
Bitmap scaledImage = new Bitmap(image, new Size((int)(image.Width * graphics.DpiX / image.HorizontalResolution),
(int)(image.Height * graphics.DpiY / image.VerticalResolution)));
return scaledImage;
}
#endregion
}
}