public bool RecognizeUseCase(Strokes inkStrokes)
        {
            if (inkStrokes.Count == 1)
            {
                StrokeInfo strokeInfo1 = new StrokeInfo(inkStrokes[0]);

                if (strokeInfo1.StrokeStatistics.StartEndProximity < CLOSED_PROXIMITY &&
                    strokeInfo1.StrokeStatistics.Square < 0.85 && strokeInfo1.StrokeStatistics.Diagonal > 0.13)
                    return true;
                else
                    return false;
            }
            else
                return false;
        }
示例#2
0
        /// <summary>
        /// Populates the stroke objects in an Ink Overlay object using the
        /// substrokes in a sketch object
        /// </summary>
        /// <param name="sketch">Sketch containing substrokes to convert</param>
        private void FillInkOverlay(Strokes strokes)
        {
            _OverlayInk.Ink.DeleteStrokes();
            foreach (Stroke s in strokes)
            {
                _OverlayInk.Ink.CreateStroke(s.GetPoints());
            }

            // Move center the ink's origin to the top-left corner
            Rectangle bb = _OverlayInk.Ink.GetBoundingBox();

            _InkMovedX = 0.0f;
            _InkMovedY = 0.0f;
            _Scale     = 1.0f;

            ScaleAndMoveInk();
            this.InkPanel.Refresh();
        }
示例#3
0
        private void UpdateStrokes()
        {
            App.Current.Dispatcher.Invoke(() =>
            {
                // Do we need a lock here?
                IsRefreshingStrokes = true;
                var newStrokes      = new StrokeCollection(StrokeCollection.GetMergedStrokeMaps());

                Strokes.Clear();
                Strokes.Add(newStrokes);

                if (EditingMode == InkCanvasEditingMode.Select)
                {
                    SelectionChanged?.Invoke(SelectedStrokes);
                }
                IsRefreshingStrokes = false;
            });
        }
示例#4
0
        protected override void OnStrokeCollected(InkCanvasStrokeCollectedEventArgs E)
        {
            void AddCustomStroke(Stroke CustomStroke)
            {
                Strokes.Remove(E.Stroke);

                // Remove two history items
                if (DataContext is ImageEditorViewModel vm)
                {
                    vm.RemoveLastHistory();
                    vm.RemoveLastHistory();
                }

                Strokes.Add(CustomStroke);

                var args = new InkCanvasStrokeCollectedEventArgs(CustomStroke);

                base.OnStrokeCollected(args);
            }

            switch (DynamicRenderer)
            {
            case LineDynamicRenderer _:
                AddCustomStroke(new Stroke(new StylusPointCollection(new []
                {
                    E.Stroke.StylusPoints.First(),
                    E.Stroke.StylusPoints.Last()
                }), E.Stroke.DrawingAttributes));
                break;

            case RectangleDynamicRenderer _:
                AddCustomStroke(new RectangleStroke(E.Stroke.StylusPoints, E.Stroke.DrawingAttributes));
                break;

            case EllipseDynamicRenderer _:
                AddCustomStroke(new EllipseStroke(E.Stroke.StylusPoints, E.Stroke.DrawingAttributes));
                break;

            default:
                base.OnStrokeCollected(E);
                break;
            }
        }
示例#5
0
        /// <summary>
        /// 清空
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (!ic.CollectingInk)
            {
                Strokes strokesToDelete = ic.Ink.Strokes;
                ic.Ink.DeleteStrokes(strokesToDelete);
                ic.Ink.DeleteStrokes(); //清除手写区域笔画;
                ink_here.Refresh();     //刷新手写区域

                richTextBox1.Clear();

                signPoints = new List <StylusPoint>();
                strokes    = new StrokeCollection();
                strokeColl = new StylusPointCollection();
                bpoint     = new string[3] {
                    "0", "0", "0"
                };
            }
        }
        /// <summary>
        /// Event Handle from Action->Clear menu.
        /// </summary>
        /// <param name="sender">The control that raised the event.</param>
        /// <param name="e">The event arguments.</param>
        private void miClear_Click(object sender, System.EventArgs e)
        {
            Strokes strokesToDelete = myInkCollector.Ink.Strokes;

            // Check to ensure that the ink collector isn't currently
            // in the middle of a stroke before clearing the ink.
            // Deleting a stroke that is currently being collected
            // will result in an error condition.
            if (!myInkCollector.CollectingInk)
            {
                myInkCollector.Ink.DeleteStrokes(strokesToDelete);

                miInk_Click(sender, e);
            }
            else
            {
                MessageBox.Show("Cannot clear ink while the ink collector is busy.");
            }
        }
示例#7
0
    private void hover_EditDeleteClicked(object sender, EventArgs e)
    {
        Strokes doomed = inkoverlay.Selection;

        if (doomed == null || doomed.Count != 1)
        {
            return;
        }

        // Simply delegate to the UI handler for deleting strokes.
        this.inkoverlay_StrokesDeleting(this,
                                        new InkOverlayStrokesDeletingEventArgs(doomed));

        // Now, actually delete the strokes, too.
        doc.Ink.DeleteStrokes(doomed);

        // Clear the selection rectangle.
        inkoverlay.Selection = EmptyStrokes;
    }
示例#8
0
        public RTStroke(Guid documentIdentifier, Guid pageIdentifier, Stroke stroke, object extension)
        {
            DocumentIdentifier = documentIdentifier;
            PageIdentifier     = pageIdentifier;
            Extension          = extension;

            if (!stroke.ExtendedProperties.DoesPropertyExist(ExtendedPropertyStrokeIdentifier))
            {
                stroke.ExtendedProperties.Add(ExtendedPropertyStrokeIdentifier, Guid.NewGuid().ToString());
            }

            int[] strokeIds = new int[1];
            strokeIds[0] = stroke.Id;
            Strokes ourStroke = stroke.Ink.CreateStrokes(strokeIds);

            Ink fromInk = stroke.Ink;

            ink = fromInk.ExtractStrokes(ourStroke, ExtractFlags.CopyFromOriginal);
        }
        /// <summary>
        /// Event Handle from Paint event.  It is necessary to handle the
        /// paint event since this sample needs to draw red points to indicate
        /// the strokes' cusps.
        /// </summary>
        /// <param name="sender">The control that raised the event.</param>
        /// <param name="e">The event arguments.</param>
        private void InkErase_OnPaint(object sender, PaintEventArgs e)
        {
            // Get the strokes to paint from the ink
            Strokes strokesToPaint = myInkCollector.Ink.Strokes;

            // Draw the strokes - note that it is necessary to manually
            // paint the strokes since auto-redrawing is set to false.
            myInkCollector.Renderer.Draw(e.Graphics, strokesToPaint);

            switch (mode)
            {
            case ApplicationMode.CuspErase:
                PaintCusps(e.Graphics, strokesToPaint);
                break;

            case ApplicationMode.IntersectErase:
                PaintIntersections(e.Graphics, strokesToPaint);
                break;
            }
        }
示例#10
0
        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
            base.TouchesEnded(touches, evt);

            if (!Enabled)
            {
                return;
            }

            var loc = (touches.AnyObject as UITouch).LocationInView(this);

            CurrentStroke.Points.Add(new Point(loc.X, loc.Y));
            CurrentPathView.AddLineTo(loc);

            Strokes.Add(CurrentStroke);
            drawPath();

            CurrentPathView.Clear();
            SetNeedsDisplay();
        }
示例#11
0
        private void btnRecognition_Click(object sender, EventArgs e)
        {
            string inkPadValue = ic.Ink.Strokes.ToString();

            if (!ic.CollectingInk)
            {
                Strokes strokesToDelete = ic.Ink.Strokes;
                rct.StopBackgroundRecognition();
                ic.Ink.DeleteStrokes(strokesToDelete);
                rct.Strokes = ic.Ink.Strokes;
                ic.Ink.DeleteStrokes();//清除手写区域笔画;
                PicInkPad.Refresh();
            }
            InkWritingEventArgs ev = new InkWritingEventArgs(inkPadValue);

            if (UserHandWriting != null)
            {
                UserHandWriting(this, ev);
            }
        }
示例#12
0
        public DrawingRoomViewModel(Chat chat)
        {
            this.chat              = chat;
            strokes                = new StrokeCollection();
            chat.OnStrokeRecieved += StrokeHandle;

            NewStrokeCommand = new RelayCommand(x =>
            {
                var stroke = Strokes.LastOrDefault();
                Strokes.Remove(stroke);
                chat.Send(stroke);
                //MessageBox.Show(stroke?.ToString());
            });

            InkCanvasDrawingAttributes        = new DrawingAttributes();
            InkCanvasDrawingAttributes.Color  = Color.FromArgb(255, 0, 0, 0);
            InkCanvasDrawingAttributes.Height = 3;
            InkCanvasDrawingAttributes.Width  = 3;
            OnPropertyChanged("InkCanvasDrawingAttributes");
        }
示例#13
0
        private void HandleInkDeleting(object sender, StrokesEventArgs e)
        {
            using (Synchronizer.Lock(this.m_Ignore.SyncRoot)) {
                if (this.m_Ignore.Contains(e))
                {
                    this.m_Ignore.Remove(e);
                    return;
                }
            }

            // Make a copy of the strokes that were removed.  This must be done immediately
            // or the strokes _will_not_ exist by the time we need them.
            Strokes strokes = this.m_InkSheet.Ink.CreateStrokes(e.StrokeIds);

            SetStrokeIds(strokes);
            Ink ink = this.m_InkSheet.Ink.ExtractStrokes(strokes, ExtractFlags.CopyFromOriginal);

            this.m_EventQueue.Post(delegate() {
                this.m_HandleInkChangedDelegate(sender, ink.Strokes, false);
            });
        }
示例#14
0
        private void DeleteInsideRectangle(Stroke s, Rectangle r, InkCollectorGestureEventArgs e)
        {
            // Se buscan los strokes que tengan al menos un 60% en el boundingbox
            Strokes borrarStrokes =
                ink_overlay.Ink.HitTest(r, 60);

            // Si se encuentra algo, se borran los strokes afectados
            if (borrarStrokes.Count > 0)
            {
                // El stroke del scratchout no se maneja mas
                e.Cancel = true;

                // Se borran los strokes afectados
                ink_overlay.Ink.DeleteStrokes(borrarStrokes);

                // Se borra el stroke del scratchout
                ink_overlay.Ink.DeleteStrokes(e.Strokes);

                Refresh();
            }
        }
        /// <summary>
        /// Helper method that performs a hit test using the specified point.
        /// It deletes all strokes that were hit by the point
        /// </summary>
        /// <param name="pt">The point to use for hit testing</param>
        private void EraseStrokes(Point pt, Stroke currentStroke)
        {
            // Use HitTest to find the collection of strokes that are intersected
            // by the point.  The HitTestRadius constant is used to specify the
            // radius of the hit test circle in ink space coordinates (1 unit = .01mm).
            Strokes strokesHit = myInkCollector.Ink.HitTest(pt, HitTestRadius);

            if (null != currentStroke && strokesHit.Contains(currentStroke))
            {
                strokesHit.Remove(currentStroke);
            }

            // Delete all strokes that were hit by the point
            myInkCollector.Ink.DeleteStrokes(strokesHit);

            if (strokesHit.Count > 0)
            {
                // Repaint the screen to reflect the change
                this.Refresh();
            }
        }
示例#16
0
    private void hover_EditCloneClicked(object sender, EventArgs e)
    {
        Strokes selected = inkoverlay.Selection;

        if (selected == null || selected.Count != 1)
        {
            return;
        }

        // Get objects for the targeted stroke(s).  Ensure that only one is selected.
        RigidBodyBase[] bodies = doc.GetBodiesFor(selected);
        if (bodies.Length != 1)
        {
            return;
        }

        RigidBodyBase body = bodies[0];

        // First, clone the ink stroke.  Move it down and to the right a bit.
        Rectangle newrect = selected.GetBoundingBox();

        newrect.Offset(1000, 1000);
        doc.Ink.AddStrokesAtRectangle(selected, newrect);

        // Next, clone the body, binding it to the new stroke id.
        // Note: we got the new Strokes' ids by listening to the InkAdded event
        // AddStrokesAtRectangle doesn't return the strokes' ids.
        RigidBodyBase newbody = body.Clone(neweststrokeids[0]);

        doc.Bodies.Add(newbody);

        // Repaint the area around the newbody.
        Rectangle dirtybbox = newbody.BoundingBox;

        InvalidateInkSpaceRectangle(dirtybbox);

        // Select it, to show the smart tag.
        inkoverlay.Selection = doc.Ink.CreateStrokes(neweststrokeids);
    }
        public bool RecognizeActor(Strokes inkStrokes)
        {
            if (inkStrokes.Count >= 4)
            {
                StrokeInfo strokeInfo1 = new StrokeInfo(inkStrokes[0]);
                StrokeInfo strokeInfo2 = new StrokeInfo(inkStrokes[1]);

                if (strokeInfo1.StrokeStatistics.StartEndProximity < CLOSED_PROXIMITY &&
                   strokeInfo1.StrokeStatistics.Square < 0.85 && strokeInfo1.StrokeStatistics.Diagonal > 0.15)
                {
                    if (strokeInfo2.StrokeStatistics.StartEndProximity > CLOSED_PROXIMITY &&
                        strokeInfo2.StrokeStatistics.Square > 0.9 && strokeInfo2.StrokeStatistics.Diagonal < 0.2)
                        return true;
                    else
                        return false;
                }
                else
                    return false;
            }
            else
                return false;
        }
示例#18
0
        private List <GraphicsPath> InkToGraphicsPaths(bool scalePath)
        {
            Renderer renderer = _overlay.Renderer;
            Strokes  strokes  = _overlay.Ink.Strokes;

            float scaleX = _originalImage.Width / (float)pbImage.Width;
            float scaleY = _originalImage.Height / (float)pbImage.Height;

            if (strokes.Count > 0)
            {
                using (Graphics g = CreateGraphics())
                {
                    List <GraphicsPath> paths = new List <GraphicsPath>(strokes.Count);
                    foreach (Stroke stroke in strokes)
                    {
                        Point[] points = stroke.GetPoints();
                        if (points.Length >= 3)
                        {
                            for (int i = 0; i < points.Length; i++)
                            {
                                renderer.InkSpaceToPixel(g, ref points[i]);
                                if (scalePath)
                                {
                                    points[i] = new Point(
                                        (int)(scaleX * points[i].X),
                                        (int)(scaleY * points[i].Y));
                                }
                            }
                            GraphicsPath path = new GraphicsPath();
                            path.AddPolygon(points);
                            path.CloseFigure();
                            paths.Add(path);
                        }
                    }
                    return(paths);
                }
            }
            return(null);
        }
        /// <summary>
        /// Undo edit actions performed
        /// </summary>
        internal void Undo()
        {
            int index = undoActions.Count - 1;

            if (index < 0)
            {
                return;
            }
            if (undoActions[index] == InkCanvasEditingMode.Ink)
            {
                Strokes.RemoveAt(Strokes.Count - 1);
            }
            else if (undoActions[index] == InkCanvasEditingMode.EraseByStroke)
            {
                Strokes.Add(undoStrokes[index]);
            }
            else if (undoActions[index] == InkCanvasEditingMode.None)
            {
                for (int i = 0; i < index; i++)
                {
                    if (undoActions[i] == InkCanvasEditingMode.Ink)
                    {
                        Strokes.Add(undoStrokes[i]);
                    }
                    else if (undoActions[i] == InkCanvasEditingMode.EraseByStroke)
                    {
                        Strokes.Remove(undoStrokes[i]);
                    }
                    else if (undoActions[i] == InkCanvasEditingMode.None)
                    {
                        Strokes.Clear();
                    }
                }
            }
            redoActions.Add(undoActions[index]);
            redoStrokes.Add(undoStrokes[index]);
            undoActions.RemoveAt(index);
            undoStrokes.RemoveAt(index);
        }
示例#20
0
        public static void ActualiceNonRecognizedStrokes()
        {
            Strokes stks = ink_overlay.Ink.Strokes;

            foreach (Stroke stk in stks)
            {
                bool processed = false;

                foreach (Stroke s in Facade.strokes_recognized)
                {
                    if (CompareStrokes(stk, s))
                    {
                        processed = true;
                    }
                }

                if (!processed)
                {
                    Facade.strokes_without_recognize.Add(stk);
                }
            }
        }
示例#21
0
        private void inkOverlay_StrokesDeleting(object sender, InkOverlayStrokesDeletingEventArgs e)
        {
            if (this.InvokeRequired)
            {
                return;
            }
            Strokes strokes = e.StrokesToDelete;

            //Remove the corresponding nodes and edges for each stroke
            for (int i = 0; i < strokes.Count; i++)
            {
                if (StrokeManager.isClosed(strokes[i], 0))
                {
                    graph.Remove(graph.Nodes.getNode(strokes[i]));
                }
                else
                {
                    graph.Remove(graph.Edges.getEdge(strokes[i]));
                }
            }
            Invalidate();
        }
示例#22
0
        protected override void OnStrokeCollected(InkCanvasStrokeCollectedEventArgs E)
        {
            void AddCustomStroke(Stroke CustomStroke)
            {
                Strokes.Remove(E.Stroke);

                Strokes.Add(CustomStroke);

                var args = new InkCanvasStrokeCollectedEventArgs(CustomStroke);

                base.OnStrokeCollected(args);
            }

            if (DynamicRenderer is IDynamicRenderer renderer)
            {
                AddCustomStroke(renderer.GetStroke(E.Stroke.StylusPoints, E.Stroke.DrawingAttributes));
            }
            else
            {
                base.OnStrokeCollected(E);
            }
        }
        private void inkOverlay_Stroke(object sender, InkCollectorStrokeEventArgs e)
        {
            Strokes strokes   = null;
            Ink     copiedInk = null;

            try
            {
                // Eraser strokes are transparent, we don't need to send them
                if (e.Stroke.DrawingAttributes.Transparency != 255)
                {
                    // Give the stroke an identifier, so we can delete it remotely
                    e.Stroke.ExtendedProperties.Add(StrokeIdentifier, Guid.NewGuid().ToString());

                    // Copy the stroke into its own Ink object, so that it can be serialized
                    strokes   = inkOverlay.Ink.CreateStrokes(new int[] { e.Stroke.Id });
                    copiedInk = e.Stroke.Ink.ExtractStrokes(strokes, ExtractFlags.CopyFromOriginal);

                    // Send it across the network
                    wb.SendObject(new SerializedInk(copiedInk));
                }
            }
            catch (Exception ex)
            {
                Log(ex.ToString());
            }
            finally
            {
                if (strokes != null)
                {
                    strokes.Dispose();
                }

                if (copiedInk != null)
                {
                    copiedInk.Dispose();
                }
            }
        }
        public bool recognizePackage(Strokes inkStrokes)
        {
            if (inkStrokes.Count == 2)
            {
                StrokeInfo strokeInfo1 = new StrokeInfo(inkStrokes[0]);
                StrokeInfo strokeInfo2 = new StrokeInfo(inkStrokes[1]);
                if (strokeInfo1.StrokeStatistics.Square > 0.9 && strokeInfo1.StrokeStatistics.Diagonal < 0.09 &&
                    strokeInfo1.StrokeStatistics.StartEndProximity < CLOSED_PROXIMITY)
                {
                    if (strokeInfo2.StrokeStatistics.Square > 0.9 && strokeInfo2.StrokeStatistics.Diagonal < 0.09)
                        return true;
                    else
                        return false;
                }
                else
                {
                    return false;
                }

            }
            else
                return false;
        }
        /// <summary>
        /// Helper method to paint the stroke collection's intersections
        /// </summary>
        /// <param name="g">The graphics object to use for painting</param>
        /// <param name="strokesToPaint">The collection of strokes to paint</param>
        private void PaintIntersections(Graphics g, Strokes strokesToPaint)
        {
            // Draw the intersections of each stroke as little red circles
            foreach (Stroke currentStroke in strokesToPaint)
            {
                // Get the intersections of the stroke
                float[] intersections = currentStroke.FindIntersections(strokesToPaint);

                Point[] points = currentStroke.GetPoints();

                // Draw each intersection in the stroke
                foreach (float fi in intersections)
                {
                    // Get the point before the FINDEX
                    Point ptIntersect = currentStroke.GetPoint((int)fi);

                    // Find the fractional part of the FINDEX
                    float fiFraction = fi - (int)fi;

                    // if the fi does not have a fractional part, we have already
                    // found the intersection point.  Otherwise, use the FINDEX to
                    // calculate the interpolated intersection point on the stroke
                    if (fiFraction > 0.0f)
                    {
                        Point ptNextIntersect = currentStroke.GetPoint((int)fi + 1);
                        ptIntersect.X += (int)((ptNextIntersect.X - ptIntersect.X) * fiFraction);
                        ptIntersect.Y += (int)((ptNextIntersect.Y - ptIntersect.Y) * fiFraction);
                    }

                    // Convert the X, Y position to Window based pixel coordinates
                    myInkCollector.Renderer.InkSpaceToPixel(g, ref ptIntersect);

                    // Draw a red circle as the intersection position
                    g.DrawEllipse(Pens.Red, ptIntersect.X - 3, ptIntersect.Y - 3, 6, 6);
                }
            }
        }
        /// <summary>
        /// Helper method to paint the stroke collection's cusps
        /// </summary>
        /// <param name="g">The graphics object to use for painting</param>
        /// <param name="strokesToPaint">The collection of strokes to paint</param>
        private void PaintCusps(Graphics g, Strokes strokesToPaint)
        {
            // now draw PolylineCusp points
            foreach (Stroke currentStroke in strokesToPaint)
            {
                // Retrieve the cusps of the stroke.  The cusps mark the points where
                // the stroke changes direction abruptly.  A segment is defined as the
                // points between two cusps.
                int[] cusps = currentStroke.PolylineCusps;

                // Draw each cusp in the stroke
                foreach (int i in cusps)
                {
                    // Get the X, Y position of the cusp
                    Point pt = currentStroke.GetPoint(i);

                    // Convert the X, Y position to Window based pixel coordinates
                    myInkCollector.Renderer.InkSpaceToPixel(g, ref pt);

                    // Draw a red circle as the cusp position
                    g.DrawEllipse(Pens.Red, pt.X - 3, pt.Y - 3, 6, 6);
                }
            }
        }
 /// <summary>
 /// obtains and returns alternative recognition results
 /// </summary>
 /// <param name="strokes">the strokes to be recognized</param>
 /// <returns>list of alternative</returns>
 private RecognitionAlternates getAlternative(Strokes strokes)
 {
     try
     {
         RecognizerContext context = new RecognizerContext();
         context.Strokes = strokes;
         RecognitionStatus     status;
         RecognitionResult     result = context.Recognize(out status);
         RecognitionAlternates ra;
         if (RecognitionStatus.NoError == status)
         {
             ra = result.GetAlternatesFromSelection();
         }
         else
         {
             ra = null;
         }
         return(ra);
     }
     catch (Exception)
     {
         return(null);
     }
 }
示例#28
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strokes"></param>
        internal String recognize(Strokes strokes, out RecognitionAlternates alternates)
        {
            RecognizerContext rc = new RecognizerContext();
            rc.Strokes = strokes;

            try {
                RecognitionStatus status;
                RecognitionResult result;
                result = rc.Recognize(out status);
                if (status == RecognitionStatus.NoError) {
                    RecognitionAlternates alternatives = result.GetAlternatesFromSelection();
                    alternates = alternatives;
                    return result.TopString;
                }
                else {
                    Console.WriteLine("Error in recognition.");
                }
            }
            catch {
                Console.WriteLine("Exception in recognition.");
            }
            alternates = null;
            return null;
        }
示例#29
0
        public Recognition(Strokes s, string _allograph, int baseline, int midpt, bool msftRecog)
        {
            _strokes = s;
            _bbox    = s.GetBoundingBox();
            updateIds();
            allograph = _allograph;
            _curalt   = 0;
            Result[] tmpalts;

            if (_allographToAlternates.TryGetValue(allograph + (msftRecog?"MSFT":""), out tmpalts))
            {
                alts = (Result[])tmpalts.Clone();
            }
            else if (_allograph.Length == 1)
            {
                alts = new Result[] { new Result(_allograph[0]) };
            }
            else
            {
                alts = new Result[] { new Result(_allograph) };
            }

            for (int i = 0; i < alts.Length; i++)
            {
                alts[i] = new Result(alts[i]);
            }
            baselinealts = new int[alts.Length];
            xheightalts  = new int[alts.Length];
            levelsetby   = int.MaxValue;
            msftRecoged  = msftRecog;
            for (int i = 0; i < alts.Length; i++)
            {
                SetMetrics(alts[i] == Result.Special.Imaginary ? "i" : alts[i], // bcz: Hack!  need to do something similar for 'e' etc?
                           baseline, midpt, ref baselinealts[i], ref xheightalts[i]);
            }
        }
示例#30
0
    private void hover_EditPropertiesClicked(object sender, EventArgs e)
    {
        Strokes selected = inkoverlay.Selection;

        if (selected == null || selected.Count != 1)
        {
            return;
        }

        // Get objects for the targeted stroke(s).  Ensure that only one is selected.
        RigidBodyBase[] bodies = doc.GetBodiesFor(selected);
        if (bodies.Length != 1)
        {
            return;
        }

        RigidBodyBase body = bodies[0];

        using (BodyPropertiesForm bpf = new BodyPropertiesForm(body))
        {
            bpf.ShowDialog(this);
            Invalidate();
        }
    }
示例#31
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WritingRecognition"/> class.
 /// </summary>
 /// <param name="control">The control.</param>
 /// <param name="culture">The culture.</param>
 public WritingRecognition(Control control, CultureInfo culture)
 {
     foreach (Recognizer reco in _recognizers)
         for (int c = 0; c < reco.Languages.Length; c++)
             if (reco.Languages[c] == culture.LCID)
             {
                 _context = reco.CreateRecognizerContext();
                 break;
             }
     if (_context == null)
     {
         MessageBox.Show(culture.DisplayName + " handwriting recognition support isn't installed on this Windows.", "Rincevent", MessageBoxButtons.OK, MessageBoxIcon.Hand);
         return;
     }
     _inkOverlay = new InkOverlay(control, true);
     _inkOverlay.Enabled = true;
     _strokes = _inkOverlay.Ink.CreateStrokes();
     _context.Strokes = _strokes;
     _inkOverlay.Stroke += inkOverlay_Stroke;
     _inkOverlay.DefaultDrawingAttributes.AntiAliased = true;
     _inkOverlay.DefaultDrawingAttributes.Color = Color.DarkViolet;
     _inkOverlay.DefaultDrawingAttributes.FitToCurve = true;
     _context.RecognitionWithAlternates += context_RecognitionWithAlternates;
 }
 internal RigidBodyBase[] GetBodiesFor(Strokes strokes)
 {
     ArrayList list = new ArrayList();
     foreach (Stroke s in strokes)
     {
         foreach (RigidBodyBase body in Bodies)
         {
             if (body.strokeid == s.Id)
                 list.Add(body);
         }
     }
     return list.ToArray(typeof(RigidBodyBase)) as RigidBodyBase[];
 }
示例#33
0
 //Gets the edges corresponding to the given strokes
 public Edges getEdges(Strokes strokes)
 {
     Edges found = new Edges();
     for(int i=0; i<strokes.Count; i++)
     {
         Edge e = getEdge(strokes[i]);
         if(e != null)
         {
             found.Add(e);
         }
     }
     return found;
 }
 private void HandleInkChanged(object sender, Strokes changed, bool adding)
 {
     using(Synchronizer.Lock(this.Undo.SyncRoot)) {
         // Create an IUndoer that will re-add or re-delete the copied strokes.
         IUndoer undoer = new InkUndoer(this, changed, adding);
         this.Undo.Push(undoer);
     }
 }
示例#35
0
        // --------------- Form Events ---------------
        /// <summary>
        /// Event Handler from Form Load Event
        /// Setup the ink collector for collection
        /// </summary>
        /// <param name="sender">The control that raised the event.</param>
        /// <param name="e">The event arguments.</param>
        private void InkClipboard_Load(object sender, System.EventArgs e)
        {
            // Set the application mode to inking
            applicationMode = ApplicationMode.Ink;

            // Initialize the selection data
            lassoPoints = new ArrayList();
            selectionHandles = new PictureBox[] {leftTopHandle,centerTopHandle,rightTopHandle,leftCenterHandle,rightCenterHandle,leftBottomHandle,centerBottomHandle,rightBottomHandle};
            selectionRect = new Rectangle();
            selectedStrokes = null;

            // Create the pens used to draw the lasso selection
            connectorPen = new Pen(connectorColor);     // Pen used to draw dotted lasso connector line
            connectorPen.DashStyle = DashStyle.Dash;
            dotEdgePen = new Pen(dotEdgeColor);         // Pen used to draw the outer edge of the lasso dot
            dotPen = new Pen(dotColor);                 // Pen used to draw the center of the lasso dot

            // Create a new ink collector and assign it to this form's window
            myInkCollector = new InkCollector(this.Handle);

            // Set the ink collector's pen width
            myInkCollector.DefaultDrawingAttributes.Width = MediumInkWidth;

            // Turn the ink collector on
            myInkCollector.Enabled = true;
        }
 private void UpdateAndSetStrokesToRemoveIds(Strokes strokes)
 {
     using (Synchronizer.Lock(this.m_Watcher.m_InkSheet.Ink.Strokes.SyncRoot)) {
         Debug.Assert(this.m_StrokesToRemove == null);
         string[] ids = new string[strokes.Count];
         for (int i = 0; i < ids.Length; i++) {
             Stroke stroke = strokes[i];
             Debug.Assert(stroke.ExtendedProperties.DoesPropertyExist(StrokeIdExtendedProperty));
             ids[i] = ((string)stroke.ExtendedProperties[StrokeIdExtendedProperty].Data);
         }
         this.m_StrokesToRemove = ids;
     }
 }
示例#37
0
 public void addStroke(Stroke stroke)
 {
     Strokes.Add(stroke);
 }
示例#38
0
        /// <summary>
        /// Helper method to paint the stroke collection's cusps
        /// </summary>
        /// <param name="g">The graphics object to use for painting</param>
        /// <param name="strokesToPaint">The collection of strokes to paint</param>
        private void PaintCusps(Graphics g, Strokes strokesToPaint)
        {
            // now draw PolylineCusp points
            foreach (Stroke currentStroke in strokesToPaint)
            {

                // Retrieve the cusps of the stroke.  The cusps mark the points where
                // the stroke changes direction abruptly.  A segment is defined as the
                // points between two cusps.
                int[] cusps = currentStroke.PolylineCusps;

                // Draw each cusp in the stroke
                foreach (int i in cusps)
                {

                    // Get the X, Y position of the cusp
                    Point pt = currentStroke.GetPoint(i);

                    // Convert the X, Y position to Window based pixel coordinates
                    myInkCollector.Renderer.InkSpaceToPixel(g, ref pt);

                    // Draw a red circle as the cusp position
                    g.DrawEllipse(Pens.Red, pt.X-3, pt.Y-3, 6, 6);
                }
            }
        }
示例#39
0
    private void inkoverlay_StrokesDeleting(object sender, InkOverlayStrokesDeletingEventArgs e)
    {
        dbg.WriteLine("----- inkoverlay_StrokesDeleting -----");

        // Ensure we're on the UI thread.
        dbg.Assert(!this.InvokeRequired);

        // Track region to repaint.
        Rectangle dirtybbox = Rectangle.Empty;

        try         // To prevent exceptions from propagating back to ink runtime.
        {
            // Get objects for stroke(s) to delete.
            RigidBodyBase[] bodies = doc.GetBodiesFor(e.StrokesToDelete);
            MechanismBase[] mechs  = doc.GetMechanismsFor(e.StrokesToDelete);

            // Delete mechanisms.
            foreach (MechanismBase mech in mechs)
            {
                doc.Mechanisms.Remove(mech);
                dirtybbox = Rectangle.Union(dirtybbox, mech.BoundingBox);
            }

            // Delete bodies and their attached mechanisms.
            foreach (RigidBodyBase body in bodies)
            {
                mechs = doc.GetMechanismsForBody(body);
                foreach (MechanismBase mech in mechs)
                {
                    doc.Mechanisms.Remove(mech);
                    dirtybbox = Rectangle.Union(dirtybbox, mech.BoundingBox);

                    Strokes mstrokes = doc.Ink.CreateStrokes(new int[] { mech.strokeid });
                    doc.Ink.DeleteStrokes(mstrokes);
                }

                doc.Bodies.Remove(body);
                dirtybbox = Rectangle.Union(dirtybbox, body.BoundingBox);
            }

            // Check if this stroke was the gravity vector's?
            if (doc.Gravity != null)
            {
                foreach (Stroke s in e.StrokesToDelete)
                {
                    if (s.Id == doc.Gravity.strokeid)
                    {
                        this.InvalidateInkSpaceRectangle(doc.Gravity.BoundingBox);
                        doc.Gravity = null;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            // Log the error.
            Global.HandleThreadException(this, new System.Threading.ThreadExceptionEventArgs(ex));
        }
        finally
        {
            // Repaint the affected area.
            InvalidateInkSpaceRectangle(dirtybbox);
        }
    }
            public InkUndoer(InkSheetUndoService watcher, Strokes strokes, bool adding)
            {
                this.m_Watcher = watcher;

                if(adding) {
                    this.UpdateAndSetStrokesToRemoveIds(strokes);
                } else {
                    this.m_StrokesToAdd = strokes;
                }

                this.m_Adding = adding;
            }
            private void AddInk()
            {
                using(Synchronizer.Lock(this)) {
                    // Create an array of stroke Ids in order to fire the InkAdded event later.
                    int[] ids = new int[this.m_StrokesToAdd.Count];

                    using (Synchronizer.Lock(this.m_Watcher.m_InkSheet.Ink.Strokes.SyncRoot)) {
                        for (int i = 0; i < ids.Length; i++) {
                            Stroke stroke = this.m_StrokesToAdd[i];

                            // The stroke probably has no association with the current Ink object.
                            // Therefore, we have to recreate it by copying the raw packet data.
                            // This first requires recreating the TabletPropertyDescriptionCollection,
                            // which, for some stupid reason, must be done manually for lack of a better API.
                            TabletPropertyDescriptionCollection properties = new TabletPropertyDescriptionCollection();
                            foreach (Guid property in stroke.PacketDescription)
                                properties.Add(new TabletPropertyDescription(property, stroke.GetPacketDescriptionPropertyMetrics(property)));

                            // Create a new stroke from the raw packet data.
                            Stroke created = this.m_Watcher.m_InkSheet.Ink.CreateStroke(stroke.GetPacketData(), properties);

                            // Copy the DrawingAttributes and all application data
                            // (especially the StrokesIdExtendedProperty) to the new stroke.
                            created.DrawingAttributes = stroke.DrawingAttributes;
                            foreach (ExtendedProperty prop in stroke.ExtendedProperties)
                                created.ExtendedProperties.Add(prop.Id, prop.Data);

                            // Get the new stroke's Id so we can fire the InkAdded event.
                            ids[i] = created.Id;
                        }

                        // If the added strokes don't yet have StrokeIdExtendedProperty properties,
                        // create new Guids for them.  Regardless, set this.m_StrokesToRemove
                        // to the list of stroke Guids.
                        this.UpdateAndSetStrokesToRemoveIds(this.m_StrokesToAdd);

                        // Then, unset this.m_StrokesToAdd since they're already added.
                        this.m_StrokesToAdd = null;
                    }

                    // Create the event arguments and add them to the ignore list so the
                    // InkSheetUndoService won't create an InkUndoer for this change.
                    StrokesEventArgs args = new StrokesEventArgs(ids);
                    using(Synchronizer.Lock(this.m_Watcher.m_Ignore.SyncRoot)) {
                        this.m_Watcher.m_Ignore.Add(args);
                    }

                    // Finally fire the appropriate InkAdded event from the InkSheetModel.
                    this.m_Watcher.m_InkSheet.OnInkAdded(args);
                }
            }
示例#42
0
 void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
 {
     canvas !.Strokes.Clear();
     Element.Points.Clear();
 }
            private void RemoveInk()
            {
                using (Synchronizer.Lock(this)) {
                    // Collect all of the strokes we're supposed to delete.
                    using (Synchronizer.Lock(this.m_Watcher.m_InkSheet.Ink.Strokes.SyncRoot)) {
                        Strokes deleting = this.m_Watcher.m_InkSheet.Ink.CreateStrokes();
                        foreach (Stroke stroke in this.m_Watcher.m_InkSheet.Ink.Strokes)
                            if (stroke.ExtendedProperties.DoesPropertyExist(StrokeIdExtendedProperty))
                                if (Array.IndexOf(this.m_StrokesToRemove, stroke.ExtendedProperties[StrokeIdExtendedProperty].Data) >= 0)
                                    deleting.Add(stroke);

                        // It's possible that some of the strokes have been deleted elsewhere.
                        // But this shouldn't happen because doing so should have caused an InkUndoer to be
                        // pushed onto the Undo stack.  So, for now, this check is "merely" a Debug.Assert.
                        // TODO: Decide whether this should be an error, or at least whether it should
                        //   invalidate the rest of the undo stack.
                        Debug.Assert(deleting.Count == this.m_StrokesToRemove.Length);

                        // Get the stroke Ids so we can make a copy of the ink and fire the OnDeleting and OnDeleted events.
                        int[] ids = new int[deleting.Count];
                        for (int i = 0; i < ids.Length; i++) // Is there a better way to get the array of Ids?
                            ids[i] = deleting[i].Id;

                        // Make a copy of the strokes, because if the original ink is later deleted
                        // from the Ink object then it will become unusable.
                        Ink ink = this.m_Watcher.m_InkSheet.Ink.ExtractStrokes(deleting, ExtractFlags.CopyFromOriginal);
                        this.m_StrokesToAdd = ink.Strokes;
                        this.m_StrokesToRemove = null;

                        // Create the event arguments and add them to the ignore list so the
                        // InkSheetUndoService won't create an InkUndoer for this change.
                        StrokesEventArgs args = new StrokesEventArgs(ids);
                        using (Synchronizer.Lock(this.m_Watcher.m_Ignore.SyncRoot)) {
                            this.m_Watcher.m_Ignore.Add(args);
                        }

                        // Actually delete the ink, firing the appropriate events on the InkSheetModel.
                        this.m_Watcher.m_InkSheet.OnInkDeleting(args);
                        this.m_Watcher.m_InkSheet.Ink.DeleteStrokes(deleting);
                        this.m_Watcher.m_InkSheet.OnInkDeleted(args);
                    }
                }
            }
示例#44
0
        protected override void OnElementChanged(ElementChangedEventArgs <DrawingView> e)
        {
            base.OnElementChanged(e);
            if (Control == null && Element != null)
            {
                canvas = new InkCanvas
                {
                    Background = Element.BackgroundColor.ToBrush(),
                    DefaultDrawingAttributes = new()
                    {
                        Color  = Element.DefaultLineColor.ToMediaColor(),
                        Width  = Element.DefaultLineWidth,
                        Height = Element.DefaultLineWidth
                    }
                };
                Element.Lines.CollectionChanged += OnCollectionChanged;
                SetNativeControl(canvas);

                canvas.Strokes.StrokesChanged += OnStrokesChanged;
                Control !.PreviewMouseDown    += OnPreviewMouseDown;
            }

            if (e.OldElement != null)
            {
                canvas !.Strokes.StrokesChanged   -= OnStrokesChanged;
                Element !.Lines.CollectionChanged -= OnCollectionChanged;
                if (Control != null)
                {
                    Control.PreviewMouseDown -= OnPreviewMouseDown;
                }
            }
        }

        void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
        {
            canvas !.Strokes.StrokesChanged -= OnStrokesChanged;
            canvas.Strokes.Clear();
            LoadLines();
            canvas.Strokes.StrokesChanged += OnStrokesChanged;
        }

        void OnPreviewMouseDown(object sender, MouseButtonEventArgs e) => Clear();

        void Clear(bool force = false)
        {
            if (!Element.MultiLineMode || force)
            {
                canvas !.Strokes.Clear();
                Element.Lines.Clear();
            }
        }

        void OnStrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
        {
            Element.Lines.CollectionChanged -= OnCollectionChanged;
            if (e.Added.Count > 0)
            {
                if (!Element.MultiLineMode)
                {
                    Element.Lines.Clear();
                }

                var lines = Element.MultiLineMode ? e.Added : new StrokeCollection()
                {
                    e.Added.First()
                };

                foreach (var line in lines)
                {
                    var points = line.StylusPoints.Select(point => new Point(point.X, point.Y)).ToList();
                    Element.Lines.Add(new Line()
                    {
                        Points    = new ObservableCollection <Point>(points),
                        LineColor = Color.FromRgba(line.DrawingAttributes.Color.R, line.DrawingAttributes.Color.G,
                                                   line.DrawingAttributes.Color.B, line.DrawingAttributes.Color.A),
                        LineWidth = (float)line.DrawingAttributes.Width
                    });
                }

                if (Element.Lines.Count > 0)
                {
                    var lastLine = Element.Lines.Last();
                    if (Element.DrawingLineCompletedCommand?.CanExecute(lastLine) ?? false)
                    {
                        Element.DrawingLineCompletedCommand.Execute(lastLine);
                    }
                }

                if (Element.ClearOnFinish)
                {
                    Element.Lines.CollectionChanged -= OnCollectionChanged;
                    Clear(true);
                    canvas !.Strokes.StrokesChanged += OnStrokesChanged;
                }
            }

            Element.Lines.CollectionChanged += OnCollectionChanged;
        }

        void LoadLines()
        {
            var lines = Element.MultiLineMode
                                ? Element.Lines
                                : Element.Lines.Any()
                                        ? new ObservableCollection <Line> {
                Element.Lines.LastOrDefault()
            }
                                        : new ObservableCollection <Line>();

            foreach (var line in lines)
            {
                var stylusPoints = line.Points.Select(point => new StylusPoint(point.X, point.Y)).ToList();
                if (stylusPoints is { Count: > 0 })
                {
                    var stroke = new Stroke(new StylusPointCollection(stylusPoints))
                    {
                        DrawingAttributes = new()
                        {
                            Color  = line.LineColor.ToMediaColor(),
                            Width  = line.LineWidth,
                            Height = line.LineWidth
                        }
                    };
                    canvas !.Strokes.Add(stroke);
                }
            }
        }
示例#45
0
        /// <summary>
        /// Helper method to paint the stroke collection's intersections
        /// </summary>
        /// <param name="g">The graphics object to use for painting</param>
        /// <param name="strokesToPaint">The collection of strokes to paint</param>
        private void PaintIntersections(Graphics g, Strokes strokesToPaint)
        {
            // Draw the intersections of each stroke as little red circles
            foreach (Stroke currentStroke in strokesToPaint)
            {

                // Get the intersections of the stroke
                float[] intersections = currentStroke.FindIntersections(strokesToPaint);

                Point[] points = currentStroke.GetPoints();

                // Draw each intersection in the stroke
                foreach (float fi in intersections)
                {
                    // Get the point before the FINDEX
                    Point ptIntersect = currentStroke.GetPoint((int)fi);

                    // Find the fractional part of the FINDEX
                    float fiFraction = fi - (int)fi;

                    // if the fi does not have a fractional part, we have already
                    // found the intersection point.  Otherwise, use the FINDEX to
                    // calculate the interpolated intersection point on the stroke
                    if (fiFraction > 0.0f)
                    {
                        Point ptNextIntersect = currentStroke.GetPoint((int)fi + 1);
                        ptIntersect.X += (int)((ptNextIntersect.X - ptIntersect.X) * fiFraction);
                        ptIntersect.Y += (int)((ptNextIntersect.Y - ptIntersect.Y) * fiFraction);

                    }

                    // Convert the X, Y position to Window based pixel coordinates
                    myInkCollector.Renderer.InkSpaceToPixel(g, ref ptIntersect);

                    // Draw a red circle as the intersection position
                    g.DrawEllipse(Pens.Red, ptIntersect.X-3, ptIntersect.Y-3, 6, 6);
                }
            }
        }
示例#46
0
 //Get the nodes corresponding to the following strokes
 public Nodes getNodes(Strokes strokes)
 {
     Nodes found = new Nodes();
     for(int i=0; i<strokes.Count; i++)
     {
         Node a = getNode(strokes[i]);
         if(a != null)
         {
             found.Add(a);
         }
     }
     return found;
 }
示例#47
0
        /// <summary>
        /// Sets the selected strokes and selection rectangle.
        /// </summary>
        /// <param name="strokes">The strokes that should be selected.  If null, the selection becomes empty</param>
        private void SetSelection(Strokes strokes)
        {
            // Tracks whether the rectangle that bounds the selected
            // strokes should be displayed
            bool isSelectionVisible = false;

            // Update the selected strokes collection
            selectedStrokes = strokes;

            // If no strokes are selected, set the selection rectangle
            // to empty
            if (!HasSelection())
            {
                selectionRect = Rectangle.Empty;
            }
                // Otherwise, at least one stroke is selected and it is necessary
                // to display the selection rectangle.
            else
            {
                isSelectionVisible = true;

                // Retrieve the bounding box of the strokes
                selectionRect = selectedStrokes.GetBoundingBox();
                using (Graphics g = CreateGraphics())
                {
                    InkSpaceToPixel(g, ref selectionRect);
                }

                // Pad the selection rectangle so that the selected ink
                // doesn't overlap with the selection rectangle's handles.
                selectionRect.Inflate(SelectionRectBuffer, SelectionRectBuffer);

                // compute the center of the rectangle that bounds the
                // selected strokes
                int xAvg = (selectionRect.Right+selectionRect.Left)/2;
                int yAvg = (selectionRect.Top+selectionRect.Bottom)/2;

                // Draw the resize handles
                // top left
                SetLocation(selectionHandles[0],selectionRect.Left, selectionRect.Top);
                // top
                SetLocation(selectionHandles[1],xAvg, selectionRect.Top);
                // top right
                SetLocation(selectionHandles[2],selectionRect.Right, selectionRect.Top);

                // left
                SetLocation(selectionHandles[3],selectionRect.Left, yAvg);
                // right
                SetLocation(selectionHandles[4],selectionRect.Right, yAvg);

                // bottom left
                SetLocation(selectionHandles[5],selectionRect.Left, selectionRect.Bottom);
                // bottom
                SetLocation(selectionHandles[6],xAvg, selectionRect.Bottom);
                // bottom right
                SetLocation(selectionHandles[7],selectionRect.Right, selectionRect.Bottom);
            }

            // Set the visibility of each selection handle in the
            // selection rectangle.  If there is no selection, all
            // handles should be hidden.  Otherwise, all handles should
            // be visible.
            foreach(PictureBox pb in selectionHandles)
            {
                pb.Visible = isSelectionVisible;
            }

            // Turn off autoredrawing if there is a selection - otherwise,
            // the selected ink will not be displayed as selected.
            myInkCollector.AutoRedraw = !isSelectionVisible;

            // Since the selection has changed, repaint the screen.
            Refresh();
        }
 internal MechanismBase[] GetMechanismsFor(Strokes strokes)
 {
     ArrayList list = new ArrayList();
     foreach (Stroke s in strokes)
     {
         foreach (MechanismBase mech in Mechanisms)
         {
             if (mech.strokeid == s.Id)
                 list.Add(mech);
         }
     }
     return list.ToArray(typeof(MechanismBase)) as MechanismBase[];
 }
 private static void SetStrokeIds(Strokes strokes)
 {
     foreach(Stroke stroke in strokes)
         if(!stroke.ExtendedProperties.DoesPropertyExist(StrokeIdExtendedProperty))
             stroke.ExtendedProperties.Add(StrokeIdExtendedProperty, Guid.NewGuid().ToString());
 }