#region MIT License /*Copyright (c) 2012-2013, 2015 Robert Rouhani SharpFont based on Tao.FreeType, Copyright (c) 2003-2007 Tao Framework Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ #endregion using System; using System.Collections.Generic; namespace SharpFont.Cache { /// /// This object corresponds to one instance of the cache-subsystem. It is used to cache one or more /// objects, along with corresponding objects. /// /// The manager intentionally limits the total number of opened and objects /// to control memory usage. See the ‘max_faces’ and ‘max_sizes’ parameters of /// . /// /// The manager is also used to cache ‘nodes’ of various types while limiting their total memory usage. /// /// All limitations are enforced by keeping lists of managed objects in most-recently-used order, and flushing old /// nodes to make room for new ones. /// public sealed class Manager : IDisposable { #region Fields private IntPtr reference; private Library parentLibrary; private bool disposed; #endregion #region Constructors /// /// Initializes a new instance of the Manager class. /// /// The parent FreeType library handle to use. /// /// Maximum number of opened objects managed by this cache instance. Use 0 for defaults. /// /// /// Maximum number of opened objects managed by this cache instance. Use 0 for defaults. /// /// /// Maximum number of bytes to use for cached data nodes. Use 0 for defaults. Note that this value does not /// account for managed and objects. /// /// /// An application-provided callback used to translate face IDs into real objects. /// /// /// A generic pointer that is passed to the requester each time it is called (see ). /// [CLSCompliant(false)] public Manager(Library library, uint maxFaces, uint maxSizes, ulong maxBytes, FaceRequester requester, IntPtr requestData) { if (library == null) throw new ArgumentNullException("library"); IntPtr mgrRef; Error err = FT.FTC_Manager_New(library.Reference, maxFaces, maxSizes, maxBytes, requester, requestData, out mgrRef); if (err != Error.Ok) throw new FreeTypeException(err); Reference = mgrRef; this.parentLibrary = library; library.AddChildManager(this); } /// /// Finalizes an instance of the Manager class. /// ~Manager() { Dispose(false); } #endregion #region Properties /// /// Gets a value indicating whether the object has been disposed. /// public bool IsDisposed { get { return disposed; } } internal IntPtr Reference { get { if (disposed) throw new ObjectDisposedException("Reference", "Cannot access a disposed object."); return reference; } set { if (disposed) throw new ObjectDisposedException("Reference", "Cannot access a disposed object."); reference = value; } } #endregion #region Public Members /// /// Empty a given cache manager. This simply gets rid of all the currently cached and /// objects within the manager. /// public void Reset() { if (disposed) throw new ObjectDisposedException("Manager", "Cannot access a disposed object."); FT.FTC_Manager_Reset(Reference); } /// /// Retrieve the object that corresponds to a given face ID through a cache manager. /// /// /// The returned object is always owned by the manager. You should never try to discard it /// yourself. /// /// The object doesn't necessarily have a current size object (i.e., /// can be 0). If you need a specific ‘font size’, use instead. /// /// Never change the face's transformation matrix (i.e., never call the /// function) on a returned face! If you need to transform glyphs, do it yourself after glyph loading. /// /// When you perform a lookup, out-of-memory errors are detected within the lookup and force incremental /// flushes of the cache until enough memory is released for the lookup to succeed. /// /// If a lookup fails with the cache has already been completely flushed, and /// still no memory was available for the operation. /// /// The ID of the face object. /// A handle to the face object. public Face LookupFace(IntPtr faceId) { if (disposed) throw new ObjectDisposedException("Manager", "Cannot access a disposed object."); IntPtr faceRef; Error err = FT.FTC_Manager_LookupFace(Reference, faceId, out faceRef); if (err != Error.Ok) throw new FreeTypeException(err); //HACK fix this later. return new Face(faceRef, null); } /// /// Retrieve the object that corresponds to a given pointer through a /// cache manager. /// /// /// The returned object is always owned by the/ manager. You should never try to discard /// it by yourself. /// /// You can access the parent object simply as if you need it. /// Note that this object is also owned by the manager. /// /// When you perform a lookup, out-of-memory errors are detected within the lookup and force incremental /// flushes of the cache until enough memory is released for the lookup to succeed. /// /// If a lookup fails with the cache has already been completely flushed, and /// still no memory is available for the operation. /// /// A scaler handle. /// A handle to the size object. public FTSize LookupSize(Scaler scaler) { if (disposed) throw new ObjectDisposedException("Manager", "Cannot access a disposed object."); IntPtr sizeRef; Error err = FT.FTC_Manager_LookupSize(Reference, scaler.Reference, out sizeRef); if (err != Error.Ok) throw new FreeTypeException(err); //HACK fix this later. return new FTSize(sizeRef, false, null); } /// /// A special function used to indicate to the cache manager that a given FTC_FaceID is no longer valid, either /// because its content changed, or because it was deallocated or uninstalled. /// /// /// This function flushes all nodes from the cache corresponding to this ‘faceID’, with the /// exception of nodes with a non-null reference count. /// /// Such nodes are however modified internally so as to never appear in later lookups with the same /// ‘faceID’ value, and to be immediately destroyed when released by all their users. /// /// The FTC_FaceID to be removed. public void RemoveFaceId(IntPtr faceId) { if (disposed) throw new ObjectDisposedException("Manager", "Cannot access a disposed object."); FT.FTC_Manager_RemoveFaceID(Reference, faceId); } #endregion #region IDisposable Members /// /// Disposes the Manager. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!disposed) { disposed = true; FT.FTC_Manager_Done(reference); reference = IntPtr.Zero; // removes itself from the parent Library, with a check to prevent this from happening when Library is // being disposed (Library disposes all it's children with a foreach loop, this causes an // InvalidOperationException for modifying a collection during enumeration) if (!parentLibrary.IsDisposed) parentLibrary.RemoveChildManager(this); } } #endregion } }