File: MS\Internal\TextFormatting\TextPenaltyModule.cs
Web Access
Project: src\src\Microsoft.DotNet.Wpf\src\PresentationCore\PresentationCore.csproj (PresentationCore)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Windows.Media.TextFormatting;
 
namespace MS.Internal.TextFormatting
{
    /// <summary>
    /// Critical handle wrapper of unmanaged text penalty module. This class
    /// is used exclusively by Framework thru friend-access. It provides direct
    /// access to the underlying dangerous handle to the unmanaged resource whose
    /// lifetime is bound to the the underlying LS context.
    /// </summary>
    internal sealed class TextPenaltyModule : IDisposable
    {
        private IntPtr  _ploPenaltyModule;  // Pointer to LS penalty module
        private bool    _isDisposed;
 
 
        /// <summary>
        /// This constructor is called by PInvoke when returning the critical handle
        /// </summary>
        internal TextPenaltyModule(IntPtr ploc)
        {
            IntPtr ploPenaltyModule;
            LsErr lserr = UnsafeNativeMethods.LoAcquirePenaltyModule(ploc, out ploPenaltyModule);
            if (lserr != LsErr.None)
            {
                TextFormatterContext.ThrowExceptionFromLsError(SR.Format(SR.AcquirePenaltyModuleFailure, lserr), lserr);
            }
 
            _ploPenaltyModule = ploPenaltyModule;
        }
 
 
        /// <summary>
        /// Finalize penalty module
        /// </summary>
        ~TextPenaltyModule()
        {
            Dispose(false);
        }
 
 
        /// <summary>
        /// Explicitly clean up penalty module
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
 
 
        private void Dispose(bool disposing)
        {
            if (_ploPenaltyModule != IntPtr.Zero)
            {
                UnsafeNativeMethods.LoDisposePenaltyModule(_ploPenaltyModule);
                _ploPenaltyModule = IntPtr.Zero;
                _isDisposed = true;
                GC.KeepAlive(this);
            }
        }
 
 
        /// <summary>
        /// This method should only be called by Framework to authorize direct access to
        /// unsafe LS penalty module for exclusive use of PTS during optimal paragraph 
        /// penalty calculation.
        /// </summary>
        internal IntPtr DangerousGetHandle()
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(SR.TextPenaltyModuleHasBeenDisposed);
            }
 
            IntPtr penaltyModuleInternalHandle;
            LsErr lserr = UnsafeNativeMethods.LoGetPenaltyModuleInternalHandle(_ploPenaltyModule, out penaltyModuleInternalHandle);
 
            if (lserr != LsErr.None)
                TextFormatterContext.ThrowExceptionFromLsError(SR.Format(SR.GetPenaltyModuleHandleFailure, lserr), lserr);
 
            GC.KeepAlive(this);
            return penaltyModuleInternalHandle;
        }
    }
}