예제 #1
0
        public bool IsEqual(StrokeDescriptor strd)
        {
            // If the no of templates in them are different return false
            if( _strokeDescriptor.Count != strd.Template.Count ) 
                return false;
 
            // Compare each tag in the template. If any one of them is different, return false; 
            for( int i = 0; i < _strokeDescriptor.Count; i++ )
                if( _strokeDescriptor[i] != strd.Template[i] ) 
                    return false;
            return true;
        }
예제 #2
0
        public bool IsEqual(StrokeDescriptor strd)
        {
            // If the no of templates in them are different return false
            if (_strokeDescriptor.Count != strd.Template.Count)
            {
                return(false);
            }

            // Compare each tag in the template. If any one of them is different, return false;
            for (int i = 0; i < _strokeDescriptor.Count; i++)
            {
                if (_strokeDescriptor[i] != strd.Template[i])
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #3
0
        /// <summary>
        /// Loads a stroke from the stream based on Stroke Descriptor, StylusPointDescription, Drawing Attributes, Stroke IDs, transform and GuidList
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="size"></param>
        /// <param name="guidList"></param>
        /// <param name="strokeDescriptor"></param>
        /// <param name="stylusPointDescription"></param>
        /// <param name="drawingAttributes"></param>
        /// <param name="transform"></param>
        /// <param name="compressor">Compression module</param>
        /// <param name="stroke">Newly decoded stroke</param>
        /// <returns></returns>
#else
        /// <summary>
        /// Loads a stroke from the stream based on Stroke Descriptor, StylusPointDescription, Drawing Attributes, Stroke IDs, transform and GuidList
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="size"></param>
        /// <param name="guidList"></param>
        /// <param name="strokeDescriptor"></param>
        /// <param name="stylusPointDescription"></param>
        /// <param name="drawingAttributes"></param>
        /// <param name="transform"></param>
        /// <param name="stroke">Newly decoded stroke</param>
#endif
        internal static uint DecodeStroke(Stream stream,
                                          uint size,
                                          GuidList guidList,
                                          StrokeDescriptor strokeDescriptor,
                                          StylusPointDescription stylusPointDescription,
                                          DrawingAttributes drawingAttributes,
                                          Matrix transform,
#if OLD_ISF
                                          Compressor compressor,
#endif
                                          out Stroke stroke)
        {
            ExtendedPropertyCollection extendedProperties;
            StylusPointCollection      stylusPoints;

            uint cb = DecodeISFIntoStroke(
#if OLD_ISF
                compressor,
#endif
                stream,
                size,
                guidList,
                strokeDescriptor,
                stylusPointDescription,
                transform,
                out stylusPoints,
                out extendedProperties);

            if (cb != size)
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Stroke size (" +
                                                                                       cb.ToString(System.Globalization.CultureInfo.InvariantCulture) + ") != expected (" +
                                                                                       size.ToString(System.Globalization.CultureInfo.InvariantCulture) + ")"));
            }

            stroke = new Stroke(stylusPoints, drawingAttributes, extendedProperties);

            return(cb);
        }
예제 #4
0
        /// <summary>
        /// Loads a stroke from the stream based on Stroke Descriptor, StylusPointDescription, Drawing Attributes, Stroke IDs, transform and GuidList
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="size"></param>
        /// <param name="guidList"></param>
        /// <param name="strokeDescriptor"></param>
        /// <param name="stylusPointDescription"></param>
        /// <param name="drawingAttributes"></param>
        /// <param name="transform"></param>
        /// <param name="stroke">Newly decoded stroke</param>
#endif
        internal static uint DecodeStroke(Stream stream,
                                 uint size,
                                 GuidList guidList,
                                 StrokeDescriptor strokeDescriptor,
                                 StylusPointDescription stylusPointDescription,
                                 DrawingAttributes drawingAttributes,
                                 Matrix transform,
#if OLD_ISF
                                 Compressor compressor,
#endif
                                 out Stroke stroke)
        {
            ExtendedPropertyCollection extendedProperties;
            StylusPointCollection stylusPoints;

            uint cb = DecodeISFIntoStroke(
#if OLD_ISF
                compressor, 
#endif 
                stream, 
                size, 
                guidList, 
                strokeDescriptor, 
                stylusPointDescription, 
                transform, 
                out stylusPoints, 
                out extendedProperties);

            if (cb != size)
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Stroke size (" +
                    cb.ToString(System.Globalization.CultureInfo.InvariantCulture) + ") != expected (" + 
                    size.ToString(System.Globalization.CultureInfo.InvariantCulture) + ")"));
            }

            stroke = new Stroke(stylusPoints, drawingAttributes, extendedProperties);

            return cb;
        }
예제 #5
0
        /// <summary>
        /// Builds the Stroke Descriptor for this stroke based on Packet Layout and Extended Properties
        /// For details on how this is strored please refer to the spec.
        /// </summary>
        internal static void BuildStrokeDescriptor(
            Stroke stroke,
            GuidList guidList,
            StrokeCollectionSerializer.StrokeLookupEntry strokeLookupEntry,
            out StrokeDescriptor strokeDescriptor,
            out MetricBlock metricBlock)
        {
            // Initialize the metric block for this stroke
            metricBlock = new MetricBlock();

            // Clear any existing template
            strokeDescriptor = new StrokeDescriptor();

            // Uninitialized variable passed in AddMetricEntry
            MetricEntryType        metricEntryType;
            StylusPointDescription stylusPointDescription = stroke.StylusPoints.Description;

            KnownTagCache.KnownTagIndex tag = guidList.FindTag(KnownIds.X, true);
            metricEntryType = metricBlock.AddMetricEntry(stylusPointDescription.GetPropertyInfo(StylusPointProperties.X), tag);

            tag             = guidList.FindTag(KnownIds.Y, true);
            metricEntryType = metricBlock.AddMetricEntry(stylusPointDescription.GetPropertyInfo(StylusPointProperties.Y), tag);

            ReadOnlyCollection <StylusPointPropertyInfo> propertyInfos
                = stylusPointDescription.GetStylusPointProperties();

            int i = 0; //i is defined out of the for loop so we can use it later for buttons

            for (i = 2 /*past x,y*/; i < propertyInfos.Count; i++)
            {
                if (i == /*StylusPointDescription.RequiredPressureIndex //修复构建的代码 */ 2 &&
                    !strokeLookupEntry.StorePressure)
                {
                    //
                    // don't store pressure information
                    //
                    continue;
                }
                StylusPointPropertyInfo propertyInfo = propertyInfos[i];
                if (propertyInfo.IsButton)
                {
                    //we don't serialize buttons
                    break;
                }

                tag = guidList.FindTag(propertyInfo.Id, true);

                strokeDescriptor.Template.Add(tag);
                strokeDescriptor.Size += SerializationHelper.VarSize((uint)tag);

                // Create the MetricEntry for this property if necessary
                metricEntryType = metricBlock.AddMetricEntry(propertyInfo, tag);
            }

            /*
             * we drop button data on the floor.
             * int buttonCount = stylusPointDescription.ButtonCount;
             * // Now write the button tags in the Template
             * if (buttonCount > 0)
             * {
             *  // First write the TAG_BUTTONS
             *  strokeDescriptor.Template.Add(KnownTagCache.KnownTagIndex.Buttons);
             *  strokeDescriptor.Size += SerializationHelper.VarSize((uint)KnownTagCache.KnownTagIndex.Buttons);
             *
             *  // Next write the i of buttons
             *  strokeDescriptor.Template.Add((KnownTagCache.KnownTagIndex)buttonCount);
             *  strokeDescriptor.Size += SerializationHelper.VarSize((uint)buttonCount);
             *
             *  //we broke above on i when it was a button, it still
             *  //points to the first button
             *  for (; i < propertyInfos.Count; i++)
             *  {
             *      StylusPointPropertyInfo propertyInfo = propertyInfos[i];
             *      tag = guidList.FindTag(propertyInfo.Id, false);
             *
             *      strokeDescriptor.Template.Add(tag);
             *      strokeDescriptor.Size += SerializationHelper.VarSize((uint)tag);
             *  }
             * }
             */

            // Now write the extended properties in the template
            if (stroke.ExtendedProperties.Count > 0)
            {
                strokeDescriptor.Template.Add(KnownTagCache.KnownTagIndex.StrokePropertyList);
                strokeDescriptor.Size += SerializationHelper.VarSize((uint)KnownTagCache.KnownTagIndex.StrokePropertyList);

                // Now write the tags corresponding to each extended properties of the stroke
                for (int x = 0; x < stroke.ExtendedProperties.Count; x++)
                {
                    tag = guidList.FindTag(stroke.ExtendedProperties[(int)x].Id, false);

                    strokeDescriptor.Template.Add(tag);
                    strokeDescriptor.Size += SerializationHelper.VarSize((uint)tag);
                }
            }
        }
예제 #6
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="compressor"></param>
        /// <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>
        /// <returns></returns>
#else
        /// <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);
        }
예제 #7
0
    /// <summary>
    /// Reads and Decodes a stroke descriptor information from the stream. For details on how it is stored
    /// please refer the spec
    /// </summary>
    /// <param name="strm"></param>
    /// <param name="cbSize"></param>
    /// <param name="descr"></param>
    /// <returns></returns>
    private uint DecodeStrokeDescriptor(Stream strm, uint cbSize, out StrokeDescriptor descr)
    {
        descr = new StrokeDescriptor();
        if (0 == cbSize)
            return 0;

        uint cb;
        uint cbBlock = cbSize;

        while (cbBlock > 0)
        {
            // first read the tag
            KnownTagCache.KnownTagIndex tag;
            uint uiTag;

            cb = SerializationHelper.Decode(strm, out uiTag);
            tag = (KnownTagCache.KnownTagIndex)uiTag;
            if (cb > cbBlock)
                throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),"strm");

            cbBlock -= cb;
            descr.Template.Add(tag);

            // If this is TAG_BUTTONS
            if (KnownTagCache.KnownTagIndex.Buttons == tag && cbBlock > 0)
            {
                uint cbButton;

                // Read the no. of buttons first
                cb = SerializationHelper.Decode(strm, out cbButton);
                if (cb > cbBlock)
                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),"strm");

                cbBlock -= cb;
                descr.Template.Add((KnownTagCache.KnownTagIndex)cbButton);
                while (cbBlock > 0 && cbButton > 0)
                {
                    uint dw;

                    cb = SerializationHelper.Decode(strm, out dw);
                    if (cb > cbBlock)
                        throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),"strm");

                    cbBlock -= cb;
                    cbButton--;
                    descr.Template.Add((KnownTagCache.KnownTagIndex)dw);
                }
            }
            else if (KnownTagCache.KnownTagIndex.StrokePropertyList == tag && cbBlock > 0)
            {
                // Usually stroke property comes last in the template. Hence everything below this is
                // are Tags for strokes extended properties
                while (cbBlock > 0)
                {
                    uint dw;

                    cb = SerializationHelper.Decode(strm, out dw);
                    if (cb > cbBlock)
                        throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),"strm");

                    cbBlock -= cb;
                    descr.Template.Add((KnownTagCache.KnownTagIndex)dw);
                }
            }
            }

            if (0 != cbBlock)
                throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),"strm");

            return cbSize;
        }
예제 #8
0
        /// <summary>
        /// Multibyte Encodes a Stroke Descroptor
        /// </summary>
        /// <param name="strm"></param>
        /// <param name="strd"></param>
        /// <returns></returns>
        private uint EncodeStrokeDescriptor(Stream strm, StrokeDescriptor strd)
        {
            uint cbData = 0;

            // First encode the size of the descriptor
            cbData += SerializationHelper.Encode(strm, strd.Size);
            for (int count = 0; count < strd.Template.Count; count++)
            {
                // Now encode all members of the descriptor
                cbData += SerializationHelper.Encode(strm, (uint)strd.Template[count]);
            }

            return cbData;
        }
예제 #9
0
        /// <summary>
        /// Builds StylusPointDescription based on StrokeDescriptor and Metric Descriptor Block. Sometime Metric Descriptor block may contain
        /// metric information for properties which are not part of the stroke descriptor. They are simply ignored.
        /// </summary>
        /// <param name="strd"></param>
        /// <param name="block"></param>
        /// <param name="guidList"></param>
        /// <returns></returns>
        private StylusPointDescription BuildStylusPointDescription(StrokeDescriptor strd, MetricBlock block, GuidList guidList)
        {
            int cTags = 0;
            int packetPropertyCount = 0;
            uint buttonCount = 0;
            Guid[] buttonguids = null;
            System.Collections.Generic.List<KnownTagCache.KnownTagIndex> tags = null;

            // if strd is null, it means there is only default descriptor with X & Y
            if (null != strd)
            {
                tags = new System.Collections.Generic.List<KnownTagCache.KnownTagIndex>();
                while (cTags < strd.Template.Count)
                {
                    KnownTagCache.KnownTagIndex tag = (KnownTagCache.KnownTagIndex)strd.Template[cTags];

                    if (KnownTagCache.KnownTagIndex.Buttons == tag)
                    {
                        cTags++;

                        // The next item in the array is no of buttongs.
                        buttonCount = (uint)strd.Template[cTags];
                        cTags++;

                        // Currently we skip the the no of buttons as buttons is not implimented yet
                        buttonguids = new Guid[buttonCount];
                        for (uint u = 0; u < buttonCount; u++)
                        {
                            Guid guid = guidList.FindGuid(strd.Template[cTags]);
                            if (guid == Guid.Empty)
                            {
                                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Button guid tag embedded in ISF stream does not match guid table"),"strd");
                            }

                            buttonguids[(int)u] = guid;
                            cTags++;
                        }
                    }
                    else if (KnownTagCache.KnownTagIndex.StrokePropertyList == tag)
                    {
                        break; // since no more Packet properties can be stored
                    }
                    else
                    {
                        if (KnownTagCache.KnownTagIndex.NoX == tag ||
                            KnownTagCache.KnownTagIndex.NoY == tag)
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF with NoX or NoY specified"), "strd");
                        }

                        tags.Add(strd.Template[cTags]);
                        packetPropertyCount++;
                        cTags++;
                    }
                }
            }


            List<StylusPointPropertyInfo> stylusPointPropertyInfos = new List<StylusPointPropertyInfo>();
            stylusPointPropertyInfos.Add(GetStylusPointPropertyInfo(KnownIds.X, (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.X), block));
            stylusPointPropertyInfos.Add(GetStylusPointPropertyInfo(KnownIds.Y, (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.Y), block));
            stylusPointPropertyInfos.Add(GetStylusPointPropertyInfo(KnownIds.NormalPressure, (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.NormalPressure), block));

            int pressureIndex = -1;
            if (tags != null)
            {
                for (int i = 0; i < tags.Count; i++)
                {
                    Guid guid = guidList.FindGuid(tags[i]);
                    if (guid == Guid.Empty)
                    {
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Packet Description Property tag embedded in ISF stream does not match guid table"), "strd");
                    }
                    if (pressureIndex == -1 && guid == StylusPointPropertyIds.NormalPressure)
                    {
                        pressureIndex = i + 2; //x,y have already been accounted for
                        continue; //we've already added pressure (above)
                    }

                    stylusPointPropertyInfos.Add(GetStylusPointPropertyInfo(guid, tags[i], block));
                }

                if (null != buttonguids)
                {
                    //
                    // add the buttons to the end of the description if they exist
                    //
                    for (int i = 0; i < buttonguids.Length; i++)
                    {
                        StylusPointProperty buttonProperty = new StylusPointProperty(buttonguids[i], true);
                        StylusPointPropertyInfo buttonInfo = new StylusPointPropertyInfo(buttonProperty);
                        stylusPointPropertyInfos.Add(buttonInfo);
                    }
                }
            }

            return new StylusPointDescription(stylusPointPropertyInfos, pressureIndex);
        }
예제 #10
0
        /// <summary>
        /// Builds the Stroke Descriptor for this stroke based on Packet Layout and Extended Properties
        /// For details on how this is strored please refer to the spec.
        /// </summary>
        internal static void BuildStrokeDescriptor(
            Stroke stroke, 
            GuidList guidList, 
            StrokeCollectionSerializer.StrokeLookupEntry strokeLookupEntry,
            out StrokeDescriptor strokeDescriptor, 
            out MetricBlock metricBlock)
        {
            // Initialize the metric block for this stroke
            metricBlock = new MetricBlock();

            // Clear any existing template
            strokeDescriptor = new StrokeDescriptor();

            // Uninitialized variable passed in AddMetricEntry
            MetricEntryType metricEntryType;
            StylusPointDescription stylusPointDescription = stroke.StylusPoints.Description;

            KnownTagCache.KnownTagIndex tag = guidList.FindTag(KnownIds.X, true);
            metricEntryType = metricBlock.AddMetricEntry(stylusPointDescription.GetPropertyInfo(StylusPointProperties.X), tag);

            tag = guidList.FindTag(KnownIds.Y, true);
            metricEntryType = metricBlock.AddMetricEntry(stylusPointDescription.GetPropertyInfo(StylusPointProperties.Y), tag);

            ReadOnlyCollection<StylusPointPropertyInfo> propertyInfos
                = stylusPointDescription.GetStylusPointProperties();

            int i = 0; //i is defined out of the for loop so we can use it later for buttons
            for (i = 2/*past x,y*/; i < propertyInfos.Count; i++)
            {
                if (i == StylusPointDescription.RequiredPressureIndex/*2*/ && 
                    !strokeLookupEntry.StorePressure)
                {
                    //
                    // don't store pressure information
                    //
                    continue;
                }
                StylusPointPropertyInfo propertyInfo = propertyInfos[i];
                if (propertyInfo.IsButton)
                {
                    //we don't serialize buttons
                    break;
                }

                tag = guidList.FindTag(propertyInfo.Id, true);

                strokeDescriptor.Template.Add(tag);
                strokeDescriptor.Size += SerializationHelper.VarSize((uint)tag);

                // Create the MetricEntry for this property if necessary
                metricEntryType = metricBlock.AddMetricEntry(propertyInfo, tag);
            }

            /*
            we drop button data on the floor.  See Windows OS Bugs 1413460 for details
            int buttonCount = stylusPointDescription.ButtonCount;
            // Now write the button tags in the Template
            if (buttonCount > 0)
            {
                // First write the TAG_BUTTONS
                strokeDescriptor.Template.Add(KnownTagCache.KnownTagIndex.Buttons);
                strokeDescriptor.Size += SerializationHelper.VarSize((uint)KnownTagCache.KnownTagIndex.Buttons);

                // Next write the i of buttons
                strokeDescriptor.Template.Add((KnownTagCache.KnownTagIndex)buttonCount);
                strokeDescriptor.Size += SerializationHelper.VarSize((uint)buttonCount);

                //we broke above on i when it was a button, it still
                //points to the first button
                for (; i < propertyInfos.Count; i++)
                {
                    StylusPointPropertyInfo propertyInfo = propertyInfos[i];
                    tag = guidList.FindTag(propertyInfo.Id, false);

                    strokeDescriptor.Template.Add(tag);
                    strokeDescriptor.Size += SerializationHelper.VarSize((uint)tag);
                }
            }
            */

            // Now write the extended properties in the template
            if (stroke.ExtendedProperties.Count > 0)
            {
                strokeDescriptor.Template.Add(KnownTagCache.KnownTagIndex.StrokePropertyList);
                strokeDescriptor.Size += SerializationHelper.VarSize((uint)KnownTagCache.KnownTagIndex.StrokePropertyList);

                // Now write the tags corresponding to each extended properties of the stroke
                for (int x = 0; x < stroke.ExtendedProperties.Count; x++)
                {
                    tag = guidList.FindTag(stroke.ExtendedProperties[(int)x].Id, false);

                    strokeDescriptor.Template.Add(tag);
                    strokeDescriptor.Size += SerializationHelper.VarSize((uint)tag);
                }
            }
        }
예제 #11
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;
        }