/// <summary>
        /// Loads a single ExtendedProperty from the stream and add that to the list. Tag may be passed as in
        /// the case of Stroke ExtendedPropertyCollection where tag is stored in the stroke descriptor or 0 when tag
        /// is embeded in the stream
        /// </summary>
        /// <param name="stream">Memory buffer to load from</param>
        /// <param name="cbSize">Maximum length of buffer to read</param>
        /// <param name="guidList">Guid cache to read from</param>
        /// <param name="tag">Guid tag to lookup</param>
        /// <param name="guid">Guid of property</param>
        /// <param name="data">Data of property</param>
        /// <returns>Length of buffer read</returns>
#endif
        internal static uint DecodeAsISF(Stream stream, uint cbSize, GuidList guidList, KnownTagCache.KnownTagIndex tag, ref Guid guid, out object data)
        {
            uint cb, cbRead = 0;
            uint cbTotal = cbSize;

            if (0 == cbSize)
            {
                throw new InvalidOperationException(SR.Get(SRID.EmptyDataToLoad));
            }

            if (0 == tag) // no tag is passed, it must be embedded in the data
            {
                uint uiTag;
                cb = SerializationHelper.Decode(stream, out uiTag);
                tag = (KnownTagCache.KnownTagIndex)uiTag;
                if (cb > cbTotal)
                    throw new ArgumentException(SR.Get(SRID.InvalidSizeSpecified), "cbSize");

                cbTotal -= cb;
                cbRead += cb;
                System.Diagnostics.Debug.Assert(guid == Guid.Empty);
                guid = guidList.FindGuid(tag);
            }

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

            // Try and find the size
            uint size = GuidList.GetDataSizeIfKnownGuid(guid);

            if (size > cbTotal)
                throw new ArgumentException(SR.Get(SRID.InvalidSizeSpecified), "cbSize");

            // if the size is 0
            if (0 == size)
            {
                // Size must be embedded in the stream. Find out the compressed data size
                cb = SerializationHelper.Decode(stream, out size);

                uint cbInsize = size + 1;

                cbRead += cb;
                cbTotal -= cb;
                if (cbInsize > cbTotal)
                    throw new ArgumentException();

                byte[] bytes = new byte[cbInsize];

                uint bytesRead = (uint) stream.Read(bytes, 0, (int)cbInsize);
                if (cbInsize != bytesRead)
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Read different size from stream then expected"), "cbSize");
                }

                cbRead += cbInsize;
                cbTotal -= cbInsize;

		        //Find out the Decompressed buffer size
                using (MemoryStream decompressedStream = new MemoryStream(Compressor.DecompressPropertyData(bytes)))
                {
                    // Add the property
                    data = ExtendedPropertySerializer.DecodeAttribute(guid, decompressedStream);
                }
            }
            else
            {
                // For known size data, we just read the data directly from the stream
                byte[] bytes = new byte[size];

                uint bytesRead = (uint) stream.Read(bytes, 0, (int)size);
                if (size != bytesRead)
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Read different size from stream then expected"), "cbSize");
                }

                using (MemoryStream subStream = new MemoryStream(bytes))
                {
                    data = ExtendedPropertySerializer.DecodeAttribute(guid, subStream);
                }

                cbTotal -= size;
                cbRead +=  size;
            }

            return cbRead;
        }
Beispiel #2
0
 public MetricEntryList (KnownTagCache.KnownTagIndex tag, StylusPointPropertyInfo prop)
 {
     Tag = tag;
     PropertyMetrics = prop;
 }
Beispiel #3
0
        /// <summary>
        /// Adds a new metric entry in the existing list of metric entries
        /// </summary>
        /// <param name="property"></param>
        /// <param name="tag"></param>
        /// <returns></returns>
        public MetricEntryType AddMetricEntry(StylusPointPropertyInfo property, KnownTagCache.KnownTagIndex tag)
        {
            // Create a new metric entry based on the packet information passed.
            MetricEntry entry = new MetricEntry();
            MetricEntryType type = entry.CreateMetricEntry(property, tag);

            // Don't add this entry to the global list if size is 0, means default metric values!
            if( 0 == entry.Size )
            {
                return type;
            }

            MetricEntry start = _Entry;
            if( null == start )
            {
                _Entry = entry;
            }
            else    // tack on data at the end, want to keep x,y at the beginning
            {
                while(start.Next != null)
                {
                    start = start.Next;
                }
                start.Next = entry;
            }
            _Count++;
            _size += entry.Size + SerializationHelper.VarSize(entry.Size) + SerializationHelper.VarSize((uint)_Entry.Tag);
            return type;
        }
Beispiel #4
0
        /// <summary>
        /// Creates a metric entry based on a PropertyInfo and Tag and returns the Metric Entry Type created
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="tag"></param>
        /// <returns></returns>
        public MetricEntryType CreateMetricEntry(StylusPointPropertyInfo propertyInfo, KnownTagCache.KnownTagIndex tag)
        {
            // First create the default Metric entry based on the property and type of metric entry and then use that to initialize the
            // metric entry data.
            uint index = 0;
            Tag = tag;

            MetricEntryType type;
            if( IsValidMetricEntry(propertyInfo, Tag, out type, out index) )
            {
                switch(type)
                {
                    case MetricEntryType.Optional:
                    {
                        Initialize(propertyInfo, MetricEntry_Optional[index].PropertyMetrics);
                        break;
                    }
                    case MetricEntryType.Must :
                    case MetricEntryType.Custom:
                        Initialize(propertyInfo, DefaultPropertyMetrics);
                        break;
                    default:
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("MetricEntryType was persisted with Never flag which should never happen"));
                }
            }
            return type;
        }
Beispiel #5
0
        /// <summary>
        /// This function checks if this packet property results in a valid metric entry. This will be a valid entry if
        /// 1. it is a custom property, 2. Does not belong to the global list of gaMetricEntry_Never, 3. Belongs to the
        /// global list of gaMetricEntry_Must and 4. Belongs to global list of gaMetricEntry_Optional and at least one of
        /// its metric values is different from the corresponding default.
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="tag"></param>
        /// <param name="metricEntryType"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        
        static bool IsValidMetricEntry(StylusPointPropertyInfo propertyInfo, KnownTagCache.KnownTagIndex tag, out MetricEntryType metricEntryType, out uint index)
        {
            index = 0;
            // If this is a custom property, check if all the Metric values are null or not. If they are then this is not a 
            // valid metric entry
            if (tag >= (KnownTagCache.KnownTagIndex)KnownIdCache.CustomGuidBaseIndex)
            {
                metricEntryType = MetricEntryType.Custom;
                if( Int32.MinValue == propertyInfo.Minimum &&
                    Int32.MaxValue == propertyInfo.Maximum &&
                    StylusPointPropertyUnit.None == propertyInfo.Unit &&
                    DoubleUtil.AreClose(1.0, propertyInfo.Resolution) )
                    return false;
                else
                    return true;
            }
            else
            {
                int ul;
                // First find the property in the gaMetricEntry_Never. If it belongs to this list,
                // we will never write the metric table for this prop. So return FALSE;
                for( ul = 0; ul < MetricEntry_Never.Length ; ul++ )
                {
                    if( MetricEntry_Never[ul] == tag )
                    {
                        metricEntryType = MetricEntryType.Never;
                        return false;
                    }
                }

                // Then search the property in the gaMetricEntry_Must list. If it belongs to this list,
                // we must always write the metric table for this prop. So return TRUE;
                for( ul = 0; ul<MetricEntry_Must.Length; ul++ )
                {
                    if( MetricEntry_Must[ul] == tag )
                    {
                        metricEntryType = MetricEntryType.Must;
                        if( propertyInfo.Minimum == DefaultPropertyMetrics.Minimum &&
                            propertyInfo.Maximum == DefaultPropertyMetrics.Maximum &&
                            propertyInfo.Unit == DefaultPropertyMetrics.Unit &&
                            DoubleUtil.AreClose(propertyInfo.Resolution, DefaultPropertyMetrics.Resolution ))
                            return false;
                        else
                            return true;
                    }
                }

                // Now seach it in the gaMetricEntry_Optional list. If it is there, check the metric values
                // agianst the default values and if there is any non default value, return TRUE;
                for( ul = 0; ul<MetricEntry_Optional.Length; ul++ )
                {
                    if( ((MetricEntryList)MetricEntry_Optional[ul]).Tag == tag )
                    {
                        metricEntryType = MetricEntryType.Optional;
                        if( propertyInfo.Minimum == MetricEntry_Optional[ul].PropertyMetrics.Minimum &&
                            propertyInfo.Maximum == MetricEntry_Optional[ul].PropertyMetrics.Maximum &&
                            propertyInfo.Unit == MetricEntry_Optional[ul].PropertyMetrics.Unit &&
                            DoubleUtil.AreClose(propertyInfo.Resolution, MetricEntry_Optional[ul].PropertyMetrics.Resolution) )
                            return false;
                        else
                        {
                            index = (uint)ul;
                            return true;
                        }
                    }
                }
                // it is not found in any of the list. Force to write all metric entries for the property.
                metricEntryType = MetricEntryType.Must;
                return true;
            }
        }
        /// <summary>
        /// Sets the Property Metrics for a property based on Tag and metric descriptor block
        /// </summary>
        /// <param name="guid"></param>
        /// <param name="tag"></param>
        /// <param name="block"></param>
        /// <returns></returns>
        private StylusPointPropertyInfo GetStylusPointPropertyInfo(Guid guid, KnownTagCache.KnownTagIndex tag, MetricBlock block)
        {
            int dw = 0;
            bool fSetDefault = false;
            uint cbEntry;
            // StylusPointPropertyInfo values that we need to read in.
            int minimum = 0;
            int maximum = 0;
            StylusPointPropertyUnit unit = StylusPointPropertyUnit.None;
            float resolution = 1.0f;

            // To begin with initialize the property metrics with respective default valuses
            // first check if this property belongs to optional list
            for (dw = 0; dw < 11; dw++)
            {
                if (MetricEntry.MetricEntry_Optional[dw].Tag == tag)
                {
                    minimum = MetricEntry.MetricEntry_Optional[dw].PropertyMetrics.Minimum;
                    maximum = MetricEntry.MetricEntry_Optional[dw].PropertyMetrics.Maximum;
                    resolution = MetricEntry.MetricEntry_Optional[dw].PropertyMetrics.Resolution;
                    unit = MetricEntry.MetricEntry_Optional[dw].PropertyMetrics.Unit;
                    fSetDefault = true;
                    break;
                }
            }

            if (false == fSetDefault)
            {
                // We will come here if the property is not found in the Optional List
                // All other cases, we will have only default values
                minimum = Int32.MinValue;
                maximum = Int32.MaxValue;
                unit = StylusPointPropertyUnit.None;
                resolution = 1.0f;
                fSetDefault = true;
            }

            // Now see if there is a valid MetricBlock. If there is one, update the PROPERTY_METRICS with
            // values from this Block
            if (null != block)
            {
                MetricEntry entry = block.GetMetricEntryList();

                while (null != entry)
                {
                    if (entry.Tag == tag)
                    {
                        cbEntry = 0;

                        int range;

                        using (MemoryStream strm = new MemoryStream(entry.Data))
                        {
                            // Decoded the Logical Min
                            cbEntry += SerializationHelper.SignDecode(strm, out range);
                            if (cbEntry >= entry.Size)
                            {
                                break; // return false;
                            }

                            minimum = range;

                            // Logical Max
                            cbEntry += SerializationHelper.SignDecode(strm, out range);
                            if (cbEntry >= entry.Size)
                            {
                                break; // return false;
                            }

                            maximum = range;

                            uint cb;

                            // Units
                            cbEntry += SerializationHelper.Decode(strm, out cb);
                            unit = (StylusPointPropertyUnit)cb;
                            if (cbEntry >= entry.Size)
                            {
                                break; // return false;
                            }

                            using (BinaryReader br = new BinaryReader(strm))
                            {
                                resolution = br.ReadSingle();
                                cbEntry += Native.SizeOfFloat;
                            }
                        }

                        break;
                    }

                    entry = entry.Next;
                }
            }

            // return a new StylusPointPropertyInfo
            return new StylusPointPropertyInfo( new StylusPointProperty(guid, StylusPointPropertyIds.IsKnownButton(guid)),
                                                minimum,
                                                maximum,
                                                unit,
                                                resolution);
        }
        /// <summary>
        /// Reads and Decodes a Transfrom Descriptor Block from the stream. For information on how it is stored in the stream,
        /// please refer to the spec.
        /// </summary>
        /// <param name="strm"></param>
        /// <param name="tag"></param>
        /// <param name="cbSize"></param>
        /// <param name="useDoubles"></param>
        /// <param name="xform"></param>
        /// <returns></returns>
        private uint DecodeTransformBlock(Stream strm, KnownTagCache.KnownTagIndex tag, uint cbSize, bool useDoubles, out TransformDescriptor xform)
        {
            xform = new TransformDescriptor();
            xform.Tag = tag;

            uint cbRead = 0;
            uint cbTotal = cbSize;

            if (0 == cbSize)
                return 0;

            // samgeo - Presharp issue
            // Presharp gives a warning when local IDisposable variables are not closed
            // in this case, we can't call Dispose since it will also close the underlying stream
            // which still needs to be read from
#pragma warning disable 1634, 1691
#pragma warning disable 6518
            BinaryReader bw = new BinaryReader(strm);

            if (KnownTagCache.KnownTagIndex.TransformRotate == tag)
            {
                uint angle;

                cbRead = SerializationHelper.Decode(strm, out angle);
                if (cbRead > cbSize)
                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),"strm");


                xform.Transform[0] = (double)angle;
                xform.Size = 1;
            }
            else
            {
                if (tag == KnownTagCache.KnownTagIndex.TransformIsotropicScale)
                {
                    xform.Size = 1;
                }
                else if (tag == KnownTagCache.KnownTagIndex.TransformAnisotropicScale || tag == KnownTagCache.KnownTagIndex.TransformTranslate)
                {
                    xform.Size = 2;
                }
                else if (tag == KnownTagCache.KnownTagIndex.TransformScaleAndTranslate)
                {
                    xform.Size = 4;
                }
                else
                {
                    xform.Size = 6;
                }

                if (useDoubles)
                {
                    cbRead = xform.Size * Native.SizeOfDouble;
                }
                else
                {
                    cbRead = xform.Size * Native.SizeOfFloat;
                }

                if (cbRead > cbSize)
                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),"strm");


                for (int i = 0; i < xform.Size; i++)
                {
                    if (useDoubles)
                    {
                        xform.Transform[i] = bw.ReadDouble();
                    }
                    else
                    {
                        xform.Transform[i] = (double)bw.ReadSingle();
                    }
                }
            }

            return cbRead;
#pragma warning restore 6518
#pragma warning restore 1634, 1691
        }
Beispiel #8
0
        /// <summary>
        /// Finds a guid based on Tag 
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public Guid FindGuid(KnownTagCache.KnownTagIndex tag) 
        {
            if (tag < (KnownTagCache.KnownTagIndex)KnownIdCache.CustomGuidBaseIndex) 
            { 
                Guid guid = FindKnownGuid(tag);
 
                if (Guid.Empty != guid)
                    return guid;

                return FindCustomGuid(tag); 
            }
            else 
            { 
                Guid guid = FindCustomGuid(tag);
 
                if (Guid.Empty != guid)
                    return guid;

                return FindKnownGuid(tag); 
            }
        } 
Beispiel #9
0
        /// <summary>
        /// Finds a Custom Guid based on a Tag
        /// </summary> 
        /// <param name="tag"></param>
        /// <returns></returns> 
        Guid FindCustomGuid(KnownTagCache.KnownTagIndex tag) 
        {
            if ((int)tag < (int)KnownIdCache.CustomGuidBaseIndex) 
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Tag is outside of the known guid tag range"));
            }
 
            // Get the index in the OriginalISFIdTable array first
            int nIndex = (int)(tag - KnownIdCache.CustomGuidBaseIndex); 
 
            // If invalid, return Guid.Empty
            if ((0 > nIndex) || (_CustomGuids.Count <= nIndex)) 
                return Guid.Empty;

            // Otherwise, return the guid
            return (Guid)_CustomGuids[(int)nIndex]; 
        }
Beispiel #10
0
        /// <summary>
        /// Finds a known guid based on a Tag 
        /// </summary> 
        /// <param name="tag"></param>
        /// <returns></returns> 
        static Guid FindKnownGuid(KnownTagCache.KnownTagIndex tag)
        {
            if (tag < KnownIdCache.KnownGuidBaseIndex)
            { 
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Tag is outside of the known guid tag range"));
            } 
 
            // Get the index in the OriginalISFIdTable array first
            uint nIndex = (uint)(tag - KnownIdCache.KnownGuidBaseIndex); 

            // If invalid, return Guid.Empty
            if (KnownIdCache.OriginalISFIdTable.Length <= nIndex)
                return Guid.Empty; 

            // Otherwise, return the guid 
            return KnownIdCache.OriginalISFIdTable[nIndex]; 
        }