2

I am using pdftron lib for rendering and editing pdf. I have a scenario where I have to get the coordinates of annotation and save it to db and if shape got erased delete those coordinates from database. I have manged to log both drawn coordinates & erased coordinates but drawn coordinates and erased coordinates are not matching in here. How am I suppose to delete drawn coordinates from my db if erased coordinates are not matching even though the lib deletes the shapes successfully.

My commit method

  public void commitAnnotation() {

        ArrayList<DrawPoints> points=new ArrayList<DrawPoints>();

        try {
            mPDFView.docLock(true);

            pdftron.PDF.Rect rect = getShapeBBox();
            if (rect != null) {
                float sx = mPDFView.getScrollX();
                float sy = mPDFView.getScrollY();
                pdftron.PDF.Annots.Ink ink = pdftron.PDF.Annots.Ink.create(mPDFView.getDoc(), rect);

                int pathIdx = 0;
                ListIterator<LinkedList<PointF>> itrPaths = mStrokes.listIterator(0);
                while (itrPaths.hasNext()) {
                    LinkedList<PointF> path = itrPaths.next();
                    ListIterator<PointF> itr = path.listIterator(0);
                    double[] pts = new double[2];
                    pdftron.PDF.Point p = new pdftron.PDF.Point();
                    int pointIdx = 0;
                    while (itr.hasNext()) {
                        PointF p_ = itr.next();
                        DrawPoints drawPoints=new DrawPoints();
                        pts = mPDFView.convScreenPtToPagePt(p_.x - sx, p_.y - sy, mPageForFreehandAnnot);
                        p.x = pts[0];
                        p.y = pts[1];
                        ink.setPoint(pathIdx, pointIdx++, p);
                        drawPoints.setPoint(p_);
                        drawPoints.setPathindex(pathIdx);
                        drawPoints.setPointindex(pointIdx);
                        points.add(drawPoints);
                    }
                    pathIdx++;
                }

                setStyle(ink);

                ink.refreshAppearance();

                Page page = mPDFView.getDoc().getPage(mPageForFreehandAnnot);
                page.annotPushBack(ink);

                mAnnot = ink;
                mAnnotPageNum = mPageForFreehandAnnot;
                buildAnnotBBox();

                mPDFView.update(mAnnot, mAnnotPageNum); // Update the region where the annotation occupies.
            }

            mPaint.setStrokeJoin(oldStrokeJoin);
            mPaint.setStrokeCap(oldStrokeCap);

        } catch (Exception ex) {
            mNextToolMode = ToolManager.e_pan;

        } finally {
            mPDFView.docUnlock();

            mStrokePoints.clear();
            mStrokes.clear();
        }
        if(mListener!=null){
            mListener.getStrokePoints(points);
        }else{
            Log.e(TAG, " No Listener Registered ");
        }
        mPDFView.waitForRendering();
    }

Snippet of erase

 // Erase
            double[] pt1points = mPDFView.convScreenPtToPagePt(mPrevPt.x, mPrevPt.y, mDownPageNum);
            double[] pt2points = mPDFView.convScreenPtToPagePt(mCurrentPt.x, mCurrentPt.y, mDownPageNum);
            Point pdfPt1 = new Point(pt1points[0], pt1points[1]);
            Point pdfPt2 = new Point(pt2points[0], pt2points[1]);

            try {
                mPDFView.docLock(true);
                Page page = mPDFView.getDoc().getPage(mDownPageNum);
                int annot_num = page.getNumAnnots();
                for (int i=annot_num-1;i>=0;--i) {
                    Annot annot = page.getAnnot(i);
                    if (!annot.isValid())
                        continue;
                    if (annot.getType() == Annot.e_Ink) {
                        Ink ink = new Ink(annot);
                        if (ink.erase(pdfPt1, pdfPt2, mEraserHalfThickness)) {
                            Log.i("Erased", "Erased onMove "+pdfPt1.x+" "+pdfPt1.y+" "+pdfPt2.x+" "+pdfPt2.y);
                             double[] pts = new double[2];
                             pts=mPDFView.convCanvasPtToPagePt(pdfPt1.x, pdfPt1.y, mDownPageNum);
                             for (int j = 0; j < pts.length; j++) {
                                Log.i("Erased ", "Erased converted pts "+pts[0]+" "+pts[1]);
                            }
//                          DrawPoints points=new DrawPoints();
                            if (!mInkList.contains(ink)) {
                                mInkList.add(ink);
                                mDoUpdate = true;
                            }
                        }

                    }

                }
            } catch (Exception ex) {

            } finally {
                mPDFView.docUnlock();
                mPrevPt.x = mCurrentPt.x;
                mPrevPt.y = mCurrentPt.y;
            }

This is how my log looks like :

03-06 14:53:04.947: E/Draw(1746): Draw Points x 1131.558 y 347.78265 pathIndex 0 pointIndex 1
03-06 14:53:04.947: E/Draw(1746): Draw Points x 1131.558 y 369.04636 pathIndex 0 pointIndex 2
03-06 14:53:04.947: E/Draw(1746): Draw Points x 1131.558 y 389.84354 pathIndex 0 pointIndex 3
03-06 14:53:04.951: E/Draw(1746): Draw Points x 1131.558 y 425.15198 pathIndex 0 pointIndex 4
03-06 14:53:04.951: E/Draw(1746): Draw Points x 1137.5557 y 475.53995 pathIndex 0 pointIndex 5
03-06 14:53:04.951: E/Draw(1746): Draw Points x 1137.5557 y 523.5142 pathIndex 0 pointIndex 6
03-06 14:53:04.955: E/Draw(1746): Draw Points x 1140.1648 y 553.43933 pathIndex 0 pointIndex 7
03-06 14:53:04.955: E/Draw(1746): Draw Points x 1143.5533 y 575.1314 pathIndex 0 pointIndex 8
03-06 14:53:04.955: E/Draw(1746): Draw Points x 1143.5533 y 585.5112 pathIndex 0 pointIndex 9
03-06 14:53:04.959: E/Draw(1746): Draw Points x 1143.5533 y 588.13245 pathIndex 0 pointIndex 10
03-06 14:53:04.959: E/Draw(1746): Draw Points x 1143.5533 y 589.7196 pathIndex 0 pointIndex 11
03-06 14:53:04.959: E/Draw(1746): Draw Points x 1143.5533 y 632.37 pathIndex 0 pointIndex 12
03-06 14:53:04.959: E/Draw(1746): Draw Points x 1137.4645 y 683.9676 pathIndex 0 pointIndex 13
03-06 14:53:04.963: E/Draw(1746): Draw Points x 1137.5557 y 708.979 pathIndex 0 pointIndex 14
03-06 14:53:04.963: E/Draw(1746): Draw Points x 1137.5557 y 711.25366 pathIndex 0 pointIndex 15
03-06 14:53:04.971: E/Draw(1746): Draw Points x 1137.5557 y 715.0531 pathIndex 0 pointIndex 16



03-06 14:53:29.295: I/Erased(1746): Erased onMove 197.8857521641508 607.0408325297578 199.44002904429334 593.6879611452792
03-06 14:53:29.311: I/Erased(1746): Erased onMove 199.44002904429334 593.6879611452792 199.44002904429334 589.8265169549495
03-06 14:53:29.327: I/Erased(1746): Erased onMove 199.44002904429334 589.8265169549495 200.99430592443588 585.3476263723171
03-06 14:53:29.351: I/Erased(1746): Erased onMove 200.99430592443588 585.3476263723171 200.99430592443588 583.0830710249556
03-06 14:53:29.379: I/Erased(1746): Erased onMove 200.99430592443588 583.0830710249556 200.99430592443588 581.9483495694424
03-06 14:53:29.511: I/Erased(1746): Erased onMove 200.99430592443588 581.9483495694424 200.99430592443588 576.6664117141074
03-06 14:53:29.527: I/Erased(1746): Erased onMove 200.99430592443588 576.6664117141074 202.54864607401095 572.73110046127
03-06 14:53:29.551: I/Erased(1746): Erased onMove 202.54864607401095 572.73110046127 202.54864607401095 568.2373890140615
03-06 14:53:29.563: I/Erased(1746): Erased onMove 202.54864607401095 568.2373890140615 202.54864607401095 563.1586725760926
03-06 14:53:29.587: I/Erased(1746): Erased onMove 202.54864607401095 563.1586725760926 204.10292295415348 560.3824098755857
03-06 14:53:29.619: I/Erased(1746): Erased onMove 204.10292295415348 560.3824098755857 204.10292295415348 554.1803288452473
03-06 14:53:29.639: I/Erased(1746): Erased onMove 204.10292295415348 554.1803288452473 204.10292295415348 550.7530078663927
03-06 14:53:29.667: I/Erased(1746): Erased onMove 204.10292295415348 550.7530078663927 204.70252736647586 546.8737375134407
03-06 14:53:29.679: I/Erased(1746): Erased onMove 204.70252736647586 546.8737375134407 205.65726310372855 545.2844568197372
03-06 14:53:29.699: I/Erased(1746): Erased onMove 205.65726310372855 545.2844568197372 205.65726310372855 542.818894485149
03-06 14:53:29.731: I/Erased(1746): Erased onMove 205.65726310372855 542.818894485149 205.65726310372855 537.4532037184695
03-06 14:53:29.755: I/Erased(1746): Erased onMove 205.65726310372855 537.4532037184695 205.65726310372855 534.3117340358978
03-06 14:53:29.775: I/Erased(1746): Erased onMove 205.65726310372855 534.3117340358978 205.65726310372855 531.5041846009924
03-06 14:53:29.803: I/Erased(1746): Erased onMove 205.65726310372855 531.5041846009924 205.65726310372855 526.8179600878776
03-06 14:53:29.815: I/Erased(1746): Erased onMove 205.65726310372855 526.8179600878776 205.65726310372855 524.163522679755
03-06 14:53:29.835: I/Erased(1746): Erased onMove 205.65726310372855 524.163522679755 205.65726310372855 521.9044401383096
03-06 14:53:29.871: I/Erased(1746): Erased onMove 205.65726310372855 521.9044401383096 205.65726310372855 516.5835283125208
03-06 14:53:29.895: I/Erased(1746): Erased onMove 205.65726310372855 516.5835283125208 205.65726310372855 511.1228068581439
03-06 14:53:29.923: I/Erased(1746): Erased onMove 205.65726310372855 511.1228068581439 205.65726310372855 509.33579337034837
03-06 14:53:29.947: I/Erased(1746): Erased onMove 205.65726310372855 509.33579337034837 205.65726310372855 502.5355314899201
03-06 14:53:29.971: I/Erased(1746): Erased onMove 205.65726310372855 502.5355314899201 205.65726310372855 499.1108203751584
03-06 14:53:29.991: I/Erased(1746): Erased onMove 205.65726310372855 499.1108203751584 205.65726310372855 495.58421383926714
03-06 14:53:30.019: I/Erased(1746): Erased onMove 205.65726310372855 495.58421383926714 205.65726310372855 489.60904862878675
03-06 14:53:30.031: I/Erased(1746): Erased onMove 205.65726310372855 489.60904862878675 205.65726310372855 485.9805783064822
03-06 14:53:30.071: I/Erased(1746): Erased onMove 205.65726310372855 485.9805783064822 205.65726310372855 480.81070643356
03-06 14:53:30.087: I/Erased(1746): Erased onMove 205.65726310372855 480.81070643356 205.65726310372855 478.3197888738754
03-06 14:53:30.115: I/Erased(1746): Erased onMove 205.65726310372855 478.3197888738754 205.65726310372855 473.6962801857806
03-06 14:53:30.127: I/Erased(1746): Erased onMove 205.65726310372855 473.6962801857806 205.65726310372855 470.0352577404266
03-06 14:53:30.155: I/Erased(1746): Erased onMove 205.65726310372855 470.0352577404266 205.65726310372855 468.72412528959234
03-06 14:53:30.187: I/Erased(1746): Erased onMove 205.65726310372855 468.72412528959234 205.65726310372855 463.74788951500426
03-06 14:53:30.215: I/Erased(1746): Erased onMove 205.65726310372855 463.74788951500426 205.65726310372855 459.25237488896795
03-06 14:53:30.235: I/Erased(1746): Erased onMove 205.65726310372855 459.25237488896795 205.65726310372855 456.2922195827403
03-06 14:53:30.251: I/Erased(1746): Erased onMove 205.65726310372855 456.2922195827403 205.65726310372855 452.85498112033275
03-06 14:53:30.279: I/Erased(1746): Erased onMove 205.65726310372855 452.85498112033275 205.65726310372855 451.0065646482427
03-06 14:53:30.303: I/Erased(1746): Erased onMove 205.65726310372855 451.0065646482427 205.65726310372855 445.2987127903066
03-06 14:53:30.327: I/Erased(1746): Erased onMove 205.65726310372855 445.2987127903066 205.65726310372855 439.7794671108165
03-06 14:53:30.355: I/Erased(1746): Erased onMove 205.65726310372855 439.7794671108165 204.10292295415348 435.30290167983037
03-06 14:53:30.375: I/Erased(1746): Erased onMove 204.10292295415348 435.30290167983037 204.10292295415348 431.77831976578085
03-06 14:53:30.403: I/Erased(1746): Erased onMove 204.10292295415348 431.77831976578085 204.10292295415348 427.22364822030573
03-06 14:53:30.439: I/Erased(1746): Erased onMove 204.10292295415348 427.22364822030573 204.10292295415348 424.5336850258036
03-06 14:53:30.463: I/Erased(1746): Erased onMove 204.10292295415348 424.5336850258036 204.10292295415348 422.06991005268503
03-06 14:53:30.543: I/Erased(1746): Erased onMove 204.10292295415348 422.06991005268503 204.10292295415348 420.3948518257953
03-06 14:53:30.811: I/Erased(1746): Erased onMove 204.10292295415348 420.3948518257953 206.43440154379988 411.2446050466984
03-06 14:53:30.827: I/Erased(1746): Erased onMove 206.43440154379988 411.2446050466984 205.65726310372855 409.66018028194344
03-06 14:53:30.847: I/Erased(1746): Erased onMove 205.65726310372855 409.66018028194344 205.65726310372855 404.82079628997155
03-06 14:53:30.879: I/Erased(1746): Erased onMove 205.65726310372855 404.82079628997155 205.65726310372855 402.87418565855637
Manoj
  • 2,799
  • 5
  • 30
  • 49
  • Looks like the erased coordinates are canvas coordinates, while the annotation coordinates are page coordinates. Use the PDFViewCtrl's `convCanvasPtToPagePt()` methods to convert. – 323go Mar 06 '15 at 15:00
  • @323go didnt work Let me update my question with commit method where ( i am getting draw point) and erase method. – Manoj Mar 06 '15 at 15:57
  • 2
    is the drawPoints data structure what is going into your database? If so, those are in screen coordinates, as @323go suggested. You should always store annotation info in page coordinates. Then in the erase code, pdfPt[1|2] data is page coordinates, but then later on you use them to convert from canvasToPage! When dealing with annots, you want to normalize all coordinates to page coordinates. – Ryan Mar 06 '15 at 17:01
  • @Ryan Thanks for pointing out. But I am still not getting accurate point. Drawn coordinates (x=50.745094 y=590.98346) erased start coordinates(x=47.63651, y=594.0914)I want to get draw cordinates pass it to server if I erase them I have to earse points from server too. :-( How can I achieve this? – Manoj Mar 07 '15 at 08:09
  • @Ryan How can I get erased point from annotation that is being erased. – Manoj Mar 07 '15 at 11:58

2 Answers2

1

You're searching for annotationon Page by comparing coordinates, I think that finding annotation using UDID is much simpler, and you don't have to deal with coordinates conversions from page to screen and vice versa.

use this function to set the UDID

public void SetUniqueID(string data);

and

  public Obj GetUniqueID()

Finding annotation function can look like that:

IAnnot FindAnnotOnPageByUDID(int pageIndex, long annotId)
{
    IAnnot result = null;
    Page page = _doc.GetPage(pageIndex);
    if (page != null && page.IsValid())
    {
        int num_annots = page.GetNumAnnots();
        for (int i = 0; i < num_annots; ++i)
        {
            IAnnot annot = page.GetAnnot(i);
            if (annot.IsValid())
            {
                var UniqueIdObj = annot.GetUniqueID();
                if (UniqueIdObj != null)
                {
                    var strUniqueId = UniqueIdObj.GetAsPDFText();
                    if (strUniqueId.Contains(annotId.ToString()))
                    {
                        result = annot;
                        break;
                    }
                }

            }
        }
    }
    return result;
}

This approach is also recommended by PdfTron documentation.

Just keep track of the udids of your annotations collection.

Pavel Durov
  • 1,287
  • 2
  • 13
  • 28
0

First you are passing in the mouse coordinates (pdfPt[1|2]), which of course doesn't match the ink points.

Also, when erasing, PDFNet might create/modify/delete other surrounding points can. For instance when erasing the midpoint between two Ink points.

What you should do is reload the entire Ink list from the Annotation after erasing, and replace what is in your database. This will save you a lot of headaches, and will protect you from possible future implementation changes in our library.

Ryan
  • 2,473
  • 1
  • 11
  • 14
  • Consider I have five shapes drawn on page. How do I get all points for individual shapes? I am iterating over number of annotation getting Ink ink=new Ink(annot) from current annotation but how can i get pathIndex and pointIndex for ink.GetPoint(pathIndex, pointIndex); – Manoj Mar 10 '15 at 09:52
  • I don't understand the question. Ink.getPathCount and Ink.getPointCount give the range to iterate over. As suggested you wipe out all the entries for that annot in your DB, and replace with the latest set. If you are asking how to ID an annot, there is Annot.[Set|Get]UniqueID. You can set the annots with a GUID from the OS and store the GUID in your DB. Unique is not auto generated, so you would need to do it. – Ryan Mar 11 '15 at 16:33
  • can you point me to code snippet where it shows how to get all cords of shapes on screen? we need path index and point index to redraw if we are drawing again on screen right? correct me if I am wrong . – Manoj Mar 12 '15 at 05:56