Ejemplo n.º 1
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);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Saves the packets into a stream of bytes
        /// </summary>
        /// <param name="stroke">Stroke to save</param>
        /// <param name="stream">null to calculate size only</param>
        /// <param name="strokeLookupEntry"></param>
#endif
        static uint SavePackets(
            Stroke stroke,
            Stream stream, 
#if OLD_ISF
            Compressor compressor,
#endif
            StrokeCollectionSerializer.StrokeLookupEntry strokeLookupEntry)
        {
            // First write or calculate how many points are there
            uint pointCount = (uint)stroke.StylusPoints.Count;
            uint localBytesWritten = (stream != null) ? SerializationHelper.Encode(stream, pointCount) : SerializationHelper.VarSize(pointCount);
            byte compressionAlgorithm;

            int[][] outputArrays = strokeLookupEntry.ISFReadyStrokeData;
            //We don't serialize button data, see Windows OS Bugs 1413460 for details
            //int valuesPerPoint = stroke.StylusPoints.Description.GetOutputArrayLengthPerPoint();
            //int buttonCount = stroke.StylusPoints.Description.ButtonCount;
            
            ReadOnlyCollection<StylusPointPropertyInfo> propertyInfos
                = stroke.StylusPoints.Description.GetStylusPointProperties();

            int i = 0;
            for (; i < propertyInfos.Count; i++)
            {
                StylusPointPropertyInfo propertyInfo = propertyInfos[i];
                if (i == 2 && !strokeLookupEntry.StorePressure)
                {
                    //
                    // only store pressure if we need to
                    //
                    continue;
                }
                if (propertyInfo.IsButton)
                {
                    //
                    // we're at the buttons, handle this below
                    //
                    break;
                }
                compressionAlgorithm = strokeLookupEntry.CompressionData;
                localBytesWritten += SavePacketPropertyData(outputArrays[i], 
                                                            stream,
#if OLD_ISF
                                                            compressor, 
#endif
                                                            propertyInfo.Id, 
                                                            ref compressionAlgorithm);
            }

            /*
            We don't serialize button data, see Windows OS Bugs 1413460 for details
            // Now write all button data. Button data is stored as if it is another packet property
            // with size (cbuttoncount + 7)/8 bytes and corresponding guids are stored in the packet
            // description. Button data is only stored if buttons are present in the description and there
            // are packets in the stroke
            if (buttonCount > 0 && pointCount > 0)
            {
                Debug.Assert(i == valuesPerPoint - 1);
                BitStreamWriter bitWriter = new BitStreamWriter();
                //
                // Get the array of button data (i is still pointing at it)
                //
                int[] buttonData = outputArrays[i];

                for (int x = 0; x < pointCount; x++)
                {
                    //
                    // each int in the button data array contains buttonCount number
                    // of bits that need to be written to the BitStreamWriter
                    // the BitStreamWriter takes bytes at a time.  We always write the most
                    // signifigant bits first
                    //
                    int uncompactedButtonDataForPoint = buttonData[x];

                    // calculate the number of full bytes used for buttons per packet
                    //   Example: 10 buttons would require 1 full byte
                    //            but 8 would require 
                    int fullBytesForButtonsPerPacket = buttonCount / Native.BitsPerByte;

                    // calculate the number of bits that spill beyond the full byte boundary
                    //   Example: 10 buttons would require 2 extra bits (8 fit in a full byte)
                    int bitsToWrite = buttonCount % Native.BitsPerByte;

                    for (; fullBytesForButtonsPerPacket >= 0; fullBytesForButtonsPerPacket--)
                    {
                        byte byteOfButtonData = 
                            Convert.ToByte(uncompactedButtonDataForPoint >> (fullBytesForButtonsPerPacket * Native.BitsPerByte));
                        //
                        // write 8 or less bytes to the bitwriter
                        // checking for 0 handles the case where we're writing 8, 16 or 24 bytes
                        // and bitsToWrite is initialize to zero
                        //
                        if (bitsToWrite > 0)
                        {
                            bitWriter.Write(byteOfButtonData, bitsToWrite);
                        }
                        if (fullBytesForButtonsPerPacket > 0)
                        {
                            bitsToWrite = Native.BitsPerByte;
                        }
                    }
                }

                // retrieve the button bytes
                byte[] packedButtonData = bitWriter.ToBytes();

                if (packedButtonData.Length !=
                    ((buttonCount * pointCount + 7) / Native.BitsPerByte))
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Packed button length not equal to expected length"));
                }

                // write out the packed button data to the output stream
                stream.Write(packedButtonData, 0, packedButtonData.Length);
                localBytesWritten += (uint)packedButtonData.Length;
            }
            */

            return localBytesWritten;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns an array of bytes of the saved stroke
        /// </summary>
        /// <param name="stroke">Stroke to save</param>
        /// <param name="stream">null to calculate only the size</param>
        /// <param name="compressionAlgorithm"></param>
        /// <param name="guidList"></param>
        /// <param name="strokeLookupEntry"></param>
#endif
        internal static uint EncodeStroke(
            Stroke stroke, 
            Stream stream, 
#if OLD_ISF
            Compressor compressor, 
#endif
            byte compressionAlgorithm, 
            GuidList guidList,
            StrokeCollectionSerializer.StrokeLookupEntry strokeLookupEntry)
        {
            uint cbWrite = SavePackets( stroke, 
                                        stream, 
#if OLD_ISF
                                        compressor, 
#endif
                                        strokeLookupEntry);

            if (stroke.ExtendedProperties.Count > 0)
                cbWrite += ExtendedPropertySerializer.EncodeAsISF(stroke.ExtendedProperties, stream, guidList, compressionAlgorithm, false);

            return cbWrite;
        }