Working with Page Views and Contents¶
A page view is the area of the Acrobat or Adobe Reader window that displays the visible content of a document page. An example of a page view is a PDF document page displayed within Adobe Reader or Acrobat at a 120% magnification.
About page coordinates¶
When working with page views and page contents, it is often necessary to specify page coordinates. Two coordinate systems are applicable to the Acrobat core API:
User space
Device space
User space is the coordinate system used within PDF documents. It specifies coordinates for most objects in the PD layer. (See Portable Document layer.)
When working with the user space coordinate system, you use an ASFixedRect
object to represent a rectangle. For example, to place an annotation on a page, create an ASFixedRect
object and specify its coordinates. To specify a ASFixedRect
object’s coordinates, you must define its top
, right
, bottom
, and left
attributes. (See Creating text annotations.)
The following diagram shows a user space coordinate system.
Device space specifies coordinates in screen pixels and is used in the AV layer to specify screen coordinates of windows. In device space, you use an AVRect
object to represent a specific coordinate. The following diagram shows a device space coordinate system.
The AVPageViewRectToDevice
method can transform a rectangle’s coordinates from user space to device space. For example, you can use PD methods to determine user space coordinates of a rectangle. However, to display an outline around the rectangle, you must convert user space coordinates to device space coordinates. (See Modifying page contents.)
About page views¶
A page view is represented by an AVPageView
object. To create an AVPageView
object, invoke the AVDocGetPageView
method. (See Displaying page views.)
Using AVPageView
methods, you can perform page-view tasks such as:
Displaying a page.
Selecting a zoom factor.
Scrolling the displayed page.
Highlighting one or more words.
Controlling screen redrawing.
Traversing the view stack that records where users have been in a document.
Note
To control the size of the page view, you can invoke the AVWindowSetFrame
and AVDocSetSplitterPosition
methods. (See the Acrobat and PDF Library API Reference.)
Displaying page views¶
Using the Acrobat core API, you can programmatically display a page view by performing the following tasks:
Create an
AVDoc
object that represents the PDF document that contains the page on which the page view is based. (See Opening PDF documents.)If desired, ensure that the specified page number does not exceed the number of pages located in the document. Convert the
AVDoc
object to aPDDoc
object by invoking theAVDocGetPDDoc
method. This method requires anAVDoc
and returns aPDDoc
object. Get the total number of pages located within the document by invoking thePDDocGetNumPages
method. This method requires aPDDoc
object and returns anASInt32
object representing the number of pages within the document.Create an
AVPageView
object that represents the page view by invoking theAVDocGetPageView
method. This method requires anAVDoc
object and returns anAVPageView
object.Specify the page view’s page number by invoking the
AVPageViewGoTo
method. This method requires anAVPageView
object that represents the page view and anASInt32
object that specifies the page number. The page number uses a zero-based index value. Therefore the value of the first page is0
.Display the page view by invoking the
AVPageViewDrawNow
method and passing theAVPageView
object. When you invoke a method that affects a page view, you must invoke this method to redraw the page and display the page view. Otherwise, changes to a page view are not displayed.
The following code example displays a page view that is based on an AVDoc
object named myDocument
. The specified page of the page view is 40 (which displays page 41). For information about creating an AVDoc
object, see Opening PDF documents.
//Create local variables
ASInt32 totalPages;
ASInt32 pageNum= 40;
AVPageView pageView;
//Convert the AVDoc to a PDDoc and get the page count
PDDoc pdDoc = AVDocGetPDDoc(myDocument);
totalPages= PDDocGetNumPages(pdDoc);
if (pageNum < totalPages){
//Get a AVPageView object and display it
pageView = AVDocGetPageView(myDocument);
AVPageViewGoTo(pageView,pageNum);
AVPageViewDrawNow (pageView);
}
Modifying page contents¶
Pages in a PDF document are represented by a PDPage
object. Pages can contain properties such as annotations, contents, resources, bounding box, media box, crop box, rotation state, and Cos objects. These properties make up the page’s content. PDPage
methods enable you to perform tasks such as retrieving objects such as annotations, adding new objects, removing objects, and modifying existing objects.
To access a PDPage
object, you must obtain the applicable PDDoc
object, either directly or by invoking the AVDocGetPDDoc
method. You can then invoke the PDDocAcquirePage
method to acquire the page (the PDPage
object).
To access the contents of PDF pages, you use PD
layer methods. In addition, the Acrobat core API provides the PDFEdit
typedef, which provides an easy way to access to the contents of a PDF page. PDFEdit
methods are useful when working with page items such as images, paths, graphics, and text objects. This API treats the contents of a page as a list of objects whose values and attributes can be modified.
Each PDFEdit
object encapsulates all the relevant information about itself. A PDEText
object, for example, contains text and its attributes such as font and position on the page. It can access single characters or multiple character strings, but not words. To access words, you need to use PD
layer methods. For information see Portable Document layer.
Creating a PDEContent object¶
A PDEContent
object is a container object that contains modifiable contents of a PDPage
including PDEText
, PDEPath
, and PDEImage
objects. After you create a PDEContent
object, you can access and modify objects that it contains.
Create a PDEContent
object by performing the following tasks:
Create an
AVDoc
object by invoking theAVAppGetActiveDoc
method. This method gets the frontmost document located within Adobe Reader or Acrobat.Create an
AVPageView
object by invoking theAVDocGetPageView
method. This method requires anAVDoc
object and returns anAVPageView
object.Get the current page number of the PDF document by invoking the
AVPageViewGetPageNum
method. This method requires anAVPageView
object and returns aPDPageNumber
object that represents the current page number.Create a
PDDoc
object by invoking theAVDocGetPDDoc
method. This method requires anAVDoc
object and returns aPDDoc
object.Create a
PDPage
object by invoking thePDDocAcquirePage
method. This method requires aPDDoc
object and aPDPageNumber
object as arguments and returns aPDPage
object.Create a
PDEContent
object by invoking thePDPageAcquirePDEContent
method and passing aPDPageNumber
object and anASExtension
object that represents the identity of the caller. For plugins, you can use thegExtensionID
extension (this is defined in the PIMain.c file).
The following code example creates a PDEContent
object.
AVDoc avDoc = AVAppGetActiveDoc();
AVPageView pageView = AVDocGetPageView(avDoc);
PDPageNumber
pageNum = AVPageViewGetPageNum(pageView);
/* Bridge method to PD doc*/
PDDoc pdDoc = AVDocGetPDDoc(avDoc);
/* Acquire current page */
PDPage
pdPage = PDDocAcquirePage(pdDoc, pageNum);
PDEContent
pdeContent = PDPageAcquirePDEContent(pdPage, gExtensionID);
Accessing page contents¶
Before you can modify page contents, you must access them by using a PDEContent
object, which is a collection object that stores page contents. Each page content is stored as an element within the PDEContent
object. An element is represented by a PDEElement
object. For example, a PDEElement
object can contain an annotation.
To access page contents, perform the following tasks:
Create a
PDEContent
object. (See Creating a PDEContent object.)Invoke the
PDEContentGetNumElems
method to retrieve the number of elements located within thePDEContent
object. This method requires aPDEContent
object and returns anASInt32
object that specifies the number of elements.Iterate through the
PDEContent
object and retrieve each element by invoking thePDEContentGetElem
method. This method requires aPDEContent
object and anASInt32
object that specifies the element index (this is a zero-based value) and returns aPDEElement
object that represents a specific page property.
The following code example accesses each element located in a PDEContent
object.
Accessing page contents
//Declare a PDEElement object
PDEElement pdeElement;
//Get the number of elements in the PDEContent object
ASInt32 eleNum = PDEContentGetNumElems(pdeContent);
//Get each element in the PDEContent object
for (int j=0; j<eleNum; j++){
pdeElement = PDEContentGetElem(pdeContent, j);
}
Determining page element types¶
You can determine the element type that a PDEElement
object represents by invoking the PDEObjectGetType
method. This method requires a PDEObject
; however, you can pass a PDEElement
object and cast it to a PDEObject
. This method returns an ASInt32
object that specifies the element type. For example, if the element is a text element, this method returns kPDEText
. For a listing of all element types, see the Acrobat and PDF Library API Reference.
The following code example determines the element type by adding application logic to the application logic introduced in Accessing page contents.
//Declare a PDEElement object
PDEElement pdeElement;
//Get the number of elements located in the PDEContent object
ASInt32 eleNum = PDEContentGetNumElems(pdeContent);
//Get each element located within the PDEContent object
for (int j=0; j<eleNum; j++){
pdeElement = PDEContentGetElem(pdeContent, j);
//Determine if the element is a text element
if (PDEObjectGetType((PDEObject)pdeElement) == kPDEText){
//Perform an action
}
Modifying text elements¶
You can modify elements located within a PDEContent
object. This section discusses modifying text elements by placing a red border around them. To place a red border around a text element, you must create a PDColorValueRec
object and define its attributes.
//Create a PDColorValue and define red
PDColorValueRec red;
red.space = PDDeviceRGB;
red.value[0] = ASInt32ToFixed(1);
red.value[1] = 0;
red.value[2] = 0;
After you create a PDColorValueRec
object, you can attach it to an AVPageView
object by invoking the AVPageViewSetColor
method. This method requires an AVPageView
object and a PDVColorValueRec
object. Once set, this color is used in drawing operations.
A text element is represented by a PDEText
object, which is a container of text runs. A text run can be a single character or multiple characters having the same attributes in a PDF file. You can get the number of text runs located within a PDEElement
object by invoking the PDETextGetNumRuns
method and passing the PDEElement
object and casting it as a PDEText
object.
int numRuns = PDETextGetNumRuns((PDEText) pdeElement);
You can draw a red border around each PDEText
object by performing the following tasks:
Get the bounding box of the
PDEText
object by invoking thePDETextGetBBox
method and passing the following arguments:A
PDEText
object that represents the text element whose bounding box is obtained.A
PDETextFlags
value that specifies whether index refers to the character offset from the beginning of the text object or the index of the text run. Must be eitherkPDETextChar
for a text character orkPDETextRun
for a text run.An
ASInt32
value that specifies the index of the character or text run.The address of an
ASFixedRect
object that is populated with the coordinates of the bounding box of a specified character or text run.
Transform the bounding box’s coordinates from user space to device space by invoking the
AVPageViewRectToDevice
method and passing the following arguments:An
AVPageView
object that represents the page view for which the coordinates are transformed. Use the sameAVPageView
object that was used to create aPDEContent
object. (See Creating a PDEContent object.)The address of the
ASFixedRect
object that was passed to thePDETextGetBBox
method. This object contains coordinate data that is transformed.The address of an
AVRect
object that is populated with device space coordinates.
Draw a stroked, but not filled, rectangle by invoking the
AVPageViewDrawRectOutline
method and passing the following arguments:An
AVPageView
object that represents the page view in which the rectangle is drawn.The address of the
AVRect
object that specifies device space coordinates. You can pass the address of the sameAVRect
object that was passed to theAVPageViewRectToDevice
method.An
AVDevSize
object that specifies the border width in pixels.The address of an
ASFixed
object whose elements specify the length of dashes and gaps. You can specifyNULL
to draw a solid outline.An
AVTArraySize
object that specifies the number of elements in theASFixed
object. This value is ignored if you specifiedNull
as the previous argument. As a result, you can specify0
for this argument. The maximum allowed number of elements is currently 10.
The following code example modifies page contents by placing a red border around text elements and places a blue border around other elements that are located within a PDEContent
object.
//Declare objects used in this code example
PDEElement pdeElement;
ASFixedRect bbox;
AVRect rect;
PDColorValueRec red, blue;
//Define red
red.space = PDDeviceRGB;
red.value[0] = ASInt32ToFixed(1);
red.value[1] = 0;
red.value[2] = 0;
//Define blue
blue.space = PDDeviceRGB;
blue.value[0] = 0;
blue.value[1] = 0;
blue.value[2] = ASInt32ToFixed(1);
//Create a PDEContent object based on the current page view
AVDoc avDoc = AVAppGetActiveDoc();
AVPageView pageView = AVDocGetPageView(avDoc);
PDPageNumber pageNum = AVPageViewGetPageNum(pageView);
PDDoc pdDoc = AVDocGetPDDoc(avDoc);
PDPage pdPage = PDDocAcquirePage(pdDoc, pageNum);
PDEContent pdeContent = PDPageAcquirePDEContent(pdPage, gExtensionID);
//Get the number of elements located in the PDEContent object
ASInt32 eleNum = PDEContentGetNumElems(pdeContent);
//Retrieve each element in the PDEContent object
for (int j=0; j < eleNum; j++){
//Get a specific element
pdeElement = PDEContentGetElem(pdeContent, j);
//Determine if the object is of type text
if (PDEObjectGetType((PDEObject) pdeElement) == kPDEText){
//Get the number of text runs in the text element
int numTextRuns = PDETextGetNumRuns((PDEText) pdeElement);
//Assign red to the page view
AVPageViewSetColor(pageView, &red);
for (int i = 0; i < numTextRuns; i++){
//Get the bounding box of the text run
PDETextGetBBox ((PDEText) pdeElement, kPDETextRun, i, &bbox);
//Convert from user space bbox to device space rect
AVPageViewRectToDevice (pageView, &bbox, &rect);
//Draw the rect
AVPageViewDrawRectOutline (pageView,&rect, 1, NULL, 0);
}
}
else
{
//Assign blue to the page view
AVPageViewSetColor(pageView, &blue);
//Get the bounding box of the non-text element
PDEElementGetBBox (pdeElement, &bbox);
//Convert from user space bbox to device space rect
AVPageViewRectToDevice (pageView, &bbox, &rect);
//Draw the rect
AVPageViewDrawRectOutline (pageView, &rect, 1, NULL, 0);
}
}
//Release objects
PDPageRelease(pdPage);
PDPageReleasePDEContent (pdPage, gExtensionID);