123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- #region MIT License
- /*Copyright (c) 2012 Robert Rouhani <robert.rouhani@gmail.com>
- 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.Runtime.InteropServices;
- using SharpFont.Internal;
- namespace SharpFont
- {
- /// <summary>
- /// FreeType root size class structure. A size object models a face object at a given size.
- /// </summary>
- public sealed class FTSize : IDisposable
- {
- #region Fields
- private bool userAlloc;
- private bool disposed;
- private bool duplicate;
- private IntPtr reference;
- private SizeRec rec;
- private Face parentFace;
- #endregion
- #region Constructors
- /// <summary>
- /// Initializes a new instance of the <see cref="FTSize"/> class.
- /// </summary>
- /// <param name="parent">The parent face.</param>
- public FTSize(Face parent)
- {
- IntPtr reference;
- Error err = FT.FT_New_Size(parent.Reference, out reference);
- if (err != Error.Ok)
- throw new FreeTypeException(err);
- Reference = reference;
- userAlloc = true;
- }
- internal FTSize(IntPtr reference, bool userAlloc, Face parentFace)
- {
- Reference = reference;
- this.userAlloc = userAlloc;
- if (parentFace != null)
- {
- this.parentFace = parentFace;
- parentFace.AddChildSize(this);
- }
- else
- {
- duplicate = true;
- }
- }
- /// <summary>
- /// Finalizes an instance of the FTSize class.
- /// </summary>
- ~FTSize()
- {
- Dispose(false);
- }
- #endregion
- #region Properties
- /// <summary>
- /// Gets a value indicating whether the object has been disposed.
- /// </summary>
- public bool IsDisposed
- {
- get
- {
- return disposed;
- }
- }
- /// <summary>
- /// Gets a handle to the parent face object.
- /// </summary>
- public Face Face
- {
- get
- {
- if (disposed)
- throw new ObjectDisposedException("Face", "Cannot access a disposed object.");
- return parentFace;
- }
- }
- /// <summary>
- /// Gets or sets a typeless pointer, which is unused by the FreeType library or any of its drivers. It can be used by
- /// client applications to link their own data to each size object.
- /// </summary>
- public Generic Generic
- {
- get
- {
- if (disposed)
- throw new ObjectDisposedException("Generic", "Cannot access a disposed object.");
- return new Generic(rec.generic);
- }
- set
- {
- if (disposed)
- throw new ObjectDisposedException("Generic", "Cannot access a disposed object.");
- value.WriteToUnmanagedMemory(new IntPtr(reference.ToInt64() + Marshal.OffsetOf(typeof(FaceRec), "generic").ToInt64()));
- Reference = reference; //update rec.
- }
- }
- /// <summary>
- /// Gets metrics for this size object. This field is read-only.
- /// </summary>
- public SizeMetrics Metrics
- {
- get
- {
- if (disposed)
- throw new ObjectDisposedException("Metrics", "Cannot access a disposed object.");
- return new SizeMetrics(rec.metrics);
- }
- }
- 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;
- this.rec = PInvokeHelper.PtrToStructure<SizeRec>(reference);
- }
- }
- #endregion
- #region Public Methods
- /// <summary><para>
- /// Even though it is possible to create several size objects for a given face (see
- /// <see cref="SharpFont.Face.NewSize"/> for details), functions like <see cref="SharpFont.Face.LoadGlyph"/> or
- /// <see cref="SharpFont.Face.LoadChar"/> only use the one which has been activated last to determine the
- /// ‘current character pixel size’.
- /// </para><para>
- /// This function can be used to ‘activate’ a previously created size object.
- /// </para></summary>
- /// <remarks>
- /// If ‘face’ is the size's parent face object, this function changes the value of ‘face->size’ to the input
- /// size handle.
- /// </remarks>
- public void Activate()
- {
- if (disposed)
- throw new ObjectDisposedException("Activate", "Cannot access a disposed object.");
- Error err = FT.FT_Activate_Size(Reference);
- if (err != Error.Ok)
- throw new FreeTypeException(err);
- }
- /// <summary>
- /// Diposes the FTSize.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- #endregion
- #region Private Methods
- private void Dispose(bool disposing)
- {
- if (!disposed)
- {
- disposed = true;
- //only dispose the user allocated sizes that are not duplicates.
- if (userAlloc && !duplicate)
- {
- Error err = FT.FT_Done_Size(reference);
- if (err != Error.Ok)
- throw new FreeTypeException(err);
- // removes itself from the parent Face, with a check to prevent this from happening when Face is
- // being disposed (Face disposes all it's children with a foreach loop, this causes an
- // InvalidOperationException for modifying a collection during enumeration)
- if (!parentFace.IsDisposed)
- parentFace.RemoveChildSize(this);
- }
- reference = IntPtr.Zero;
- rec = null;
- }
- }
- #endregion
- }
- }
|