pdf_prim.c

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