public void process(InkAnalyzer inkAnalyzer) { ContextNodeCollection contextNodeCollection = inkAnalyzer.FindLeafNodes(); List <Stroke> horizontalLines = InkUtils.findLines(contextNodeCollection); findAndDeleteStrikethrough(inkAnalyzer, canvas, horizontalLines, contextNodeCollection); }
public void process(InkAnalyzer inkAnalyzer) { ContextNodeCollection contextNodeCollection = inkAnalyzer.FindLeafNodes(); List <Stroke> horizontalLines = InkUtils.findLines(contextNodeCollection); List <HeadingItem> headings = findHeadings(horizontalLines, contextNodeCollection); //Here is the end result of the headings mainHeading.headings = headings; //Invalidate and render the headings to the side panel mainHeading.invalidate(); }
private void InkAnalyzer_ResultsUpdated(object sender, ResultsUpdatedEventArgs e) { running = false; InkUtils.MergeParagraphs(inkAnalyzer); if (processor < inkProcessors.Count) { InkProcessor proc = inkProcessors[processor]; proc.process(inkAnalyzer); processor++; fireoff(); return; } if (adds.Count > 0 || removes.Count > 0) { //Flush adds and removes while (adds.Count > 0) { Stroke stroke = adds.Dequeue(); inkAnalyzer.AddStroke(stroke); } while (removes.Count > 0) { Stroke stroke = removes.Dequeue(); inkAnalyzer.RemoveStroke(stroke); } fireoff(); return; } if (PipelineComplete != null) { PipelineComplete(this, new EventArgs()); } processor = 0; processing = false; if (queued) { queued = false; processor = 0; processing = true; fireoff(); } }
private bool strokeIsCaret(Stroke oldStrokes) { StylusPointCollection styluses = InkUtils.toPolyline(oldStrokes.StylusPoints); if (styluses.Count == 5) { double distance1 = (Math.Sqrt(InkUtils.distSquared(styluses[0], styluses[4]))); double distance2 = (Math.Sqrt(InkUtils.distSquared(styluses[1], styluses[3]))); bool closeFirst = distance1 < 24; bool closeSecond = distance2 < 24; double offset = (styluses[0].Y - styluses[1].Y) / (styluses[0].X - styluses[1].X); double levelOffset = (styluses[0].Y - styluses[2].Y); bool isHigh = -offset > 1.5; bool level = Math.Abs(levelOffset) < 50; Debug.Print(distance1 + " " + distance2 + " " + offset + " " + levelOffset); return(closeFirst && closeSecond && isHigh && level); } return(false); }
private void reflowParagraph(ParagraphNode node, InkAnalyzer inkAnalyzer, InkCanvas inkCanvas) { ContextNodeCollection lines = node.SubNodes; Rect bounds = node.Strokes.GetBounds(); List <InkWordNode> resultWords = new List <InkWordNode>(); double lineHeight = 0; double spacing = 30; //Collect all strokes foreach (ContextNode line in lines) { ContextNodeCollection words = line.SubNodes; foreach (ContextNode word in words) { lineHeight += word.Strokes.GetBounds().Height; InkWordNode wordNode = word as InkWordNode; resultWords.Add(wordNode); } } lineHeight /= resultWords.Count; List <List <InkWordNode> > resultLines = new List <List <InkWordNode> >(); List <double> lineMaxBaseline = new List <double>(); //Reflow strokes double x = 0; double maxX = inkCanvas.ActualWidth - bounds.X; resultLines.Add(new List <InkWordNode>()); lineMaxBaseline.Add(0); foreach (InkWordNode word in resultWords) { //Does word fit? Rect wordBound = word.Strokes.GetBounds(); if (x + wordBound.Width + spacing > maxX && multiline) { //Not fitting! Newline x = 0; resultLines.Add(new List <InkWordNode>()); lineMaxBaseline.Add(0); } x += spacing + wordBound.Width; PointCollection baseline = word.GetBaseline(); if (baseline != null && baseline.Count > 0) { double baselineFromTop = baseline[0].Y - wordBound.Y; resultLines[resultLines.Count - 1].Add(word); if (baselineFromTop > lineMaxBaseline[resultLines.Count - 1]) { lineMaxBaseline[resultLines.Count - 1] = baselineFromTop; } } } double y = 0; int lineNumber = 0; foreach (List <InkWordNode> line in resultLines) { double lineBaseline = lineMaxBaseline[lineNumber]; x = 0; foreach (InkWordNode word in line) { Rect wordBound = word.Strokes.GetBounds(); PointCollection baseline = word.GetBaseline(); double baselineFromTop = baseline[0].Y - wordBound.Y; double destX = (x + bounds.X); double dx = destX - (wordBound.X); //Match mid double dy = (y + lineBaseline + bounds.Y) - (wordBound.Y + baselineFromTop); InkUtils.transposeStrokes(inkAnalyzer, word.Strokes, dx, dy); x += spacing + wordBound.Width; } y += lineHeight + spacing; lineNumber++; } }
private void findAndDeleteStrikethrough(InkAnalyzer inkAnalyzer, InkCanvas canvas, List <Stroke> horizontalLines, ContextNodeCollection contextNodeCollection) { List <ContextNode> deletedNodes = new List <ContextNode>(); List <Stroke> removedHorizontalLines = new List <Stroke>(); //Find things to apply gestures to foreach (ContextNode node in contextNodeCollection) { if (node.Strokes.Count == 0) { continue; } Rect strikethroughBounds = node.Strokes.GetBounds(); strikethroughBounds.Height *= 0.75d; if (node is InkWordNode) { PointCollection bl = (node as InkWordNode).GetBaseline(); if (bl != null && bl.Count() > 0) { double baseline = bl[0].Y; strikethroughBounds.Height = baseline - strikethroughBounds.Y; } } for (int j = 0; j < horizontalLines.Count; j++) { if (node.Strokes[0] == horizontalLines[j]) { break; } Stroke horizontalLine = horizontalLines[j]; Rect horizontalLineBounds = horizontalLine.GetBounds(); double sideBuffer = (1 - Constants.LINE_WORD_OVERLAPSE_RATIO) / 2; double strikethroughBoundLeft = strikethroughBounds.X + strikethroughBounds.Width * sideBuffer; double strikethroughBoundRight = strikethroughBounds.X + strikethroughBounds.Width * (1 - sideBuffer); if (strikethroughBounds.IntersectsWith(horizontalLineBounds) && strikethroughBoundLeft > horizontalLineBounds.X && strikethroughBoundRight < horizontalLineBounds.X + horizontalLineBounds.Width) { //Delete strikethrough deletedNodes.Add(node); removedHorizontalLines.Add(horizontalLine); } } } foreach (Stroke stroke in removedHorizontalLines) { horizontalLines.Remove(stroke); canvas.Strokes.Remove(stroke); inkAnalyzer.RemoveStroke(stroke); } //Final step to apply the gestures, commit changes for (int i = deletedNodes.Count - 1; i >= 0; i--) { ContextNode node = deletedNodes[i]; try { Rect bounds = node.Strokes.GetBounds(); double nodeX = bounds.X; ContextNode parent = node.ParentNode; double closestX = double.MaxValue; foreach (ContextNode sibling in parent.SubNodes) { double siblingX = sibling.Strokes.GetBounds().X; if (siblingX > nodeX && siblingX < closestX) { closestX = siblingX; } } double dx = nodeX - closestX; foreach (ContextNode sibling in parent.SubNodes) { //Nodes right side of current if (sibling.Strokes.GetBounds().X > nodeX) { InkUtils.transposeStrokes(inkAnalyzer, sibling.Strokes, dx, 0d); } } canvas.Strokes.Remove(node.Strokes); inkAnalyzer.RemoveStrokes(node.Strokes); } catch (Exception e) { //Ignore already deleted error } } }