PDF In-Depth

Converting to text to PDF using C

May 30, 1998

Advertisement
Advertisement
 

This code sample is posted here for the general benefit of the PDF development community. Attribution and usage guidelines are as noted in the code source; please respect the wishes of the author when using this code.


/*
Copyright 1998
P. G. Womack, Diss, Norfolk, UK.
"BugBear"
Do what you like, but don't claim you wrote it.
*/

#include 
#include 
#include 

float page_width = 594.0;
float page_depth = 828.0;
float margin = 30.0;
float font_size = 10.0;
float lead_size = 10.0;
int object_id = 1;
int page_tree_id;

typedef struct _PageList {
   struct _PageList *next;
   int page_id;
} PageList;

int num_pages = 0;
PageList *pages = NULL;
PageList **insert_page = &pages;
store_page(int id)
{
   PageList *n = (PageList *)malloc(sizeof(*n));
   if(n == NULL)
   {
      fprintf(stderr, 
         "Unable to allocate array for page %d.", num_pages + 1);
      exit(1);
   }
   n->next = NULL;
   n->page_id = id;
   *insert_page = n;
   insert_page = &n->next;
   num_pages++;
}

int num_xrefs = 0;
long *xrefs = NULL;

start_object(int id)
{
   if(id >= num_xrefs)
   {
      long *new_xrefs;
      int delta, new_num_xrefs;
      delta = num_xrefs / 5;
      if(delta < 1000)
         delta += 1000;
      new_num_xrefs = num_xrefs + delta;
      new_xrefs = (long *)malloc(new_num_xrefs * sizeof(*new_xrefs));
      if(new_xrefs == NULL)
      {
         fprintf(stderr, 
            "Unable to allocate array for object %d.", id);
         exit(1);
      }
      memcpy(new_xrefs, xrefs, num_xrefs * sizeof(*xrefs));
      free(xrefs);
      xrefs = new_xrefs;
      num_xrefs = new_num_xrefs;
   }
   xrefs[id] = ftell(stdout);
   printf("%d 0 obj\n", id);
}

int stream_id, stream_len_id;
long stream_start;
float ypos;
start_page()
{
   stream_id = object_id++;
   stream_len_id = object_id++;
   start_object(stream_id);
   printf("<< /Length %d 0 R >>\n", stream_len_id);
   printf("stream\n");
   stream_start = ftell(stdout);
   printf("BT\n/F0 %g Tf\n", font_size);
   ypos = page_depth - margin;
   printf("%g %g Td\n", margin, ypos);
   printf("%g TL\n", lead_size);
}

end_page()
{
   long stream_len;
   int page_id = object_id++;
   store_page(page_id);
   printf("ET\n");
   stream_len = ftell(stdout) - stream_start;
   printf("endstream\nendobj\n");
   start_object(stream_len_id);
   printf("%ld\nendobj\n", stream_len);
   start_object(page_id);
   printf("<>\nendobj\n", page_tree_id, stream_id);
}

do_text()
{
   char buffer[8192];
   start_page();
   while(gets(buffer) != NULL)
   {
      if(ypos < margin)
      {
         end_page();
         start_page();
      }

      if(strlen(buffer) == 0)
         printf("T*\n");
       else
      {
         if(buffer[0] == '\f')
         {
            end_page();
            start_page();
         }
         else
         {
            char c, *s = buffer;
            putchar('(');
            while((c = *s++) != '\0')
            {
               switch(c)
               {
                  case '(':
                  case ')':
                  case '\\':
                     putchar('\\');
               }
               putchar(c);
            }
            printf(")'\n");
         }
      }
      ypos -= lead_size;
   }
   end_page();
}


int main(int argc, char **argv)
{
   int i, catalog_id, font_id;
   long start_xref;
   printf("%%PDF-1.0\n");
   page_tree_id = object_id++;
   do_text();
   font_id = object_id++;
   start_object(font_id);
   printf("<>\nendobj\n");
   start_object(page_tree_id);
   printf("<, num_pages);
   {
      PageList *ptr = pages;
      printf("/Kids[\n");
      while(ptr != NULL)
       {
         printf("%d 0 R\n", ptr->page_id);
         ptr = ptr->next;
      }
      printf("]\n");
   }
   printf("/Resources<> >>\n", font_id);
   printf("/MediaBox [ 0 0 %g %g ]\n", page_width, page_depth);
   printf(">>\nendobj\n");
   catalog_id = object_id++;
   start_object(catalog_id);
   printf("<>\nendobj\n", page_tree_id);
   start_xref = ftell(stdout);
   printf("xref\n");
   printf("0 %d\n", object_id);
   printf("0000000000 65535 f \n");
   for(i = 1; i < object_id; i++)
      printf("%010ld 00000 n \n", xrefs[i]);
   printf("trailer\n<<\n/Size %d\n/Root %d 0 R\n>>\n", object_id, catalog_id);
   printf("startxref\n%ld\n%%%%EOF\n", start_xref);
   exit(0);
   return 0;
}
PDF In-Depth Free Product Trials Ubiquitous PDF

Debenu Quick PDF Library

Get products to market faster with this amazing PDF developer SDK. Over 900 functions and an equally...

Download free demo

Back to the past, 15 years ago! Open Publish 2002

Looking back to 2002, it's amazing how much of the prediction became a reality. Take a read and see what you think!

September 14, 2017
Platinum Sponsor





Search Planet PDF
more searching options...
Planet PDF Newsletter
Most Popular Articles
Featured Product

Debenu PDF Aerialist

The ultimate plug-in for Adobe Acrobat. Advanced splitting, merging, stamping, bookmarking, and link control. Take Acrobat to the next level.

Features

Adding a PDF Stamp Comment

OK, so you want to stamp your document. Maybe you need to give reviewers some advice about the document's status or sensitivity. This tip from author Ted Padova demonstrates how to add stamps with the Stamp Tool along with related comments.