How to change the margins of PDF files while keeping the page size (”scale the content”)?

August 2nd, 2008 by matthias

This is on how to achieve that on Linux. There are multiple alternatives, but none of them proved perfect yet. Let’s start.

Alternative 1: using pstops

The task can be performed with pstops (whereof psnup is a simplified frontend).

  1. Convert your PDF file to a PS file, by printing to a file in Adobe Reader, or by using pdf2ps (Ghostscript-based) or pdftops (xpdf-based).
  2. Use pstops to adjust the marginspstops -p a4 "L@.9(1cm,1cm)" in.ps out.ps

    On mounting pages: here, the the task is to mount two A4 pages in A5 format on one A4 page, guaranteeing page margins of 3cm at left and right and 2cm at top and bottom. We need a width of 150mm and a height of 257mm. To scale 297mm (A4 height) to 150mm, use factor 0.505. Such n-up mounting together with freestyle adjustment of margins is not possible ith psnup, which has a simpler user interface.

    pstops -p a4 "2:0L@.505(18cm,2cm)+1L@.505(18cm,14.85cm)" in.ps out.ps

  3. Convert the PS file back to PDF by using pdftops.

The problem with psnup (from PSUtils Release 1 Patchlevel 17) and also of its frontend psnup is that it converts fonts to bitmap fonts (Adobe Type 3). This can be detected as rastered fonts when viewing the PDF file with Adobe Reader. It generates somewhat lower print quality, but is still acceptable. What is not acceptable (with respect to file size) is that pstops converts the whole file to an image if it has no idea how to treat it.

To debug pstops and psnup output, you can use the -b option, which will mark out the original pages’ borders.

Alternative 2: Using Adobe Reader and printer margins

This has not yet been worked out, but might be possible. When printing (to a file or otherwise) Adobe Reader will fit the pages into the printable area of the selected printer. Now the idea would be to choose the special printer “Custom …”. This allows you to enter a lp print command. Per the lp documentation, CUPS lp understands options to set the margins. For 2cm at top and bottom and 3cm at left and right, use this command:

/usr/bin/lp -o page-top=57 -o page-bottom=57 -o page-left=85 -o page-right=85

However, this currently does not work our, for an unknown reason. It does not change anything, i.e. the document is printed as if you selected “Page scaling: none” instead of “Page scaling: fit to printable area”. If this command is not possible, another alternative would be to set up a printer definition with exactly the margins you desire, in a way that lets you change these margins easily.

If you just need “larger” margins around your page (without exact measures), you can do the following:

  1. Print the file with Adobe Reader to a PS file. Use the option “Page scaling: fit o printable area”. Try several different printers including the “Custom …” special printer to find one that adds margins of the same size all around the page. This step will generate a PS file with larger margins than the original PDF file had, even though this is not correctly shown in the preview of Adobe Reader 8.1.1.
  2. Convert the file to a PDF file by using ps2pdf.
  3. Repeat from step 1 with your new PDF file until the margins are large enough for you.

This method has the obvious disadvantage of not allowing to specify the margins exactly, but at least the file retains vector fonts and graphics (unlike whenusing pstops, see above).

If you need the margin adjustents in combination with Adobe Readers n-up printing (e.g. 2 pages per sheet), and if you can adjust the margins in your source file (before generating the initial PDF), you can do the following: adust the margins in the original file so that, after the n-up scaling, these margins together with the selected printer’s margins, result in the margins you desire. When printing one two pages A4 on one sheet A4 with the special prnter “Custom …” in Adobe Reader 8.1.1, the following margins are used (measured in the output A4 page):

  • left 5,25mm
  • right 13,71mm
  • top 6,59mm
  • bottom 6,59mm (probably)

Alternative 3: Using Adobe Reader and printing the “current view”

Another alternative:

  1. Use Adobe Reader to print your page to a large sheet without scaling.
  2. Use ps2pdf to re-destill the PS file to PDF.
  3. Open the new PDF file in Adobe Reader and choose an appropriate view. Use the “print current view” option in Adobe Reader to print exactly thet view.
  4. Re-destill the PS output to PDF.
  5. That way, you can even achieve n-up mounting: say you generated to pages, each with content in different places and the rest white space. You can overlay these pages on top of each other using pdftk with the background option.

Alternative 4: Using ghostscript

The following would constitute an elegant solution: freely adjustable margins and vector fonts and images, and avoiding the GUI hassles. Sad enough, it does not work yet. The idea come from this thread.

gs \
  -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER \
  -dCompatibilityLevel="1.3" -dPDFSETTINGS="/printer" \
  -dSubsetFonts=true -dEmbedAllFonts=true \
  -sPAPERSIZE=a4 -sOutputFile="out.pdf" \
  -c "<</BeginPage{0.5 0.5 scale -90 rotate -2384 0 translate}>> setpagedevice" \
  -f in.pdf

The instruction works, apart from the important -c option part, which adds a postscript command. This instruction would also work with PDF files.

Posted in Acrobat Reader, DTP, Sprache: Englisch, alle Artikel | No Comments »

How can I do arbitrary vector-oriented modifications to a PDF file on Linux, though all the editors are still buggy?

August 1st, 2008 by matthias

If you have a PDF which you want to modify (and can’t get hold of the source format file), you might have tried scribus to open and change it. This works well for some simple cases, but there are many import errors for more complex files. Also, the same might happen with Inkscape if you have managed to convert the file to SVG format, e.g. using CorelDraw on a Windows virtual machine.

What’s always possible is to import the file in GIMP (”File -> Open”), using a high resolution such as 300dpi. But you might want to avoid the big file sizes and loss in quality, and want to do it vector-oriented.

Therefore, the following solution should work out:

  1. Convert a low resolution raster image version of the PDF file, e.g. by opening in GIMP (with 150dpi) and saving in JPG format.
  2. Create a OpenOffice.org Draw drawing with the same page size as your PDF file, and place the raster image file into the background.
  3. Now that you have the placement of things, change the appearance by adding other elements on top your background. You might want to get some vector oriented elements out of the PDF file by importing the file in scribus and saving as SVG or EPS file, importing that in OOo Draw.
  4. Export the OOo file to PDF, temporarily removing your background for that. The good thing is that all OOo Draw elements get high-quality vecor oriented PDF elements.
  5. Add your new PDF file on top of the original one, by saying something like:
    pdftk in.pdf stamp overlay.pdf output out.pdf;

As the original vector elements are never converted from PDF to another format and back, no import / export bugs can come in the way!

Posted in DTP, Graphikbearbeitung, OpenOffice, Sprache: Englisch, alle Artikel | No Comments »

How can I combine two PDF files so that they are “overlayed” one to the other?

July 21st, 2008 by matthias

This might become necessary if you want to add content to an already existing PDF file, e.g. when doing pre-press work for flyers etc.. For example, you might resize one PDF file to have additional place on the page, and put other content into that free space.

Get yourself two PDF files to overlay on each other, both of the same page size (else automatic resizing is employed), and both one-sided.

Then use this command to generate the combined PDF file with overlays:

pdftk file1.pdf background file2.pdf output out.pdf

Posted in Acrobat Reader, DTP, Sprache: Englisch, alle Artikel | No Comments »

How can I place a PDF file on a bigger, custom-sized page, with free choice of placement?

July 21st, 2008 by matthias

You might open the PDF file in Adobe Reader and print it there to a Postscript file (setting page size to “Custom…” and choosing a bigger than current), but this does not allow free placement, instead Adobe Reader always centers the output on the paper.

Instead, use xpdf. Start it and set the desired print page output size simulteneously:

xpdf -paperw 3444 -paperh 4252 -z page infile.pdf

xpdf expects the sized in Postscript points: 1 point = 127360 mm = 352.7 µm. Sad enough, xpdf also centers the output on the page.

But we have another trick: calculate a page size where you can cut out your desired page size after the content gets centered on it. Generate a PDF with that size using either xpdf or Adobe Reader, printing to file with them and re-destilling to a PDF file. Then, open it in Adobe Reader and bring place the view (i.e. what you see on your screen) exactly so that it covers the page size you want the document to have. You need to set the zoom level for that (which is also possible in 0.01% steps!).

Then print in Adobe Reader to a Postscript file and select “current view”. Adobe Reader informs you about the size of the view in the print preview, so that you can adjust your settings.

And to conclude, destill the Postscript file again to PDF using ps2pdf.

Posted in Acrobat Reader, Sprache: Englisch, alle Artikel | No Comments »

How can I print a StampIt! stamp directly in my document though my word processor does not integrate with StampIt?

July 12th, 2008 by matthias

This problem arises e.g. when you use StampIt! in a Windows virtual machine with Linux, because Linux is not supported natively yet. Then you might want to print the stamp in OpenOffice.org (or whatever) documents, but how?

Solution:

  1. In your Windows virtual machine, create a PDF pseudo printer (PrimoPDF or other, there are some free to download).
  2. Print from StampIt to your PDF pseudo printer. Normally, a window will appear that asks you where to save your file. You may save it directly in a directory that you can access from your Linux host OS (e.g. a VirtualBox shared directory, if you use VirtuslBox as your VM).
  3. Open the PDF file in Linux with GIMP (import with at least 300dpi).
  4. Use the “auto crop image” feature of GIMP.
  5. Use the “brightness & contrast” feature of GIMP, choose maximum contrast and minimum brightness. This prepares your image for black&white, because greyscale printing will destroy the 2D barcode here.
  6. Use the “image: mode: one bit palette” feature in GIMP.
  7. Save as a PNG image. Steps 3-6 can also be performed by an automated script using ImageMagick.
  8. Insert the image in your OOo document, choosing “anchor to page” and “run-through”, placing it simply to hide the normal address (which stays intact this way).
  9. Print your document out.

Posted in Sprache: Englisch, StampIt, alle Artikel | No Comments »

How to solve a “java.lang.LinkageError: <some class>” between two JAR files?

June 17th, 2008 by matthias

A java.lang.LinkageError happens when “a class has some dependency on another class; however, the latter class has incompatibly changed after the compilation of the former class.” [Java Platform SE 6 API Docs on LinkageError]. Normally, the error is more concretely defined by subclasses of LinkageError, but not always. There are multiple reasons possible:

  1. You have a JAR file in your project that requires another JAR file that’s not in your project. In this case, the latter JAR file is installed somewhere on your system. It is found, but it’s version differs from the version where the JAR file in your project was compiled against. So to speak, the JAR file “changed (in version) after the compilation of the JAR file that’s in your project”.
    A solution (sometimes possible) is to include the requiring JAR as source code into your project. Then, it is comiled itself, and correctly linked against the available version of the required JAR file.
    The alternative, obvious solution is to let the JAR find its expected version of the required JAR files. You may influence this by the order of entries in the Java build path, or if you do Eclipse plugin development and you want JAR files within your plugin to be found, in the plugin classpath in MANIFEST.MF.
  2. You run into an error of Eclipse 3.3.1.1. You recognize this if the java.lang.linkage error persists even if both the requiring and the required JAR files are replaced by source versions in the Eclipse project. (This bug possibly applies only to Eclipse plugin projects.) If this is the case, the required library is one that’s also part of the Java system library. It seems that the Eclipse framework uses its own class loader and replaces the Java class loader, or something with similar effect. The effect is that at runtime, the code refers to other code (always the library that’s part of the Java system library) than at compile time (the library within the same or another plugin project). So again, the required JAR file “changed” (in version) from compile time to runtime.
    Solution: include the requiring JAR as source code, and remove all duplicates of the library from your projects, so that the only installed version of the required JAR library is in the Java system library. Now both at compile and runtime, this is the only thing where requiring code can refer to.

A concrete example for the Eclipse bug described above: the error message was “java.lang.LinkageError: org/xml/sax/ContentHandler” in a plugin used to capsule JDOM code (as source, not as a JAR file).

Due to the bug, at runtime JDOM code always used the Java system library’s SAX when doing “import org.xml.sax.ContentHandler”. Regardless of what the code referred to at compile time: SAX in a JAR file in the same or a required plugin project, SAX as source code in the same source folder of the same plugin project etc..

Also, using the “order” feature when configuring the Java build path of the JDOM plugin project did not help: “plugin dependencies” can be placed above “Java system library”, but regardless of that setting, at runtime the Java system library was used. And this was a JAR file with a different version than what the project was compiled against at compile time … .

The solution was this: remove the dependency from another plugin that contained SAX as a JAR library, and (!) remove the SAX source and JAR files from the plugin project that encapsuled JDOM. Only one of these steps is not enough. Both together probably made Eclipse compile against the same lib as used at runtime, namely SAX form the Java system library.

To conclude: currently, there seems to be no possibility to use a package in place of a package of the same name that’s supplied by the Java system library; which is an Eclipse bug.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | No Comments »

How to fix a “NoClassDefFoundError: [some class]” error when developing Eclipse plugins?

June 17th, 2008 by matthias

Here’s one solution to one cause, there might be other causes as well. The error means that the class definition existed when compiling but disappeared in the meantime (see Sun Documentation). You see this from the fact that this error message is thrown e.g. when deleting a necessary .class file in the bin output folder of a project. (However, deleting a .class file may also result in java.lang.ClassNotFoundException, for classes that are dynamically loaded by some configurable class loader utility.

In this case, a plugin needed a library (JDOM), which was capsuled in another plugin. Note that these errors are hard to trace with a debugger: the line that generates the exception may need one type of the required library in the other plugin, and that type might be a subtype of the one that’s in the error message, or similar complicated things. With the debugger, you cannot “step into” the loading of statically bound .class files (that’s behind the scenes), and therefore just see this error message appearin out of nothing. You can, however, “step into” the loading of dynamically loaded classes, where some configurable class loader utility is involved.

First, here’s the list of things that did not help:

  1. It was no problem of a missing .class file, as the required .class file was in place.
  2. Cleaning and rebuilding the at.ezra.thirdparty.jsword project (equivalent to deleting bin/*) changes nothing regarding these errors. So it’s not just due to a missing or erroneous .class file.
  3. “PDE-Tools -> Update classpath…” for all or some plugins does not cure the errors.
  4. It might be necessary to include a plugin dependency to the plugin that contains the library, even if Eclipse doesn’t demand this. Eclipse might not notice that this dependency is necessary if the library is just necessary in dynamically loaded classes, involving some configurable class loader utility. However, this did not solve the issue here.
  5. It was no problem of lacking dependencies etc. between the two plugins, as the error even arouse when placing the library .jar file directly into the plugin that needed it.

And now, the thing that did the cure:

  1. Open MANIFEST.MF of the plugin that contains your not-found class definition (here the library plugin). Use the Eclipse manifest editor for this.
  2. Go to tab “Runtime”, section “Classpath”, click “New” and enter “.” in the edit box. That’s it. In this tab, it’s written that the plugin root dir is automatically (!) the plugin’s class path, but they mean, only if there are no additional entries, in which case one must enter “.” additionally. You need additional entries if you plugin’s library file is located outside of the plugin root dir, e.g. in “lib/”.

The result is a new line “.” (last line in code below!) in the build.properties file, meaning that the plugin’s root dir is now included into the plugin’s classpath. Only then, the .class files in the bin directory can be found, as the bin directory is placed below the plugins root dir. (This whole thing might be an Eclipse bug, actually …).

bin.includes = META-INF/,\
lib/jaxen-core.jar,\
lib/jaxen-jdom.jar,\
lib/saxpath.jar,\
.

Additionally, the following steps might be necessary: add the following lines in the plugin’s build. properties file (they might be missing, but at least the src.. and bin.. lines should be present in all plugins):

jars.compile.order = .
source.. = src/
output.. = bin/

A tip: the general process of removing path-related / class search related errors is probably this: compare build.properties, .classpath and MANIFEST.MF with working species of these files from other plugins.

And if you get a “java.lang.LinkageError: <some class>” error, this might be just a synonym of this error, so check this first.

Posted in Eclipse, Sprache: Englisch, alle Artikel | No Comments »

How to correct wrong / missing SVN annotation icons in Subclipse 1.2.4?

June 16th, 2008 by matthias

Annotation icons are the small icons placed on top of other icons, mainly in the package explorer view of Eclipse. In Subclipse 1.2.4, it can happen that these are no longer shown (or incorrectly shown), though the project is in SVN.

To correct missing icons, restart Eclipse or switch the workspace forth and back.

To correct wrong icons (like »?« where »in sync« should be), disconnect the project from SVN without deleting the SVN metadata, then reconnect.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | No Comments »

How to correct the error “dir .svn missing” when using “Team -> Share project …” (of Subclipse 1.2.4)?

June 16th, 2008 by matthias

The full error message is:

org.tigris.subversion.javahl.ClientException: svn: Directory '[...]/.svn’ containing working copy admin area is missing

And when creating the .svn directory yourself in your local directory, the following error appears:

org.tigris.subversion.javahl.ClientException: svn: Unable to lock '<plugin project name>'

This seems to be a bug in Subclipse 1.2.4. The solution: do manually what the “share project …” wizard would do. That is:

  1. Create a new remote directory in the SVN repository view.
  2. Check that directory out on top of the existing project.
  3. Say yes to deleting the local resource: that means just the directory, not the files in it.
  4. Commit your files to SVN.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | No Comments »

How to create a Java project in Eclipse from an existing JAR file, that way that the JAR is not uncompressed?

June 16th, 2008 by matthias

Create a new plugin and choose “from existing archive file”.

If you want to add the JAR file to an existing project, the simplest way is to import the JAR file using “File -> Import …”. You now need to tell Eclipse that it’s something where Eclipse is allowed to read executable code from, i.e. you need  to add it to the Java classpath. The simplest way would be to right-click the file in package explorer and add it to the build path. The problem is that the effect gets lost when choosing “PDE-Tools > Update classpath …”. Therefore, better follow the way described in this post.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | No Comments »