XpsFontSubsetter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Print / Reach / Serialization / XpsFontSubsetter.cs / 1 / XpsFontSubsetter.cs

                            /*++ 

    Copyright (C) 2004 - 2005 Microsoft Corporation
    All rights reserved.
 
    Module Name:
        XpsFontSubsetter.cs 
 
    Abstract:
        This file implements the XpsFontSubsetter used by 
        the Xps Serialization APIs for serializing fonts
        to a Xps package.

    Author: 
        [....] ([....]) 1-December-2004
 
    Revision History: 
--*/
 
using System;
using System.Collections;
using System.IO;
using System.Windows.Media; 
using System.Windows.Shapes;
using System.Windows.Media.Imaging; 
using System.Collections.Generic; 
using System.IO.Packaging;
using System.Windows.Xps.Packaging; 
using System.Security;
using System.Security.Permissions;
using MS.Internal.Utility;
using MS.Internal.IO.Packaging; 

namespace System.Windows.Xps.Serialization 
{ 
    /// 
    /// Flags indicating which parts are to be exluded 
    /// from a digital signature
    /// May not be or'ed together
    /// 
    [FlagsAttribute] 
    public enum FontSubsetterCommitPolicies
    { 
        ///  
        /// No font subsettint, the entire font is copied
        /// fonts are assumed shared accross all documents 
        /// 
        None                        = 0x00000000,
        /// 
        /// Font parts will be generted for the fonts 
        /// used in a single page
        ///  
        CommitPerPage               = 0x00000001, 
        /// 
        /// Font parts will be generted for the fonts 
        /// used in a single document
        /// 
        CommitPerDocument           = 0x00000002,
        ///  
        /// Font parts will be generted for all fonts
        /// used in accros the entire sequence 
        ///  
        CommitEntireSequence       =  0x00000003,
    }; 

    /// 
    /// Actions to be taken to embed font
    /// based on type flag 
    /// 
    [FlagsAttribute] 
    internal enum FontEmbeddingAction 
    {
        ///  
        /// No action
        /// 
        None                       = 0x00000000,
        ///  
        /// Obfuscate and subset the font
        ///  
        ObfuscateSubsetFont        = 0x00000001, 

        ///  
        /// Obfuscate but copy the data
        /// directly from the font stream
        /// 
        ObfuscateOnlyFont         = 0x00000002, 

        ///  
        /// Generate Images of glyps using Image Brush 
        /// directly from the font stream
        ///  
        ImageOnlyFont             = 0x00000004,

    }
 

    ///  
    /// Implements the functionality to generate font subsets 
    /// based on glyph runs obtained.  This class uses the
    /// serialization manager to write data to the Xps 
    /// package.
    /// 
    internal class XpsFontSubsetter
    { 
        #region Constructors
 
        ///  
        /// Constructs a XpsFontSubsetter instance.
        ///  
        /// 
        /// The serialization manager to serialize to.
        /// 
        public 
        XpsFontSubsetter(
            BasePackagingPolicy packagingPolicy 
            ) 
        {
            if (null == packagingPolicy) 
            {
                throw new ArgumentNullException("packagingPolicy");
            }
 
            _packagingPolicy = packagingPolicy;
            _fontEmbeddingManagerCache = new Hashtable(3); 
        } 

        #endregion Constructors 

        #region Public methods

        ///  
        /// Adds a specified Glyph run to an existing or new
        /// cache item and returns the part Uri where font 
        /// will be committed. 
        /// 
        ///  
        /// The GlyphRun to add.
        /// 
        /// 
        /// A Uri to locate the font within the Xps package. 
        /// 
        /// 
        /// Critical    - It calls critical internal function CriticalFileReadPermission 
        /// TreatAsSafe - EmbeddingRights data is used internally and not returned
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        public
        Uri
        ComputeFontSubset( 
            GlyphRun        glyphRun
            ) 
        { 
            FontEmbeddingRight embeddingRights = FontEmbeddingRight.RestrictedLicense;
            if (null == glyphRun) 
            {
                throw new ArgumentNullException("glyphRun");
            }
 
            Uri fontUri = null;
 
            CodeAccessPermission fontReadPermission = glyphRun.GlyphTypeface.CriticalFileReadPermission; 

            if (fontReadPermission != null) 
            {
                fontReadPermission.Assert();
            }
 
            try
            { 
                embeddingRights  = glyphRun.GlyphTypeface.EmbeddingRights; 
            }
            finally 
            {
                if (fontReadPermission != null)
                {
                    CodeAccessPermission.RevertAssert(); 
                }
            } 
 
            if (DetermineEmbeddingAction(embeddingRights) ==
                    FontEmbeddingAction.ImageOnlyFont) 
            {
                //
                // Aquire a bit map stream to embedd the Glyph Run image
                // 
                fontUri = _packagingPolicy.AcquireResourceStreamForXpsImage(XpsS0Markup.ImageUriPlaceHolder).Uri;
            } 
            else 
            {
                 FEMCacheItem cacheItem = AcquireCacheItem( 
                                            glyphRun.GlyphTypeface
                                            );
                if (cacheItem != null)
                { 
                    cacheItem.CurrentPageReferences = true;
                    if( _commitPolicy == FontSubsetterCommitPolicies.None && 
                        !cacheItem.IsStreamWritten ) 
                    {
                        fontUri = cacheItem.CopyFontStream(); 
                    }
                    else
                    {
                        fontUri = cacheItem.AddGlyphRunUsage(glyphRun); 
                    }
                } 
            } 

            return fontUri; 
        }


        ///  
        /// Commits all fonts that are currently in the cache
        /// and clears the cache out. 
        ///  
        /// 
        /// Signal indicating the font should be subsetted 
        /// according to which policy.
        /// 
        /// 
        /// true if the signal completed a subset. 
        /// 
        public 
        bool 
        CommitFontSubsetsSignal(
            FontSubsetterCommitPolicies signal 
            )
        {
            //
            // flag indicating if this signal completed a subset 
            //
            bool completedSubset = false; 
            if( signal == FontSubsetterCommitPolicies.CommitPerPage ) 
            {
                foreach (DictionaryEntry o in _fontEmbeddingManagerCache) 
                {
                    FEMCacheItem item = o.Value as FEMCacheItem;
                    if (item != null)
                    { 
                        item.AddRelationship();
                        item.CurrentPageReferences = false; 
                    } 
                }
 
            }
            else
            if( signal == FontSubsetterCommitPolicies.CommitPerDocument &&
                _commitPolicy == FontSubsetterCommitPolicies.CommitEntireSequence ) 
            {
                foreach (DictionaryEntry o in _fontEmbeddingManagerCache) 
                { 
                    FEMCacheItem item = o.Value as FEMCacheItem;
                    if (item != null) 
                    {
                        item.AddRestrictedRelationship();
                    }
                } 

            } 
            // 
            // If we recieve a signal to commit a superset of what we are commiting on
            // i.e. Document Signal with commit Policy is per page 
            // we must commit
            //
            if( signal >= _commitPolicy )
            { 
                if (signal == _commitPolicy)
                { 
                    _currentCommitCnt++; 
                }
                if( signal > _commitPolicy || _currentCommitCnt%_commitCountPolicy == 0 ) 
                {
                    foreach (DictionaryEntry o in _fontEmbeddingManagerCache)
                    {
                        FEMCacheItem item = o.Value as FEMCacheItem; 
                        if (item != null && _commitPolicy != FontSubsetterCommitPolicies.None)
                        { 
                            item.Commit(); 
                            //
                            // We will be removing this FEMCacheItem from the cache 
                            // after this loop so we must add its document relationship
                            // if restricted.  If the policy is CommitPerDocumentSequence
                            // we do not need to add since it will have been added at the document signal
                            // 
                            if (signal != FontSubsetterCommitPolicies.CommitEntireSequence)
                            { 
                                item.AddRestrictedRelationship(); 
                            }
                        } 
                    }
                    _fontEmbeddingManagerCache.Clear();
                    _currentCommitCnt = 0;
                    completedSubset = true; 
                }
            } 
            return completedSubset; 
        }
 

        /// 
        /// Determines Embedding action based
        /// on flags in the fsType field 
        /// 
        /// 
        /// Critical    - It calls critical internal function CriticalFileReadPermission 
        /// TreatAsSafe - It only returns a font embedding value
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        public
        static
        FontEmbeddingAction 
        DetermineEmbeddingAction(GlyphTypeface glyphTypeface)
        { 
            FontEmbeddingRight fsType = FontEmbeddingRight.RestrictedLicense; 
            CodeAccessPermission fontReadPermission = glyphTypeface.CriticalFileReadPermission;
 
            if (fontReadPermission != null)
            {
                fontReadPermission.Assert();
            } 

            try 
            { 
                fsType = glyphTypeface.EmbeddingRights;
            } 
            finally
            {
                if (fontReadPermission != null)
                { 
                    CodeAccessPermission.RevertAssert();
                } 
            } 
            return DetermineEmbeddingAction(fsType);
        } 
        /// 
        /// Determines Embedding action based
        /// on flags in the fsType field
        /// 
        public
        static 
        FontEmbeddingAction 
        DetermineEmbeddingAction(
           FontEmbeddingRight fsType 
            )
        {
            FontEmbeddingAction action = FontEmbeddingAction.ObfuscateSubsetFont;
 
            switch( fsType )
            { 
                case FontEmbeddingRight.RestrictedLicense: 
                case FontEmbeddingRight.PreviewAndPrintButWithBitmapsOnly:
                case FontEmbeddingRight.PreviewAndPrintButNoSubsettingAndWithBitmapsOnly: 
                case FontEmbeddingRight.EditableButWithBitmapsOnly:
                case FontEmbeddingRight.EditableButNoSubsettingAndWithBitmapsOnly:
                case FontEmbeddingRight.InstallableButWithBitmapsOnly:
                case FontEmbeddingRight.InstallableButNoSubsettingAndWithBitmapsOnly: 
                    action = FontEmbeddingAction.ImageOnlyFont;
                    break; 
 
                case FontEmbeddingRight.PreviewAndPrint:
                case FontEmbeddingRight.Editable: 
                case FontEmbeddingRight.Installable:
                    action = FontEmbeddingAction.ObfuscateSubsetFont;
                    break;
 
                case FontEmbeddingRight.EditableButNoSubsetting:
                case FontEmbeddingRight.PreviewAndPrintButNoSubsetting: 
                case FontEmbeddingRight.InstallableButNoSubsetting: 
                    action = FontEmbeddingAction.ObfuscateOnlyFont;
                    break; 
            }
            return action;
        }
 
        /// 
        /// Determines Embedding action based 
        /// on flags in the fsType field 
        /// 
        /// 
        /// Critical    - It calls critical internal function CriticalFileReadPermission
        /// TreatAsSafe - It only returns a font embedding value
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        public
        static 
        bool 
        IsRestrictedFont(GlyphTypeface glyphTypeface)
        { 
            FontEmbeddingRight fsType = FontEmbeddingRight.RestrictedLicense;
            CodeAccessPermission fontReadPermission = glyphTypeface.CriticalFileReadPermission;

            if (fontReadPermission != null) 
            {
                fontReadPermission.Assert(); 
            } 

            try 
            {
                fsType = glyphTypeface.EmbeddingRights;
            }
            finally 
            {
                if (fontReadPermission != null) 
                { 
                    CodeAccessPermission.RevertAssert();
                } 
            }
            return IsRestrictedFont(fsType);
        }
        ///  
        /// Determines Embedding action based
        /// on flags in the fsType field 
        /// 
        public
        static 
        bool
        IsRestrictedFont(
           FontEmbeddingRight fsType
            ) 
        {
            bool isRestrictedFont = false; 
 
            switch( fsType )
            { 
                case FontEmbeddingRight.PreviewAndPrintButNoSubsetting:
                case FontEmbeddingRight.PreviewAndPrint:
                    isRestrictedFont = true;
                    break; 
           }
           return isRestrictedFont; 
        } 

        ///  
        /// Determines on what signal subsets will be commited
        ///
        public
        void 
        SetSubsetCommitPolicy( FontSubsetterCommitPolicies policy )
        { 
           if( policy == FontSubsetterCommitPolicies.CommitEntireSequence && 
                _commitCountPolicy != 1 )
            { 
                throw new ArgumentOutOfRangeException(ReachSR.Get(ReachSRID.ReachPackaging_SequenceCntMustBe1));
            }
          _commitPolicy = policy;
        } 

        ///  
        /// Determines the number of signals subsets will be commited on 
        ///
        public 
        void
        SetSubsetCommitCountPolicy( int commitCount )
        {
            if( _commitPolicy == FontSubsetterCommitPolicies.CommitEntireSequence && 
                commitCount != 1 )
            { 
                throw new ArgumentOutOfRangeException(ReachSR.Get(ReachSRID.ReachPackaging_SequenceCntMustBe1)); 
            }
            else 
            if( commitCount < 1 )
            {
                throw new ArgumentOutOfRangeException(ReachSR.Get(ReachSRID.ReachPackaging_CommitCountPolicyLessThan1));
            } 
            _commitCountPolicy = commitCount;
        } 
        #endregion Public methods 

        #region Private data 

        private Hashtable                       _fontEmbeddingManagerCache;
        private BasePackagingPolicy             _packagingPolicy;
        private FontSubsetterCommitPolicies     _commitPolicy = FontSubsetterCommitPolicies.CommitEntireSequence; 
        private int                             _commitCountPolicy = 1;
        private int                             _currentCommitCnt = 0; 
        #endregion Private data 

        #region Private methods 

        /// 
        /// Acquires a cache item for the specified font.  If one
        /// does not exist a new one is created. 
        /// 
        ///  
        /// glyphTypeface of font to acquire. 
        /// 
        ///  
        /// A reference to a FEMCacheItem.
        /// 
        ///
        /// Critical    - Assert permision to read glyphtypeface uri.  Uri is used internally never returned 
        ///
        [SecurityCritical] 
        private 
        FEMCacheItem
        AcquireCacheItem( 
            GlyphTypeface         glyphTypeface
            )
        {
            FEMCacheItem manager = null; 
            Uri fontUri;
            CodeAccessPermission uriDiscoveryPermission = glyphTypeface.CriticalUriDiscoveryPermission; 
 
            if (uriDiscoveryPermission != null)
            { 
                uriDiscoveryPermission.Assert();
            }

            try 
            {
                fontUri = glyphTypeface.FontUri; 
            } 
            finally
            { 
                if (uriDiscoveryPermission != null)
                {
                    CodeAccessPermission.RevertAssert();
                } 
            }
 
            if (_fontEmbeddingManagerCache.Contains(fontUri)) 
            {
                manager = (FEMCacheItem)_fontEmbeddingManagerCache[fontUri]; 
            }
            else
            {
                manager = new FEMCacheItem(glyphTypeface, _packagingPolicy); 
                _fontEmbeddingManagerCache.Add(fontUri, manager);
            } 
 
            return manager;
        } 


        #endregion Private methods
    } 

    ///  
    /// This class represents a single cache item for 
    /// a FontEmbeddingManager.  Each manager represents
    /// one font. 
    /// 
    internal class FEMCacheItem
    {
        #region Constructors 

        ///  
        /// Constructs a new FEMCacheItem. 
        /// 
        ///  
        /// The glyphTypeface of the font for this cache item.
        /// 
        /// 
        /// The BasePackagingPolicy to write to. 
        /// 
        /// 
        /// Critical    - Assert permision to read glyphtypeface uri.  Uri is used internally never returned 
        ///
        [SecurityCritical] 
        public
        FEMCacheItem(
            GlyphTypeface                   glyphTypeface,
            BasePackagingPolicy             packagingPolicy 
            )
        { 
            if (null == packagingPolicy) 
            {
                throw new ArgumentNullException("packagingPolicy"); 
            }
            if (null == glyphTypeface)
            {
                throw new ArgumentNullException("glyphTypeface"); 
            }
 
            _packagingPolicy = packagingPolicy; 
            _streamWritten = false;
 
            //
            // Acquire the stream that will be used to save the font.
            // if the font is Image only we do not need a font stream
            // since each glyph run will be saved in its own image stream 
            //
            _fontEmbeddingManager = new FontEmbeddingManager(); 
            _glyphTypeface = glyphTypeface; 

            CodeAccessPermission uriDiscoveryPermission = glyphTypeface.CriticalUriDiscoveryPermission; 

            if (uriDiscoveryPermission != null)
            {
                uriDiscoveryPermission.Assert(); 
            }
 
            try 
            {
                _fontUri = glyphTypeface.FontUri; 
            }
            finally
            {
                if (uriDiscoveryPermission != null) 
                {
                    CodeAccessPermission.RevertAssert(); 
                } 
            }
 
            Uri fontUri = new Uri(_fontUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.SafeUnescaped), UriKind.RelativeOrAbsolute);
            string fontUriAsString = fontUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
            _fontResourceStream = packagingPolicy.AcquireResourceStreamForXpsFont(fontUriAsString);
 
            //
            // Aquiring the Resource stream will instantiate the font 
            // and add the require resource relationship 
            //
            _curPageRelAdded = true; 
        }

        #endregion Constructors
 
        #region Public methods
 
        ///  
        /// Adds a specified glyph run to the ongoing subset.
        ///  
        /// 
        /// The GlyphRun to add to subset.
        /// 
        ///  
        /// A reference to a Uri where font is stored
        /// within the package. 
        ///  
        ///
        /// Critical    - Calls RecordUsage which demands descovery permision for GlyphTypeFace 
        /// TreatAsSafe - The Uri is used inernally to Record usage it is never returned
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        public 
        Uri
        AddGlyphRunUsage( 
            GlyphRun        glyphRun 
            )
        { 
            Uri fontUri = null;
            FontEmbeddingAction action = XpsFontSubsetter.DetermineEmbeddingAction( _glyphTypeface );
            switch( action )
            { 
                //
                // Provide an empty image stream.  The Glyphs serializer 
                // will check content type and render adn serialize an 
                // image into this stream based on content type
                // 
                case FontEmbeddingAction.ImageOnlyFont:
                    break;

                case FontEmbeddingAction.ObfuscateOnlyFont: 
                    fontUri = _fontResourceStream.Uri;
                    // nothing to do here since the entire font will be added 
                    break; 

                case FontEmbeddingAction.ObfuscateSubsetFont: 
                    CodeAccessPermission uriDiscoveryPermission = glyphRun.GlyphTypeface.CriticalUriDiscoveryPermission;

                    if (uriDiscoveryPermission != null)
                    { 
                        uriDiscoveryPermission.Assert();
                    } 
 
                    try
                    { 
                        _fontEmbeddingManager.RecordUsage(glyphRun);
                    }
                    finally
                    { 
                        if (uriDiscoveryPermission != null)
                        { 
                            CodeAccessPermission.RevertAssert(); 
                        }
                    } 

                    fontUri = _fontResourceStream.Uri;
                    break;
            } 
            return fontUri;
        } 
 
        /// 
        /// Computes the font subset of all GlyphRuns seen 
        /// and commits the font to the Xps package.
        /// This ends the lifetime of this cache item.
        /// 
        ///  
        /// Critical -  1)  Calls SubSet font which assert unmanaged and returns raw font data
        /// 
        /// TreatAsSafe -  This passes an internally created stream to Subset font 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        public
        void
        Commit(
            ) 
        {
            FontEmbeddingAction action = XpsFontSubsetter.DetermineEmbeddingAction( _glyphTypeface ); 
            switch( action ) 
            {
                case FontEmbeddingAction.ImageOnlyFont: 
                    // nothing to do here since the glyph runs have already been converted
                    break;

                case FontEmbeddingAction.ObfuscateOnlyFont: 
                    CopyFontStream();
                    break; 
 
                case FontEmbeddingAction.ObfuscateSubsetFont:
                    SubSetFont( 
                        _fontEmbeddingManager.GetUsedGlyphs(_fontUri),
                        _fontResourceStream.Stream
                        );
                    break; 

            } 
        } 

        public 
        void
        AddRestrictedRelationship(
            )
        { 
            FontEmbeddingAction action = XpsFontSubsetter.DetermineEmbeddingAction( _glyphTypeface );
            if( action != FontEmbeddingAction.ImageOnlyFont && 
                XpsFontSubsetter.IsRestrictedFont(_glyphTypeface) ) 
            {
                _packagingPolicy. 
                   RelateRestrictedFontToCurrentDocument(
                    _fontResourceStream.Uri
                    );
            }        } 
        public
        void 
        AddRelationship( 
            )
        { 
            if( !_curPageRelAdded && CurrentPageReferences)
            {
                FontEmbeddingAction action = XpsFontSubsetter.DetermineEmbeddingAction( _glyphTypeface );
                switch( action ) 
                {
                    case FontEmbeddingAction.ImageOnlyFont: 
                        break; 

                    case FontEmbeddingAction.ObfuscateOnlyFont: 
                    case FontEmbeddingAction.ObfuscateSubsetFont:
                        _packagingPolicy.
                            RelateResourceToCurrentPage(
                            _fontResourceStream.Uri, 
                            XpsS0Markup.ResourceRelationshipName);
                         break; 
                } 
            }
 
            // Now we are finished with the current page
            // and need flag the need for relationship on the next
            _curPageRelAdded = false;
        } 
        #endregion Public methods
 
        #region Private static methods 

        ///  
        /// Critical -  1)  Asserts to access the unmanged code.  Access unmanged which is
        ///                 capable of memory overuns and uncontroled access the resources.
        ///
        ///             2)  returns raw font data. 
        ///
        ///  
        [SecurityCritical] 
        private
        void 
        SubSetFont(
            ICollection glyphs,
            Stream stream
            ) 
        {
            byte[] fontData; 
 
            PermissionSet permissions = new PermissionSet(null);
            permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)); 
            CodeAccessPermission criticalFileReadPermission = _glyphTypeface.CriticalFileReadPermission;
            if (criticalFileReadPermission != null)
            {
                permissions.AddPermission(criticalFileReadPermission); 
            }
 
            permissions.Assert(); 
            try
            { 
                fontData = _glyphTypeface.ComputeSubset(glyphs);
            }
            finally
            { 
                CodeAccessPermission.RevertAssert();
            } 
 
            Guid guid = ParseGuidFromUri(_fontResourceStream.Uri);
            ObfuscateData(fontData, guid); 

            stream.Write(fontData, 0, fontData.Length);

            Uri fontUri = new Uri(_fontUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.SafeUnescaped), UriKind.RelativeOrAbsolute); 
            string fontUriAsString = fontUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
            _packagingPolicy.ReleaseResourceStreamForXpsFont(fontUriAsString); 
 
            _streamWritten = true;
        } 

        ///
        /// Critical    - It calls critical internal function CriticalFileReadPermission
        /// 
        [SecurityCritical]
        internal 
        Uri 
        CopyFontStream()
        { 
            Uri sourceUri =     _fontUri;
            Uri destUri =       _fontResourceStream.Uri;
            Stream destStream = _fontResourceStream.Stream;
            Stream sourceStream = null; 
            byte [] memoryFont;
            GlyphTypeface glyphTypeface = new GlyphTypeface(sourceUri); 
            CodeAccessPermission fontReadPermission = glyphTypeface.CriticalFileReadPermission; 

            if (fontReadPermission != null) 
            {
                fontReadPermission.Assert();
            }
 
            try
            { 
                sourceStream = glyphTypeface.GetFontStream(); 
            }
            finally 
            {
                if (fontReadPermission != null)
                {
                    CodeAccessPermission.RevertAssert(); 
                }
            } 
 
            memoryFont = new byte[_readBlockSize];
            Guid guid = ParseGuidFromUri(destUri); 

            int bytesRead = PackagingUtilities.ReliableRead(sourceStream, memoryFont,0,_readBlockSize);
            if (bytesRead > 0)
            { 
                 // Obfuscate the first block
                ObfuscateData(memoryFont, guid ); 
            } 

            while( bytesRead > 0 ) 
            {
                destStream.Write(memoryFont, 0, bytesRead);
                bytesRead = PackagingUtilities.ReliableRead( sourceStream, memoryFont, 0, _readBlockSize);
            } 

            Uri fontUri = new Uri(_fontUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.SafeUnescaped), UriKind.RelativeOrAbsolute); 
            string fontUriAsString = fontUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); 
            _packagingPolicy.ReleaseResourceStreamForXpsFont(fontUriAsString);
 
            _streamWritten = true;
            return destUri;
        }
 
        /// 
        /// Parses a Guid from the file name 
        /// in accordence with 6.2.7.3  Embedded Font Obfuscation 
        /// of the metro spec
        ///  
        /// 
        /// Uri to parse
        /// 
        ///  
        /// Guid parsed out of Uri
        ///  
        private 
        static
        Guid 
        ParseGuidFromUri( Uri uri )
        {
            string fileName = System.IO.Path.GetFileNameWithoutExtension(
                                BindUriHelper.UriToString(uri) 
                              );
            return new Guid( fileName ); 
        } 

        ///  
        /// Obfuscate font data
        /// in accordence with 6.2.7.3  Embedded Font Obfuscation
        /// of the metro spec
        ///  
        /// 
        ///  Data to obfuscate 
        ///  
        /// 
        /// Guid to be used in XORing the header 
        /// 
        public
        static
        void 
        ObfuscateData( byte[] fontData, Guid guid )
        { 
            byte[] guidByteArray = new byte[16]; 
          // Convert the GUID into string in 32 digits format (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
            string guidString = guid.ToString("N"); 


            for (int i = 0; i < guidByteArray.Length; i++)
            { 

                guidByteArray[i] = Convert.ToByte(guidString.Substring(i * 2, 2), 16); 
 
            }
 


            for( int j = 0; j < 2; j++ )
            { 
                for( int i = 0; i < 16; i ++ )                {
                    fontData[i+j*16] ^= guidByteArray[15-i]; 
                } 
            }
        } 
        #endregion Private static methods

        #region Public Properties
        public 
        bool
        IsStreamWritten 
        { 
         get
         { 
            return _streamWritten;
         }
        }
 
        public
        bool 
        CurrentPageReferences 
        {
            get 
            {
                return _currentPageReferences;
            }
            set 
            {
                _currentPageReferences = value; 
            } 
        }
        #endregion Public Properties 

        #region Private data

        private bool                    _currentPageReferences; 
        private bool                    _curPageRelAdded;
        private FontEmbeddingManager    _fontEmbeddingManager; 
        private BasePackagingPolicy     _packagingPolicy; 
        private XpsResourceStream       _fontResourceStream;
        private GlyphTypeface           _glyphTypeface; 
        private bool                    _streamWritten;
        ///
        /// Critical    - This property is filled under assert permision thus
        ///               must be security critical 
        ///
        [SecurityCritical] 
        private Uri _fontUri; 
        private static readonly int _readBlockSize = 1048576; //1MB
 
        #endregion Private data
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK