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);
18
void emb_otf_get_pdf_fontdescr(OTF_FILE *otf,EMB_PDF_FONTDESCR *ret);
20
static inline int copy_file(FILE *f,OUTPUT_FN output,void *context) // {{{
31
iA=fread(buf,1,4096,f);
32
(*output)(buf,iA,context);
39
EMB_PARAMS *emb_new(FONTFILE *font,EMB_DESTINATION dest,EMB_CONSTRAINTS mode) // {{{
43
EMB_PARAMS *ret=calloc(1,sizeof(EMB_PARAMS));
45
fprintf(stderr,"Bad alloc: %m\n");
46
if (mode&EMB_C_TAKE_FONTFILE) {
53
if (mode&EMB_C_TAKE_FONTFILE) {
54
ret->plan|=EMB_A_CLOSE_FONTFILE;
58
if ( (mode&EMB_C_KEEP_T1)&&(mode&EMB_C_FORCE_MULTIBYTE) ) {
59
fprintf(stderr,"Incompatible mode: KEEP_T1 and FORCE_MULTIBYTE\n");
64
fprintf(stderr,"Bad subset specification\n");
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;
82
if ( (ret->intype==EMB_INPUT_CFF)&&
83
(ret->cffFont.is_cid()) ) {
84
ret->plan|=EMB_A_MULTIBYTE;
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;
95
ret->outtype=EMB_OUTPUT_TTF;
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");
105
return ret; // never subset
106
} else { // T1, OTF, CFF
107
if (ret->intype==EMB_INPUT_T1) {
108
ret->plan|=EMB_A_CONVERT_CFF;
110
if (mode&EMB_C_PDF_OT) {
111
ret->outtype=EMB_OUTPUT_SFNT;
112
ret->plan|=EMB_A_WRAP_SFNT;
114
ret->outtype=EMB_OUTPUT_CFF;
118
if (mode&EMB_C_FORCE_MULTIBYTE) {
119
ret->plan|=EMB_A_MULTIBYTE;
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");
130
} else if ( (!(ret->rights&EMB_RIGHT_NO_SUBSET))&&
131
(!(mode&EMB_C_NEVER_SUBSET)) ) {
132
ret->plan|=EMB_A_SUBSET;
136
if (ret->plan&EMB_A_SUBSET) {
137
ret->subset=bitset_new(numGlyphs);
139
fprintf(stderr,"Bad alloc: %m\n");
149
int emb_embed(EMB_PARAMS *emb,OUTPUT_FN output,void *context) // {{{
153
if (emb->dest==EMB_DEST_PS) {
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) {
161
ret=emb_otf_ps(emb->font->sfnt,NULL,4,NULL,output,context); // TODO?
166
(*output)("%%EndFont\n",10,context);
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);
178
return copy_file(emb->font->sfnt->f,output,context);
181
fprintf(stderr,"NOT IMPLEMENTED\n");
188
void emb_close(EMB_PARAMS *emb) // {{{
192
if (emb->plan&EMB_A_CLOSE_FONTFILE) {
193
fontfile_close(emb->font);
200
/*** PDF out stuff ***/
201
static const int emb_pdf_font_format[]={0,1,0,0}; // {{{ (input_format) }}}
203
static const char *emb_pdf_font_subtype[][2]={ // {{{ (format,multibyte)
204
{"Type1","CIDFontType0"},
205
{"TrueType","CIDFontType2"}};
208
static const char *emb_pdf_fontfile_key[]={ // {{{ (output_format)
209
"FontFile1","FontFile2","FontFile3","Fontfile3"};
212
static const char *emb_pdf_fontfile_subtype[][2]={ // {{{ (output_format,multibyte)
215
{"Type1C","CIDFontType0C"},
216
{"OpenType","OpenType"}};
219
static inline int emb_multibyte(EMB_PARAMS *emb) // {{{
221
return (emb->plan&EMB_A_MULTIBYTE)?1:0;
225
static const char *emb_pdf_escape_name(const char *name,int len) // {{{ // - statically allocated buffer
231
assert(len<=127); // pdf implementation limit
233
static char buf[128*3];
235
const char hex[]="0123456789abcdef";
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])) ) {
241
buf[++iB]=hex[(name[iA]>>4)&0x0f];
242
buf[++iB]=hex[name[iA]&0xf];
252
const char *emb_pdf_get_font_subtype(EMB_PARAMS *emb) // {{{
255
return emb_pdf_font_subtype[emb_pdf_font_format[emb->intype]][emb_multibyte(emb)];
259
const char *emb_pdf_get_fontfile_key(EMB_PARAMS *emb) // {{{
262
return emb_pdf_fontfile_key[emb->outtype];
266
const char *emb_pdf_get_fontfile_subtype(EMB_PARAMS *emb) // {{{
269
return emb_pdf_fontfile_subtype[emb->outtype][emb_multibyte(emb)];
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
281
EMB_PDF_FONTDESCR *ret;
283
int len=sizeof(EMB_PDF_FONTDESCR);
285
assert(strlen(subset_tag)==6);
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;
298
fprintf(stderr,"Bad alloc: %m\n");
303
// now fill the struct
305
if (cid_supplement>=0) { // free space for panose is at beginning
308
ret->fontname=ret->data+len;
309
len+=strlen(fontname)+1;
311
strncpy(ret->fontname,subset_tag,6);
312
ret->fontname[6]='+';
313
strcpy(ret->fontname+7,fontname);
316
strcpy(ret->fontname,fontname);
319
if (cid_supplement>=0) {
320
ret->registry=ret->data+len;
321
strcpy(ret->registry,cid_registry);
322
len+=strlen(cid_registry)+1;
324
ret->ordering=ret->data+len;
325
strcpy(ret->ordering,cid_ordering);
326
len+=strlen(cid_registry)+1;
328
ret->supplement=cid_supplement;
334
EMB_PDF_FONTDESCR *emb_pdf_fontdescr(EMB_PARAMS *emb) // {{{ - to be freed by user
338
const char *subset_tag=NULL;
339
// {{{ generate pdf subtag
340
static unsigned int rands=0;
347
if (emb->plan&EMB_A_SUBSET) {
349
for (iA=0;iA<6;iA++) {
350
const int x=(int)(26.0*(rand_r(&rands)/(RAND_MAX+1.0)));
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) {
364
fprintf(stderr,"NOT IMPLEMENTED\n");
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
373
ret=emb_pdf_fd_new(fontname,subset_tag,NULL,NULL,-1);
379
if (emb->intype==EMB_INPUT_TTF) {
380
emb_otf_get_pdf_fontdescr(emb->font->sfnt,ret);
388
// TODO: encoding into EMB_PARAMS
389
EMB_PDF_FONTWIDTHS *emb_pdf_fw_new(int datasize);
391
EMB_PDF_FONTWIDTHS *emb_pdf_fw_new(int datasize) // {{{
394
EMB_PDF_FONTWIDTHS *ret=calloc(1,sizeof(EMB_PDF_FONTWIDTHS)+datasize*sizeof(int));
396
fprintf(stderr,"Bad alloc: %m\n");
404
EMB_PDF_FONTWIDTHS *emb_pdf_fontwidths(EMB_PARAMS *emb) // {{{
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);
413
return emb_otf_get_pdf_widths(emb->font->sfnt,NULL,emb->font->sfnt->numGlyphs,emb->subset); // TODO: encoding
416
fprintf(stderr,"NOT IMPLEMENTED\n");
423
#define NEXT /* {{{ */ \
424
if ( (len<0)||(len>=size) ) { \
432
char *emb_pdf_simple_fontdescr(EMB_PARAMS *emb,EMB_PDF_FONTDESCR *fdes,int fontfile_obj_ref) // {{{ - to be freed by user
441
pos=ret=malloc(size);
443
fprintf(stderr,"Bad alloc: %m\n");
447
len=snprintf(pos,size,
448
"<</Type /FontDescriptor\n"
449
" /FontName /%s\n" // TODO? handle quoting in struct?
451
" /ItalicAngle %d\n",
452
emb_pdf_escape_name(fdes->fontname,-1),
457
if (1) { // TODO type!=EMB_PDF_TYPE3
458
len=snprintf(pos,size,
459
" /FontBBox [%d %d %d %d]\n"
462
" /CapHeight %d\n" // if font has Latin chars
464
fdes->bbxmin,fdes->bbymin,fdes->bbxmax,fdes->bbymax,
472
len=snprintf(pos,size," /XHeight %d\n",fdes->xHeight);
475
if (fdes->avgWidth) {
476
len=snprintf(pos,size," /AvgWidth %d\n",fdes->avgWidth);
481
len=snprintf(pos,size," /Style << /Panose <");
488
for (iA=0;iA<12;iA++) {
489
snprintf(pos+iA*2,size-iA*2,"%02x",fdes->panose[iA]);
493
len=snprintf(pos,size,"> >>\n");
496
len=snprintf(pos,size,
499
emb_pdf_get_fontfile_key(emb),
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
516
if (dyn_init(&ret,500)==-1) {
520
dyn_printf(&ret,"<</Type /Font\n"
523
" /FontDescriptor %d 0 R\n",
524
emb_pdf_get_font_subtype(emb),
525
emb_pdf_escape_name(fdes->fontname,-1),
528
if (emb->plan&EMB_A_MULTIBYTE) { // multibyte
529
assert(fwid->warray);
530
dyn_printf(&ret," /CIDSystemInfo <<\n"
536
// " /CIDToGIDMap /Id...\n" // TrueType only, default /Identity
540
fwid->default_width);
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",
548
fwid->warray[iA+1]-fwid->warray[iA],
551
} else { // c [w ... w]
552
iB=fwid->warray[iA++]; // len
553
dyn_printf(&ret," %d [",fwid->warray[iA++]); // c
555
dyn_printf(&ret," %d",fwid->warray[iA++]);
557
dyn_printf(&ret,"]");
560
dyn_printf(&ret,"]\n");
562
} else { // "not std14"
563
assert(fwid->widths);
565
" /Encoding /MacRomanEncoding\n" // optional; TODO!!!!!
566
// " /ToUnicode ?\n" // optional
572
for (iA=0,iB=fwid->first;iB<=fwid->last;iA++,iB++) {
573
dyn_printf(&ret," %d",fwid->widths[iA]);
575
dyn_printf(&ret,"]\n");
577
dyn_printf(&ret,">>\n");
588
char *emb_pdf_simple_cidfont(EMB_PARAMS *emb,const char *fontname,int descendant_obj_ref) // {{{ - to be freed by user
597
pos=ret=malloc(size);
599
fprintf(stderr,"Bad alloc: %m\n");
603
len=snprintf(pos,size,
606
" /BaseFont /%s\n" // TODO? "-CMap-name"(/Encoding) for CidType0
607
" /Encoding /Identity-H\n"
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),
616
len=snprintf(pos,size,">>\n");
623
char *emb_pdf_simple_stdfont(EMB_PARAMS *emb) // {{{ - to be freed by user
626
assert(emb->font->stdname);
632
pos=ret=malloc(size);
634
fprintf(stderr,"Bad alloc: %m\n");
638
len=snprintf(pos,size,