Пример #1
0
        //
        //

        /// <summary>
        /// This function compares pMetricColl with the current one. If pMetricColl has more entries apart from the one
        /// in the current list with which some of its entries are identical, setType is set as SUPERSET.
        /// </summary>
        /// <param name="metricColl"></param>
        /// <param name="setType"></param>
        /// <returns></returns>
        public bool CompareMetricBlock( MetricBlock metricColl, ref SetType setType)
        {
            if( null == metricColl )
                return false;

            // if both have null entry, implies default metric Block for both of them 
            // and it already exists in the list. Return TRUE
            // If only one of the blocks is empty, return FALSE - they cannot be merged 
            // because the other block may have customized GUID_X or GUID_Y.

            if (null == GetMetricEntryList())
                return (metricColl.GetMetricEntryList() == null);
            
            if (null == metricColl.GetMetricEntryList()) 
                return false;

            // Else compare the entries

            bool  fTagFound = false;
            uint cbLhs = this.MetricEntryCount;    // No of entries in this block
            uint cbRhs = metricColl.MetricEntryCount;   // No of entries in the block to be compared

            MetricEntry outside, inside;
            if( metricColl.MetricEntryCount <= MetricEntryCount )
            {
                outside = metricColl.GetMetricEntryList();
                inside  = GetMetricEntryList();
            }
            else
            {
                inside   = metricColl.GetMetricEntryList();
                outside  = GetMetricEntryList();
                setType   = SetType.SuperSet;
            }

            // For each entry in metricColl, search for the same in this Block. 
            // If it is found, continue with the next entry of smaller Block. 
            while( null != outside )
            {
                fTagFound = false;
                // Always start at the begining of the larger block
                MetricEntry temp = inside;
                while( null != temp )
                {
                    if( outside.Compare(temp) )
                    {
                        fTagFound = true;
                        break;
                    }
                    else
                        temp = temp.Next;
                }
                if( !fTagFound )
                    return false;

                // Found the entry; Continue with the next entry in the outside block
                outside = outside.Next;
            }

            return true;
        }
Пример #2
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);
                }
            }
        }
Пример #3
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);
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        /// <summary>
        /// Decodes a Metric Block from the stream. For information on how they are stored in the stream, please refer to the spec.
        /// </summary>
        /// <param name="strm"></param>
        /// <param name="cbSize"></param>
        /// <param name="block"></param>
        /// <returns></returns>
        private uint DecodeMetricBlock(Stream strm, uint cbSize, out MetricBlock block)
        {
            // allocate the block
            block = new MetricBlock();
            if (cbSize == 0)
                return 0;

            uint cb;
            uint cbTotal = cbSize;
            uint size;

            while (cbTotal > 0)
            {
                // First decode the tag for this entry
                uint dw;

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


                cbTotal -= cb;

                // Next read the size of the metric data
                cb = SerializationHelper.Decode(strm, out size);
                if (cb + size > cbTotal)
                    throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),"strm");


                cbTotal -= cb;

                // now create new metric entry
                MetricEntry entry = new MetricEntry();

                entry.Tag = (KnownTagCache.KnownTagIndex)dw;

                byte[] data = new byte[size];

                uint bytesRead = StrokeCollectionSerializer.ReliableRead(strm, data, size);
                cbTotal -= bytesRead;

                if ( bytesRead != size )
                {
                    // Make sure the bytes read are expected. If not, we should bail out.
                    // An exception will be thrown.
                    break;
                }

                entry.Data = data;
                block.AddMetricEntry(entry);

            }

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


            return cbSize;
        }
Пример #6
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);
                }
            }
        }
        //
        //

        /// <summary>
        /// This function compares pMetricColl with the current one. If pMetricColl has more entries apart from the one
        /// in the current list with which some of its entries are identical, setType is set as SUPERSET.
        /// </summary>
        /// <param name="metricColl"></param>
        /// <param name="setType"></param>
        /// <returns></returns>
        public bool CompareMetricBlock(MetricBlock metricColl, ref SetType setType)
        {
            if (null == metricColl)
            {
                return(false);
            }

            // if both have null entry, implies default metric Block for both of them
            // and it already exists in the list. Return TRUE
            // If only one of the blocks is empty, return FALSE - they cannot be merged
            // because the other block may have customized GUID_X or GUID_Y.

            if (null == GetMetricEntryList())
            {
                return(metricColl.GetMetricEntryList() == null);
            }

            if (null == metricColl.GetMetricEntryList())
            {
                return(false);
            }

            // Else compare the entries

            bool fTagFound = false;
            uint cbLhs     = this.MetricEntryCount;       // No of entries in this block
            uint cbRhs     = metricColl.MetricEntryCount; // No of entries in the block to be compared

            MetricEntry outside, inside;

            if (metricColl.MetricEntryCount <= MetricEntryCount)
            {
                outside = metricColl.GetMetricEntryList();
                inside  = GetMetricEntryList();
            }
            else
            {
                inside  = metricColl.GetMetricEntryList();
                outside = GetMetricEntryList();
                setType = SetType.SuperSet;
            }

            // For each entry in metricColl, search for the same in this Block.
            // If it is found, continue with the next entry of smaller Block.
            while (null != outside)
            {
                fTagFound = false;
                // Always start at the begining of the larger block
                MetricEntry temp = inside;
                while (null != temp)
                {
                    if (outside.Compare(temp))
                    {
                        fTagFound = true;
                        break;
                    }
                    else
                    {
                        temp = temp.Next;
                    }
                }
                if (!fTagFound)
                {
                    return(false);
                }

                // Found the entry; Continue with the next entry in the outside block
                outside = outside.Next;
            }

            return(true);
        }