One of the nice things about Acrobat's JavaScript implementation is that
you can use JavaScript to change the fillColor, strokeColor, and textColor
properties of the Field object at runtime. In plain English, that means you
can alter the color of text-field backgrounds and borders (and the text
itself) programmatically so that, for example, the text in a text field
could change color in response to a mouse-over event. Or, the text on a
certain part of the page could be in black up to a certain cutoff date,
then appear red after that date. Or, you could give the user a popup list
of color preferences (see code example further below).
Without further ado, let's go through a crash course in Acrobat JavaScript
color conventions, so that you'll know how to manipulate colors when you
need to do so.
Colors Are Arrays
Rule No. 1 is: in Acrobat, colors are arrays. By convention, the first item
in the array is the color space (designated by a string): 'T' for
transparent, 'G' for grayscale, 'RGB' for red-green-blue, or 'CMYK' for
cyan-magenta-yellow-black. Subsequent positions in the array designate
color-channel values (which can range from zero to one). For 'T', there are
no subsequent positions. For 'G', there is one channel value (indicating
the amount of white, incidentally; not black). For 'RGB' there are three
extra array slots, and for 'CMYK' there are (obviously) four channel values.
Creating a new color on the fly is as easy as:
var myDarkRed = ['RGB',0.5,0,0]; // dark red
var darkRed = new Array('RGB',0.5,0,0); // equivalent
In either case, you've created an array that meets the definition of a
color. To access the green channel of the darkRed color, you'd inspect or
set darkRed[2]. The blue channel would be darkRed[3]. To check whether
you're dealing with an 'RGB' color, you'd inspect darkRed[0].
Convenience Colors
For convenience, Adobe's engineers have predefined some colors that you can
use wherever a quick color choice is needed. The colors are defined in the
AForm.js file as follows:
color.transparent = new Array("T");
color.black = new Array("G", 0);
color.white = new Array("G", 1);
color.dkGray = new Array("G", 0.25);
color.gray = new Array("G", 0.5);
color.ltGray = new Array("G", 0.75);
color.red = new Array("RGB", 1, 0, 0);
color.green = new Array("RGB", 0, 1, 0);
color.blue = new Array("RGB", 0, 0, 1);
color.cyan = new Array("CMYK", 1, 0, 0, 0);
color.magenta = new Array("CMYK", 0, 1, 0, 0);
color.yellow = new Array("CMYK", 0, 0, 1, 0);
To specify a dark gray (75% gray) background color for a text field named
'CustomerName', you'd do:
Notice that white is defined as the array ["G",1]. It could just as easily
be defined as ['RGB',1,1,1]. But it's not! If you write a custom function
that "averages" colors (by numerically averaging the RGB channel values),
you'll get in trouble when you try to average, say, color.red with
color.white. You'll also get in trouble if you try to interpolate between
color.red and color.yellow. The colors (as defined above) are in different
color spaces. In Adobe's world, color.white and color.yellow are not RGB
colors.
The lesson here is, always check the color-space value (the zeroth item of
the color array) first, to see which color space you're operating in,
BEFORE trying to manipulate channel values. Otherwise, you're asking for a
runtime error.
Color Comparison
If you have version 4.05 of Acrobat or Reader, you'll find that the
AForm.js file (in your Plug-Ins:AcroForm:JavaScripts folder) contains
convenience methods for doing color comparisons and converting between
color spaces. You can use color.equal(c1,c2) to compare two colors, c1 and
c2, for equality:
var y1 = ['RGB',1,1,0]; // yellow in RGB
var y2 = ['CMYK',0,0,1,0]; // yellow in CMYK
var bool = color.equal(y1,y2); // bool is true!
The color comparison is done in a "smart" way, by first converting both
colors to the same color space. Then the arrays are checked position by
position. The actual code for this is shown in AForm.js.
Color-Space Conversion
Also available in Acrobat 4.05 is a convenience method for converting
between color spaces. Say you have an RGB color that you'd like to know the
CMYK equivalent of.
var myRed = ['RGB',0.8,0,0];
var myRed2 = color.convert(myRed,'CMYK'); //
After the second line executes, myRed2 will equal ['CMYK',0.8,1,0.8,0]. You
can also set a text field's background color to the new color to see how it
compares to the original. (As you probably know, colors don't always stay
the same when converted from one space to another.)
A Popup Menu for Colors
Here's a code example for advanced JavaScript users that shows how to set
the fill color for a text-field named 'swatch' on the fly, on the basis of
a user selection from a popup menu. To try it out, create a new text field
(using Acrobat's Form tool) and name it 'swatch', then create a push button
(with whatever name you want) and attach the following code to the
mouse-DOWN event of the button:
var colors = new Array();
for (var i in color)
colors.push(i); // get a list of colors
while (colors[0] != 'transparent')
colors.shift(); // bump the non-colors
colors.unshift('Choose a Color:'); // label
var choice = app.popUpMenu(colors); // show menu
if (choice != null) // did user select something?
this.getField('swatch').fillColor = eval('color.' + choice);
Let's walk through this code one statement (one semicolon) at a time.
First, we start by creating an empty array named 'colors'. In the second
statement, we use JavaScript's "for-in" loop construct to enumerate all the
properties of Adobe's color object (in AForm.js), pushing them into our
array. The first two members of the array, however, will be 'equal' and
'convert' (the convenience methods described above), which we don't want.
Therefore we 'shift' those out of the array. In the zeroth position of the
array, we want the label "Choose a Color:" for our popup menu, so we
unshift that string into place. Then we use the undocumented popUpMenu()
method of the App object to create a popup menu for the user to select a
color from.
Finally, we check to be sure the user actually CHOSE something (i.e., the
'choice' was non-null), then set the 'swatch' fill color to whatever the
user chose. If the user chose 'blue', we construct the string 'color.blue'
and evaluate it. Remember Rule No. 1. Colors are not Strings. Colors are
Arrays. If we had left the eval() operation off the color choice, in the
last line of code, we would have been trying to set the fill color to a
String, which is a no-no.
One more caveat: Don't try to use 'color.transparent' for a textColor or a
fgColor. (The latter property has been deprecated. It is replaced by
textColor.) Only background (fill) colors can be set to transparent.
Despite the numerous benefits, there can be potential issues with the conversion of paper documents into electronic archives. When scanning paper pages into PDF, it's possible to end up with the odd- and even-numbered pages in separate PDF files. It can be very time-consuming to collate them manually, but there is an easier way. Sean Stewart explains.
BCL easyPDF SDK is a set of PDF Programming Libraries designed specifically to help Software Developers / Programmers build and deploy enterprise class PDF applications for corporate wide PDF...