| File: Serialization\Manager\XpsPackagingPolicy.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\ReachFramework\ReachFramework.csproj (ReachFramework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. /*++ Abstract: This file contains the definition of a theclass that controls the serialization packaging policy. It is the buffering layer between the serializer and the package --*/ using System.Collections; using System.Xml; using System.IO; using System.Windows.Xps.Packaging; using System.Printing; namespace System.Windows.Xps.Serialization { /// <summary> /// Class encapsulating both a Stream and Uri reprenting /// the main important elements in a Resource /// </summary> public class XpsResourceStream { #region Constructor /// <summary> /// Construct resource stream with the stream and uri /// </summary> /// <param name="stream">Stream to initialze the Resource Stream with</param> /// <param name="uri">Uri of the stream</param> public XpsResourceStream( Stream stream, Uri uri ) { this._stream = stream; this._uri = uri; } #endregion Constructor #region Public Properties /// <summary> /// return the stream back to the caller. /// </summary> public Stream Stream { get { return _stream; } } /// <summary> /// return the uri back to the caller. /// </summary> public Uri Uri { get { return _uri; } } #endregion Public Properties #region Public Methods /// <summary> /// Initializes resource stream /// </summary> public void Initialize( ) { _uri = null; _stream = null; } #endregion Public Methods private Stream _stream; private Uri _uri; }; /// <summary> /// This class is created in order to allow sharing of resources /// across different parts of the package. It keeps an internal /// ref count of the resource usage. /// </summary> internal class ResourceStreamCacheItem { #region Constructor internal ResourceStreamCacheItem( ) { this._resourceStreamRefCount = 1; } #endregion Constructor #region Internal Properties internal XpsResourceStream XpsResourceStream { get { return _resourceStream; } set { _resourceStream = value; } } internal XpsResource XpsResource { get { return _reachResource; } set { _reachResource = value; } } #endregion Internal Properties #region Internal Methods internal void IncRef( ) { _resourceStreamRefCount++; } internal int Release( ) { if(_resourceStreamRefCount>0) { _resourceStreamRefCount--; } return _resourceStreamRefCount; } #endregion Internal Methods #region Private Data private XpsResourceStream _resourceStream; private XpsResource _reachResource; private int _resourceStreamRefCount; #endregion Private Data }; /// <summary> /// Base Class representing a packaging policy. It mainly /// defines methods that help acquiring readers / writers /// to different part types in the reach package. /// </summary> public abstract class BasePackagingPolicy : IDisposable { #region Constructor /// <summary> /// Instantiates a BasePackagingPolicy /// </summary> protected BasePackagingPolicy( ) { } #endregion Constructor #region Public Base methods /// <summary> /// Acquire an Xml Writer for a DocumentSequence /// </summary> public abstract XmlWriter AcquireXmlWriterForFixedDocumentSequence( ); /// <summary> /// Release a reference to the current DocumentSequence /// </summary> public abstract void ReleaseXmlWriterForFixedDocumentSequence( ); /// <summary> /// Acquire a XmlWriter for a FixedDocument /// </summary> public abstract XmlWriter AcquireXmlWriterForFixedDocument( ); /// <summary> /// Release a reference to the current FixedDocument /// </summary> public abstract void ReleaseXmlWriterForFixedDocument( ); /// <summary> /// Acquire an XmlWriter for a FixedPage /// </summary> public abstract XmlWriter AcquireXmlWriterForFixedPage( ); /// <summary> /// Release a reference to the current XmlWriter /// </summary> public abstract void ReleaseXmlWriterForFixedPage( ); /// <summary> /// /// </summary> public abstract void RelateResourceToCurrentPage( Uri targetUri, string relationshipName ); /// <summary> /// This method adds a relationship to the current active /// document using the specified target and relationship name. /// </summary> /// <param name="targetUri"> /// Uri to Target for relationship. /// </param> public abstract void RelateRestrictedFontToCurrentDocument( Uri targetUri ); /// <summary> /// /// </summary> public abstract void PersistPrintTicket( PrintTicket printTicket ); /// <summary> /// /// </summary> public abstract XmlWriter AcquireXmlWriterForPage( ); /// <summary> /// /// </summary> public abstract XmlWriter AcquireXmlWriterForResourceDictionary( ); /// <summary> /// /// </summary> public abstract IList<String> AcquireStreamForLinkTargets( ); /// <summary> /// /// </summary> public abstract void PreCommitCurrentPage( ); /// <summary> /// Acquire a ResourceStream for a XpsFont /// </summary> public abstract XpsResourceStream AcquireResourceStreamForXpsFont( ); /// <summary> /// Acquire a ResourceStream for a XpsFont /// </summary> /// <param name="resourceId"> /// Id of Font /// </param> public abstract XpsResourceStream AcquireResourceStreamForXpsFont( String resourceId ); /// <summary> /// Release a reference to the current XpsFont ResourceStream /// </summary> public abstract void ReleaseResourceStreamForXpsFont( ); /// <summary> /// Release a reference to the current XpsFont ResourceStream /// </summary> /// <param name="resourceId"> /// Id of Font to release /// </param> public abstract void ReleaseResourceStreamForXpsFont( String resourceId ); /// <summary> /// Acquire a ResourceStream for a XpsImage /// </summary> /// <param name="resourceId"> /// Id of XpsImage /// </param> public abstract XpsResourceStream AcquireResourceStreamForXpsImage( String resourceId ); /// <summary> /// Release a reference of the current XpsImage ResourceStream /// </summary> public abstract void ReleaseResourceStreamForXpsImage( ); /// <Summary> /// Acquire a ResourceSTream for a XpsColorContext /// </Summary> /// <param name="resourceId"> /// A id for the ResourceStream /// </param> public abstract XpsResourceStream AcquireResourceStreamForXpsColorContext( String resourceId ); /// <Summary> /// Release a reference to the current XpsColorContext ResourceStream /// </Summary> public abstract void ReleaseResourceStreamForXpsColorContext( ); /// <Summary> /// Acquire a ResoureSTream for a XpsResourceDictionary /// </Summary> /// <param name="resourceId"> /// A resource Id for the ResourceStream /// </param> public abstract XpsResourceStream AcquireResourceStreamForXpsResourceDictionary( String resourceId ); /// <Summary> /// Release a reference to the current XpsResourceDictionary /// </Summary> public abstract void ReleaseResourceStreamForXpsResourceDictionary( ); #endregion Public Base Methods #region Public Properties /// <summary> /// /// </summary> public abstract Uri CurrentFixedDocumentUri { get; } /// <summary> /// /// </summary> public abstract Uri CurrentFixedPageUri { get; } #endregion Public Properties void IDisposable.Dispose( ) { GC.SuppressFinalize(this); } }; /// <summary> /// A class implementing a Xps specific packaging policy /// </summary> public class XpsPackagingPolicy : BasePackagingPolicy { #region Constructor /// <summary> /// Instantiate a XpsPackagingPolicy class /// </summary> /// <exception cref="ArgumentNullException">reachPackage is NULL.</exception> public XpsPackagingPolicy( System.Windows.Xps.Packaging.XpsDocument xpsPackage ): this( xpsPackage, PackageInterleavingOrder.None ) { } /// <summary> /// Instantiate a XpsPackagingPolicy class /// </summary> /// <exception cref="ArgumentNullException">reachPackage is NULL.</exception> public XpsPackagingPolicy( System.Windows.Xps.Packaging.XpsDocument xpsPackage, PackageInterleavingOrder interleavingType ): base() { ArgumentNullException.ThrowIfNull(xpsPackage); this._reachPackage = xpsPackage; Initialize(); _interleavingPolicy = new XpsInterleavingPolicy(interleavingType, true); _interleavingPolicy.AddItem((INode)xpsPackage,0,null); _fontAcquireMode = ResourceAcquireMode.NoneAcquired; _fontsCache = new Hashtable(11); _fontResourceStream = null; _imageResourceStream = null; _colorContextResourceStream = null; _resourceDictionaryResourceStream = null; InitializeResourceReferences(); } #endregion Constructor #region Public Methods /// <Summary> /// Acquire an Xml Writer for a DocumentSequence /// </Summary> public override XmlWriter AcquireXmlWriterForFixedDocumentSequence( ) { XmlWriter xmlWriter = null; if(_currentDocumentSequenceWriterRef == 0) { // // We need to create the corresponding part in the Xps package // and then acquire the writer // _currentFixedDocumentSequenceWriter = _reachPackage.AddFixedDocumentSequence(); // // retreive the appropriate writer from the reach package api layer // if(_currentFixedDocumentSequenceWriter != null) { _currentDSWriter = ((XpsFixedDocumentSequenceReaderWriter)_currentFixedDocumentSequenceWriter).XmlWriter; _interleavingPolicy.AddItem((INode)_currentFixedDocumentSequenceWriter, 0, (INode) _reachPackage); } } _currentDocumentSequenceWriterRef++; xmlWriter = _currentDSWriter; return xmlWriter; } /// <Summary> /// Release a reference to the current DocumentSequence /// </Summary> public override void ReleaseXmlWriterForFixedDocumentSequence( ) { if(_currentFixedDocumentSequenceWriter != null && _currentDocumentSequenceWriterRef > 0) { _currentDocumentSequenceWriterRef--; if(_currentDocumentSequenceWriterRef == 0) { // // if any of the other low level writer exist, then // throw an exception or is it better if we just close // them and consider that if any additional call on them // would be the one that throws the expcetion // _interleavingPolicy.Commit((INode) _currentFixedDocumentSequenceWriter); Initialize(); } } else { throw new XpsSerializationException(SR.ReachSerialization_CannotReleaseXmlWriter); } } /// <Summary> /// Acquire a XmlWriter for a FixedDocument /// </Summary> public override XmlWriter AcquireXmlWriterForFixedDocument( ) { XmlWriter xmlWriter = null; if(_currentFixedDocumentWriterRef == 0) { // // We need to create the corresponding part in the Xps package // and then acquire the writer // if(_currentFixedDocumentSequenceWriter != null) { _currentFixedDocumentWriter = _currentFixedDocumentSequenceWriter.AddFixedDocument(); _interleavingPolicy.AddItem((INode)_currentFixedDocumentWriter, 0, (INode) _currentFixedDocumentSequenceWriter); } // // retreive the appropriate writer from the reach package api layer // if(_currentFixedDocumentWriter!=null) { _currentFDWriter = ((XpsFixedDocumentReaderWriter)_currentFixedDocumentWriter).XmlWriter; } } _currentFixedDocumentWriterRef++; xmlWriter = _currentFDWriter; return xmlWriter; } /// <Summary> /// Release a reference to the current FixedDocument /// </Summary> public override void ReleaseXmlWriterForFixedDocument( ) { if(_currentFixedDocumentWriter != null && _currentFixedDocumentWriterRef > 0) { _currentFixedDocumentWriterRef--; if(_currentFixedDocumentWriterRef == 0) { // // if any of the other low level writer exist, then // throw an exception or is it better if we just close // them and consider that if any additional call on them // would be the one that throws the expcetion // _interleavingPolicy.Commit((INode) _currentFixedDocumentWriter); // // All current lower references should be cleared // _currentFixedDocumentWriter = null; _currentFixedPageWriter = null; _currentFixedPageWriterRef = 0; } } else { throw new XpsSerializationException(SR.ReachSerialization_CannotReleaseXmlWriter); } } /// <Summary> /// Acquire an XmlWriter for a FixedPage /// </Summary> public override XmlWriter AcquireXmlWriterForFixedPage( ) { XmlWriter xmlWriter = null; if(_currentFixedPageWriterRef == 0) { // // We need to create the corresponding part in the Xps package // and then acquire the writer // if(_currentFixedDocumentWriter != null) { _currentFixedPageWriter = _currentFixedDocumentWriter.AddFixedPage(); _interleavingPolicy.AddItem((INode)_currentFixedPageWriter, 0, (INode)_currentFixedDocumentWriter); } // // retreive the appropriate writer from the reach package api layer // if(_currentFixedPageWriter != null) { _currentFPWriter = ((XpsFixedPageReaderWriter)_currentFixedPageWriter).XmlWriter; } } _currentFixedPageWriterRef++; xmlWriter = _currentFPWriter; return xmlWriter; } /// <Summary> /// Release a reference to the current XmlWriter /// </Summary> public override void ReleaseXmlWriterForFixedPage( ) { if(_currentFixedPageWriter!=null && _currentFixedPageWriterRef>0) { _currentFixedPageWriterRef--; if(_currentFixedPageWriterRef == 0) { // // if any of the other low level writer exist, then // throw an exception or is it better if we just close // them and consider that if any additional call on them // would be the one that throws the expcetion // _interleavingPolicy.Commit((INode)_currentFixedPageWriter); // // All current lower references should be cleared // _currentFixedPageWriter = null; // // Notify current document that the page is complete so it // flush the link target information. This normally would // occur when the page is committed but this may be delayed // due to font subsetting. Nothing negative occurs if this called multiple times // (_currentFixedDocumentWriter as XpsFixedDocumentReaderWriter).CurrentPageCommitted(); } } else { throw new XpsSerializationException(SR.ReachSerialization_CannotReleaseXmlWriter); } } /// <Summary> /// Acquire a ResourceStream for a XpsFont /// </Summary> public override XpsResourceStream AcquireResourceStreamForXpsFont( ) { XpsResourceStream resourceStream = null; if(_fontAcquireMode != ResourceAcquireMode.MultipleAcquired) { if(_fontAcquireMode == ResourceAcquireMode.NoneAcquired) { _fontAcquireMode = ResourceAcquireMode.SingleAcquired; } if(_currentXpsFontRef == 0) { // // We need to create the corresponding part in the Xps package // and then acquire the Stream // if(_currentFixedPageWriter != null) { _currentXpsFont = _currentFixedPageWriter.AddFont(); _interleavingPolicy.AddItem((INode)_currentXpsFont, 0, (INode)_currentFixedPageWriter); } else { throw new XpsSerializationException(SR.ReachSerialization_NoFixedPageWriter); } // // retreive the appropriate stream and uri from the reach package api layer // if(_currentXpsFont != null) { _fontResourceStream = new XpsResourceStream(_currentXpsFont.GetStream(), _currentXpsFont.Uri); } } _currentXpsFontRef++; resourceStream = _fontResourceStream; } return resourceStream; } /// <Summary> /// Acquire a ResourceStream for a XpsFont /// </Summary> /// <param name="resourceId"> /// Id of Resource /// </param> public override XpsResourceStream AcquireResourceStreamForXpsFont( String resourceId ) { XpsResourceStream resourceStream = null; if(_fontAcquireMode != ResourceAcquireMode.SingleAcquired) { if(_fontAcquireMode == ResourceAcquireMode.NoneAcquired) { _fontAcquireMode = ResourceAcquireMode.MultipleAcquired; } ResourceStreamCacheItem resourceStreamCacheItem = (ResourceStreamCacheItem)_fontsCache[resourceId]; if(resourceStreamCacheItem == null) { resourceStreamCacheItem = new ResourceStreamCacheItem(); // // We need to create the corresponding part in the Xps package // and then acquire the Stream // if(_currentFixedPageWriter != null) { XpsFont reachFont = _currentFixedPageWriter.AddFont(); if(reachFont != null) { _interleavingPolicy.AddItem((INode)reachFont, 0, (INode) _currentFixedPageWriter); resourceStreamCacheItem.XpsResource = (XpsResource)reachFont; // // retreive the appropriate stream and uri from the reach package api layer // _fontResourceStream = new XpsResourceStream(reachFont.GetStream(), reachFont.Uri); resourceStreamCacheItem.XpsResourceStream = _fontResourceStream; _fontsCache[resourceId] = resourceStreamCacheItem; resourceStream = _fontResourceStream; } } else { throw new XpsSerializationException(SR.ReachSerialization_NoFixedPageWriter); } } else { resourceStream = resourceStreamCacheItem.XpsResourceStream; resourceStreamCacheItem.IncRef(); } } return resourceStream; } /// <Summary> /// Release a reference to the current XpsFont ResourceStream /// </Summary> public override void ReleaseResourceStreamForXpsFont( ) { if(_fontAcquireMode == ResourceAcquireMode.SingleAcquired) { if(_currentXpsFont != null && _currentXpsFontRef > 0) { _currentXpsFontRef--; if(_currentXpsFontRef == 0) { _interleavingPolicy.Commit((INode)_currentXpsFont); _fontResourceStream.Initialize(); _currentXpsFont = null; _fontResourceStream = null; _fontAcquireMode = ResourceAcquireMode.NoneAcquired; } } else { throw new XpsSerializationException(SR.ReachSerialization_CannotReleaseXmlWriter); } } } /// <Summary> /// Release a reference to the current XpsFont ResourceStream /// </Summary> /// <param name="resourceId"> /// Id of Resource to release /// </param> public override void ReleaseResourceStreamForXpsFont( String resourceId ) { if(_fontAcquireMode == ResourceAcquireMode.MultipleAcquired) { ResourceStreamCacheItem resourceStreamCacheItem = (ResourceStreamCacheItem)_fontsCache[resourceId]; if(resourceStreamCacheItem != null) { if(resourceStreamCacheItem.Release() == 0) { _interleavingPolicy.Commit((INode)resourceStreamCacheItem.XpsResource); _fontsCache.Remove(resourceId); if(_fontsCache.Count == 0) { _fontAcquireMode = ResourceAcquireMode.NoneAcquired; } } } else { throw new XpsSerializationException(SR.ReachSerialization_CannotReleaseXmlWriter); } } } /// <Summary> /// Acquire a ResourceStream for a XpsImage /// </Summary> /// <param name="resourceId"> /// Id of Resource /// </param> public override XpsResourceStream AcquireResourceStreamForXpsImage( String resourceId ) { XpsResourceStream resourceStream = null; if(_currentXpsImageRef == 0) { // // We need to create the corresponding part in the Xps package // and then acquire the Stream // if(_currentFixedPageWriter != null) { _currentXpsImage = _currentFixedPageWriter.AddImage(resourceId); _interleavingPolicy.AddItem((INode)_currentXpsImage, 0, (INode) _currentFixedPageWriter); } else { throw new XpsSerializationException(SR.ReachSerialization_NoFixedPageWriter); } // // retreive the appropriate stream and uri from the reach package api layer // if(_currentXpsImage != null) { _imageResourceStream = new XpsResourceStream(_currentXpsImage.GetStream(), _currentXpsImage.Uri); } } _currentXpsImageRef++; resourceStream = _imageResourceStream; return resourceStream; } /// <Summary> /// Release a reference of the current XpsImage ResourceStream /// </Summary> public override void ReleaseResourceStreamForXpsImage( ) { if(_currentXpsImage != null && _currentXpsImageRef > 0) { _currentXpsImageRef--; if(_currentXpsImageRef == 0) { _interleavingPolicy.Commit((INode)_currentXpsImage); _imageResourceStream.Initialize(); _currentXpsImage = null; _imageResourceStream = null; } } else { throw new XpsSerializationException(SR.ReachSerialization_CannotReleaseXmlWriter); } } /// <Summary> /// Acquire a ResourceSTream for a XpsColorContext /// </Summary> /// <param name="resourceId"> /// A id for the ResourceStream /// </param> public override XpsResourceStream AcquireResourceStreamForXpsColorContext( String resourceId ) { XpsResourceStream resourceStream = null; if(_currentXpsColorContextRef == 0) { // // We need to create the corresponding part in the Xps package // and then acquire the Stream // if(_currentFixedPageWriter != null) { _currentXpsColorContext = _currentFixedPageWriter.AddColorContext(); _interleavingPolicy.AddItem((INode)_currentXpsColorContext, 0, (INode) _currentFixedPageWriter); } else { throw new XpsSerializationException(SR.ReachSerialization_NoFixedPageWriter); } // // retreive the appropriate stream and uri from the reach package api layer // if(_currentXpsColorContext != null) { _colorContextResourceStream = new XpsResourceStream(_currentXpsColorContext.GetStream(), _currentXpsColorContext.Uri); } } _currentXpsColorContextRef++; resourceStream = _colorContextResourceStream; return resourceStream; } /// <Summary> /// Release a reference to the current XpsColorContext ResourceStream /// </Summary> public override void ReleaseResourceStreamForXpsColorContext( ) { if(_currentXpsColorContext != null && _currentXpsColorContextRef > 0) { _currentXpsColorContextRef--; if(_currentXpsColorContextRef == 0) { _interleavingPolicy.Commit((INode) _currentXpsColorContext); _colorContextResourceStream.Initialize(); _currentXpsColorContext = null; _colorContextResourceStream = null; } } else { throw new XpsSerializationException(SR.ReachSerialization_CannotReleaseXmlWriter); } } /// <Summary> /// Acquire a ResoureSTream for a XpsResourceDictionary /// </Summary> /// <param name="resourceId"> /// A resource Id for the ResourceStream /// </param> public override XpsResourceStream AcquireResourceStreamForXpsResourceDictionary( String resourceId ) { XpsResourceStream resourceStream = null; if(_currentXpsResourceDictionaryRef == 0) { // // We need to create the corresponding part in the Xps package // and then acquire the Stream // if(_currentFixedPageWriter != null) { _currentXpsResourceDictionary = _currentFixedPageWriter.AddResourceDictionary(); _interleavingPolicy.AddItem((INode) _currentXpsResourceDictionary, 0, (INode) _currentFixedPageWriter); } else { throw new XpsSerializationException(SR.ReachSerialization_NoFixedPageWriter); } // // retreive the appropriate stream and uri from the reach package api layer // if(_currentXpsResourceDictionary != null) { _resourceDictionaryResourceStream = new XpsResourceStream(_currentXpsResourceDictionary.GetStream(), _currentXpsResourceDictionary.Uri); } } _currentXpsResourceDictionaryRef++; resourceStream = _resourceDictionaryResourceStream; return resourceStream; } /// <Summary> /// Release a reference to the current XpsResourceDictionary /// </Summary> public override void ReleaseResourceStreamForXpsResourceDictionary( ) { if(_currentXpsResourceDictionary != null && _currentXpsResourceDictionaryRef > 0) { _currentXpsResourceDictionaryRef--; if(_currentXpsResourceDictionaryRef == 0) { _interleavingPolicy.Commit((INode)_currentXpsResourceDictionary); _resourceDictionaryResourceStream.Initialize(); _currentXpsResourceDictionary = null; _resourceDictionaryResourceStream = null; } } else { throw new XpsSerializationException(SR.ReachSerialization_CannotReleaseXmlWriter); } } /// <summary> /// This method adds a relationship to the current active /// page using the specified target and relationship name. /// </summary> /// <param name="targetUri"> /// Uri to Target for relationship. /// </param> /// <param name="relationshipName"> /// Relationship name to add. /// </param> public override void RelateResourceToCurrentPage( Uri targetUri, string relationshipName ) { if (_currentFixedPageWriter != null) { ((XpsFixedPageReaderWriter)_currentFixedPageWriter).AddRelationship(targetUri, relationshipName); } } /// <summary> /// This method adds a relationship to the current active /// document using the specified target and relationship name. /// </summary> /// <param name="targetUri"> /// Uri to Target for relationship. /// </param> /// public override void RelateRestrictedFontToCurrentDocument( Uri targetUri ) { if (_currentFixedDocumentWriter != null) { ((XpsFixedDocumentReaderWriter)_currentFixedDocumentWriter).AddRelationship(targetUri, XpsS0Markup.RestrictedFontRelationshipType); // // This code is in for restricted fonts and should be // enabled later when we figure out a way to commit // the special relation for that font // //_currentFixedDocumentWriter.Commit(); // } } /// <summary> /// Persists the PrintTicket to the packaging layer /// </summary> /// <exception cref="ArgumentNullException">printTicket is NULL.</exception> /// <param name="printTicket"> /// Caller supplied PrintTicket. /// </param> public override void PersistPrintTicket( PrintTicket printTicket ) { ArgumentNullException.ThrowIfNull(printTicket); // // We need to figure out at which level of the package // is this printTicket targeted // if (_currentFixedPageWriter != null) { _currentFixedPageWriter.PrintTicket = printTicket; } else if(_currentFixedDocumentWriter != null) { _currentFixedDocumentWriter.PrintTicket = printTicket; } else { _currentFixedDocumentSequenceWriter?.PrintTicket = printTicket; } } /// <summary> /// Acquire a XmlWriter fro the current page /// </summary> public override XmlWriter AcquireXmlWriterForPage( ) { if (_currentFixedPageWriter == null) { throw new InvalidOperationException("CurrentFixedPageWriter uninitialized"); } return ((XpsFixedPageReaderWriter)_currentFixedPageWriter).PageXmlWriter; } /// <summary> /// Prepare to commit the current page. /// </summary> public override void PreCommitCurrentPage( ) { if (_currentFixedPageWriter == null) { throw new InvalidOperationException("CurrentFixedPageWriter uninitialized"); } ((XpsFixedPageReaderWriter)_currentFixedPageWriter).PrepareCommit(); } /// <summary> /// /// </summary> public override XmlWriter AcquireXmlWriterForResourceDictionary( ) { if (_currentFixedPageWriter == null) { throw new InvalidOperationException("CurrentFixedPageWriter uninitialized"); } return ((XpsFixedPageReaderWriter)_currentFixedPageWriter).ResourceDictionaryXmlWriter; } /// <summary> /// /// </summary> public override IList<String> AcquireStreamForLinkTargets( ) { if (_currentFixedPageWriter == null) { throw new ArgumentNullException("CurrentFixedPageWriter"); } return ((XpsFixedPageReaderWriter)_currentFixedPageWriter).LinkTargetStream; } #endregion Public Methods #region Public Properties /// <summary> /// Get the Uri of the Current FixedDocumentWriter. Null is returned if there is /// not a current FixedDocumentWriter. /// </summary> public override Uri CurrentFixedDocumentUri { get { if (_currentFixedDocumentWriter != null) { return _currentFixedDocumentWriter.Uri; } else { return null; } } } /// <summary> /// Get the Uri of the Current FixedPageWriter. Null is returned if there is /// not a current FixedPageWriter /// </summary> public override Uri CurrentFixedPageUri { get { if (_currentFixedPageWriter != null) { return _currentFixedPageWriter.Uri; } else { return null; } } } /// <summary> /// /// </summary> /// <summary> /// /// </summary> public event PackagingProgressEventHandler PackagingProgressEvent { add{ InterleavingPolicy.PackagingProgressEvent += value; } remove{ InterleavingPolicy.PackagingProgressEvent -= value; } } internal XpsInterleavingPolicy InterleavingPolicy { get { return _interleavingPolicy; } } #endregion Public Properties #region Private Methods private void Initialize( ) { _currentFixedDocumentSequenceWriter = null; _currentFixedDocumentWriter = null; _currentFixedPageWriter = null; _currentDocumentSequenceWriterRef = 0; _currentFixedDocumentWriterRef = 0; _currentFixedPageWriterRef = 0; } private void InitializeResourceReferences( ) { _currentXpsFont = null; _currentXpsImage = null; _currentXpsColorContext = null; _currentXpsResourceDictionary = null; _currentXpsFontRef = 0; _currentXpsImageRef = 0; _currentXpsColorContextRef = 0; _currentXpsResourceDictionaryRef = 0; _fontResourceStream?.Initialize(); _imageResourceStream?.Initialize(); _colorContextResourceStream?.Initialize(); _resourceDictionaryResourceStream?.Initialize(); } #endregion Private Methods #region Private Data private System. Windows. Xps. Packaging. XpsDocument _reachPackage; private XpsInterleavingPolicy _interleavingPolicy; private IXpsFixedDocumentSequenceWriter _currentFixedDocumentSequenceWriter; private IXpsFixedDocumentWriter _currentFixedDocumentWriter; private IXpsFixedPageWriter _currentFixedPageWriter; private int _currentDocumentSequenceWriterRef; private int _currentFixedDocumentWriterRef; private int _currentFixedPageWriterRef; private XmlWriter _currentDSWriter; private XmlWriter _currentFDWriter; private XmlWriter _currentFPWriter; private XpsFont _currentXpsFont; private XpsImage _currentXpsImage; private XpsColorContext _currentXpsColorContext; private XpsResourceDictionary _currentXpsResourceDictionary; private int _currentXpsFontRef; private int _currentXpsImageRef; private int _currentXpsColorContextRef; private int _currentXpsResourceDictionaryRef; private XpsResourceStream _fontResourceStream; private XpsResourceStream _imageResourceStream; private XpsResourceStream _colorContextResourceStream; private XpsResourceStream _resourceDictionaryResourceStream; private ResourceAcquireMode _fontAcquireMode; private Hashtable _fontsCache; private enum ResourceAcquireMode { NoneAcquired = 0, SingleAcquired = 1, MultipleAcquired = 2 }; #endregion Private Data }; }