Karakas Online

7.2.2. Figures

This is a serious problem most people fail in first place. LaTeX (and LyX) expects the images to be in encapsulated PostScript® (.eps) format (see Section 5.7). On the other hand, pdfjadetex (see Section 3.4) is not capable of dealing with eps (only with PDF, JPEG, PNG or MetaPost), we will have to convert the images to encapsulated PDF (.epdf) format, while still carrying the .pdf ending! This is best done by the addd script, which in turn uses convert (from the Image Magick package) and eps2pdf. The script works as follows (FIXME: The script has been simplified. I didn't test it extensively though. The following describes the old script):

Some variables are set first:

CONVERT="/usr/bin/convert" (1)
DENSITY=133 (2)
(1)
The location of the convert utility. It is part of the ImageMagick package, so you must have ImageMagick installed.
(2)
The "dots-per-inch" of the device where the image was made. If you plan to use the addd script to add density to screenshots, then this is the DPI value of the monitor where the screenshots were made.

This procedure will create pdf and png files with the right resolution (density) information. Unfortunately the eps file that is also created as a by-product, will display somewhat smaller. FIXME: This may be the result of ghostview not using the right DPI when it displays the image, so it may be a problem of my system configuration.

You can automate the “add density” procedure using the adddscr script, which is included in the packages that you will find in Section 1.2:

#! /bin/sh
for x in `ls *.$1`; do
y=`basename $x .$1`
convert $y.$1 $y.png
addd $y
convert $y.png $y.bmp
done

The adddscr script accepts one parameter: the format from which you want to start the conversion. The idea is the following: suppose you have a set of GIFs, but no PNGs or any other format. Then you can change to the directory of the images, type

adddscr gif

and get your GIFs converted to PNGs, then get EPDF (renamed as PDF) and EPS version with added density. If you only have, say, BMP versions, just type

adddscr bmp

and the script will convert your BMPs to PNGs first, then to all other formats, adding density on the way.

For example, you can use the adddscr script the very first time you install the docbook-dsssl-stylesheets RPM. The RPM package offers GIF, EPS and PDF versions of admonitions (see Section 4.7) and callouts (see Section 4.8). The EPS and PDF versions surely come with the density of the system (read: monitor) they were created on, so it may not be wise to add density to them once again (if you do it, it may make the admonition and callout icons display smaller or larger than they should in PDF and PS documents)[3]. However, while you might want to leave the EPS and PDF versions untouched, you definitely need PNG and BMP versions of the images. Here's where the adddscr script comes in handy:

Comment the line that adds density in adddscr:

#! /bin/sh
for x in `ls *.$1`; do
y=`basename $x .$1`
convert $y.$1 $y.png
# addd $y
convert $y.png $y.bmp
done

change to the directory of the admonitions and callouts:

cd /usr/share/sgml/docbook/docbook-dsssl-stylesheets/images

then type

adddscr gif

Do the same for the callouts:

cd /usr/share/sgml/docbook/docbook-dsssl-stylesheets/images/callouts
adddscr gif

Now you have PNG and BMP versions of all your admonition and callout icons![4]

If you wondered why your images dont't get included in the PDF, although you meticulously prepared everything “right”, now you know why! But there's more to it - read on!smile

Note But what is this "density" anyway?
 

From problem downsampling:

You should think of a digital image as a rectangular pixel grid. Suppose you have an image of 1500 by 2000 pixels. The image could be printed (on paper) or viewed (on screen). For that purpose, you have to tell the printer software or the "display" utility program how large an image pixel should be printed as.

Suppose you want a single image pixel for a single printer dot, at 300 dots per inch (dpi). That means that the image will come out of the printer with a size of about 5 inch by 6.6 inch (or 127 mm by 169 mm).

But the image file (normally) only knows about its pixel size (1500x2000), not its size at which it should be printed (since you could as well print it at double or half of the size; that's up to the printer software).

However, some image formats (e.g. TIFF, EPS, EPDF) allow to store the "density", i.e., the real physical size of a pixel, as extra (header) information. This is what we have to do with our EPS and PDF images too.

Having converted the images to all possible formats and having used the right parameters for each format, still does not mean we are done! If we are not very careful about the way we will use them, we will end up in a real mess, even though all seems to be right according to the packages, the SGML specification, the Stylesheets etc.

The problem is that when you generate "print" output, the stylesheets don't have any means to know which print format you mean, EPS, PDF or RTF -- there's no way to provide them with that information yet. Given the choice of PNG, BMP or EPS they'll choose EPS every time. As we've said, pdfjadetex doesn't handle .eps files.

The solution is to use parameter entities (if that's an unfamiliar term, read the FreeBSD Documentation Project Primer for New Contributors: Entities, there's a section in there which explains them, and gives examples of using them to conditionally include certain parts of your document).

In a nutshell, start your document like this:

<!DOCTYPE book  PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
<!ENTITY % output.print.png "IGNORE">
<!ENTITY % output.print.pdf "IGNORE">
<!ENTITY % output.print.eps "IGNORE">
<!ENTITY % output.print.bmp "IGNORE">
]>
<!-- rest of the document as normal -->

Adjust that as necessary, depending on which version of the DTD you're using. The key bits are the ENTITY lines.

Then, when you want to include an image, do this (see the explanation of the sedscr file in Section 7.1.4.1):

<mediaobject>
      <![ %output.print.png; [
      <imageobject>
         <imagedata fileref="./images/imagename.png" format="PNG">
      </imageobject>
      ]]>
      <![ %output.print.pdf; [
      <imageobject>
         <imagedata fileref="imagename.pdf" format="PDF" scale="65">
      </imageobject>
      ]]>
      <![ %output.print.eps; [
      <imageobject>
         <imagedata fileref="imagename.eps" format="EPS">
      </imageobject>
       ]]>
      <![ %output.print.bmp; [
      <imageobject>
         <imagedata fileref="imagename.bmp" format="BMP">
      </imageobject>
       ]]>
</mediaobject>

Now, when you process your document with "openjade ...", the "%output.print.xxx;" is replaced by the word "IGNORE". This tells Jade to ignore that section of the document. The overall effect is that no image will be included, neither PNG, nor PDF, nor EPS, nor BMP.

In order to get one (and only one) image included, you have to tell Jade that one or other of the %output.print.xxx; entities must contain "INCLUDE" rather than "IGNORE". You can do this on the command line with the "-i" flag. So if you're producing a HTML file, you would do (see lyxtox and Section 7.1.4.6):

$SGMLTOOLS -b html -s $HTML_DSL -j "-i output.print.png" $1.sgml

If you're producing a PDF file, you would do (see lyxtox and Section 7.1.4.7):

$SGMLTOOLS -b pdf -s sgmltools-pdf -j "-i output.print.pdf" $1.sgml

and so on. With the -j option to sgmltools you can pass options to Jade - we thus pass the aproppriate "-i output.print.xxx" for each format.

Using openjade and pdfjadetex, these commands are equivalent to:

${OPENJADE} -t sgml -d $HTML_NOCHUNKS_DSL -i output.print.png -V nochunks $1.sgml > $1.html

and:

${OPENJADE} -t tex -d ${PRINT_PDF_DSL} -o $1.tex -i "output.print.pdf" $1.sgml
${PDFJADETEX} $1.tex

respectively.

Yes, it's a kludge. But once incorporated in a script (like sedscr, see Section 7.1.4.1), that doesn't have to bother us any more. I owe it to Nik Clayton, who posted it to the docbook-apps mailing list on June 8th, 2000 . It works great! Thanks Nik.

Notes

[1]

A PostScript® and an encapsulated PostScript® file differ only in the bounding box statement. The preamble of the PostScript® file contains, for example

%%BoundingBox: 65 242 547 550 

while the preamble of the encapsulated PostScript® file contains

%%BoundingBox: 0 0 482 308 

Thus, the PostScript® file specifies an absolute position for the image, while the encapsulated PostScript® file does not. The encapsulated PostScript® file will be offset by some amount, to be determined by the program that includes it. Knowing this, you can easily convert from one format to the other manually, just by editing the BoundingBox statement.

(O.K., there is another small difference: the PostScript® file contains a showpage command that instructs the printer to print the page after rendering it.)

[2]

A PostScript® and an encapsulated PostScript® file differ only in the bounding box statement. The preamble of the PostScript® file contains, for example

%%BoundingBox: 65 242 547 550 

while the preamble of the encapsulated PostScript® file contains

%%BoundingBox: 0 0 482 308 

Thus, the PostScript® file specifies an absolute position for the image, while the encapsulated PostScript® file does not. The encapsulated PostScript® file will be offset by some amount, to be determined by the program that includes it. Knowing this, you can easily convert from one format to the other manually, just by editing the BoundingBox statement.

(O.K., there is another small difference: the PostScript® file contains a showpage command that instructs the printer to print the page after rendering it.)

[3]

Although, I must say that I had to add the right density to the EPS and PDF versions too, after all - the original ones appeared too large in the PDF and PS documents.

[4]

Depending on your stylesheets, you may need to copy them to wherever they expect the icons to be, e.g. /usr/share/sgml/docbkdsl/images or somewhere else. YMMV.

Last updated Mon Sep 24 01:19:25 CEST 2007 Permalink: http://www.karakas-online.de/mySGML/explain-figures.html All contents © 2002-2007 Chris Karakas