Ejemplo n.º 1
0
        /// <summary>
        /// Retrieve the packet description, packets data and XFORM which is the information the native recognizer needs.
        /// The method is called from AddStrokes.
        /// </summary>
        private void GetPacketData
        (
            Stroke stroke,
            out MS.Win32.Recognizer.PACKET_DESCRIPTION packetDescription,
            out int countOfBytes,
            out IntPtr packets,
            out NativeMethods.XFORM xForm
        )
        {
            int i;

            countOfBytes      = 0;
            packets           = IntPtr.Zero;
            packetDescription = new MS.Win32.Recognizer.PACKET_DESCRIPTION();
            Matrix matrix = Matrix.Identity;

            xForm = new NativeMethods.XFORM((float)(matrix.M11), (float)(matrix.M12), (float)(matrix.M21),
                                            (float)(matrix.M22), (float)(matrix.OffsetX), (float)(matrix.OffsetY));

            StylusPointCollection stylusPoints = stroke.StylusPoints;

            if (stylusPoints.Count == 0)
            {
                return; //we'll fail when the calling routine sees that packets is IntPtr.Zer
            }

            if (stylusPoints.Description.PropertyCount > StylusPointDescription.RequiredCountOfProperties)
            {
                //
                // reformat to X, Y, P
                //
                StylusPointDescription reformatDescription
                    = new StylusPointDescription(
                          new StylusPointPropertyInfo[] {
                    new StylusPointPropertyInfo(StylusPointProperties.X),
                    new StylusPointPropertyInfo(StylusPointProperties.Y),
                    stylusPoints.Description.GetPropertyInfo(StylusPointProperties.NormalPressure)
                });
                stylusPoints = stylusPoints.Reformat(reformatDescription);
            }

            //
            // now make sure we only take a finite amount of data for the stroke
            //
            if (stylusPoints.Count > MaxStylusPoints)
            {
                stylusPoints = stylusPoints.Clone(MaxStylusPoints);
            }

            Guid[] propertyGuids = new Guid[] { StylusPointPropertyIds.X,                //required index for SPD
                                                StylusPointPropertyIds.Y,                //required index for SPD
                                                StylusPointPropertyIds.NormalPressure }; //required index for SPD

            Debug.Assert(stylusPoints != null);
            Debug.Assert(propertyGuids.Length == StylusPointDescription.RequiredCountOfProperties);

            // Get the packet description
            packetDescription.cbPacketSize      = (uint)(propertyGuids.Length * Marshal.SizeOf(typeof(Int32)));
            packetDescription.cPacketProperties = (uint)propertyGuids.Length;

            //
            // use X, Y defaults for metrics, sometimes mouse metrics can be bogus
            // always use NormalPressure metrics, though.
            //
            StylusPointPropertyInfo[] infosToUse = new StylusPointPropertyInfo[StylusPointDescription.RequiredCountOfProperties];
            infosToUse[StylusPointDescription.RequiredXIndex]        = StylusPointPropertyInfoDefaults.X;
            infosToUse[StylusPointDescription.RequiredYIndex]        = StylusPointPropertyInfoDefaults.Y;
            infosToUse[StylusPointDescription.RequiredPressureIndex] =
                stylusPoints.Description.GetPropertyInfo(StylusPointProperties.NormalPressure);

            MS.Win32.Recognizer.PACKET_PROPERTY[] packetProperties =
                new MS.Win32.Recognizer.PACKET_PROPERTY[packetDescription.cPacketProperties];

            StylusPointPropertyInfo propertyInfo;

            for (i = 0; i < packetDescription.cPacketProperties; i++)
            {
                packetProperties[i].guid = propertyGuids[i];
                propertyInfo             = infosToUse[i];

                MS.Win32.Recognizer.PROPERTY_METRICS propertyMetrics = new MS.Win32.Recognizer.PROPERTY_METRICS( );
                propertyMetrics.nLogicalMin         = propertyInfo.Minimum;
                propertyMetrics.nLogicalMax         = propertyInfo.Maximum;
                propertyMetrics.Units               = (int)(propertyInfo.Unit);
                propertyMetrics.fResolution         = propertyInfo.Resolution;
                packetProperties[i].PropertyMetrics = propertyMetrics;
            }

            unsafe
            {
                int allocationSize = (int)(Marshal.SizeOf(typeof(MS.Win32.Recognizer.PACKET_PROPERTY)) * packetDescription.cPacketProperties);
                packetDescription.pPacketProperties = Marshal.AllocCoTaskMem(allocationSize);
                MS.Win32.Recognizer.PACKET_PROPERTY *pPacketProperty =
                    (MS.Win32.Recognizer.PACKET_PROPERTY *)(packetDescription.pPacketProperties.ToPointer());
                MS.Win32.Recognizer.PACKET_PROPERTY *pElement = pPacketProperty;
                for (i = 0; i < packetDescription.cPacketProperties; i++)
                {
                    Marshal.StructureToPtr(packetProperties[i], new IntPtr(pElement), false);
                    pElement++;
                }
            }

            // Get packet data
            int[] rawPackets  = stylusPoints.ToHiMetricArray();
            int   packetCount = rawPackets.Length;

            if (packetCount != 0)
            {
                countOfBytes = packetCount * Marshal.SizeOf(typeof(Int32));
                packets      = Marshal.AllocCoTaskMem(countOfBytes);
                Marshal.Copy(rawPackets, 0, packets, packetCount);
            }
        }