• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Selection is extended with PDTextSelectGetBoundingRect

New Here ,
Apr 12, 2017 Apr 12, 2017

Copy link to clipboard

Copied

Hello,

I am trying to create highlight annotation for the selected text over multiple line.

For example, see in the below image:

This is my selected text. Now when I apply the annotation to this text, it looks like below:

That means selection is getting extended while applying the annotation.

Here is my code:

I have used

ACCB1 void ACCB2 createRequirement(char *sectionName) {

AVDoc avDoc = AVAppGetActiveDoc();

if (avDoc == NULL) {

  AVAlertNote("Please open the document first.");

  return;

}

PDDoc pdDoc = AVDocGetPDDoc(avDoc);

ASFixedRect boundingRect;

PDPage page = NULL;

PDAnnot annot, hilightAnnot;

LPCWSTR secName = convertCharArrayToLPCWSTR(sectionName);

LPCWSTR arg = L"value";

DWORD size = 1024;

LPCWSTR filePath = convertCharArrayToLPCWSTR(iniFilePath);

PDTextSelect pdtext =static_cast<PDTextSelect>(AVDocGetSelection(avDoc));

char reqId[2048];

char ident[2048];

int numPages = PDDocGetNumPages(pdDoc);

//Check if text is not selected

if (pdtext == NULL) {

  AVAlertNote("Please select the text first.");

  if (sectionName != NULL) {

  WritePrivateProfileString(_T(sectionName), _T("selectedText"), _T(""), _T(iniFilePath));

  }

  return;

}

if (sectionName != NULL) {

  //Create requirement from Reqtify

  GetPrivateProfileString(sectionName, "value", NULL, reqId, size, iniFilePath);

  strcpy(ident,reqId);

}

else {

  //Input box to create requirement manually

  createInputDialogBox(0, NULL, L"Requirement creation", L"Requirement ID:", L"REQ");

  if (TheText[0] == 0) {

  return;

  }

  wstring reqIdent(TheText); 

  string str(reqIdent.begin(), reqIdent.end()); 

  strcpy(ident, str.c_str());

}

//Get selected text

AVDocCopySelection(avDoc);

wchar_t* selectedText = getClipboardText();

if (selectedText == NULL) {

  AVAlertNote("Could not copy to clipboard.");

  return;

}

// Get the bounding box for the selection

PDTextSelectGetBoundingRect(pdtext, &boundingRect);

//Create a PDPage object

AVPageView currentPageView = AVDocGetPageView(avDoc);

ASInt32 pageNum = AVPageViewGetPageNum(currentPageView);

page = PDDocAcquirePage(pdDoc, pageNum);

PDColorValueRec yellow;

yellow.space = PDDeviceRGB;

yellow.value[0] = ASInt32ToFixed(1);

yellow.value[1] = ASInt32ToFixed(1);

yellow.value[2] = ASInt32ToFixed(0);

//Use the bbox to create a highight annotation QuadPoints

CosObj ArrayObj, RecObj;

CosDoc cd = PDDocGetCosDoc(pdDoc);

CosObj cosPage = PDPageGetCosObj(page);

ArrayObj = CosNewArray(cd, false, 8);

CosArrayPut(ArrayObj, 0, CosNewFixed(cd, false, boundingRect.right));

CosArrayPut(ArrayObj, 1, CosNewFixed(cd, false, boundingRect.bottom));

CosArrayPut(ArrayObj, 2, CosNewFixed(cd, false, boundingRect.left));

CosArrayPut(ArrayObj, 3, CosNewFixed(cd, false, boundingRect.bottom));

CosArrayPut(ArrayObj, 4, CosNewFixed(cd, false, boundingRect.right));

CosArrayPut(ArrayObj, 5, CosNewFixed(cd, false, boundingRect.top));

CosArrayPut(ArrayObj, 6, CosNewFixed(cd, false, boundingRect.left));

CosArrayPut(ArrayObj, 7, CosNewFixed(cd, false, boundingRect.top));

// for the Rect. Highlight annotations don't require, but API call to create annotation requires this key

RecObj = CosNewArray(cd, false, 4);

CosArrayPut(RecObj, 0, CosNewFixed(cd, false, boundingRect.left));

CosArrayPut(RecObj, 1, CosNewFixed(cd, false, boundingRect.right));

CosArrayPut(RecObj, 2, CosNewFixed(cd, false, boundingRect.bottom));

CosArrayPut(RecObj, 3, CosNewFixed(cd, false, boundingRect.top));

CosObj cosDict = CosNewDict(cd, true, 4);

CosDictPutKeyString(cosDict, "Subtype", CosNewNameFromString(cd, false, "Highlight"));

CosDictPutKeyString(cosDict, "QuadPoints", ArrayObj);

CosDictPutKeyString(cosDict, "Rect", RecObj);

annot = PDAnnotFromCosObj(cosDict);

hilightAnnot = CastToPDTextAnnot(annot);

//Open the annotation, set the text, and add it to a page

PDTextAnnotSetOpen(hilightAnnot, true);

PDTextAnnotSetContents(hilightAnnot, ident, strlen(ident));

//Fix 197842 starts

//Adds logged in Username as a Annotation title

char username[UNLEN + 1];

DWORD username_len = UNLEN + 1;

GetUserName(username, &username_len);

PDAnnotSetTitle(hilightAnnot, username, strlen(username));

//Fix 197842 ends

PDPageAddAnnot(page, -2, annot);

PDPageNotifyContentsDidChange(page);

PDAnnotSetColor(annot, &yellow);

AVPageViewDrawNow(currentPageView);

if (ASAtomFromString("Highlight") == PDAnnotGetSubtype(annot) && sectionName != NULL)

{

  std::wstring  text;

  std::wstring str;

  std::wstringstream stringStream;

  stringStream << selectedText;

  while (stringStream >> text)

  {

  str.append(text);

  str.append(L" ");

  }

  trim(str);

  LPCWSTR secName = convertCharArrayToLPCWSTR(sectionName);

  LPCWSTR arg = L"selectedText";

  LPCWSTR reqText = str.c_str();

  LPCWSTR filePath = convertCharArrayToLPCWSTR(iniFilePath);

  WritePrivateProfileStringW(secName, arg, reqText, filePath);

}

PDPageRelease(page);

}

I have used PDTextSelect to select the text and PDTextSelectGetBoundingRect to get the bounding rect of selected text.

Can you please tell me what is missing or wrong in this code?

Thank you in advance!!

TOPICS
Acrobat SDK and JavaScript

Views

988

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 12, 2017 Apr 12, 2017

Copy link to clipboard

Copied

You make only one quad point, the enclosing rectangle. The highlight correctly shows this. There is no magic to adjust the highlight to actual text. Normally there is a quad per selected line.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 12, 2017 Apr 12, 2017

Copy link to clipboard

Copied

Okay. So, how can I get the quad for per selected line?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 13, 2017 Apr 13, 2017

Copy link to clipboard

Copied

I believe there is a method to list or enumerate the quads for a PDTextSelect.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 19, 2017 Apr 19, 2017

Copy link to clipboard

Copied

Hello,

As you said, I used PDTextSelectEnumQuads method to enumerate the quads and apply the annotation.

But this method returns quads to every word inside the selection text and hence, highlight annotation is getting applied to every word.

So now there are multiple annotations to selected text whereas my intention is to have only a single annotation.

How to merge these annotations into single one.

Any example or method names will be helpful.

Thanks.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 19, 2017 Apr 19, 2017

Copy link to clipboard

Copied

It sounds as if you are making a new annotation for each quad that is enumerated. No. Collect all of the quads and make ONE annotation with all of the quads. No other methods are needed.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 19, 2017 Apr 19, 2017

Copy link to clipboard

Copied

OK. But how to put those quads in Cos object? And to create annotation we need a Cos Dictionary with three keys as below:

  1. CosDictPutKeyString(cosDict, "Subtype", CosNewNameFromString(cd, false, "Highlight")); 
  2. CosDictPutKeyString(cosDict, "QuadPoints", ArrayObj); 
  3. CosDictPutKeyString(cosDict, "Rect", RecObj); 

How can I map those quad with my code?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 19, 2017 Apr 19, 2017

Copy link to clipboard

Copied

Did you read the specification of QuadPoints in the PDF Reference?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 19, 2017 Apr 19, 2017

Copy link to clipboard

Copied

Hello,

Yes, I read the PDF reference.

According to them, I created 8 X n array of quads where n is the number of quads.

Here is my code:

arr = CosNewArray(cd, false, quadCount);

for (int i = 0; i < quadCount; i++) {

  ArrayObj = CosNewArray(cd, false, 8);

  boundingRect = rects;

  CosArrayPut(ArrayObj, 0, CosNewFixed(cd, false, boundingRect.right));

  CosArrayPut(ArrayObj, 1, CosNewFixed(cd, false, boundingRect.bottom));

  CosArrayPut(ArrayObj, 2, CosNewFixed(cd, false, boundingRect.left));

  CosArrayPut(ArrayObj, 3, CosNewFixed(cd, false, boundingRect.bottom));

  CosArrayPut(ArrayObj, 4, CosNewFixed(cd, false, boundingRect.right));

  CosArrayPut(ArrayObj, 5, CosNewFixed(cd, false, boundingRect.top));

  CosArrayPut(ArrayObj, 6, CosNewFixed(cd, false, boundingRect.left));

  CosArrayPut(ArrayObj, 7, CosNewFixed(cd, false, boundingRect.top));

  CosArrayPut(arr, i, ArrayObj);

}

CosObj cosDict = CosNewDict(cd, true, 4);

CosDictPutKeyString(cosDict, "Subtype", CosNewNameFromString(cd, false, "Highlight"));

CosDictPutKeyString(cosDict, "QuadPoints", arr);

annot = PDAnnotFromCosObj(cosDict);

But at line 28, I am receiving "Invalid annotation object" error.

Please help.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 19, 2017 Apr 19, 2017

Copy link to clipboard

Copied

Ah, I see the problem. You are not creating an array of 8 x "n" numbers. Rather you are creating an array of "n" arrays. If your two quads were [a b c d e f g h] and [p q r s t u v w], you create [ [a b c d e f g h]  [p q r s t u v w] ] but what is needed is [ a b c d e f g h p q r s t u v w ], just 16 numbers in 1 array.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 20, 2017 Apr 20, 2017

Copy link to clipboard

Copied

Hello,

Thank you for this additional information.

Now I am able to create annotation. But the problem is when I select the annotation, selection border does not seem good.

Here is the snapshot when I select my highlighted annotation:

And here is my latest code:

ArrayObj = CosNewArray(cd, false, 8*quadCount);

RecObj = CosNewArray(cd, false, 4);

for (int i = 0; i < quadCount; i++) {

  boundingRect = rects;

  CosArrayPut(ArrayObj, index++, CosNewFixed(cd, false, boundingRect.right));

  CosArrayPut(ArrayObj, index++, CosNewFixed(cd, false, boundingRect.bottom));

  CosArrayPut(ArrayObj, index++, CosNewFixed(cd, false, boundingRect.left));

  CosArrayPut(ArrayObj, index++, CosNewFixed(cd, false, boundingRect.bottom));

  CosArrayPut(ArrayObj, index++, CosNewFixed(cd, false, boundingRect.right));

  CosArrayPut(ArrayObj, index++, CosNewFixed(cd, false, boundingRect.top));

  CosArrayPut(ArrayObj, index++, CosNewFixed(cd, false, boundingRect.left));

  CosArrayPut(ArrayObj, index++, CosNewFixed(cd, false, boundingRect.top));

}

ASFixedRect annotLoc = rects[quadCount-1];

CosArrayPut(RecObj, 0, CosNewFixed(cd, false, annotLoc.left));

CosArrayPut(RecObj, 1, CosNewFixed(cd, false, annotLoc.right));

CosArrayPut(RecObj, 2, CosNewFixed(cd, false, annotLoc.bottom));

CosArrayPut(RecObj, 3, CosNewFixed(cd, false, annotLoc.top));

CosObj cosDict = CosNewDict(cd, true, 2);

CosDictPutKeyString(cosDict, "Subtype", CosNewNameFromString(cd, false, "Highlight"));

CosDictPutKeyString(cosDict, "QuadPoints", ArrayObj);

CosDictPutKeyString(cosDict, "Rect", RecObj);

annot = PDAnnotFromCosObj(cosDict);

Selection border should look like below:

What am I missing or doing wrong here?

Thanks.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 20, 2017 Apr 20, 2017

Copy link to clipboard

Copied

Ah, this was not what I expected but I understand it. The selection gives you a quad for each word. But when you make a highlight in Acrobat I believe it stores a quad for each line.

You should examine existing annotations made by Acrobat to confirm this. (By examine, I mean look at PDF internals).

It it will be up to you to transform this information. Print out the selection quads and look for a pattern you can match. Do they have the same baseline? Or do you need to use more complex fuzzy logic? Interesting problem. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 20, 2017 Apr 20, 2017

Copy link to clipboard

Copied

>>Print out the selection quads and look for a pattern you can match. Do they have the same baseline?

I did understand this statement. How to print out the selection quads and which matching pattern do you mean?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 20, 2017 Apr 20, 2017

Copy link to clipboard

Copied

You must write code that analyses the quads (one per word), and derives a new list of quads (one per line). Your first step is to look in detail at the input, so you can start to derive an algorithm, to make your output.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 20, 2017 Apr 20, 2017

Copy link to clipboard

Copied

But even if I make a list of quads for per line and make annotation, then when that annotation is selected, selection border will appear for each line. I want the border as I mentioned below image:

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 20, 2017 Apr 20, 2017

Copy link to clipboard

Copied

What set of quads is used in the example? It is time for detailed analysis of what you hope to copy.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 20, 2017 Apr 20, 2017

Copy link to clipboard

Copied

Oh, that isn't what I said. I did NOT say to make a list of quads per line.

You need to make ONE annotation. If the selection has three lines it needs THREE sets of quads. Your difficult task is to work out the coordinates of the three quads you must make, from the many quads from each word.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 27, 2023 Jun 27, 2023

Copy link to clipboard

Copied

LATEST

@kundan24352562 do you have example code to PDTextSelectEnumQuads? 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines