~ubuntu-branches/ubuntu/jaunty/cups/jaunty

« back to all changes in this revision

Viewing changes to debian/local/filters/pdf-filters/filter/fontembed/embed.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt, Till Kamppeter, Martin Pitt
  • Date: 2009-02-15 18:39:03 UTC
  • mfrom: (6.1.30 jaunty)
  • Revision ID: james.westby@ubuntu.com-20090215183903-i0nhvqyqj4vyn52a
Tags: 1.3.9-13
[ Till Kamppeter ]
* debian/local/filters/pdf-filters/filter/imagetopdf.c: Added support for
  the new "fit-to-page" option (new, more intuitive name for "fitplot").
* debian/filters/pstopdf: Only apply paper size if the "fitplot" or the
  "fit-to-page" option is set.
* debian/local/filters/cpdftocps: Only the last digit of the number of
  copies was used (LP: #309314).
* debian/local/filters/pdf-filters/pdftopdf/pdftopdf.cxx: Do not preceed the
  PDF output with a newline (LP: #303691). Only impose the page size from
  the PPD file to all pages if the "fitplot" or the "fit-to-page" option is 
  set. This prevented from automatic paper tray switching to the correct paper
  sizes when a multiple-page-size document is printed (partial fix for
  LP: #310575).
* debian/patches/pdftops-cups-1.4.dpatch: Updated from CUPS 1.4 SVN. Contains
  fixes for multiple-page-size document printing (partial fix for
  LP: #310575).
* debian/patches/pdftops-dont_fail_on_cancel.dpatch: Removed, should be
  fixed in the new upstream version of pdftops.

[ Martin Pitt ]
* debian/patches/pdftops-cups-1.4.dpatch: Add definition of
  HAVE_PDFTOPS and CUPS_PDFTOPS, so that the filter actually gets
  again built with pdftops support. (Fixes Till's change from above).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "embed.h"
 
2
#include <assert.h>
 
3
#include <stdio.h>
 
4
#include <stdlib.h>
 
5
#include <string.h>
 
6
#include <time.h>
 
7
#include "dynstring.h"
 
8
 
 
9
#include "sfnt.h"
 
10
 
 
11
// from embed_sfnt.c
 
12
EMB_RIGHT_TYPE emb_otf_get_rights(OTF_FILE *otf);
 
13
const char *emb_otf_get_fontname(OTF_FILE *otf);
 
14
EMB_PDF_FONTWIDTHS *emb_otf_get_pdf_widths(OTF_FILE *otf,const unsigned short *encoding,int len,const BITSET glyphs);
 
15
EMB_PDF_FONTWIDTHS *emb_otf_get_pdf_cidwidths(OTF_FILE *otf,const BITSET glyph);
 
16
int emb_otf_ps(OTF_FILE *otf,unsigned short *encoding,int len,unsigned short *to_unicode,OUTPUT_FN output,void *context);
 
17
 
 
18
void emb_otf_get_pdf_fontdescr(OTF_FILE *otf,EMB_PDF_FONTDESCR *ret);
 
19
 
 
20
static inline int copy_file(FILE *f,OUTPUT_FN output,void *context) // {{{
 
21
{
 
22
  assert(f);
 
23
  assert(output);
 
24
 
 
25
  char buf[4096];
 
26
  int iA,ret=0;
 
27
 
 
28
  ret=0;
 
29
  rewind(f);
 
30
  do {
 
31
    iA=fread(buf,1,4096,f);
 
32
    (*output)(buf,iA,context);
 
33
    ret+=iA;
 
34
  } while (iA>0);
 
35
  return ret;
 
36
}
 
37
// }}}
 
38
 
 
39
EMB_PARAMS *emb_new(FONTFILE *font,EMB_DESTINATION dest,EMB_CONSTRAINTS mode) // {{{
 
40
{
 
41
  assert(font);
 
42
 
 
43
  EMB_PARAMS *ret=calloc(1,sizeof(EMB_PARAMS));
 
44
  if (!ret) {
 
45
    fprintf(stderr,"Bad alloc: %m\n");
 
46
    if (mode&EMB_C_TAKE_FONTFILE) {
 
47
      fontfile_close(font);
 
48
    }
 
49
    return NULL;
 
50
  }
 
51
  ret->dest=dest;
 
52
  ret->font=font;
 
53
  if (mode&EMB_C_TAKE_FONTFILE) {
 
54
    ret->plan|=EMB_A_CLOSE_FONTFILE;
 
55
  }
 
56
 
 
57
  // check parameters
 
58
  if ( (mode&EMB_C_KEEP_T1)&&(mode&EMB_C_FORCE_MULTIBYTE) ) {
 
59
    fprintf(stderr,"Incompatible mode: KEEP_T1 and FORCE_MULTIBYTE\n");
 
60
    emb_close(ret);
 
61
    return NULL;
 
62
  }
 
63
  if ((mode&0x07)>5) {
 
64
    fprintf(stderr,"Bad subset specification\n");
 
65
    emb_close(ret);
 
66
    return NULL;
 
67
  }
 
68
 
 
69
  // determine intype
 
70
  int numGlyphs=0;
 
71
  if (font->sfnt) {
 
72
    ret->intype=EMB_INPUT_TTF; // for now
 
73
    ret->rights=emb_otf_get_rights(ret->font->sfnt);
 
74
    numGlyphs=ret->font->sfnt->numGlyphs; // TODO
 
75
  } else if (font->stdname) {
 
76
    ret->intype=EMB_INPUT_STDFONT;
 
77
    ret->rights=EMB_RIGHT_NONE;
 
78
  } else {
 
79
    assert(0);
 
80
  }
 
81
/*
 
82
  if ( (ret->intype==EMB_INPUT_CFF)&&
 
83
       (ret->cffFont.is_cid()) ) {
 
84
    ret->plan|=EMB_A_MULTIBYTE;
 
85
  }
 
86
*/
 
87
 
 
88
  // determine outtype
 
89
  if ( (ret->intype==EMB_INPUT_T1)&&(mode&EMB_C_KEEP_T1) ) {
 
90
    ret->outtype=EMB_OUTPUT_T1;
 
91
  } else if (ret->intype==EMB_INPUT_TTF) {
 
92
    if (mode&EMB_C_PDF_OT) {
 
93
      ret->outtype=EMB_OUTPUT_SFNT;
 
94
    } else {
 
95
      ret->outtype=EMB_OUTPUT_TTF;
 
96
    }
 
97
  } else if (ret->intype==EMB_INPUT_STDFONT) {
 
98
    // the stdfonts are treated as Type1 for now
 
99
    ret->outtype=EMB_OUTPUT_T1;
 
100
    if (mode&EMB_C_FORCE_MULTIBYTE) {
 
101
      fprintf(stderr,"Multibyte stdfonts are not possible\n");
 
102
      emb_close(ret);
 
103
      return NULL;
 
104
    }
 
105
    return ret; // never subset
 
106
  } else { // T1, OTF, CFF
 
107
    if (ret->intype==EMB_INPUT_T1) {
 
108
      ret->plan|=EMB_A_CONVERT_CFF;
 
109
    }
 
110
    if (mode&EMB_C_PDF_OT) {
 
111
      ret->outtype=EMB_OUTPUT_SFNT;
 
112
      ret->plan|=EMB_A_WRAP_SFNT;
 
113
    } else {
 
114
      ret->outtype=EMB_OUTPUT_CFF;
 
115
    }
 
116
  }
 
117
 
 
118
  if (mode&EMB_C_FORCE_MULTIBYTE) {
 
119
    ret->plan|=EMB_A_MULTIBYTE;
 
120
  }
 
121
 
 
122
  // check rights
 
123
  if (  (ret->rights&EMB_RIGHT_NONE)||
 
124
        (ret->rights&EMB_RIGHT_BITMAPONLY)||
 
125
        ( (ret->rights&EMB_RIGHT_READONLY)&&(mode&EMB_C_EDITABLE_SUBSET) )||
 
126
        ( (ret->rights&EMB_RIGHT_NO_SUBSET)&&(mode&EMB_C_MUST_SUBSET) )  ) {
 
127
    fprintf(stderr,"The font does not permit the requested embedding\n");
 
128
    emb_close(ret);
 
129
    return NULL;
 
130
  } else if ( (!(ret->rights&EMB_RIGHT_NO_SUBSET))&&
 
131
              (!(mode&EMB_C_NEVER_SUBSET)) ) {
 
132
    ret->plan|=EMB_A_SUBSET;
 
133
  }
 
134
 
 
135
  // alloc subset
 
136
  if (ret->plan&EMB_A_SUBSET) {
 
137
    ret->subset=bitset_new(numGlyphs);
 
138
    if (!ret->subset) {
 
139
      fprintf(stderr,"Bad alloc: %m\n");
 
140
      emb_close(ret);
 
141
      return NULL;
 
142
    }
 
143
  }
 
144
 
 
145
  return ret;
 
146
}
 
147
// }}}
 
148
 
 
149
int emb_embed(EMB_PARAMS *emb,OUTPUT_FN output,void *context) // {{{
 
150
{
 
151
  assert(emb);
 
152
 
 
153
  if (emb->dest==EMB_DEST_PS) {
 
154
    int ret=0;
 
155
    const char *fontname=emb_otf_get_fontname(emb->font->sfnt); // TODO!!
 
156
    (*output)("%%BeginFont: ",13,context);
 
157
    (*output)(fontname,strlen(fontname),context);
 
158
    (*output)("\n",1,context);
 
159
    if (emb->intype==EMB_INPUT_TTF) {
 
160
      // do Type42
 
161
      ret=emb_otf_ps(emb->font->sfnt,NULL,4,NULL,output,context); // TODO?
 
162
    } else {
 
163
      assert(0);
 
164
      ret=-1;
 
165
    }
 
166
    (*output)("%%EndFont\n",10,context);
 
167
    return ret;
 
168
  }
 
169
 
 
170
  if (emb->intype==EMB_INPUT_TTF) {
 
171
    assert(emb->font->sfnt);
 
172
    if (emb->plan&EMB_A_SUBSET) {
 
173
      return otf_subset(emb->font->sfnt,emb->subset,output,context);
 
174
    } else if (emb->font->sfnt->numTTC) { // 
 
175
      return otf_ttc_extract(emb->font->sfnt,output,context);
 
176
    } else {
 
177
      // copy verbatim
 
178
      return copy_file(emb->font->sfnt->f,output,context);
 
179
    }
 
180
  } else {
 
181
    fprintf(stderr,"NOT IMPLEMENTED\n");
 
182
    assert(0);
 
183
    return -1;
 
184
  }
 
185
}
 
186
// }}}
 
187
 
 
188
void emb_close(EMB_PARAMS *emb) // {{{
 
189
{
 
190
  if (emb) {
 
191
    free(emb->subset);
 
192
    if (emb->plan&EMB_A_CLOSE_FONTFILE) {
 
193
      fontfile_close(emb->font);
 
194
    }
 
195
    free(emb);
 
196
  }
 
197
}
 
198
// }}}
 
199
 
 
200
/*** PDF out stuff ***/
 
201
static const int emb_pdf_font_format[]={0,1,0,0}; // {{{ (input_format) }}}
 
202
 
 
203
static const char *emb_pdf_font_subtype[][2]={ // {{{ (format,multibyte)
 
204
        {"Type1","CIDFontType0"},
 
205
        {"TrueType","CIDFontType2"}};
 
206
// }}}
 
207
 
 
208
static const char *emb_pdf_fontfile_key[]={ // {{{ (output_format)
 
209
        "FontFile1","FontFile2","FontFile3","Fontfile3"};
 
210
// }}}
 
211
 
 
212
static const char *emb_pdf_fontfile_subtype[][2]={ // {{{ (output_format,multibyte)
 
213
        {NULL,NULL},
 
214
        {NULL,NULL},
 
215
        {"Type1C","CIDFontType0C"},
 
216
        {"OpenType","OpenType"}};
 
217
// }}}
 
218
 
 
219
static inline int emb_multibyte(EMB_PARAMS *emb) // {{{
 
220
{
 
221
  return (emb->plan&EMB_A_MULTIBYTE)?1:0;
 
222
}
 
223
// }}}
 
224
 
 
225
static const char *emb_pdf_escape_name(const char *name,int len) // {{{ // - statically allocated buffer
 
226
{
 
227
  assert(name);
 
228
  if (len==-1) {
 
229
    len=strlen(name);
 
230
  }
 
231
  assert(len<=127); // pdf implementation limit
 
232
 
 
233
  static char buf[128*3];
 
234
  int iA,iB;
 
235
  const char hex[]="0123456789abcdef";
 
236
 
 
237
  for (iA=0,iB=0;iA<len;iA++,iB++) {
 
238
    if ( ((unsigned char)name[iA]<33)||((unsigned char)name[iA]>126)||
 
239
         (strchr("#()<>[]{}/%",name[iA])) ) {
 
240
      buf[iB]='#';
 
241
      buf[++iB]=hex[(name[iA]>>4)&0x0f];
 
242
      buf[++iB]=hex[name[iA]&0xf];
 
243
    } else {
 
244
      buf[iB]=name[iA];
 
245
    }
 
246
  }
 
247
  buf[iB]=0;
 
248
  return buf;
 
249
}
 
250
// }}}
 
251
 
 
252
const char *emb_pdf_get_font_subtype(EMB_PARAMS *emb) // {{{
 
253
{
 
254
  assert(emb);
 
255
  return emb_pdf_font_subtype[emb_pdf_font_format[emb->intype]][emb_multibyte(emb)];
 
256
}
 
257
// }}}
 
258
 
 
259
const char *emb_pdf_get_fontfile_key(EMB_PARAMS *emb) // {{{
 
260
{
 
261
  assert(emb);
 
262
  return emb_pdf_fontfile_key[emb->outtype];
 
263
}
 
264
// }}}
 
265
 
 
266
const char *emb_pdf_get_fontfile_subtype(EMB_PARAMS *emb) // {{{
 
267
{
 
268
  assert(emb);
 
269
  return emb_pdf_fontfile_subtype[emb->outtype][emb_multibyte(emb)];
 
270
}
 
271
// }}}
 
272
 
 
273
// {{{ EMB_PDF_FONTDESCR *emb_pdf_fd_new(fontname,subset_tag,cid_registry,cid_ordering,cid_supplement,panose)
 
274
EMB_PDF_FONTDESCR *emb_pdf_fd_new(const char *fontname,
 
275
                                  const char *subset_tag,
 
276
                                  const char *cid_registry, // or supplement==-1
 
277
                                  const char *cid_ordering, // or supplement==-1
 
278
                                  int cid_supplement) // -1 for non-cid
 
279
{
 
280
  assert(fontname);
 
281
  EMB_PDF_FONTDESCR *ret;
 
282
 
 
283
  int len=sizeof(EMB_PDF_FONTDESCR);
 
284
  if (subset_tag) {
 
285
    assert(strlen(subset_tag)==6);
 
286
    len+=7;
 
287
  }
 
288
  len+=strlen(fontname)+1;
 
289
  if (cid_supplement>=0) { // cid font
 
290
    len+=12; // space for panose
 
291
    assert(cid_registry);
 
292
    assert(cid_ordering);
 
293
    len+=strlen(cid_registry)+1;
 
294
    len+=strlen(cid_ordering)+1;
 
295
  }
 
296
  ret=calloc(1,len);
 
297
  if (!ret) {
 
298
    fprintf(stderr,"Bad alloc: %m\n");
 
299
    assert(0);
 
300
    return NULL;
 
301
  }
 
302
 
 
303
  // now fill the struct
 
304
  len=0;
 
305
  if (cid_supplement>=0) { // free space for panose is at beginning
 
306
    len+=12;
 
307
  }
 
308
  ret->fontname=ret->data+len;
 
309
  len+=strlen(fontname)+1;
 
310
  if (subset_tag) {
 
311
    strncpy(ret->fontname,subset_tag,6);
 
312
    ret->fontname[6]='+';
 
313
    strcpy(ret->fontname+7,fontname);
 
314
    len+=7;
 
315
  } else {
 
316
    strcpy(ret->fontname,fontname);
 
317
  }
 
318
  ret->italicAngle=90;
 
319
  if (cid_supplement>=0) {
 
320
    ret->registry=ret->data+len;
 
321
    strcpy(ret->registry,cid_registry);
 
322
    len+=strlen(cid_registry)+1;
 
323
 
 
324
    ret->ordering=ret->data+len;
 
325
    strcpy(ret->ordering,cid_ordering);
 
326
    len+=strlen(cid_registry)+1;
 
327
  }
 
328
  ret->supplement=cid_supplement;
 
329
 
 
330
  return ret;
 
331
}
 
332
// }}}
 
333
 
 
334
EMB_PDF_FONTDESCR *emb_pdf_fontdescr(EMB_PARAMS *emb) // {{{ -  to be freed by user
 
335
{
 
336
  assert(emb);
 
337
 
 
338
  const char *subset_tag=NULL;
 
339
  // {{{ generate pdf subtag
 
340
  static unsigned int rands=0;
 
341
  if (!rands) {
 
342
    rands=time(NULL);
 
343
  }
 
344
  
 
345
  char subtag[7];
 
346
  subtag[6]=0;
 
347
  if (emb->plan&EMB_A_SUBSET) {
 
348
    int iA;
 
349
    for (iA=0;iA<6;iA++) {
 
350
      const int x=(int)(26.0*(rand_r(&rands)/(RAND_MAX+1.0)));
 
351
      subtag[iA]='A'+x;
 
352
    }
 
353
    subset_tag=subtag;
 
354
  }
 
355
  // }}}
 
356
 
 
357
  const char *fontname=NULL;
 
358
  if (emb->intype==EMB_INPUT_TTF) {
 
359
    assert(emb->font->sfnt);
 
360
    fontname=emb_otf_get_fontname(emb->font->sfnt);
 
361
  } else if (emb->intype==EMB_INPUT_STDFONT) {
 
362
    return NULL;
 
363
  } else {
 
364
    fprintf(stderr,"NOT IMPLEMENTED\n");
 
365
    assert(0);
 
366
    return NULL;
 
367
  }
 
368
 
 
369
  EMB_PDF_FONTDESCR *ret;
 
370
  if (emb->plan&EMB_A_MULTIBYTE) { // multibyte
 
371
    ret=emb_pdf_fd_new(fontname,subset_tag,"Adobe","Identity",0); // TODO /ROS
 
372
  } else {
 
373
    ret=emb_pdf_fd_new(fontname,subset_tag,NULL,NULL,-1);
 
374
  }
 
375
  if (!ret) {
 
376
    return NULL;
 
377
  }
 
378
 
 
379
  if (emb->intype==EMB_INPUT_TTF) {
 
380
    emb_otf_get_pdf_fontdescr(emb->font->sfnt,ret);
 
381
  } else {
 
382
    assert(0); 
 
383
  }
 
384
  return ret;
 
385
}
 
386
// }}}
 
387
 
 
388
// TODO: encoding into EMB_PARAMS
 
389
EMB_PDF_FONTWIDTHS *emb_pdf_fw_new(int datasize); 
 
390
 
 
391
EMB_PDF_FONTWIDTHS *emb_pdf_fw_new(int datasize) // {{{
 
392
{
 
393
  assert(datasize>=0);
 
394
  EMB_PDF_FONTWIDTHS *ret=calloc(1,sizeof(EMB_PDF_FONTWIDTHS)+datasize*sizeof(int));
 
395
  if (!ret) {
 
396
    fprintf(stderr,"Bad alloc: %m\n");
 
397
    assert(0);
 
398
    return NULL;
 
399
  }
 
400
  return ret;
 
401
}
 
402
// }}}
 
403
 
 
404
EMB_PDF_FONTWIDTHS *emb_pdf_fontwidths(EMB_PARAMS *emb) // {{{
 
405
{
 
406
  assert(emb);
 
407
 
 
408
  if (emb->intype==EMB_INPUT_TTF) {
 
409
    assert(emb->font->sfnt);
 
410
    if (emb->plan&EMB_A_MULTIBYTE) {
 
411
      return emb_otf_get_pdf_cidwidths(emb->font->sfnt,emb->subset);
 
412
    } else {
 
413
      return emb_otf_get_pdf_widths(emb->font->sfnt,NULL,emb->font->sfnt->numGlyphs,emb->subset); // TODO: encoding
 
414
    }
 
415
  } else {
 
416
    fprintf(stderr,"NOT IMPLEMENTED\n");
 
417
    assert(0);
 
418
    return NULL;
 
419
  }
 
420
}
 
421
// }}}
 
422
 
 
423
#define NEXT /* {{{ */ \
 
424
  if ( (len<0)||(len>=size) ) { \
 
425
    assert(0); \
 
426
    free(ret); \
 
427
    return NULL; \
 
428
  } \
 
429
  pos+=len; \
 
430
  size-=len; /* }}} */ 
 
431
 
 
432
char *emb_pdf_simple_fontdescr(EMB_PARAMS *emb,EMB_PDF_FONTDESCR *fdes,int fontfile_obj_ref) // {{{ - to be freed by user
 
433
{
 
434
  assert(emb);
 
435
  assert(fdes);
 
436
 
 
437
  char *ret=NULL,*pos;
 
438
  int len,size;
 
439
 
 
440
  size=300;
 
441
  pos=ret=malloc(size);
 
442
  if (!ret) {
 
443
    fprintf(stderr,"Bad alloc: %m\n");
 
444
    return NULL;
 
445
  }
 
446
 
 
447
  len=snprintf(pos,size,
 
448
               "<</Type /FontDescriptor\n"
 
449
               "  /FontName /%s\n" // TODO? handle quoting in struct?
 
450
               "  /Flags %d\n"
 
451
               "  /ItalicAngle %d\n",
 
452
               emb_pdf_escape_name(fdes->fontname,-1),
 
453
               fdes->flags,
 
454
               fdes->italicAngle);
 
455
  NEXT;
 
456
 
 
457
  if (1) { // TODO type!=EMB_PDF_TYPE3
 
458
    len=snprintf(pos,size,
 
459
                 "  /FontBBox [%d %d %d %d]\n"
 
460
                 "  /Ascend %d\n"
 
461
                 "  /Descend %d\n"
 
462
                 "  /CapHeight %d\n" // if font has Latin chars
 
463
                 "  /StemV %d\n",
 
464
                 fdes->bbxmin,fdes->bbymin,fdes->bbxmax,fdes->bbymax,
 
465
                 fdes->ascend,
 
466
                 fdes->descend,
 
467
                 fdes->capHeight,
 
468
                 fdes->stemV);
 
469
    NEXT;
 
470
  }
 
471
  if (fdes->xHeight) {
 
472
    len=snprintf(pos,size,"  /XHeight %d\n",fdes->xHeight);
 
473
    NEXT;
 
474
  }
 
475
  if (fdes->avgWidth) {
 
476
    len=snprintf(pos,size,"  /AvgWidth %d\n",fdes->avgWidth);
 
477
    NEXT;
 
478
  }
 
479
  if (fdes->panose) {
 
480
    int iA;
 
481
    len=snprintf(pos,size,"  /Style << /Panose <");
 
482
    NEXT;
 
483
    if (size<30) {
 
484
      assert(0);
 
485
      free(ret);
 
486
      return NULL;
 
487
    }
 
488
    for (iA=0;iA<12;iA++) {
 
489
      snprintf(pos+iA*2,size-iA*2,"%02x",fdes->panose[iA]);
 
490
    }
 
491
    size-=24;
 
492
    pos+=24;
 
493
    len=snprintf(pos,size,"> >>\n");
 
494
    NEXT;
 
495
  }
 
496
  len=snprintf(pos,size,
 
497
               "  /%s %d 0 R\n"
 
498
               ">>\n",
 
499
               emb_pdf_get_fontfile_key(emb),
 
500
               fontfile_obj_ref);
 
501
  NEXT;
 
502
 
 
503
  return ret;
 
504
}
 
505
// }}}
 
506
 
 
507
char *emb_pdf_simple_font(EMB_PARAMS *emb,EMB_PDF_FONTDESCR *fdes,EMB_PDF_FONTWIDTHS *fwid,int fontdescr_obj_ref) // {{{ - to be freed by user
 
508
{
 
509
  assert(emb);
 
510
  assert(fdes);
 
511
  assert(fwid);
 
512
 
 
513
  int iA,iB;
 
514
  DYN_STRING ret;
 
515
 
 
516
  if (dyn_init(&ret,500)==-1) {
 
517
    return NULL;
 
518
  }
 
519
 
 
520
  dyn_printf(&ret,"<</Type /Font\n"
 
521
                  "  /Subtype /%s\n"
 
522
                  "  /BaseFont /%s\n"
 
523
                  "  /FontDescriptor %d 0 R\n",
 
524
                  emb_pdf_get_font_subtype(emb),
 
525
                  emb_pdf_escape_name(fdes->fontname,-1),
 
526
                  fontdescr_obj_ref);
 
527
 
 
528
  if (emb->plan&EMB_A_MULTIBYTE) { // multibyte
 
529
    assert(fwid->warray);
 
530
    dyn_printf(&ret,"  /CIDSystemInfo <<\n"
 
531
                    "    /Registry (%s)\n"
 
532
                    "    /Ordering (%s)\n"
 
533
                    "    /Supplement %d\n"
 
534
                    "  >>\n"
 
535
                    "  /DW %d\n",
 
536
//                    "  /CIDToGIDMap /Id...\n" // TrueType only, default /Identity
 
537
                    fdes->registry,
 
538
                    fdes->ordering,
 
539
                    fdes->supplement,
 
540
                    fwid->default_width);
 
541
 
 
542
    if (fwid->warray[0]) {
 
543
      dyn_printf(&ret,"  /W [");
 
544
      for (iA=0;fwid->warray[iA];) {
 
545
        if (fwid->warray[iA]<0) { // c1 (c1-len) w
 
546
          dyn_printf(&ret," %d %d %d",
 
547
                          fwid->warray[iA+1],
 
548
                          fwid->warray[iA+1]-fwid->warray[iA],
 
549
                          fwid->warray[iA+2]);
 
550
          iA+=3;
 
551
        } else { // c [w ... w]
 
552
          iB=fwid->warray[iA++]; // len
 
553
          dyn_printf(&ret," %d [",fwid->warray[iA++]); // c
 
554
          for (;iB>0;iB--) {
 
555
            dyn_printf(&ret," %d",fwid->warray[iA++]);
 
556
          }
 
557
          dyn_printf(&ret,"]");
 
558
        }
 
559
      }
 
560
      dyn_printf(&ret,"]\n");
 
561
    }
 
562
  } else { // "not std14"
 
563
    assert(fwid->widths);
 
564
    dyn_printf(&ret,
 
565
                    "  /Encoding /MacRomanEncoding\n"  // optional; TODO!!!!!
 
566
//                    "  /ToUnicode ?\n"  // optional
 
567
                    "  /FirstChar %d\n"
 
568
                    "  /LastChar %d\n"
 
569
                    "  /Widths [",
 
570
                    fwid->first,
 
571
                    fwid->last);
 
572
    for (iA=0,iB=fwid->first;iB<=fwid->last;iA++,iB++) {
 
573
      dyn_printf(&ret," %d",fwid->widths[iA]);
 
574
    }
 
575
    dyn_printf(&ret,"]\n");
 
576
  }
 
577
  dyn_printf(&ret,">>\n");
 
578
  if (ret.len==-1) {
 
579
    dyn_free(&ret);
 
580
    assert(0);
 
581
    return NULL;
 
582
  }
 
583
 
 
584
  return ret.buf;
 
585
}
 
586
// }}}
 
587
 
 
588
char *emb_pdf_simple_cidfont(EMB_PARAMS *emb,const char *fontname,int descendant_obj_ref) // {{{ - to be freed by user
 
589
{
 
590
  assert(emb);
 
591
  assert(fontname);
 
592
 
 
593
  char *ret=NULL,*pos;
 
594
  int len,size;
 
595
 
 
596
  size=200;
 
597
  pos=ret=malloc(size);
 
598
  if (!ret) {
 
599
    fprintf(stderr,"Bad alloc: %m\n");
 
600
    return NULL;
 
601
  }
 
602
  
 
603
  len=snprintf(pos,size,
 
604
               "<</Type /Font\n"
 
605
               "  /Subtype /Type0\n"
 
606
               "  /BaseFont /%s\n"  // TODO? "-CMap-name"(/Encoding) for CidType0
 
607
               "  /Encoding /Identity-H\n"
 
608
         // for CFF: one of:
 
609
         // UniGB-UCS2-H, UniCNS-UCS2-H, UniJIS-UCS2-H, UniKS-UCS2-H
 
610
               "  /DescendantFonts [%d 0 R]\n",
 
611
//               "  /ToUnicode ?\n" // TODO
 
612
               emb_pdf_escape_name(fontname,-1),
 
613
               descendant_obj_ref);
 
614
  NEXT;
 
615
 
 
616
  len=snprintf(pos,size,">>\n");
 
617
  NEXT;
 
618
 
 
619
  return ret;
 
620
}
 
621
// }}}
 
622
 
 
623
char *emb_pdf_simple_stdfont(EMB_PARAMS *emb) // {{{ - to be freed by user
 
624
{
 
625
  assert(emb);
 
626
  assert(emb->font->stdname);
 
627
 
 
628
  char *ret=NULL,*pos;
 
629
  int len,size;
 
630
 
 
631
  size=300;
 
632
  pos=ret=malloc(size);
 
633
  if (!ret) {
 
634
    fprintf(stderr,"Bad alloc: %m\n");
 
635
    return NULL;
 
636
  }
 
637
 
 
638
  len=snprintf(pos,size,
 
639
               "<</Type/Font\n"
 
640
               "  /Subtype /Type1\n"
 
641
               "  /BaseFont /%s\n"
 
642
               ">>\n",
 
643
               emb->font->stdname);
 
644
  NEXT;
 
645
 
 
646
  return ret;
 
647
}
 
648
// }}}
 
649
#undef NEXT
 
650
 
 
651
//...
 
652