예제 #1
0
        /// <summary>
        /// Receive stroke for Presenter 1.
        /// </summary>
        /// <param name="bc"></param>
        private void ReceiveStroke(BufferChunk bc)
        {
            BinaryFormatter formatter    = new BinaryFormatter();
            MemoryStream    memoryStream = new MemoryStream(bc.Buffer, 1, bc.Length - 1);
            int             slideIndex   = (int)formatter.Deserialize(memoryStream);

            if (this.SlideDeck != null && slideIndex >= 0)
            {
                InkScribble s = (InkScribble)this.SlideDeck.GetOverlay(slideIndex).Scribble;

                // Restore the bytes to ink.
                byte[] bytes = new byte[memoryStream.Length - memoryStream.Position];
                memoryStream.Read(bytes, 0, bytes.Length);

                Ink.Ink ink = new Ink.Ink();
                ink.Load(bytes);

                // Delete the previous version of this stroke if necessary.
                foreach (Ink.Stroke stroke in ink.Strokes)
                {
                    if (stroke.ExtendedProperties.DoesPropertyExist(GUID_TAG))
                    {
                        Ink.Stroke foundStroke;
                        bool       found = FastFindStrokeFromGuid(s,
                                                                  new Guid((string)stroke.ExtendedProperties[GUID_TAG].Data),
                                                                  out foundStroke, GUID_TAG);
                        if (found)
                        {
                            s.Ink.DeleteStroke(foundStroke);
                        }
                    }
                }

                lock (this) {
                    Rectangle r = ink.Strokes.GetBoundingBox();
                    r.X      = (int)(r.X * XinkScaleFactor);
                    r.Y      = (int)(r.Y * YinkScaleFactor);
                    r.Width  = (int)(r.Width * XinkScaleFactor);
                    r.Height = (int)(r.Height * YinkScaleFactor);
                    s.Ink.AddStrokesAtRectangle(ink.Strokes, r);

                    // Make note of the ink's strokes in the guidtable.
                    // ASSUME that these strokes went on the end.
                    int sCount   = s.Ink.Strokes.Count;
                    int newCount = ink.Strokes.Count;
                    for (int i = sCount - newCount; i < sCount; i++)
                    {
                        Ink.Stroke stroke = s.Ink.Strokes[i];
                        if (stroke.ExtendedProperties.Contains(GUID_TAG))
                        {
                            Guid guid = new Guid((string)stroke.ExtendedProperties[GUID_TAG].Data);
                            this.myGuidTable[new ScribbleIntPair(s, stroke.Id)] = guid;
                            this.myGuidReverseTable[guid] = new ScribbleIntPair(s, stroke.Id);
                        }
                    }
                }
            }
        }
예제 #2
0
        public override void SerializePoints(Stream stream, int numPoints)
        {
            IFormatter formatter = new BinaryFormatter();

            // Calculate the number of strokes to serialize
            int index     = this.myInk.Strokes.Count;
            int countLeft = numPoints;

            while (countLeft > 0 && index > 0)
            {
                index--;
                countLeft -= this.myInk.Strokes[index].GetPoints().Length;
            }
            // Index is now -1 or the first stroke to send.
            if (index < 0)
            {
                index = 0;
            }

            if (countLeft < 0)
            {
                countLeft += this.myInk.Strokes[index].GetPoints().Length;
            }

            // If there is a partial stroke, serialize it specially
            if (countLeft > 0)
            {
                formatter.Serialize(stream, true);                 // Flag that there is a partial stroke.
            }
            else
            {
                formatter.Serialize(stream, false);                 // Flag that there is no partial stroke.
            }
            // Serialize just a zero (length) for an empty scribble.
            if (this.myInk.Strokes.Count - index == 0)
            {
                formatter.Serialize(stream, 0);
            }
            else
            {
                // Serialize all remaining strokes completely
                Ink.Ink ink = new Ink.Ink();
                int[]   ids = new int[this.myInk.Strokes.Count - index];
                for (int i = index; i < this.myInk.Strokes.Count; i++)
                {
                    ids[i - index] = this.myInk.Strokes[i].Id;
                }
                // Note: AddStrokesAtRectangle is used since the documentation for AddStrokes
                // states that the strokes must *already* be in the ink object (so, it's only
                // used for updating custom strokes collections??).
                Ink.Strokes strokes = this.myInk.CreateStrokes(ids);
                ink.AddStrokesAtRectangle(strokes, strokes.GetBoundingBox());
                byte[] inkBytes = ink.Save();
                formatter.Serialize(stream, inkBytes.Length);
                stream.Write(inkBytes, 0, inkBytes.Length);
            }
        }
예제 #3
0
        /// <summary>
        /// Find Stroke from Guid
        /// </summary>
        /// The original version was much too slow for the archive replay scenario.
        /// <param name="scribble"></param>
        /// <param name="guid"></param>
        /// <param name="stroke"></param>
        /// <param name="guidTag"></param>
        /// <returns></returns>
        private bool FastFindStrokeFromGuid(InkScribble scribble, Guid guid, out Ink.Stroke stroke, Guid guidTag)
        {
            Ink.Ink ink = scribble.Ink;

            if (this.myGuidReverseTable.Contains(guid))
            {
                if (((ScribbleIntPair)this.myGuidReverseTable[guid]).scribble == scribble)
                {
                    ScribbleIntPair pair = (ScribbleIntPair)this.myGuidReverseTable[guid];

                    /// The count can be zero right after a clear slide or clear deck operation
                    /// if count is zero, CreateStrokes will except.
                    if (pair.scribble.Count == 0)
                    {
                        stroke = null;
                        return(false);
                    }

                    Ink.Strokes targetStrokes = null;
                    try
                    {
                        targetStrokes = ink.CreateStrokes(new int[] { pair.id });
                    }
                    catch (Exception e)
                    {                     //not clear when this would happen?
                        stroke = null;
                        Trace.WriteLine("FastFindStrokeFromGuid: Exception during CreateStrokes: " + e.ToString());
                        return(false);
                    }

                    if (targetStrokes.Count < 1)                     //not clear when this would happen?
                    {
                        stroke = null;
                        Trace.WriteLine("FastFindStrokeFromGuid: Found target with zero stroke count.");
                        return(false);
                    }

                    // Found it.
                    stroke = targetStrokes[0];
                    return(true);
                }
                else
                {                   //This happens when we revisit slides we've been on previously
                    this.myGuidReverseTable.Remove(guid);
                    stroke = null;
                    return(false);
                }
            }
            else
            {
                stroke = null;
                return(false);
            }
        }
예제 #4
0
        /// <summary>
        /// Receive Presenter2 stroke
        /// </summary>
        /// <param name="drawStroke"></param>
        public void ReceiveStroke(ArchiveRTNav.RTDrawStroke drawStroke)
        {
            int slideIndex;

            slideIndex = slideMap.GetMapping(drawStroke.SlideIndex, drawStroke.DeckGuid);
            InkScribble s = (InkScribble)this.SlideDeck.GetOverlay(slideIndex).Scribble;

            Ink.Stroke foundStroke;
            bool       found = FastFindStrokeFromGuid(s, drawStroke.Guid, out foundStroke, NEW_GUID_TAG);

            if (found)
            {
                s.Ink.DeleteStroke(foundStroke);
            }

            Ink.Ink ink = drawStroke.Ink;

            lock (this) {
                Rectangle r = ink.Strokes.GetBoundingBox();
                r.X      = (int)(r.X * XinkScaleFactor);
                r.Y      = (int)(r.Y * YinkScaleFactor);
                r.Width  = (int)(r.Width * XinkScaleFactor);
                r.Height = (int)(r.Height * YinkScaleFactor);
                s.Ink.AddStrokesAtRectangle(ink.Strokes, r);

                // Make note of the ink's strokes in the guidtable.
                // ASSUME that these strokes went on the end.
                int sCount   = s.Ink.Strokes.Count;
                int newCount = ink.Strokes.Count;
                for (int i = sCount - newCount; i < sCount; i++)
                {
                    Ink.Stroke stroke = s.Ink.Strokes[i];
                    if (stroke.ExtendedProperties.Contains(NEW_GUID_TAG))
                    {
                        Guid guid = Guid.Empty;
                        try {   //Saw this except once.  Couldn't repro.  Suspect corrupted data.
                            guid = new Guid((string)stroke.ExtendedProperties[NEW_GUID_TAG].Data);
                        }
                        catch {
                            continue;
                        }
                        this.myGuidTable[new ScribbleIntPair(s, stroke.Id)] = guid;
                        this.myGuidReverseTable[guid] = new ScribbleIntPair(s, stroke.Id);
                    }
                }
            }
        }
예제 #5
0
        public override void DeserializePoints(Stream stream)
        {
            // Check if there was a partial stroke; if so, delete the current last stroke.
            IFormatter formatter = new BinaryFormatter();
            bool       partial   = (bool)formatter.Deserialize(stream);

            if (partial)
            {
                if (this.myInk.Strokes.Count == 0)
                {
                    System.Diagnostics.Debug.WriteLine("no partial stroke to delete", "WARNING");
                }
                else
                {
                    this.myInk.DeleteStroke(this.myInk.Strokes[this.myInk.Strokes.Count - 1]);
                }
            }

            // Deserialize all remaining strokes.
            int length = (int)formatter.Deserialize(stream);

            if (length > 0)
            {
                byte[] inkBytes = new byte[length];
                stream.Read(inkBytes, 0, length);
                Ink.Ink ink = new Ink.Ink();
                ink.Load(inkBytes);
                // Note: AddStrokesAtRectangle is used since the documentation for AddStrokes
                // states that the strokes must *already* be in the ink object (so, it's only
                // used for updating custom strokes collections??).
                if (ink.Strokes.Count > 0)
                {
                    this.myInk.AddStrokesAtRectangle(ink.Strokes, ink.Strokes.GetBoundingBox());
                }
            }

            foreach (Ink.Stroke stroke in this.myInk.Strokes)
            {
                this.OnStroke(new NumericEventArgs(stroke.Id));
            }
        }
예제 #6
0
 public InkScribble()
 {
     myInk = new Ink.Ink();
     Initialize();
 }
예제 #7
0
        private bool FindStrokeFromGuid(InkScribble scribble, Guid guid, out Ink.Stroke stroke, Guid guidTag)
        {
            Ink.Ink ink = scribble.Ink;

            // Check if the guid tables are out of date. This might be indicated by either:
            // * The guid is not in the reverse table.
            // * The reverse table entry's scribble does not match the given scribble.
            // If the tables are out of date, update the entries for this scribble object.
            if (!this.myGuidReverseTable.Contains(guid) ||
                ((ScribbleIntPair)this.myGuidReverseTable[guid]).scribble != scribble)
            {
                // Ensure that, at the least, the stale entry is removed.
                this.myGuidReverseTable.Remove(guid);

                // Refresh entries for all strokes in this scribble.
                foreach (Ink.Stroke s in ink.Strokes)
                {
                    try
                    {
                        if (s.ExtendedProperties.DoesPropertyExist(guidTag))
                        {
                            Guid strokeGuid = new Guid((string)s.ExtendedProperties[guidTag].Data);
                            this.myGuidReverseTable[strokeGuid] = new ScribbleIntPair(scribble, s.Id);
                            this.myGuidTable[new ScribbleIntPair(scribble, s.Id)] = strokeGuid;
                        }
                    }
                    catch
                    {
                        //this try/catch because I once saw an exception thrown here.  Not sure if it was a bug
                        // in the data, the TPC SDK, or in my code..  Anyway it seemed safe to ignore.
                    }
                }
            }

            // If the guid is still not in the table, it is not found.
            if (!this.myGuidReverseTable.Contains(guid))
            {
                stroke = null;
                return(false);
            }

            // Can we find the specific id sought?
            ScribbleIntPair pair = (ScribbleIntPair)this.myGuidReverseTable[guid];

            //This try/catch is a hack to deal with multiple-play (archive) scenario.
            //I believe the real fix is to catch WMP stop and postion change events and
            //to rebuild guid tables and InkScribble appropriately for the new media position.
            Ink.Strokes targetStrokes = null;
            try
            {
                targetStrokes = ink.CreateStrokes(new int[] { pair.id });
            }
            catch
            {
                stroke = null;
                return(false);
            }

            if (targetStrokes.Count < 1)
            {
                stroke = null;
                return(false);
            }

            // Found it.
            stroke = targetStrokes[0];
            return(true);
        }