pdf_prim.c

changeset 166
301f6f17c364
parent 145
3ed3f7f32837
     1.1 diff -r 9a505be7e7fd -r 301f6f17c364 pdf_prim.c
     1.2 --- a/pdf_prim.c	Mon Dec 14 15:44:55 2009 +0000
     1.3 +++ b/pdf_prim.c	Mon Dec 14 15:51:53 2009 +0000
     1.4 @@ -90,7 +90,10 @@
     1.5    union {
     1.6      bool              boolean;
     1.7      char              *name;
     1.8 -    char              *string;
     1.9 +    struct {
    1.10 +      char            *content;
    1.11 +      int             length;
    1.12 +    }                 string;
    1.13      long              integer;
    1.14      double            real;
    1.15      struct pdf_obj    *ind_ref;
    1.16 @@ -243,7 +246,18 @@
    1.17  struct pdf_obj *pdf_new_string (char *str)
    1.18  {
    1.19    struct pdf_obj *obj = pdf_new_obj (PT_STRING);
    1.20 -  obj->val.string = pdf_strdup (str);
    1.21 +  obj->val.string.content = pdf_strdup (str);
    1.22 +  obj->val.string.length = strlen(str);
    1.23 +  return (obj);
    1.24 +}
    1.25 +
    1.26 +
    1.27 +struct pdf_obj *pdf_new_string_n (char *str, int n)
    1.28 +{
    1.29 +  struct pdf_obj *obj = pdf_new_obj (PT_STRING);
    1.30 +  obj->val.string.length = n;
    1.31 +  obj->val.string.content = pdf_calloc (1,n);
    1.32 +  memcpy(obj->val.string.content, str, n);
    1.33    return (obj);
    1.34  }
    1.35  
    1.36 @@ -397,7 +411,16 @@
    1.37  	return (1);
    1.38        return (0);
    1.39      case PT_STRING:
    1.40 -      return (strcmp (o1->val.string, o2->val.string));
    1.41 +      {
    1.42 +	int l;
    1.43 +	l = o1->val.string.length;
    1.44 +	if(l > o2->val.string.length)
    1.45 +	  l = o2->val.string.length;
    1.46 +	l = memcmp (o1->val.string.content, o2->val.string.content, l);
    1.47 +        if (l)
    1.48 +	  return l;
    1.49 +	return o1->val.string.length - o2->val.string.length;
    1.50 +      }
    1.51      case PT_NAME:
    1.52        return (strcmp (o1->val.name, o2->val.name));
    1.53      default:
    1.54 @@ -427,22 +450,51 @@
    1.55  }
    1.56  
    1.57  
    1.58 -static int string_char_needs_quoting (char c)
    1.59 +static int pdf_write_literal_string (pdf_file_handle pdf_file, char *s, int n)
    1.60  {
    1.61 -  return ((c < ' ')  || (c > '~')  || (c == '\\') ||
    1.62 -	  (c == '(') || (c == ')'));
    1.63 +  int i,p;
    1.64 +  if(pdf_file) fprintf (pdf_file->f, "(");
    1.65 +  for (i=p=0;n;n--) {
    1.66 +    int j,k;
    1.67 +    k=0;
    1.68 +    switch(*s){
    1.69 +      case '\\':
    1.70 +	k=1;
    1.71 +	break;
    1.72 +      case '(':
    1.73 +	for(j=k=1;k && j<n;j++)
    1.74 +	  k+=(s[j]=='(')?1:(s[j]==')')?-1:0;
    1.75 +	p+=!k;
    1.76 +	break;
    1.77 +      case ')':
    1.78 +	if(p)
    1.79 +	  p--;
    1.80 +	else
    1.81 +	  k=1;
    1.82 +	break;
    1.83 +    }
    1.84 +    if(k) {
    1.85 +      i++;
    1.86 +      if(pdf_file) fprintf (pdf_file->f, "\\");
    1.87 +    }
    1.88 +    i++;
    1.89 +    if(pdf_file) fprintf (pdf_file->f, "%c", *(s++));
    1.90 +  }
    1.91 +  if(pdf_file) fprintf (pdf_file->f, ") ");
    1.92 +  return i;
    1.93  }
    1.94  
    1.95  
    1.96 -void pdf_write_string (pdf_file_handle pdf_file, char *s)
    1.97 +void pdf_write_string (pdf_file_handle pdf_file, char *s, int n)
    1.98  {
    1.99 -  fprintf (pdf_file->f, "(");
   1.100 -  while (*s)
   1.101 -    if (string_char_needs_quoting (*s))
   1.102 -      fprintf (pdf_file->f, "\\%03o", 0xff & *(s++));
   1.103 -    else
   1.104 -      fprintf (pdf_file->f, "%c", *(s++));
   1.105 -  fprintf (pdf_file->f, ") ");
   1.106 +  if(pdf_write_literal_string (NULL,s,n)<2*n)
   1.107 +    pdf_write_literal_string (pdf_file,s,n);
   1.108 +  else {
   1.109 +    fprintf (pdf_file->f, "<");
   1.110 +    for(;n--;)
   1.111 +      fprintf (pdf_file->f, "%.2X",*(s++));
   1.112 +    fprintf (pdf_file->f, "> ");
   1.113 +  }
   1.114  }
   1.115  
   1.116  
   1.117 @@ -560,7 +612,7 @@
   1.118        pdf_write_name (pdf_file, obj->val.name);
   1.119        break;
   1.120      case PT_STRING:
   1.121 -      pdf_write_string (pdf_file, obj->val.string);
   1.122 +      pdf_write_string (pdf_file, obj->val.string.content, obj->val.string.length);
   1.123        break;
   1.124      case PT_INTEGER:
   1.125        fprintf (pdf_file->f, "%ld ", obj->val.integer);