Exemple #1
0
        /// <summary>
        /// Internal only constructor that initializes a DA with an EPC
        /// </summary>
        /// <param name="extendedProperties"></param>
        internal DrawingAttributes(ExtendedPropertyCollection extendedProperties)
        {
            System.Diagnostics.Debug.Assert(extendedProperties != null);
            _extendedProperties = extendedProperties;

            Initialize();
        }
        /// <summary>
        /// Internal only constructor that initializes a DA with an EPC
        /// </summary> 
        /// <param name="extendedProperties"></param>
        internal DrawingAttributes(ExtendedPropertyCollection extendedProperties) 
        { 
            System.Diagnostics.Debug.Assert(extendedProperties != null);
            _extendedProperties = extendedProperties; 

            Initialize();
        }
Exemple #3
0
        /// <summary>
        /// Copies the ExtendedPropertyCollection
        /// </summary>
        /// <returns>Copy of the ExtendedPropertyCollection</returns>
        /// <remarks>Any reference types held in the collection will only be deep copied (e.g. Arrays).
        /// </remarks>
        internal ExtendedPropertyCollection Clone()
        {
            ExtendedPropertyCollection copied = new ExtendedPropertyCollection();

            for (int x = 0; x < _extendedProperties.Count; x++)
            {
                copied.Add(_extendedProperties[x].Clone());
            }
            return(copied);
        }
Exemple #4
0
        /// <summary>Create a stroke from a StylusPointCollection</summary>
        /// <remarks>
        /// </remarks>
        /// <param name="stylusPoints">StylusPointCollection that makes up the stroke</param> 
        /// <param name="drawingAttributes">drawingAttributes</param>
        /// <param name="extendedProperties">extendedProperties</param> 
        internal Stroke(StylusPointCollection stylusPoints, DrawingAttributes drawingAttributes, ExtendedPropertyCollection extendedProperties) 
        {
            if (stylusPoints == null) 
            {
                throw new ArgumentNullException("stylusPoints");
            }
            if (stylusPoints.Count == 0) 
            {
                throw new ArgumentException(SR.Get(SRID.InvalidStylusPointCollectionZeroCount), "stylusPoints"); 
            } 
            if (drawingAttributes == null)
            { 
                throw new ArgumentNullException("drawingAttributes");
            }

            _drawingAttributes = drawingAttributes; 
            _stylusPoints = stylusPoints;
            _extendedProperties = extendedProperties; 
 
            Initialize();
        } 
Exemple #5
0
        /// <summary>Create a stroke from a StylusPointCollection</summary>
        /// <remarks>
        /// </remarks>
        /// <param name="stylusPoints">StylusPointCollection that makes up the stroke</param>
        /// <param name="drawingAttributes">drawingAttributes</param>
        /// <param name="extendedProperties">extendedProperties</param>
        internal Stroke(StylusPointCollection stylusPoints, DrawingAttributes drawingAttributes, ExtendedPropertyCollection extendedProperties)
        {
            if (stylusPoints == null)
            {
                throw new ArgumentNullException("stylusPoints");
            }
            if (stylusPoints.Count == 0)
            {
                throw new ArgumentException(SR.Get(SRID.InvalidStylusPointCollectionZeroCount), "stylusPoints");
            }
            if (drawingAttributes == null)
            {
                throw new ArgumentNullException("drawingAttributes");
            }

            _drawingAttributes  = drawingAttributes;
            _stylusPoints       = stylusPoints;
            _extendedProperties = extendedProperties;

            Initialize();
        }
Exemple #6
0
        /// <summary>Overload of the Equals method which determines if two ExtendedPropertyCollection
        /// objects contain equivalent key/value pairs</summary>
        public override bool Equals(object o)
        {
            if (o == null || o.GetType() != GetType())
            {
                return(false);
            }

            //
            // compare counts
            //
            ExtendedPropertyCollection that = (ExtendedPropertyCollection)o;

            if (that.Count != this.Count)
            {
                return(false);
            }

            //
            // counts are equal, compare individual items
            //
            //
            for (int x = 0; x < that.Count; x++)
            {
                bool cont = false;
                for (int i = 0; i < _extendedProperties.Count; i++)
                {
                    if (_extendedProperties[i].Equals(that[x]))
                    {
                        cont = true;
                        break;
                    }
                }
                if (!cont)
                {
                    return(false);
                }
            }
            return(true);
        }
 /// <summary>
 /// Retrieve the guids for the custom attributes that are not known by
 /// the v1 ISF decoder
 /// </summary>
 /// <param name="attributes"></param>
 /// <param name="count">count of guids returned (can be less than return.Length</param>
 /// <returns></returns>
 internal static Guid[] GetUnknownGuids(ExtendedPropertyCollection attributes, out int count)
 {
     Guid[] guids = new Guid[attributes.Count];
     count = 0;
     for (int x = 0; x < attributes.Count; x++)
     {
         ExtendedProperty attribute = attributes[x];
         if (0 == GuidList.FindKnownTag(attribute.Id))
         {
             guids[count++] = attribute.Id;
         }
     }
     return guids;
 }
        /// <summary>
        /// Saves all elements in this list in the stream passed with the tags being generated based on the GuidList
        /// by the caller and using compressionAlgorithm as the preferred algorith identifier. For ExtendedPropertyCollection associated
        /// with Ink, drawing attributes and Point properties, we need to write the tag while saving them and hence
        /// fTag param is true. For strokes, the Tag is stored in the stroke descriptor and hence we don't store the
        /// tag
        /// </summary>
        /// <param name="attributes">Custom attributes to encode</param>
        /// <param name="stream">If stream is null, then size is calculated only.</param>
        /// <param name="guidList"></param>
        /// <param name="compressionAlgorithm"></param>
        /// <param name="fTag"></param>
#endif
        internal static uint EncodeAsISF(ExtendedPropertyCollection attributes, Stream stream, GuidList guidList, byte compressionAlgorithm, bool fTag)
        {
            uint cbWrite = 0;

            for (int i = 0; i < attributes.Count; i++)
            {
                ExtendedProperty prop = attributes[i];

                using (MemoryStream localStream = new MemoryStream(10)) //reasonable default
                {
                    ExtendedPropertySerializer.EncodeToStream(prop, localStream);

                    byte[] data = localStream.ToArray(); 

                    cbWrite += ExtendedPropertySerializer.EncodeAsISF(prop.Id, data, stream, guidList, compressionAlgorithm, fTag);
                }
            }

            return cbWrite;
        }
        /// <summary>
        /// Creates a DrawingAttributes with default values
        /// </summary>
        public DrawingAttributes() 
        {
            _extendedProperties = new ExtendedPropertyCollection(); 
 
            Initialize();
        } 
        /// <summary>
        /// Takes an ISF Stream and populates the StrokeCollection
        ///  attached to this StrokeCollectionSerializer.
        /// </summary>
        /// <param name="inputStream">a Stream the raw isf to decode</param>
#endif
        private void DecodeRawISF(Stream inputStream)
        {
            Debug.Assert(inputStream != null);

            KnownTagCache.KnownTagIndex isfTag;
            uint remainingBytesInStream;
            uint bytesDecodedInCurrentTag = 0;
            bool strokeDescriptorBlockDecoded = false;
            bool drawingAttributesBlockDecoded = false;
            bool metricBlockDecoded = false;
            bool transformDecoded = false;
            uint strokeDescriptorTableIndex = 0;
            uint oldStrokeDescriptorTableIndex = 0xFFFFFFFF;
            uint drawingAttributesTableIndex = 0;
            uint oldDrawingAttributesTableIndex = 0xFFFFFFFF;
            uint metricDescriptorTableIndex = 0;
            uint oldMetricDescriptorTableIndex = 0xFFFFFFFF;
            uint transformTableIndex = 0;
            uint oldTransformTableIndex = 0xFFFFFFFF;
            GuidList guidList = new GuidList();
            int strokeIndex = 0;

            StylusPointDescription currentStylusPointDescription = null;
            Matrix currentTabletToInkTransform = Matrix.Identity;

            _strokeDescriptorTable = new System.Collections.Generic.List<StrokeDescriptor>();
            _drawingAttributesTable = new System.Collections.Generic.List<DrawingAttributes>();
            _transformTable = new System.Collections.Generic.List<TransformDescriptor>();
            _metricTable = new System.Collections.Generic.List<MetricBlock>();

            // First make sure this ink is empty
            if (0 != _coreStrokes.Count || _coreStrokes.ExtendedProperties.Count != 0)
            {
                throw new InvalidOperationException(ISFDebugMessage("ISF decoder cannot operate on non-empty ink container"));
            }
#if OLD_ISF
            //
            // store a compressor reference at this scope, if it is needed (if there is a compresson header) and
            // therefore instanced during this routine, we will dispose of it
            // in the finally block
            //
            Compressor compressor = null;

            try
            {
#endif

            // First read the isfTag
            uint uiTag;
            uint localBytesDecoded = SerializationHelper.Decode(inputStream, out uiTag);
            if (0x00 != uiTag)
                throw new ArgumentException(SR.Get(SRID.InvalidStream));

            // Now read the size of the stream
            localBytesDecoded = SerializationHelper.Decode(inputStream, out remainingBytesInStream);
            ISFDebugTrace("Decoded Stream Size in Bytes: " + remainingBytesInStream.ToString());
            if (0 == remainingBytesInStream)
                return;

            while (0 < remainingBytesInStream)
            {
                bytesDecodedInCurrentTag = 0;

                // First read the isfTag
                localBytesDecoded = SerializationHelper.Decode(inputStream, out uiTag);
                isfTag = (KnownTagCache.KnownTagIndex)uiTag;
                if (remainingBytesInStream >= localBytesDecoded)
                    remainingBytesInStream -= localBytesDecoded;
                else
                {
                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));
                }

                ISFDebugTrace("Decoding Tag: " + ((KnownTagCache.KnownTagIndex)isfTag).ToString());
                switch (isfTag)
                {
                    case KnownTagCache.KnownTagIndex.GuidTable:
                    case KnownTagCache.KnownTagIndex.DrawingAttributesTable:
                    case KnownTagCache.KnownTagIndex.DrawingAttributesBlock:
                    case KnownTagCache.KnownTagIndex.StrokeDescriptorTable:
                    case KnownTagCache.KnownTagIndex.StrokeDescriptorBlock:
                    case KnownTagCache.KnownTagIndex.MetricTable:
                    case KnownTagCache.KnownTagIndex.MetricBlock:
                    case KnownTagCache.KnownTagIndex.TransformTable:
                    case KnownTagCache.KnownTagIndex.ExtendedTransformTable:
                    case KnownTagCache.KnownTagIndex.Stroke:
                    case KnownTagCache.KnownTagIndex.CompressionHeader:
                    case KnownTagCache.KnownTagIndex.PersistenceFormat:
                    case KnownTagCache.KnownTagIndex.HimetricSize:
                    case KnownTagCache.KnownTagIndex.StrokeIds:
                        {
                            localBytesDecoded = SerializationHelper.Decode(inputStream, out bytesDecodedInCurrentTag);
                            if (remainingBytesInStream < (localBytesDecoded + bytesDecodedInCurrentTag))
                            {
                                throw new ArgumentException(ISFDebugMessage("Invalid ISF data"), "inputStream");
                            }

                            remainingBytesInStream -= localBytesDecoded;

                            // Based on the isfTag figure out what information we're loading
                            switch (isfTag)
                            {
                                case KnownTagCache.KnownTagIndex.GuidTable:
                                    {
                                        // Load guid Table
                                        localBytesDecoded = guidList.Load(inputStream, bytesDecodedInCurrentTag);
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.DrawingAttributesTable:
                                    {
                                        // Load drawing attributes table
                                        localBytesDecoded = LoadDrawAttrsTable(inputStream, guidList, bytesDecodedInCurrentTag);
                                        drawingAttributesBlockDecoded = true;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.DrawingAttributesBlock:
                                    {
                                        //initialize to V1 defaults, we do it this way as opposed
                                        //to dr.DrawingFlags = 0 because this was a perf hot spot
                                        //and instancing the epc first mitigates it
                                        ExtendedPropertyCollection epc = new ExtendedPropertyCollection();
                                        epc.Add(KnownIds.DrawingFlags, DrawingFlags.Polyline);
                                        DrawingAttributes dr = new DrawingAttributes(epc);
                                        localBytesDecoded = DrawingAttributeSerializer.DecodeAsISF(inputStream, guidList, bytesDecodedInCurrentTag, dr);

                                        _drawingAttributesTable.Add(dr);
                                        drawingAttributesBlockDecoded = true;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.StrokeDescriptorTable:
                                    {
                                        // Load stroke descriptor table
                                        localBytesDecoded = DecodeStrokeDescriptorTable(inputStream, bytesDecodedInCurrentTag);
                                        strokeDescriptorBlockDecoded = true;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.StrokeDescriptorBlock:
                                    {
                                        // Load a single stroke descriptor
                                        localBytesDecoded = DecodeStrokeDescriptorBlock(inputStream, bytesDecodedInCurrentTag);
                                        strokeDescriptorBlockDecoded = true;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.MetricTable:
                                    {
                                        // Load Metric Table
                                        localBytesDecoded = DecodeMetricTable(inputStream, bytesDecodedInCurrentTag);
                                        metricBlockDecoded = true;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.MetricBlock:
                                    {
                                        // Load a single Metric Block
                                        MetricBlock blk;

                                        localBytesDecoded = DecodeMetricBlock(inputStream, bytesDecodedInCurrentTag, out blk);
                                        _metricTable.Clear();
                                        _metricTable.Add(blk);
                                        metricBlockDecoded = true;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.TransformTable:
                                    {
                                        // Load Transform Table
                                        localBytesDecoded = DecodeTransformTable(inputStream, bytesDecodedInCurrentTag, false);
                                        transformDecoded = true;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.ExtendedTransformTable:
                                    {
                                        // non-double transform table should have already been loaded
                                        if (!transformDecoded)
                                        {
                                            throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));
                                        }

                                        // Load double-sized Transform Table
                                        localBytesDecoded = DecodeTransformTable(inputStream, bytesDecodedInCurrentTag, true);
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.PersistenceFormat:
                                    {
                                        uint fmt;

                                        localBytesDecoded = SerializationHelper.Decode(inputStream, out fmt);
                                        // Set the appropriate persistence information
                                        if (0 == fmt)
                                        {
                                            CurrentPersistenceFormat = PersistenceFormat.InkSerializedFormat;
                                        }
                                        else if (0x00000001 == fmt)
                                        {
                                            CurrentPersistenceFormat = PersistenceFormat.Gif;
                                        }


                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.HimetricSize:
                                    {
                                        // Loads the Hi Metric Size for Fortified GIFs
                                        int sz;

                                        localBytesDecoded = SerializationHelper.SignDecode(inputStream, out sz);
                                        if (localBytesDecoded > remainingBytesInStream)
                                            throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));

                                        _himetricSize.X = (double)sz;
                                        localBytesDecoded += SerializationHelper.SignDecode(inputStream, out sz);

                                        _himetricSize.Y = (double)sz;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.CompressionHeader:
                                    {
#if OLD_ISF
                                        byte[] data = new byte[bytesDecodedInCurrentTag];

                                        // read the header from the stream
                                        uint bytesRead = StrokeCollectionSerializer.ReliableRead(inputStream, data, bytesDecodedInCurrentTag);
                                        if (bytesDecodedInCurrentTag != bytesRead)
                                        {
                                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Read different size from stream then expected"), "isfStream");
                                        }

                                        uint size = bytesDecodedInCurrentTag;
                                        compressor = new Compressor(data, ref size);
                                        // in case the actual number of bytes read by the compressor
                                        //      is less than the encoder had expected (e.g. compression
                                        //      header was encoded as 10 bytes, but only 7 bytes were read)
                                        //      then we don't want to adjust the stream position because
                                        //      there are likely other following tags that are encoded
                                        //      after the compression tag. This should never happen,
                                        //      so just fail if the compressor is broken or the ISF is
                                        //      corrupted.
                                        if (size != bytesDecodedInCurrentTag)
                                        {
                                            throw new InvalidOperationException(ISFDebugMessage("Compressor intialization reported inconsistent size"));
                                        }
#else
                                        //just advance the inputstream position, we don't need
                                        //no compression header in the new isf decoding
                                        inputStream.Seek(bytesDecodedInCurrentTag, SeekOrigin.Current);
#endif
                                        localBytesDecoded = bytesDecodedInCurrentTag;
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.StrokeIds:
                                    {
                                        localBytesDecoded = LoadStrokeIds(inputStream, bytesDecodedInCurrentTag);
                                        break;
                                    }

                                case KnownTagCache.KnownTagIndex.Stroke:
                                    {
                                        ISFDebugTrace("   Decoding Stroke Id#(" + (strokeIndex + 1).ToString() + ")");

                                        StrokeDescriptor strokeDescriptor = null;

                                        // Load the stroke descriptor based on the index from the list of unique
                                        // stroke descriptors
                                        if (strokeDescriptorBlockDecoded)
                                        {
                                            if (oldStrokeDescriptorTableIndex != strokeDescriptorTableIndex)
                                            {
                                                if (_strokeDescriptorTable.Count <= strokeDescriptorTableIndex)
                                                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));
                                            }

                                            strokeDescriptor = _strokeDescriptorTable[(int)strokeDescriptorTableIndex];
                                        }

                                        // use new transform if the last transform is uninit'd or has changed
                                        if (oldTransformTableIndex != transformTableIndex)
                                        {
                                            // if transform was specified in the ISF stream
                                            if (transformDecoded)
                                            {
                                                if (_transformTable.Count <= transformTableIndex)
                                                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));

                                                // Load the transform descriptor based on the index from the list of unique
                                                // transforn descriptors
                                                currentTabletToInkTransform = LoadTransform(_transformTable[(int)transformTableIndex]);
                                            }

                                            oldTransformTableIndex = transformTableIndex; // cache the transform by remembering the index

                                            // since ISF is stored in HIMETRIC, and we want to expose packet data
                                            //      as Avalon units, we'll update the convert the transform before loading the stroke
                                            currentTabletToInkTransform.Scale(StrokeCollectionSerializer.HimetricToAvalonMultiplier, StrokeCollectionSerializer.HimetricToAvalonMultiplier);
                                        }

                                        MetricBlock metricBlock = null;

                                        // Load the metric block based on the index from the list of unique metric blocks
                                        if (metricBlockDecoded)
                                        {
                                            if (oldMetricDescriptorTableIndex != metricDescriptorTableIndex)
                                            {
                                                if (_metricTable.Count <= metricDescriptorTableIndex)
                                                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));
                                            }

                                            metricBlock = _metricTable[(int)metricDescriptorTableIndex];
                                        }

                                        DrawingAttributes activeDrawingAttributes = null;

                                        // Load the drawing attributes based on the index from the list of unique drawing attributes
                                        if (drawingAttributesBlockDecoded)
                                        {
                                            if (oldDrawingAttributesTableIndex != drawingAttributesTableIndex)
                                            {
                                                if (_drawingAttributesTable.Count <= drawingAttributesTableIndex)
                                                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));

                                                oldDrawingAttributesTableIndex = drawingAttributesTableIndex;
                                            }
                                            DrawingAttributes currDA = (DrawingAttributes)_drawingAttributesTable[(int)drawingAttributesTableIndex];
                                            //we always clone so we don't get strokes that share DAs, which can lead
                                            //to all sorts of unpredictable behavior (ex: see Windows OS Bugs 1450047)
                                            activeDrawingAttributes = currDA.Clone();
                                        }

                                        // if we didn't find an existing da to use, instance a new one
                                        if (activeDrawingAttributes == null)
                                        {
                                            activeDrawingAttributes = new DrawingAttributes();
                                        }

                                        // Now create the StylusPacketDescription from the stroke descriptor and metric block
                                        if (oldMetricDescriptorTableIndex != metricDescriptorTableIndex || oldStrokeDescriptorTableIndex != strokeDescriptorTableIndex)
                                        {
                                            currentStylusPointDescription = BuildStylusPointDescription(strokeDescriptor, metricBlock, guidList);
                                            oldStrokeDescriptorTableIndex = strokeDescriptorTableIndex;
                                            oldMetricDescriptorTableIndex = metricDescriptorTableIndex;
                                        }

                                        // Load the stroke
                                        Stroke localStroke;
#if OLD_ISF
                                        localBytesDecoded = StrokeSerializer.DecodeStroke(inputStream, bytesDecodedInCurrentTag, guidList, strokeDescriptor, currentStylusPointDescription, activeDrawingAttributes, currentTabletToInkTransform, compressor, out localStroke);
#else
                                        localBytesDecoded = StrokeSerializer.DecodeStroke(inputStream, bytesDecodedInCurrentTag, guidList, strokeDescriptor, currentStylusPointDescription, activeDrawingAttributes, currentTabletToInkTransform, out localStroke);
#endif

                                        if (localStroke != null)
                                        {
                                            _coreStrokes.AddWithoutEvent(localStroke);
                                            strokeIndex++;
                                        }
                                        break;
                                    }

                                default:
                                    {
                                        throw new InvalidOperationException(ISFDebugMessage("Invalid ISF tag logic"));
                                    }
                            }

                            // if this isfTag's decoded size != expected size, then error out
                            if (localBytesDecoded != bytesDecodedInCurrentTag)
                            {
                                throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));
                            }

                            break;
                        }

                    case KnownTagCache.KnownTagIndex.Transform:
                    case KnownTagCache.KnownTagIndex.TransformIsotropicScale:
                    case KnownTagCache.KnownTagIndex.TransformAnisotropicScale:
                    case KnownTagCache.KnownTagIndex.TransformRotate:
                    case KnownTagCache.KnownTagIndex.TransformTranslate:
                    case KnownTagCache.KnownTagIndex.TransformScaleAndTranslate:
                        {
                            // Load a single Transform Block
                            TransformDescriptor xform;

                            bytesDecodedInCurrentTag = DecodeTransformBlock(inputStream, isfTag, remainingBytesInStream, false, out xform);
                            transformDecoded = true;
                            _transformTable.Clear();
                            _transformTable.Add(xform);
                            break;
                        }

                    case KnownTagCache.KnownTagIndex.TransformTableIndex:
                        {
                            // Load the Index into the Transform Table which will be used by the stroke following this till
                            // a next different Index is found
                            bytesDecodedInCurrentTag = SerializationHelper.Decode(inputStream, out transformTableIndex);
                            break;
                        }

                    case KnownTagCache.KnownTagIndex.MetricTableIndex:
                        {
                            // Load the Index into the Metric Table which will be used by the stroke following this till
                            // a next different Index is found
                            bytesDecodedInCurrentTag = SerializationHelper.Decode(inputStream, out metricDescriptorTableIndex);
                            break;
                        }

                    case KnownTagCache.KnownTagIndex.DrawingAttributesTableIndex:
                        {
                            // Load the Index into the Drawing Attributes Table which will be used by the stroke following this till
                            // a next different Index is found
                            bytesDecodedInCurrentTag = SerializationHelper.Decode(inputStream, out drawingAttributesTableIndex);
                            break;
                        }

                    case KnownTagCache.KnownTagIndex.InkSpaceRectangle:
                        {
                            // Loads the Ink Space Rectangle information
                            bytesDecodedInCurrentTag = DecodeInkSpaceRectangle(inputStream, remainingBytesInStream);
                            break;
                        }

                    case KnownTagCache.KnownTagIndex.StrokeDescriptorTableIndex:
                        {
                            // Load the Index into the Stroke Descriptor Table which will be used by the stroke following this till
                            // a next different Index is found
                            bytesDecodedInCurrentTag = SerializationHelper.Decode(inputStream, out strokeDescriptorTableIndex);
                            break;
                        }

                    default:
                        {
                            if ((uint)isfTag >= KnownIdCache.CustomGuidBaseIndex || ((uint)isfTag >= KnownTagCache.KnownTagCount && ((uint)isfTag < (KnownTagCache.KnownTagCount + KnownIdCache.OriginalISFIdTable.Length))))
                            {
                                ISFDebugTrace("  CUSTOM_GUID=" + guidList.FindGuid(isfTag).ToString());

                                // Loads any custom property data
                                bytesDecodedInCurrentTag = remainingBytesInStream;

                                Guid guid = guidList.FindGuid(isfTag);
                                if (guid == Guid.Empty)
                                {
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Global Custom Attribute tag embedded in ISF stream does not match guid table"), "inkdata");
                                }


                                object data;

                                // load the custom property data from the stream (and decode the type)
                                localBytesDecoded = ExtendedPropertySerializer.DecodeAsISF(inputStream, bytesDecodedInCurrentTag, guidList, isfTag, ref guid, out data);
                                if (localBytesDecoded > bytesDecodedInCurrentTag)
                                {
                                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"), "inkdata");
                                }


                                // add the guid/data pair into the property collection (don't redecode the type)
                                _coreStrokes.ExtendedProperties[guid] = data;
                            }
                            else
                            {
                                // Skip objects that this library doesn't know about
                                // First read the size associated with this unknown isfTag
                                localBytesDecoded = SerializationHelper.Decode(inputStream, out bytesDecodedInCurrentTag);
                                if (remainingBytesInStream < (localBytesDecoded + bytesDecodedInCurrentTag))
                                {
                                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));
                                }
                                else
                                {
                                    inputStream.Seek(bytesDecodedInCurrentTag + localBytesDecoded, SeekOrigin.Current);
                                }
                            }

                            bytesDecodedInCurrentTag = localBytesDecoded;
                            break;
                        }
                }
                ISFDebugTrace("    Size = " + bytesDecodedInCurrentTag.ToString());
                if (bytesDecodedInCurrentTag > remainingBytesInStream)
                {
                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"));
                }

                // update remaining ISF buffer length with decoded so far
                remainingBytesInStream -= bytesDecodedInCurrentTag;
            }
#if OLD_ISF
        }
        finally
        {
            if (null != compressor)
            {
                compressor.Dispose();
                compressor = null;
            }
        }
#endif
        if (0 != remainingBytesInStream)
            throw new ArgumentException(ISFDebugMessage("Invalid ISF data"), "inkdata");
    }
 /// <summary>
 /// Copies the ExtendedPropertyCollection
 /// </summary>
 /// <returns>Copy of the ExtendedPropertyCollection</returns>
 /// <remarks>Any reference types held in the collection will only be deep copied (e.g. Arrays).
 /// </remarks>
 internal ExtendedPropertyCollection Clone()
 {
     ExtendedPropertyCollection copied = new ExtendedPropertyCollection();
     for (int x = 0; x < _extendedProperties.Count; x++)
     {
         copied.Add(_extendedProperties[x].Clone());
     }
     return copied;
 }
Exemple #12
0
        /// <summary>
        /// This functions loads a stroke from a memory stream based on the descriptor and GuidList. It returns
        /// the no of bytes it has read from the stream to correctly load the stream, which should be same as
        /// the value of the size parameter. If they are unequal throws ArgumentException. Stroke descriptor is
        /// used to load the packetproperty as well as ExtendedPropertyCollection on this stroke. Compressor is used
        /// to decompress the data.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="totalBytesInStrokeBlockOfIsfStream"></param>
        /// <param name="guidList"></param>
        /// <param name="strokeDescriptor"></param>
        /// <param name="stylusPointDescription"></param>
        /// <param name="transform"></param>
        /// <param name="stylusPoints"></param>
        /// <param name="extendedProperties"></param>
#endif
        static uint DecodeISFIntoStroke(
#if OLD_ISF
            Compressor compressor, 
#endif
            Stream stream, 
            uint totalBytesInStrokeBlockOfIsfStream, 
            GuidList guidList, 
            StrokeDescriptor strokeDescriptor,
            StylusPointDescription stylusPointDescription,
            Matrix transform,
            out StylusPointCollection stylusPoints, 
            out ExtendedPropertyCollection extendedProperties)
        {
            stylusPoints = null;
            extendedProperties = null;

            // We do allow a stroke with no packet data
            if (0 == totalBytesInStrokeBlockOfIsfStream)
            {
                return 0;
            }
             
            uint locallyDecodedBytes;
            uint remainingBytesInStrokeBlock = totalBytesInStrokeBlockOfIsfStream;

            // First try to load any packet data
            locallyDecodedBytes = LoadPackets(  stream, 
                                                remainingBytesInStrokeBlock, 
#if OLD_ISF
                                                compressor, 
#endif
                                                stylusPointDescription, 
                                                transform, 
                                                out stylusPoints);

            if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Packet buffer overflowed the ISF stream"));

            remainingBytesInStrokeBlock -= locallyDecodedBytes;
            if (0 == remainingBytesInStrokeBlock)
            {
                return locallyDecodedBytes;
            }

            // Now read the extended propertes
            for (int iTag = 1; iTag < strokeDescriptor.Template.Count && remainingBytesInStrokeBlock > 0; iTag++)
            {
                KnownTagCache.KnownTagIndex tag = strokeDescriptor.Template[iTag - 1];

                switch (tag)
                {
                    case MS.Internal.Ink.InkSerializedFormat.KnownTagCache.KnownTagIndex.StrokePropertyList:
                        {
                            // we've found the stroke extended properties. Load them now.
                            while (iTag < strokeDescriptor.Template.Count && remainingBytesInStrokeBlock > 0)
                            {
                                tag = strokeDescriptor.Template[iTag];

                                object data;
                                Guid guid = guidList.FindGuid(tag);
                                if (guid == Guid.Empty)
                                {
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Stroke Custom Attribute tag embedded in ISF stream does not match guid table"));
                                }

                                // load the extended property data from the stream (and decode the type)
                                locallyDecodedBytes = ExtendedPropertySerializer.DecodeAsISF(stream, remainingBytesInStrokeBlock, guidList, tag, ref guid, out data);

                                // add the guid/data pair into the property collection (don't redecode the type)
                                if (extendedProperties == null)
                                {
                                    extendedProperties = new ExtendedPropertyCollection();
                                }
                                extendedProperties[guid] = data;
                                if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                                remainingBytesInStrokeBlock -= locallyDecodedBytes;
                                iTag++;
                            }
                        }
                        break;

                    case MS.Internal.Ink.InkSerializedFormat.KnownTagCache.KnownTagIndex.Buttons:
                        {
                            // Next tag is count of buttons and the tags for the button guids
                            iTag += (int)((uint)strokeDescriptor.Template[iTag]) + 1;
                        }
                        break;

                    // ignore any tags embedded in the Stroke block that this
                    //      version of the ISF decoder doesn't understand
                    default:
                        {
                            System.Diagnostics.Trace.WriteLine("Ignoring unhandled stroke tag in ISF stroke descriptor");
                        }
                        break;
                }
            }

            // Now try to load any tagged property data or point property data
            while (remainingBytesInStrokeBlock > 0)
            {
                // Read the tag first
                KnownTagCache.KnownTagIndex tag;
                uint uiTag;

                locallyDecodedBytes = SerializationHelper.Decode(stream, out uiTag);
                tag = (KnownTagCache.KnownTagIndex)uiTag;
                if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                remainingBytesInStrokeBlock -= locallyDecodedBytes;

                // if it is a point property block
                switch (tag)
                {
                    case MS.Internal.Ink.InkSerializedFormat.KnownTagCache.KnownTagIndex.PointProperty:
                        {
                            // First load the totalBytesInStrokeBlockOfIsfStream of the point property block
                            uint cbsize;

                            locallyDecodedBytes = SerializationHelper.Decode(stream, out cbsize);
                            if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                            remainingBytesInStrokeBlock -= locallyDecodedBytes;
                            while (remainingBytesInStrokeBlock > 0)
                            {
                                // First read the tag corresponding to the property
                                locallyDecodedBytes = SerializationHelper.Decode(stream, out uiTag);
                                tag = (KnownTagCache.KnownTagIndex)uiTag;
                                if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                                remainingBytesInStrokeBlock -= locallyDecodedBytes;

                                // Now read the packet index for which the property will apply
                                uint propindex;

                                locallyDecodedBytes = SerializationHelper.Decode(stream, out propindex);
                                if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                                remainingBytesInStrokeBlock -= locallyDecodedBytes;

                                uint propsize;

                                locallyDecodedBytes = SerializationHelper.Decode(stream, out propsize);
                                if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                                remainingBytesInStrokeBlock -= locallyDecodedBytes;

                                // Compressed data totalBytesInStrokeBlockOfIsfStream
                                propsize += 1;

                                // Make sure we have enough data to read
                                if (propsize > remainingBytesInStrokeBlock)
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                                byte[] in_buffer = new byte[propsize];

                                uint bytesRead = StrokeCollectionSerializer.ReliableRead(stream, in_buffer, propsize);
                                if (propsize != bytesRead)
                                {
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Read different size from stream then expected"));
                                }

                                byte[] out_buffer = Compressor.DecompressPropertyData(in_buffer);

                                System.Diagnostics.Debug.Assert(false, "ExtendedProperties for points are not supported");

                                // skip the bytes in both success & failure cases
                                // Note: Point ExtendedProperties are discarded
                                remainingBytesInStrokeBlock -= propsize;
                            }
                        }
                        break;

                    default:
                        {
                            object data;
                            Guid guid = guidList.FindGuid(tag);
                            if (guid == Guid.Empty)
                            {
                                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Stroke Custom Attribute tag embedded in ISF stream does not match guid table"));
                            }

                            // load the extended property data from the stream (and decode the type)
                            locallyDecodedBytes = ExtendedPropertySerializer.DecodeAsISF(stream, remainingBytesInStrokeBlock, guidList, tag, ref guid, out data);

                            // add the guid/data pair into the property collection (don't redecode the type)
                            if (extendedProperties == null)
                            {
                                extendedProperties = new ExtendedPropertyCollection();
                            }
                            extendedProperties[guid] = data;
                            if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                            {
                                throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage("ExtendedProperty decoded totalBytesInStrokeBlockOfIsfStream exceeded ISF stream totalBytesInStrokeBlockOfIsfStream"));
                            }

                            remainingBytesInStrokeBlock -= locallyDecodedBytes;
                        }
                        break;
                }
            }

            if (0 != remainingBytesInStrokeBlock)
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

            return totalBytesInStrokeBlockOfIsfStream;
        }
Exemple #13
0
        /// <summary>
        /// Creates a DrawingAttributes with default values
        /// </summary>
        public DrawingAttributes()
        {
            _extendedProperties = new ExtendedPropertyCollection();

            Initialize();
        }