Hold it right there!

It's been nearly three years since this post, and in those three years, I found the time to write 177 lines of code. Now, with my fork, gfx2gfx-pdftext, you can convert SWFs to PDFs, while preserving the text, resulting in smaller and more user-friendly PDF files! Check it out here!

The old version

0. Preamble

So you've downloaded (legally?) digital copies of a textbook, but they're individual pages in SWF format. (Okay, it needn't be this specific) What now?

Just to be clear, before we continue, the kind of SWF files I'm talking about are static, one frame SWF files consisting of bitmap images and text. While swfrender from SWFTools could be used to convert these into PNGs/PDFs, the text wouldn't be scalable. This guide will take these static SWF files and turn them into PDF files with scalable text. Unfortunately, the text will be converted to paths, and so will not be searchable, and will be several times larger than the original SWF file for text-heavy files.

This process is applicable, for example, to some Pearson eBooks, which are stored by the Pearson eBook client as ZIP files containing SWFs. Oxford textbook ORB files are ZIP files containing lots of ‘GAU’ files. Renaming these files to SWF files will also allow this process to work.

1. gfx2gfx

This guide will be using the undocumented tool gfx2gfx from SWFTools. As this tool is undocumented, it must be compiled from source.

You might be able to compile this tool by following this guide on GitHub, however I had issues, and so I will be compiling (on Arch Linux) by modifying the swftools package. Note that this method is based on Arch Linux, but similar approaches should work for other distributions. It may also be possible to do this on Windows using MinGW.

  1. Install the dependency pdflib-lite from the Arch Linux repositories.

  2. Open a terminal window and cd to a directory of your choice.

  3. Download the source files for the swftools Arch package, either by manually following the ‘plain’ links or, if you have ABS, by running something like ABSROOT=$PWD abs community/swftools.

  4. Open the PKGBUILD file in an editor of your choice.

  5. Make the necessary adjustments to build only gfx2gfx:

     pkgdesc="A collection of SWF manipulation and creation utilities"
     arch=('i686' 'x86_64')
     depends=('giflib' 'freeglut' 'lame' 't1lib' 'libjpeg' 'fontconfig')
     makedepends=('bison' 'flex' 'zlib' 'patch')
     #        $pkgname-$pkgver.patch
     prepare() {
     #  cd ${srcdir}/$pkgname-$pkgver
       cd ${srcdir}/swftools
     #  patch -Np0 -i ../giflib-5.1.patch
     #  sed -i 's#PrintGifError()#fprintf(stderr, "%s\\n", GifErrorString())#g' src/gif2swf.c
     # Insert the following line:
       sed -i '/^install_programs =/ s/.*/install_programs = gfx2gfx$(E)/' src/Makefile.in
     build() {
     #  cd ${srcdir}/$pkgname-$pkgver
       cd ${srcdir}/swftools
       ./configure --prefix=/usr
     package() {
     #  cd ${srcdir}/$pkgname-$pkgver
       cd ${srcdir}/swftools
     #  patch -Np0 -i ${srcdir}/swftools-$pkgver.patch
     #  make prefix=${pkgdir}/usr install
     #  cd ${pkgdir}/usr/share/swftools/swfs
     #  rm -f default_loader.swf default_viewer.swf
     #  ln -s tessel_loader.swf default_loader.swf
     #  ln -s simple_viewer.swf default_viewer.swf
     # Insert the following lines:
       mkdir -p ${pkgdir}/usr/bin
       install -c src/gfx2gfx ${pkgdir}/usr/bin/gfx2gfx
  6. Run makepkg -s.

  7. If all went well, there should be a gfx2gfx executable file inside the src/swftools/src directory. Copy it to the folder where your SWF files are, or simply install the generated package.

2. Convert Time!

The complex part is over!

./gfx2gfx page_1.swf -o page_1.pdf

It's that easy! Or, if for loops are your thing,

for i in {1..350}; do ./gfx2gfx chapter0/page_$i.swf -o pdf/page_$i.pdf; done

gfx2gfx imposes a maximum DPI of 72 by default. If you think this is ridiculous, you can add an -r 300 parameter to raise the DPI to 300, or set -r 0 to disable the restriction.