New issue
Advanced search Search tips
Starred by 8 users

Issue metadata

Status: Accepted
Owner: ----

Sign in to add a comment

Issue 492: PDF Tagging and highliting does not seem to work as it does in Adobe Acrobat

Reported by, May 10 2016

Issue description

What steps will reproduce the problem?

1. Open the following url 

Internet Explorer 9/10/11 (Environment: Adobe Acrobat installed + Window 7; if you don't have this configuration you can obtain the VM here

2. you will see that word "morbi" is highlighted

What is the expected output? What do you see instead?

Open same URL in Chrome (Tested on most versions up to Version 50.0.2661.94 m) and you will see that the word morbi is not highlighted

It would be expected to bring the user to the tag on the page where it was created and highlight the tagged text

What version of the product are you using? On what operating system?

Chrome (Tested on most versions up to Version 50.0.2661.94 m)

Please provide any additional information below.

additional items tagged in this document are:

Tag-1 => p1 (475,512,690,681) 'morbi'

Tag-2 => p2 (430,472,685,672) 'adipiscing'

Tag-3 => p3 (475,472,690,679) 'commodo'

Tag-4 => p4 (475,543,678,668) 'viverra'

Also here is the content of the (simplified) OpenAction script:

this.disclosed = true;
var u = this.URL;
var args = u.split('calcrtid=');
var tags;
if ( args.length > 1 ) {
	tags = args[1].split('&');
    var a = this.getAnnot( this.pageNum, tags[0] );
	var hilite = ( u.indexOf( 'hilite=true' ) == -1 ) ? 0 : 1;
	if ( hilite ) {
		var selected = '';
		if ( a != null ) {
			selected =;
		var list = this.getAnnots();
		for ( var ix = 0; ix < list.length; ++ix ) {
			var ann = list[ ix ];
			if ( ann.type == 'Highlight' ) {
				var nm =;
				ann.hidden = false;
				if ( nm == selected ) {
					ann.contents = nm + ' (SELECTED)';
				} else {
					ann.contents = nm;
    if ( a != null ) {
		a.hidden = false;
		var rect = a.rect;
		if ( rect != null ) {
			this.scroll( rect[ 2 ] + 100, rect[ 3 ] + 100 );

This functionality is very important for many users in my case more than 250,000+.  Thank you

Comment 1 by, May 10 2016

Project Member
Status: Accepted (was: New)
Is the Javascript actually relevant, or is it just a case of highlight annotations not displaying?

FWIW, opening the PDF in Safari does not show any highlighting either.

Comment 2 by, May 10 2016

Hi yes OpenAction script is for highlighting.

Comment 3 by, May 11 2016

Key part of the OpenAction script is capturing the tag name from the URL.
The tag name is used to position to proper page (goto action using named destination matching tag name), turn on the proper highlighting (un-hide annotation matching tag name), and scroll the annotation rectangle into view.

Chrome does not set the URL, so the tag is unknown, which results in no highlighting and no positioning of the annotation into view.

Using the parameter #nameddest=Tag-4 with Chrome does position to the correct page, but the parameter value is not available in the OpenAction script, so the proper annotation cannot be identified. Thus, the highlighting does not appear, nor does the rectangle scroll into view.

Comment 4 by, May 12 2016

Attaching example of what is expected when I navigate to
Tag-2 => p2 (430,472,685,672) 'adipiscing'
280 KB View Download

Comment 6 by, Aug 19 2016

Project Member
The following revision refers to this bug:

commit 618cb1f3e561b5d2a1dea9ec4653804f0da7267c
Author: tonikitoo <>
Date: Fri Aug 19 03:10:17 2016

Add initial Document::getAnnot support

CL implements the first step in order to support
Annotations manipulation in PDFium: Document::getAnnot.

The method takes two arguments, an integer (page number)
and a string (annotation name).
When called, it iterates over the annotations on
the given page number, searching for the one whose name
matches the string in the second parameter.
If found, then an Annot instance (see Annot.cpp/g added by this
CL), is bound to a Javascript object and returned.

With the use cases described in bug [1] as an initial test case,
CL adds support to the following Annotation object properties:

- hidden
- name
- type

Idea is to keep evolving the implementation with more methods
and properties in follow up CLs.





Comment 7 by, Aug 19 2016

Project Member
The following revision refers to this bug:

commit bb5fa043a7ef2de165c7903548e5663a6f8bcf9a
Author: tonikitoo <>
Date: Fri Aug 19 18:18:29 2016

Stub out Document::syncAnnotScan method.

The PDF specification [1] says:

syncAnnotScan guarantees that all annotations will be scanned
by the time this method returns.
Normally a background task runs that examine every page and
looks for annotations during idle times.

The statement details specifically how Acrobat implements
this method.
Although, neither the method itself nor the background scanner
task are implemented in PDFium (as of today, Ago/2016),
not having ::syncAnnotScan at least stubbed out can be considered
harmfull since its absence makes JS acrobat scripts silently
fail when it has a call to it.

Given that, and following a stub-out pattern present in other
methods including ::addAnnot and ::addField, CL provides
a stubbed out implementation of Document::syncAnnotScan.





Comment 8 by, Aug 24 2016

Project Member
The following revision refers to this bug:

commit ade4b495433751ac853f2d677b9e1da94d0d6bf7
Author: tonikitoo <>
Date: Wed Aug 24 17:37:00 2016

Lazy generate an "AP" when an Annot's hidden state changes

Now that Document::getAnnot works and annotation instances
can have its properties changed, consider the following

- A PDF content has an annotation without AP and
CPVT_GenerateAP is called to generate one.
- However the annotation also has its hidden flag set (/F 2),
and CPVT_GenerateAP bails out earlier, not generating an AP.
- When the PDF's Javascript runs, it acquires an instance of
this annotation object, bounded to JS using Document::getAnnot(),
and set its "hidden" flag to false.
- At this point, the annotation should get drawn, but it does
not because its "AP" was never generated.

CL fixes this scenario by making PDFium able to lazy
generate APs, if needed.




Comment 9 by, Aug 26 2016

Project Member
The following revision refers to this bug:

commit 3e98158a6c47361ca7d6c2c18d47c9f8f3aabb8a
Author: tonikitoo <>
Date: Fri Aug 26 15:37:10 2016

Extend pdfium_test capability so that more Javascript can be executed

In [1], the lack of support of pdfium_test to some application
level hooks was felt.
More specifically, the lack of implementation of the hook FFI_GetPage,
called  when 'this.getAnnot()' is executed in an Acrobar JS context,
makes it non-trivial to JS texts that manipulate PDF annotations.


Here is the failing call stack in pdfium_test:

0 ::RenderPdf                              (samples/
1 ::FORM_DoDocumentOpenAction              (fpdfsdk/fpdfformfill.cpp)
2 CPDFSDK_Document::ProcOpenAction         (fpdfsdk/fsdk_mgr.cpp)
3 CPDFSDK_ActionHandler::DoAction_DocOpen  (fpdfsdk/fsdk_actionhandler.cpp)
4 Document::getAnnot                       (fpdfsdk/javascript/Document.cpp)
5 CPDFSDK_Document::GetPageView            (fpdfsdk/fsdk_mgr.cpp)
6 CPDFDoc_Environment::FFI_GetPage         (fpdfsdk/include/fsdk_mgr.h)

(frame 6 returns nullptr, and getAnnot call in frame 4 bails)

CL extends pdfium_test app with a FFI_GetPage hook implementation.

Basically what FFI_GetPage does is returning a FPDF_PAGE instance.
In case of pdfium_test, FPDF_PAGE instances were only created on demand
when the page was going to get rendered, and then discarded.

Since FFI_GetPage can be called by JS before pages are rendered,
CL moved the page creation code into a helper function, and cached
the FPDF_PAGE instances created in a map, so it does not recreate
them needlessly.




Comment 11 by, Aug 27 2016

Project Member
The following revision refers to this bug:

commit 3e0099107a8a8e3f6d685f220530b047c9c90105
Author: tonikitoo <>
Date: Sat Aug 27 11:05:49 2016

Allows the PDF engine return the page index it is scrolling to

Chromium/PDFium behave differently from IE/Acrobat, when it
comes to the way some Javascript that scroll to a given
page index is handled.

For instance, lets assume a PDF file is showing its page
'0' and the following JS runs:

  this.pageNum = 1;

The output of the alert in IE/Acrobat is '1', whereas it is
'0' in Chromium/PDFium.
This happens because of the asynchronous way Chromium's PDF
plugin handles the "scroll to page X" request.

Also, a similar behavior difference is seen on other
Acrobat JS APIs, including Document::gotoNamedDest, where
the same code path is taken to scroll to a given page index.

CL adds an "optional" class member variable that
caches the page index the PDF is going to be scrolled
to, and allows the PDF plugin to return the target page
index even before the it has finished handling the scroll


Cr-Commit-Position: refs/heads/master@{#414921}


Comment 12 by, Aug 29 2016

Project Member
The following revision refers to this bug:

commit 5283e674fecf3732d89a8f7f144545af2301ccec
Author: tonikitoo <>
Date: Mon Aug 29 16:15:47 2016

Fix the test case added in

In [1], it was made a mistake in the way the test case
testing/resources/pixel/bug_492.pdf was generated.

This CL aims at fixing this mistake by:

1- keep making use of the new pdfium_test capability
   introduced by [1],
2- add a proper .in file for the test case to generate
   its respective .pdf file.





Comment 13 by, Aug 31 2016

Project Member
Labels: Api

Sign in to add a comment