/// <summary> /// Moves all selected annotations a set amount /// </summary> /// <param name="pointOrigin"></param> /// <param name="pointDestination"></param> private void MoveSelectedAnnotations(Point pointOrigin, Point pointDestination) { try { int pageOrigin = 0; int pageDestination = 0; PdfSourcePoint pointOriginPage = controller.TransformOnScreenToOnNearestPage(new PdfTargetPoint(pointOrigin), ref pageOrigin); PdfSourcePoint pointDestinationPage = controller.TransformOnScreenToOnNearestPage(new PdfTargetPoint(pointDestination), ref pageDestination); if (pageOrigin == pageDestination) { PdfSourcePoint delta = pointDestinationPage - pointOriginPage; controller.UpdateAnnotations(new UpdateAnnotationArgs(selectedAnnotations.Select(annot => annot.Move(delta.dX, delta.dY)).ToList())); } } catch (ArgumentOutOfRangeException ex) { Logger.LogError("Could not transform origin odr destination point into page coordinates"); Logger.LogException(ex); } InvalidateVisual(); }
public IList <PdfTextFragment> GetTextWithinSelection(PdfSourcePoint start, PdfSourcePoint end, int firstPage, int lastPage, ref bool swap) { IList <PdfTextFragment> containedFragments = new List <PdfTextFragment>(); IList <int> pageRange = Enumerable.Range(firstPage, lastPage - firstPage + 1).ToList(); //intersect the markedRect with the textFragments (transformed to canvas coordinates) foreach (int page in pageRange) { List <PdfTextFragment> frags; try { frags = (List <PdfTextFragment>)documentManager.GetTextFragments(page); }catch (PdfRequestCanceledException) { Logger.LogWarning("Request to load textfragments was canceled somehow (that is not supposed to happen)"); continue; } if (frags.Count == 0) { continue; } PdfTextFragment firstFrag = frags.First(); PdfTextFragment lastFrag = frags.Last(); if (page == firstPage) { firstFrag = FindNearestTextFragment(start, frags, GetPageRect(page)); } if (page == lastPage) { lastFrag = FindNearestTextFragment(end, frags, GetPageRect(page)); } if (firstFrag == frags.First() && lastFrag == frags.Last()) { containedFragments = containedFragments.Concat(frags).ToList(); } else { int firstIndex = frags.IndexOf(firstFrag); int lastIndex = frags.IndexOf(lastFrag); if (firstIndex > lastIndex) //first and last are swapped { swap = true; containedFragments = containedFragments.Concat(frags.GetRange(lastIndex, firstIndex - lastIndex + 1)).ToList(); } else { swap = false; containedFragments = containedFragments.Concat(frags.GetRange(firstIndex, lastIndex - firstIndex + 1)).ToList(); } } } return(containedFragments); }
private PdfTextFragment FindNearestTextFragment(PdfSourcePoint location, List <PdfTextFragment> haystack, PdfSourceRect pageRect) { /* To use This, you have to invert y axis of if-checks * int needle = haystack.Count / 2; //the fragment we currently look at * int start = 0; * int end = haystack.Count - 1; * while (true) * { * PdfSourceRect rect = haystack[needle].RectOnUnrotatedPage; * * if (location.dY < rect.dY) * end = haystack.IndexOf(haystack[needle].LastOnLine); * else if (location.dY > rect.dBottom) * start = haystack.IndexOf(haystack[needle].FirstOnLine); * else * { * start = haystack.IndexOf(haystack[needle].FirstOnLine); * end = haystack.IndexOf(haystack[needle].LastOnLine); * break; * } * int s = haystack.IndexOf(haystack[start].LastOnLine) + 1; * int t = haystack.IndexOf(haystack[end].FirstOnLine) - 1; * if (s > t) * break; * needle = (t - s) / 2 + s; * } * //there are only two ways to reach this: * // * haystack[needle] is on the correct line (and thus [start,end] interval describes this one line * // * [start,end] interval spans 2 lines or less * haystack = haystack.GetRange(start, end - start + 1); */ //figure out the closest one double minDist = double.MaxValue; PdfTextFragment minDistFrag = null; foreach (PdfTextFragment frag in haystack) { double dist = frag.RectOnUnrotatedPage.ShortestDistanceSquared(location); if (dist < minDist) { minDist = dist; minDistFrag = frag; } } return(minDistFrag); }
/// <summary> /// Creates a new ink Annotation with the points from the annotationPoints list /// </summary> private void CreateInkAnnotation() { int pointCount = annotationPoints.Count; double[] points = new double[pointCount * 2]; try { int firstPage = 0; PdfSourcePoint firstPoint = controller.TransformOnScreenToOnNearestPage(new PdfTargetPoint(annotationPoints[0]), ref firstPage); points[0] = firstPoint.dX; points[1] = firstPoint.dY; if (pointCount >= 2) { for (int pointIndex = 1; pointIndex < pointCount; pointIndex++) { PdfSourcePoint point = controller.TransformOnScreenToOnSpecificPage(new PdfTargetPoint(annotationPoints[pointIndex]), firstPage); points[pointIndex * 2] = point.dX; points[pointIndex * 2 + 1] = point.dY; } } double[] color = new double[] { AnnotationStrokeColor.R / 255.0, AnnotationStrokeColor.G / 255.0, AnnotationStrokeColor.B / 255.0 }; double width = AnnotationStrokeWidthZoomDependent ? AnnotationStrokeWidth / controller.ZoomFactor : AnnotationStrokeWidth; controller.CreateAnnotation(new PdfAnnotation(PdfDocument.TPdfAnnotationType.eAnnotationInk, firstPage, points, color, width)); annotationPoints = null; } catch (ArgumentOutOfRangeException e) { Logger.LogError("Could not transform a point into page coordinates. Aborting creation."); Logger.LogException(e); annotationPoints = null; InvalidateVisual(); } }
/// <summary> /// Transforms the strokes using the selected TextConverter /// </summary> public void RecognizeText() { if (strokes != null && strokes.Count > 0) { Stroke firstStroke = strokes[0]; if (firstStroke != null && firstStroke.StylusPoints != null && firstStroke.StylusPoints.Count > 0) { StylusPoint firstPoint = firstStroke.StylusPoints[0]; int pageNr = 0; PdfSourcePoint firstPointOnPage = controller.TransformOnScreenToOnNearestPage(new PdfTargetPoint((int)firstPoint.X, (int)firstPoint.Y), ref pageNr); string content = controller.ConvertAnnotations(strokes); double[] point = new double[] { firstPointOnPage.dX, firstPointOnPage.dY }; double[] color = new double[] { AnnotationStrokeColor.R / 255.0, AnnotationStrokeColor.G / 255.0, AnnotationStrokeColor.B / 255.0 }; controller.CreateTextAnnotation(content, pageNr, point, color); } } }
/// <summary> /// Checks whether a point is inside the bounding rectangle of this annotation /// </summary> /// <param name="point"></param> /// <returns></returns> public bool ContainsPoint(PdfSourcePoint point) { return(Rect[0] <= point.dX && Rect[1] <= point.dY && Rect[2] >= point.dX && Rect[3] >= point.dY); }
private void MouseMoveEventHandler(Object sender, MouseEventArgs e) { if (!controller.IsOpen) { return; } if (OverrideMouseModeToWait) { return; } if (mouseScrolling) { Vector delta = System.Windows.Point.Subtract(e.GetPosition(this), lastMousePosition); controller.Scroll(delta); lastMousePosition = e.GetPosition(this); } else if (middleMouseScrolling) { Vector delta = System.Windows.Point.Subtract(e.GetPosition(this), lastMousePosition); double fac = delta.X / -delta.Y; if (delta.Length < 10) { Cursor = Cursors.ScrollAll; } else if (Math.Abs(-delta.Y) <= 1.0) { if (delta.X > 0) { Cursor = Cursors.ScrollE; } else { Cursor = Cursors.ScrollW; } } else if (-delta.Y > 0) { if (fac > 4) { Cursor = Cursors.ScrollE; } else if (fac > 0.25) { Cursor = Cursors.ScrollNE; } else if (fac > -0.25) { Cursor = Cursors.ScrollN; } else if (fac > -4) { Cursor = Cursors.ScrollNW; } else { Cursor = Cursors.ScrollW; } } else { if (fac > 4) { Cursor = Cursors.ScrollW; } else if (fac > 0.25) { Cursor = Cursors.ScrollSW; } else if (fac > -0.25) { Cursor = Cursors.ScrollS; } else if (fac > -4) { Cursor = Cursors.ScrollSE; } else { Cursor = Cursors.ScrollE; } } } else if (markingRectangle) { selectedRect = new Rect(lastMousePosition, e.GetPosition(this)); InvalidateVisual(); } else if (selectingText) { PdfTargetPoint p2 = new PdfTargetPoint(e.GetPosition(this)); double s1 = 0.0, s2 = 0.0; //IList<PdfTextFragment> frags = controller.GetTextWithinSelection(new PdfTargetPoint(lastMousePosition), p2, ref s1, ref s2); IList <PdfTextFragment> frags = null; try { frags = controller.GetTextWithinSelection(null, p2, ref s1, ref s2); } catch (PdfNoFileOpenedException) { selectingText = false; return; } if (frags == null) { return; } selectedRects.Clear(); StringBuilder textBuilder = new StringBuilder(); // If there are no fragments return; if (!frags.Any()) { return; } //special treatment for first and last element PdfTextFragment first = frags[0]; PdfTextFragment last = frags[frags.Count - 1]; int firstIndex = first.GetIndexOfClosestGlyph(s1); int lastIndex = last.GetIndexOfClosestGlyph(s2); int firstPageNo = controller.InversePageOrder[first.PageNo - 1]; int lastPageNo = controller.InversePageOrder[last.PageNo - 1]; if (frags.Count == 1) { //It might be that start and end point are in wrong order, as they are only ordered by textfragment and there is only one in this collection if (lastIndex < firstIndex) { int tmp = lastIndex; lastIndex = firstIndex; firstIndex = tmp; } selectedRects.Add(firstPageNo, new List <PdfSourceRect>() { first.GetRectOnUnrotatedPage(firstIndex, lastIndex) }); textBuilder.Append(first.Text.Substring(firstIndex, lastIndex - firstIndex)).Append(" "); } else { selectedRects.Add(firstPageNo, new List <PdfSourceRect>() { first.GetRectOnUnrotatedPage(firstIndex, int.MaxValue) }); textBuilder.Append(first.Text.Substring(firstIndex, first.Text.Length - firstIndex)).Append(" "); if (firstPageNo != lastPageNo) { selectedRects.Add(lastPageNo, new List <PdfSourceRect>()); } selectedRects[lastPageNo].Add(last.GetRectOnUnrotatedPage(0, lastIndex)); //remove first and last frags.RemoveAt(0); frags.RemoveAt(frags.Count - 1); foreach (PdfTextFragment frag in frags) { int fragPageNo = controller.InversePageOrder[frag.PageNo - 1]; if (!selectedRects.ContainsKey(fragPageNo)) { selectedRects.Add(fragPageNo, new List <PdfSourceRect>()); } selectedRects[fragPageNo].Add(frag.RectOnUnrotatedPage); textBuilder.Append(frag.Text).Append(" "); } textBuilder.Append(last.Text.Substring(0, lastIndex)); } _selectedText = textBuilder.ToString(); this.InvalidateVisual(); } else if (creatingDrawingAnnotation || creatingTextRecognitionNote) //[InkingForPDF] { if (annotationPoints == null) { annotationPoints = new List <Point>(); } annotationPoints.Add(e.GetPosition(this)); InvalidateVisual(); } else if (creatingClickAnnotation) //[InkingForPDF] { lastMousePosition = e.GetPosition(this); InvalidateVisual(); } else if (movingAnnotations) //[InkingForPDF] { lastMousePosition = e.GetPosition(this); InvalidateVisual(); } else if (MouseMode == TMouseMode.eMouseMarkMode && selectedAnnotations != null && selectedAnnotations.Count > 0) //[InkingForPDF] { int page = 0; try { PdfSourcePoint point = controller.TransformOnScreenToOnNearestPage(new PdfTargetPoint(e.GetPosition(this)), ref page); if (page > 0 && selectedAnnotations.Any(annot => annot.ContainsPoint(point) && annot.PageNr == page)) { this.Cursor = Cursors.SizeAll; this.mouseOverAnnotationInMarkMode = true; } else { this.Cursor = Cursors.Cross; this.mouseOverAnnotationInMarkMode = false; } } catch (ArgumentOutOfRangeException ex) { Logger.LogError("Could not transform the point into page coordinates"); Logger.LogException(ex); this.Cursor = Cursors.Cross; } } e.Handled = true; }