Tuesday, August 9, 2011

PDFlib & PHP - (2) What is the optlist param in many functions?

The next thing I need to understand is the optlist. This is a parameter (string) that is passed into many of the PDFlib functions. In the HELLO WERLD post, previously, the parameter is passed as a blank string in functions: begin_page_ext AND begin_document.


But what is it?


Looking through the PDFlib.com Cookbook we can see all sorts of usage, but how to make that understandable? Over in one we have a table of contents structured within an optlist structure, but what does it mean? How does it jibe with the optlist in the link-annotations example: "boxsize={50 50} fitmethod=meet matchbox={name=image_matchbox}"; ? We can see that this optlist is passed to fit_image, where as the optlist in the insert-toc, reflecting structure, is passed to begin_page_ext.


I'll explain as best as I can these questions:

  1. What options CAN GO in an optlist for what function/where to find this?
  2. How is optlist used for a suspend page/resume page?


OPTLIST for different functions - answering question one


NOTE: The API listing/real documentation for PDFlib lives here under Reference


"Option lists are a powerful yet easy method for controlling API function calls. Instead of
requiring a multitude of function parameters, many API methods support option lists,
or optlists for short. These are strings which can contain an arbitrary number of options.
Option lists support various data types and composite data like lists. In most language
bindings optlists can easily be constructed by concatenating the required keywords and
values."
"An option may have a list value according to its documentation in this PDFlib Reference.
List values contain one or more elements (which may themselves be lists). They
are separated according to the rules above, with the only difference that the equal sign
is no longer treated as a separator.
Note Option names (i.e. the key) never contain"
- Section 1, Option Lists, PDFlib API Reference

Now that I've found/read-into the available PDFlib API Reference things are starting to become much more clear. Check the Reference for syntax questions, limits, color, etc.


Using the optlist/finding possible values


The aforementioned reference contains a table of contents (known as TOC from now on). Starting there I'll explain how to use the optslist.

  1. At the end of the TOC are sections: A, B, C, and D (as of 8.0.3-API-reference). Peruse section 'C' or the equivalent: List of all Options and Keywords. This is a little overwhelming and not applicable to every function taking an optlist, but we can see there are MANY options.
    For the example we want 'A' or the equivalent: List of All Functions (it is clickable).
  2. Now that we can see the entire list it is easy to pick out what I will make a usable example of:
    • suspend_page
    • resume_page

Suspend and resume are on the same page. Suspend states:

optslist - An option list for future use.
Not extremely helpful if you ask me :)


Resume documentation is a bit more helpful, and these must be paired, i.e. where we have suspended... we must eventually resume. Resume states:

optlist - An option list according to Table 3.8. The following options can be used:

group, pagenumber


PDFlib-8.0.3-API-reference - Table 3.8 Options for PDF_resume_page( )


optiondescription
group(String; required if the document uses page groups, but not allowed otherwise) Name of the page group of the resumed page. The group name must have been defined with the groups option in PDF_begin_document( ).
pagenumber(Integer) If this option is supplied, the page with the specified number within the page group chosen in the group option (or in the document if the document doesn’t use page groups) will be resumed. If this option is missing the last page in the group will be resumed.

It seems my journey to understand how to use suspend/resume took me on a nearly full-day segue to learn about the OPTLIST for begin_document(name, optlist). So, the full example below works AND does a bunch of un-necessary extras for plain vanilla example. The important parts for suspend/resume are: We have some grouping defined in the optlist of begin_document, then we use this to suspend/resume.



try{
# number reflect an A4 sized document.
$doc_width = 595;
$doc_height = 842;
# create a new instance of PDFlib.
$p = new PDFlib();
# extras here. in cookbook examples these are not mentioned.
# but, for error logging add logging and set errorpolicy to exception.
# (thanks PDFLib support for these setting info)
$p->set_parameter("logging", "filename {PDFlib.log}");
$p->set_parameter("errorpolicy", "exception");
# set textformat
$p->set_parameter("textformat", "utf8");
# SPACES are important here, at end of concatenated lines.
# all we really need for example to work are the groups and labels chunk.
# NOTE: the index group is never used in this example and it
# does not cause any break.
$optlist = "groups={title toc content index} ".
"labels={{group=title prefix=title} ".
"{group=toc prefix={toc } start=1 style=r} ".
# style=D says: Decimal, Arabic numerals.
# search in API ref: Suboptions for the labels
"{group=content start=1 style=D} ".
"{group=index prefix={index } start=1 style=r} } ".
# we can exercise the suspend/resume now, the rest of
# theses optlist option are to simply show the usage of
# what I thought were some cool/useful ones...
"destination={ type=fixed zoom=.5 } " .
# direction defaults to l2r. switch to r2l to reverse layout,
# i.e. page 2 will be before page 1.
"viewerpreferences={displaydoctitle=true direction=l2r} ".
# "openmode=bookmarks ". If you add some new options you want/need
# and get an error that that option is wrong,
# first check you have spaces around the key=value pair.
# show thumbnails menu on open.
"openmode=thumbnails ".
# show pages side by side [1][2] odd then even.
"pagelayout=twocolumnleft ";
if ($p->begin_document("", $optlist) == 0)
throw new Exception("Error@begin_document: " . $p->get_errmsg());
# add some meta data on file
$p->set_info("Creator", "Neil Lindberg");
$p->set_info("Title", "Blog 2");
# loading font (that most will have)
$font = $p->load_font("Helvetica", "unicode", "");
# make/begin page, see:
# http://www.php.net/manual/en/function.pdf-begin-page-ext.php
$p->begin_page_ext($doc_width, $doc_height, "group=title");
# setfont before adding text, see:
# http://www.php.net/manual/en/function.pdf-setfont.php
if ($p->setfont($font, 24) == 0)
throw new Exception("Error@setfont: " . $p->get_errmsg());
# add line of text, to center of page, approximately :)
# doing a few things here to center the width and then place text.
$message = "Hello Werld!";
$message_width = $p->stringwidth($message, $font, 24);
$p->show_xy($message, ($doc_width*.5)-($message_width*.5), $doc_height*.5);
# suspending page for future access.
$p->suspend_page("");
# the first page has been suspended,
# add a second w/ content, then resume first.
$p->begin_page_ext($doc_width, $doc_height, "group=content");
if ($p->setfont($font, 12) == 0)
throw new Exception("Error@setfont: " . $p->get_errmsg());
$message = "I am page one of content group!";
$message_width = $p->stringwidth($message, $font, 12);
$p->show_xy($message, ($doc_width-$message_width)*.5, $doc_height*.5);
$p->end_page_ext("");
# second page is done, resume first via group
# opt setting and add more content.
# this resume would resume the last suspended page for group
# and would work just fine for this example: $p->resume_page("group=title");
# but, if we want to resume a specific page of multiple suspends...
# we add the pagenumber (which will not break example).
$p->resume_page("group=title pagenumber=1");
# CHECK THIS OUT: if not setting font here the font will display
# NOT in the size of the last setfont, but in the last setfont on
# the resumed page, i.e. size 24.
# Try it: comment out the setfont/throw below.
if ($p->setfont($font, 12) == 0)
throw new Exception("Error@setfont: " . $p->get_errmsg());
$message = "Or is it Hello World!?";
$message_width = $p->stringwidth($message, $font, 12);
# throwing in a little color change.
$spot = $p->makespotcolor("PANTONE 1935 U");
$p->setcolor("fill", "spot", $spot, 1.0, 0, 0);
# put this
$p->show_xy($message, ($doc_width-$message_width)*.5, ($doc_height*.5)-24);
# end page...
$p->end_page_ext("");
#
$p->end_document("");
# get and send buffer
$buf = $p->get_buffer();
$len = strlen($buf);
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=blog_2.pdf");
print $buf;
} catch (PDFlibException $e) {
die("PDFlib exception occurred:\n".
"[" . $e->get_errnum() . "] " . $e->get_apiname() .
": " . $e->get_errmsg() . "\n");
} catch (Exception $e) {
die($e->getMessage());
}



No comments: