private bool ScribbleDelete(Stroq stroq, out StroqCollection erasedStroqs) { bool canBeScribble = stroq.OldPolylineCusps().Length > 4; if (stroq.OldPolylineCusps().Length == 4) { int[] pcusps = stroq.OldPolylineCusps(); Deg a1 = fpdangle(stroq[0], stroq[pcusps[1]], stroq[pcusps[2]] - stroq[pcusps[1]]); Deg a2 = fpdangle(stroq[pcusps[1]], stroq[pcusps[1]], stroq[pcusps[3]] - stroq[pcusps[1]]); if (a1 < 35 && a2 < 35) { canBeScribble = stroq.BackingStroke.HitTest(stroq.ConvexHull().First(), 1); } } if (canBeScribble) { IEnumerable <Pt> hull = stroq.ConvexHull(); StroqCollection stqs = inqCanvas.Stroqs.HitTest(hull, 1); if (stqs.Count > 1) { inqCanvas.Stroqs.Remove(stqs); erasedStroqs = stqs; inqCanvas.Stroqs.Remove(stroq); return(true); } } erasedStroqs = null; return(false); }
private bool IsLassoSelect(Stroq stroq) { if (stroq.OldPolylineCusps().Length <= 4 && stroq.Count > 4) { Stroq estroq = stroq; CuspDetector.CuspSet cs = CuspDetector.FeaturePoints(estroq); Pt[] first = new Pt[cs.pts.Count / 2]; for (int i = 0; i < first.Length; i++) { if (cs.distances[i] > cs.dist / 2) { break; } else { first[i] = cs.pts[i]; } } Pt[] second = new Pt[cs.pts.Count - first.Length]; for (int j = 0; j < second.Length; j++) { second[j] = cs.pts[first.Length + j]; } Stroq s1 = new Stroq(first); Stroq s2 = new Stroq(second); float d1, d2; s1.OldNearestPoint(s2[-1], out d1); s2.OldNearestPoint(s1[0], out d2); if (Math.Min(d1, d2) / Math.Max(estroq.GetBounds().Width, estroq.GetBounds().Height) < 0.3f) { StroqCollection stqs = _mathStroqs.HitTest(estroq, 50); StroqCollection stqs2 = _mathStroqs.HitTest(estroq.Reverse1(), 50); if (stqs2.Count > stqs.Count) { stqs = stqs2; } stqs.Remove(estroq); StroqCollection stqs3 = new StroqCollection(stqs.Where((Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s]) != null)); stqs = stqs3; Recognition rtemp = _mrec.ClassifyOneTemp(estroq); if (stqs.Count > 0 && (rtemp == null || !rtemp.alts.Contains(new Recognition.Result(Unicode.S.SQUARE_ROOT)))) { if (rtemp != null) { Console.WriteLine("select recognized for " + rtemp.allograph); } return(true); } else { // Generic additional selections would be called here. return(false); } } } return(false); }
/// <summary> /// Note: this should be expected to be significantly slower because it has to convert all the strokes into the same Ink before it can /// run the old FindIntersections(). /// </summary> public static float[] OldFindIntersections(this Stroq s, StroqCollection ss) { Stroke oldStroke = s.OldStroke(); Ink ink = oldStroke.Ink; List <int> ids = new List <int>(); foreach (Stroq st in ss) { if (st != s) { ids.Add(st.OldStroke(ink).Id); } } return(oldStroke.FindIntersections(ink.CreateStrokes(ids.ToArray()))); }
/// <summary> /// Create a selection of inq strokes /// </summary> /// <param name="contents">The set of stroqs to be selected.</param> /// <param name="outline">The outline to be used for the selection; can be null.</param> /// <param name="stroq2char">Delegate taking a Stroq as input and returns the (character) Recognition record the stroke is a part of.</param> /// <param name="char2stroqs">Given a Recognition, return the Stroqs that compose it.</param> /// <param name="dispstrs">A StroqCollection controlling what Stroqs are displayed; the outline is automatically removed from here on deselection. /// Can be null.</param> public StroqSel(IEnumerable<Stroq> contents, Stroq outline, Func<Stroq, Recognition> stroq2char, Func<Recognition, IEnumerable<Stroq>> char2stroqs, StroqCollection dispstrs) { // sc would be Charreco.Classification(s); sqs the mapping of r.strokes AllStroqs = new StroqCollection(contents); Outline = outline; ReRecStroqs = new StroqCollection(); HashSet<Stroq> additional = new HashSet<Stroq>(); foreach (Stroq ss in AllStroqs) { Recognition r = stroq2char(ss); if (r == null || r.levelsetby != 0) ReRecStroqs.Add(ss); else additional.UnionWith(char2stroqs(r)); } AllStroqs.Add(additional); _displayedStrokes = dispstrs; }
private void DoLassoSelect(Stroq stroq) { StroqCollection stqs = _mathStroqs.HitTest(stroq, 50); Deselect(); stroq.BackingStroke.DrawingAttributes.Color = Colors.Purple; Selected.Contents = new StroqSel(stqs, stroq, (Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s]), (Recognition r) => _mrec.Sim[r.strokes], inqCanvas.Stroqs); StroqSel Sel = (StroqSel)Selected.Contents; HashSet <Recognition> recogs = new HashSet <Recognition>(Sel.AllStroqs.Select((Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s])) .Where((Recognition r) => r != null)); if (recogs.Count != 0) { showSidebarAlts(recogs, Sel.AllStroqs); } }
// If disposing equals false, the method has been called by the // runtime from inside the finalizer and you should not reference // other objects. Only unmanaged resources can be disposed. private void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // Dispose managed resources. Stroqs.Changed -= stroqs_Changed; DeleteStrokes(Stroqs); // detach callbacks from all the stroqs // make sure further operations die _ink = null; Stroqs = null; _map = null; _map2 = null; } // Dispose unmanaged resources--but there are none for this class, so no code here. _disposed = true; } }
/// <summary> /// Create a selection of inq strokes /// </summary> /// <param name="contents">The set of stroqs to be selected.</param> /// <param name="outline">The outline to be used for the selection; can be null.</param> /// <param name="stroq2char">Delegate taking a Stroq as input and returns the (character) Recognition record the stroke is a part of.</param> /// <param name="char2stroqs">Given a Recognition, return the Stroqs that compose it.</param> /// <param name="dispstrs">A StroqCollection controlling what Stroqs are displayed; the outline is automatically removed from here on deselection. /// Can be null.</param> public StroqSel(IEnumerable <Stroq> contents, Stroq outline, Func <Stroq, Recognition> stroq2char, Func <Recognition, IEnumerable <Stroq> > char2stroqs, StroqCollection dispstrs) // sc would be Charreco.Classification(s); sqs the mapping of r.strokes { AllStroqs = new StroqCollection(contents); Outline = outline; ReRecStroqs = new StroqCollection(); HashSet <Stroq> additional = new HashSet <Stroq>(); foreach (Stroq ss in AllStroqs) { Recognition r = stroq2char(ss); if (r == null || r.levelsetby != 0) { ReRecStroqs.Add(ss); } else { additional.UnionWith(char2stroqs(r)); } } AllStroqs.Add(additional); _displayedStrokes = dispstrs; }
/// <summary> /// Remember, you must dispose of this properly by calling Dispose() when you're done with it or wrapping it in a using() call. /// </summary> /// <param name="stroqs"></param> public StroqInkMapper(StroqCollection stroqs) { Stroqs = stroqs; stroqs.Changed += stroqs_Changed; StroqsAdded(stroqs); }
private void showSidebarAlts(ICollection <Recognition> recogs, StroqCollection stroqs) { _altsMenuCrea.Populate(recogs, stroqs); }
private bool LassoSelect(Stroq stroq) { if (stroq.OldPolylineCusps().Length <= 4 && stroq.Count > 4) { Stroq estroq = stroq; CuspDetector.CuspSet cs = CuspDetector.FeaturePoints(estroq); Pt[] first = new Pt[cs.pts.Count / 2]; for (int i = 0; i < first.Length; i++) { if (cs.distances[i] > cs.dist / 2) { break; } else { first[i] = cs.pts[i]; } } Pt[] second = new Pt[cs.pts.Count - first.Length]; for (int j = 0; j < second.Length; j++) { second[j] = cs.pts[first.Length + j]; } Stroq s1 = new Stroq(first); Stroq s2 = new Stroq(second); float d1, d2; s1.OldNearestPoint(s2[-1], out d1); s2.OldNearestPoint(s1[0], out d2); if (Math.Min(d1, d2) / Math.Max(estroq.GetBounds().Width, estroq.GetBounds().Height) < 0.3f) { StroqCollection stqs = _mathStroqs.HitTest(estroq, 50); StroqCollection stqs2 = _mathStroqs.HitTest(estroq.Reverse1(), 50); if (stqs2.Count > stqs.Count) { stqs = stqs2; } stqs.Remove(estroq); StroqCollection stqs3 = new StroqCollection(stqs.Where((Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s]) != null)); stqs = stqs3; Recognition rtemp = _mrec.ClassifyOneTemp(estroq); if (stqs.Count > 0 && (rtemp == null || !rtemp.alts.Contains(new Recognition.Result(Unicode.S.SQUARE_ROOT)))) { if (rtemp != null) { Console.WriteLine("select recognized for " + rtemp.allograph); } this.Dispatcher.Invoke((Action)(() => { Deselect(); stroq.BackingStroke.DrawingAttributes.Color = Colors.Purple; Selected.Contents = new StroqSel(stqs, stroq, (Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s]), (Recognition r) => _mrec.Sim[r.strokes], inqCanvas.Stroqs); StroqSel Sel = (StroqSel)Selected.Contents; HashSet <Recognition> recogs = new HashSet <Recognition>(Sel.AllStroqs.Select((Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s])) .Where((Recognition r) => r != null)); if (recogs.Count != 0) { showSidebarAlts(recogs, Sel.AllStroqs); } })); return(true); } else { // Generic additional selections would be called here. return(false); } } } return(false); }
public void Populate(ICollection <Recognition> recogs, StroqCollection stroqs) { alternateRec = recogs.Count == 1 ? recogs.Single() : null; if (alternateRec != null && !stroqs.All((s) => alternateRec.strokes.Contains(_mrec.Sim[s]))) { alternateRec = null; } altstroqsRec = stroqs; altrecogsRec = recogs; _menuShell.Items.Clear(); MenuItem mi; bool needseparator = false; if (recogs.Count == 1) { /* regular alternates*/ Recognition rr = recogs.Single(); for (int i = 0; i < rr.alts.Length; i++) { string label; char c = rr.alts[i].Character; if (c != 0) { label = c.ToString(); } else { label = rr.alts[i].Word; if (label == null) { label = rr.alts[i].ToString(); label = label.Substring(1, label.Length - 2); } } mi = new MenuItem(); mi.Header = label; if (c != 0) { mi.ToolTip = Unicode.NameOf(c); mi.FontFamily = new FontFamily(starPadSDK.MathExpr.ExprWPF.EDrawingContext.FontFamilyURIBase, starPadSDK.MathExpr.ExprWPF.EDrawingContext.FontFamilyURIRel); if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= 'α' && c <= 'ω') || c == Unicode.G.GREEK_PHI_SYMBOL) { mi.FontStyle = FontStyles.Italic; } } else { mi.ToolTip = label; } mi.Tag = i; mi.Click += ChooseAlternate; mi.PreviewMouseDown += mi_MouseDown; mi.PreviewMouseUp += mi_MouseUp; if (i == 0) { mi.AllowDrop = true; mi.DragEnter += mi_DragCheck; mi.DragOver += mi_DragCheck; mi.Drop += mi_Drop; } if (rr.curalt == i) { mi.IsChecked = true; } _menuShell.Items.Add(mi); } needseparator = true; } if (stroqs.Count > 1 && stroqs.Count != recogs.Count /* FIXME: if a stroke has no recog, this won't work */) { /* option to split apart and recognize each stroke separately */ if (needseparator) { _menuShell.Items.Add(new Separator()); needseparator = false; } string label = ""; foreach (Stroq s1 in stroqs) { Recognition r = _mrec.Charreco.Classify(_mrec.Sim[s1], true); if (r == null) { continue; } string l; char c = r.alt.Character; if (c != 0) { l = c.ToString(); } else { l = r.alt.Word; if (l == null) { l = r.alt.ToString(); l = l.Substring(1, l.Length - 2); } } label += l; } mi = new MenuItem(); mi.Header = label; mi.ToolTip = "split combined symbol into separate symbols"; mi.Tag = -1; mi.Click += ChooseAlternate; _menuShell.Items.Add(mi); needseparator = true; } if (stroqs.Count > 0) { /* Interpret everything as a single word */ if (needseparator) { _menuShell.Items.Add(new Separator()); needseparator = false; } InkAnalyzer ia = new InkAnalyzer(); AnalysisHintNode ahn = ia.CreateAnalysisHint(); ahn.WordMode = true; ahn.Location.MakeInfinite(); foreach (Stroq s in stroqs) { ia.AddStroke(s.BackingStroke); } AnalysisStatus stat = ia.Analyze(); if (stat.Successful) { AnalysisAlternateCollection aac = ia.GetAlternates(); for (int i = 0; i < aac.Count; i++) { if (aac[i].AlternateNodes.Count > 1 || !(aac[i].AlternateNodes[0] is InkWordNode)) { continue; } mi = new MenuItem(); mi.Header = aac[i].RecognizedString; mi.ToolTip = "interpret all selected strokes as a single character or word: alternate " + (i + 1); mi.Tag = aac[i]; mi.Click += ChooseAlternate; if (alternateRec != null) { mi.PreviewMouseDown += mi_MouseDown; mi.PreviewMouseUp += mi_MouseUp; } if (aac[i].RecognizedString.Length == 1) { char c = aac[i].RecognizedString[0]; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= 'α' && c <= 'ω')) { mi.FontStyle = FontStyles.Italic; } mi.ToolTip = (string)mi.ToolTip + " (" + Unicode.NameOf(c) + ")"; } _menuShell.Items.Add(mi); } } } _menuShell.InvalidateMeasure(); // odd that I need this }
private bool LassoSelect(InqCanvas.StroqCollectedEventArgs e) { if (e.Stroq.OldPolylineCusps().Length <= 4 && e.Stroq.Count > 4) { Stroq estroq = e.Stroq; CuspDetector.CuspSet cs = CuspDetector.FeaturePoints(estroq); Pt[] first = new Pt[cs.pts.Count / 2]; for (int i = 0; i < first.Length; i++) if (cs.distances[i] > cs.dist / 2) break; else first[i] = cs.pts[i]; Pt[] second = new Pt[cs.pts.Count - first.Length]; for (int j = 0; j < second.Length; j++) second[j] = cs.pts[first.Length + j]; Stroq s1 = new Stroq(first); Stroq s2 = new Stroq(second); float d1, d2; s1.OldNearestPoint(s2[-1], out d1); s2.OldNearestPoint(s1[0], out d2); if (Math.Min(d1, d2) / Math.Max(estroq.GetBounds().Width, estroq.GetBounds().Height) < 0.3f) { StroqCollection stqs = _mathStroqs.HitTest(estroq, 50); StroqCollection stqs2 = _mathStroqs.HitTest(estroq.Reverse1(), 50); if (stqs2.Count > stqs.Count) stqs = stqs2; stqs.Remove(estroq); StroqCollection stqs3 = new StroqCollection(stqs.Where((Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s]) != null)); stqs = stqs3; Recognition rtemp = _mrec.ClassifyOneTemp(estroq); if (stqs.Count > 0 && (rtemp == null || !rtemp.alts.Contains(new Recognition.Result(Unicode.S.SQUARE_ROOT)))) { if (rtemp != null) Console.WriteLine("select recognized for " + rtemp.allograph); Deselect(); estroq.BackingStroke.DrawingAttributes.Color = Colors.Purple; Selected.Contents = new StroqSel(stqs, estroq, (Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s]), (Recognition r) => _mrec.Sim[r.strokes], inqCanvas.Stroqs); StroqSel Sel = (StroqSel)Selected.Contents; HashSet<Recognition> recogs = new HashSet<Recognition>(Sel.AllStroqs.Select((Stroq s) => _mrec.Charreco.Classification(_mrec.Sim[s])) .Where((Recognition r) => r != null)); if (recogs.Count != 0) showSidebarAlts(recogs, Sel.AllStroqs); return true; } else { // Generic additional selections would be called here. return false; } } } return false; }
private void showSidebarAlts(ICollection<Recognition> recogs, StroqCollection stroqs) { if (_altsMenuCrea != null) { _altsMenuCrea.Populate(recogs, stroqs); } }