3 This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
5 Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata,
6 the dvipdfmx project team.
8 Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
37 #include "pdfdev.h" /* pdf_rect */
39 #include "pdfencoding.h"
44 #define ENABLE_GLYPHENC 1
46 #ifndef PKFONT_DPI_DEFAULT
47 #define PKFONT_DPI_DEFAULT 600u
50 static unsigned base_dpi = PKFONT_DPI_DEFAULT;
53 PKFont_set_dpi (int dpi)
56 ERROR("Invalid DPI: %d\n", dpi);
61 /* (Only) This requires TFM to get design size... */
65 truedpi (const char *ident, double point_size, unsigned bdpi)
71 tfm_id = tfm_open(ident, 0);
75 design_size = tfm_get_design_size(tfm_id);
76 if (design_size <= 0.0)
77 WARN("DESGIN_SIZE <= 0.0? (TFM=\"%s\")", ident);
79 dpi = (unsigned) ROUND(base_dpi * point_size / design_size, 1.0);
86 dpx_open_pk_font_at (const char *ident, unsigned dpi)
90 kpse_glyph_file_type kpse_file_info;
92 fqpn = kpse_find_glyph(ident, dpi, kpse_pk_format, &kpse_file_info);
95 fp = MFOPEN(fqpn, FOPEN_RBIN_MODE);
103 pdf_font_open_pkfont (pdf_font *font)
111 ident = pdf_font_get_ident(font);
112 point_size = pdf_font_get_param(font, PDF_FONT_PARAM_POINT_SIZE);
113 encoding_id = pdf_font_get_encoding(font);
115 if (!ident || point_size <= 0.0)
118 dpi = truedpi(ident, point_size, base_dpi);
119 fp = dpx_open_pk_font_at(ident, dpi);
124 /* Type 3 fonts doesn't have FontName.
125 * FontFamily is recommended for PDF 1.5.
127 pdf_font_set_fontname(font, ident);
129 if (encoding_id >= 0) {
130 pdf_encoding_used_by_type3(encoding_id);
131 WARN("PK font is found for font \"%s\" but non built-in encoding \"%s\" is specified.",
132 ident, pdf_encoding_get_name(encoding_id));
134 WARN(">> Assuming this is for glyph name assignment.");
136 WARN(">> I can't reencode PK font. (not enough information available)");
137 WARN(">> Maybe you need to install pfb/opentype/truetype font.");
145 /* We are using Mask Image. Fill black is bit clear.
146 * Optimizing those codes doesn't improve things.
149 fill_black_run (unsigned char *dp, long left, long run_count)
151 const static unsigned char mask[8] = {
152 127u, 191u, 223u, 239u, 247u, 251u, 253u, 254u
154 long right = left + run_count - 1;
155 for ( ; left <= right; left++) {
156 dp[left / 8] &= mask[left % 8];
161 /* Just skip bits. See decode_packed() */
163 fill_white_run (unsigned char *dp, long left, long run_count)
169 pk_packed_num (long *np, int dyn_f, unsigned char *dp, long pl)
171 long nmbr = 0, i = *np;
173 #define get_nyb() ((i % 2) ? dp[i/2] & 0x0f : (dp[i/2] >> 4) & 0x0f)
176 WARN("EOD reached while unpacking pk_packed_num.");
179 nyb = get_nyb(); i++;
184 WARN("EOD reached while unpacking pk_packed_num.");
187 nyb = get_nyb(); i++;
193 WARN("EOD reached while unpacking pk_packed_num.");
196 nyb = get_nyb(); i++;
197 nmbr = nmbr * 16 + nyb;
199 nmbr += (13 - dyn_f) * 16 + dyn_f - 15;
200 } else if (nyb <= dyn_f) {
202 } else if (nyb < 14) {
204 WARN("EOD reached while unpacking pk_packed_num.");
207 nmbr = (nyb - dyn_f - 1) * 16 + get_nyb() + dyn_f + 1;
218 send_out (unsigned char *rowptr, long rowbytes, long wd, pdf_obj *stream)
221 send_out (unsigned char *rowptr, long rowbytes, pdf_obj *stream)
224 pdf_add_stream(stream, (void *)rowptr, rowbytes);
227 long i, n, len = (wd + 7) / 8;
230 for (n = 0; n < len; n++) {
232 for (i = 0; i < 8; i++) {
235 if (c & 1 << (7 - i))
248 pk_decode_packed (pdf_obj *stream, long wd, long ht,
249 int dyn_f, int run_color, unsigned char *dp, long pl)
251 unsigned char *rowptr;
254 long run_count = 0, repeat_count = 0;
256 rowbytes = (wd + 7) / 8;
257 rowptr = NEW(rowbytes, unsigned char);
258 /* repeat count is applied to the *current* row.
259 * "run" can span across rows.
260 * If there are non-zero repeat count and if run
261 * spans across row, first repeat and then continue.
264 MESG("\npkfont>> wd: %ld, ht: %ld, dyn_f: %d\n", wd, ht, dyn_f);
266 for (np = 0, i = 0; i < ht; i++) {
267 long rowbits_left, nbits;
270 memset(rowptr, 0xff, rowbytes); /* 1 is white */
272 /* Fill run left over from previous row */
274 nbits = MIN(rowbits_left, run_count);
277 rowbits_left -= fill_black_run(rowptr, 0, nbits);
280 rowbits_left -= fill_white_run(rowptr, 0, nbits);
286 /* Read nybbles until we have a full row */
287 while (np / 2 < pl && rowbits_left > 0) {
290 nyb = (np % 2) ? dp[np/2] & 0x0f : (dp[np/2] >> 4) & 0x0f;
292 MESG("\npk_nyb: %d", nyb);
294 if (nyb == 14) { /* packed number "repeat_count" follows */
295 if (repeat_count != 0)
296 WARN("Second repeat count for this row!");
297 np++; /* Consume this nybble */
298 repeat_count = pk_packed_num(&np, dyn_f, dp, pl);
300 MESG(" --> rep: %ld\n", repeat_count);
302 } else if (nyb == 15) {
303 if (repeat_count != 0)
304 WARN("Second repeat count for this row!");
305 np++; /* Consume this nybble */
308 MESG(" --> rep: %ld\n", repeat_count);
310 } else { /* run_count */
311 /* Interprete current nybble as packed number */
312 run_count = pk_packed_num(&np, dyn_f, dp, pl);
314 MESG(" --> run: %ld (%d)\n", run_count, run_color);
316 nbits = MIN(rowbits_left, run_count);
317 run_color = !run_color;
321 rowbits_left -= fill_black_run(rowptr, wd - rowbits_left, nbits);
324 rowbits_left -= fill_white_run(rowptr, wd - rowbits_left, nbits);
329 /* We got bitmap row data. */
331 send_out(rowptr, rowbytes, wd, stream);
333 send_out(rowptr, rowbytes, stream);
335 for ( ; i < ht && repeat_count > 0; repeat_count--, i++)
337 send_out(rowptr, rowbytes, wd, stream);
339 send_out(rowptr, rowbytes, stream);
348 pk_decode_bitmap (pdf_obj *stream, long wd, long ht,
349 int dyn_f, int run_color, unsigned char *dp, long pl)
351 unsigned char *rowptr, c;
353 const static unsigned char mask[8] = {
354 0x80u, 0x40u, 0x20u, 0x10u, 0x08u, 0x04u, 0x02u, 0x01u
357 ASSERT( dyn_f == 14 );
358 if (run_color != 0) {
359 WARN("run_color != 0 for bitmap pk data?");
360 } else if (pl < (wd * ht + 7) / 8) {
361 WARN("Insufficient bitmap pk data. %ldbytes expected but only %ldbytes read.",
362 (wd * ht + 7) / 8, pl);
366 rowbytes = (wd + 7) / 8;
367 rowptr = NEW(rowbytes, unsigned char);
368 memset(rowptr, 0, rowbytes);
369 /* Flip. PK bitmap is not byte aligned for each rows. */
370 for (i = 0, j = 0; i < ht * wd; i++) {
371 c = dp[i / 8] & mask[i % 8];
373 rowptr[j / 8] |= mask[i % 8]; /* flip bit */
377 send_out(rowptr, rowbytes, wd, stream);
379 send_out(rowptr, rowbytes, stream);
381 memset(rowptr, 0, rowbytes);
390 /* Read PK font file */
392 do_skip (FILE *fp, unsigned long length)
399 do_preamble (FILE *fp)
401 /* Check for id byte */
402 if (fgetc(fp) == 89) {
404 do_skip(fp, get_unsigned_byte(fp));
405 /* Skip other header info. It's normally used for verifying this
406 is the file wethink it is */
409 ERROR("embed_pk_font: PK ID byte is incorrect. Are you sure this is a PK file?");
416 unsigned long pkt_len;
418 SIGNED_QUAD wd, dx, dy;
419 SIGNED_QUAD bm_wd, bm_ht, bm_hoff, bm_voff;
420 int dyn_f, run_color;
424 read_pk_char_header (struct pk_header_ *h, unsigned char opcode, FILE *fp)
428 if ((opcode & 4) == 0) { /* short */
429 h->pkt_len = (opcode & 3) * 0x100U + get_unsigned_byte(fp);
430 h->chrcode = get_unsigned_byte(fp);
431 h->wd = get_unsigned_triple(fp); /* TFM width */
432 h->dx = get_unsigned_byte(fp) << 16; /* horizontal escapement */
434 h->bm_wd = get_unsigned_byte(fp);
435 h->bm_ht = get_unsigned_byte(fp);
436 h->bm_hoff = get_signed_byte(fp);
437 h->bm_voff = get_signed_byte(fp);
439 } else if ((opcode & 7) == 7) { /* long */
440 h->pkt_len = get_unsigned_quad(fp);
441 h->chrcode = get_signed_quad(fp);
442 h->wd = get_signed_quad(fp);
443 h->dx = get_signed_quad(fp); /* 16.16 fixed point number in pixels */
444 h->dy = get_signed_quad(fp);
445 h->bm_wd = get_signed_quad(fp);
446 h->bm_ht = get_signed_quad(fp);
447 h->bm_hoff = get_signed_quad(fp);
448 h->bm_voff = get_signed_quad(fp);
450 } else { /* extended short */
451 h->pkt_len = (opcode & 3) * 0x10000UL + get_unsigned_pair(fp);
452 h->chrcode = get_unsigned_byte(fp);
453 h->wd = get_unsigned_triple(fp);
454 h->dx = get_unsigned_pair(fp) << 16;
456 h->bm_wd = get_unsigned_pair(fp);
457 h->bm_ht = get_unsigned_pair(fp);
458 h->bm_hoff = get_signed_pair(fp);
459 h->bm_voff = get_signed_pair(fp);
463 h->dyn_f = opcode / 16;
464 h->run_color = (opcode & 8) ? 1 : 0;
466 if (h->chrcode > 0xff)
468 WARN("Unable to handle long characters in PK files: code=0x%04x", h->chrcode);
475 /* CCITT Group 4 filter may reduce file size. */
477 create_pk_CharProc_stream (struct pk_header_ *pkh,
479 unsigned char *pkt_ptr, long pkt_len)
481 pdf_obj *stream; /* charproc */
482 long llx, lly, urx, ury;
486 lly = pkh->bm_voff - pkh->bm_ht;
487 urx = pkh->bm_wd - pkh->bm_hoff;
490 stream = pdf_new_stream(STREAM_COMPRESS);
492 * The following line is a "metric" for the PDF reader:
494 * PDF Reference Reference, 4th ed., p.385.
496 * The wx (first operand of d1) must be consistent with the corresponding
497 * width in the font's Widths array. The format string of sprint() must be
498 * consistent with write_number() in pdfobj.c.
500 len = pdf_sprint_number(work_buffer, chrwid);
501 len += sprintf (work_buffer + len, " 0 %ld %ld %ld %ld d1\n", llx, lly, urx, ury);
502 pdf_add_stream(stream, work_buffer, len);
504 * Acrobat dislike transformation [0 0 0 0 dx dy].
505 * PDF Reference, 4th ed., p.147, says,
507 * Use of a noninvertible matrix when painting graphics objects can result in
508 * unpredictable behavior.
510 * but it does not forbid use of such transformation.
512 if (pkh->bm_wd != 0 && pkh->bm_ht != 0 && pkt_len > 0) {
513 /* Scale and translate origin to lower left corner for raster data */
514 len = sprintf (work_buffer, "q\n%ld 0 0 %ld %ld %ld cm\n", pkh->bm_wd, pkh->bm_ht, llx, lly);
515 pdf_add_stream(stream, work_buffer, len);
516 len = sprintf (work_buffer, "BI\n/W %ld\n/H %ld\n/IM true\n/BPC 1\nID ", pkh->bm_wd, pkh->bm_ht);
517 pdf_add_stream(stream, work_buffer, len);
518 /* Add bitmap data */
519 if (pkh->dyn_f == 14) /* bitmap */
520 pk_decode_bitmap(stream,
521 pkh->bm_wd, pkh->bm_ht,
522 pkh->dyn_f, pkh->run_color,
525 pk_decode_packed(stream,
526 pkh->bm_wd, pkh->bm_ht,
527 pkh->dyn_f, pkh->run_color,
529 len = sprintf (work_buffer, "\nEI\nQ");
530 pdf_add_stream(stream, work_buffer, len);
531 } /* Otherwise we embed an empty stream :-( */
545 #define pk_char2name(b,c) sprintf((b), "x%02X", (unsigned char)(c))
547 pdf_font_load_pkfont (pdf_font *font)
554 double point_size, pix2charu;
555 int opcode, code, firstchar, lastchar, prev;
556 pdf_obj *charprocs, *procset, *encoding, *tmp_array;
563 #endif /* ENABLE_GLYPHENC */
566 if (!pdf_font_is_in_use(font)) {
570 ident = pdf_font_get_ident(font);
571 point_size = pdf_font_get_param(font, PDF_FONT_PARAM_POINT_SIZE);
572 usedchars = pdf_font_get_usedchars(font);
574 encoding_id = pdf_font_get_encoding(font);
578 enc_vec = pdf_encoding_get_encoding(encoding_id);
580 #endif /* ENABLE_GLYPHENC */
582 ASSERT(ident && usedchars && point_size > 0.0);
584 dpi = truedpi(ident, point_size, base_dpi);
585 fp = dpx_open_pk_font_at(ident, dpi);
587 ERROR("Could not find/open PK font file: %s (at %udpi)", ident, dpi);
590 memset(charavail, 0, 256);
591 charprocs = pdf_new_dict();
592 /* Include bitmap as 72dpi image:
593 * There seems to be problems in "scaled" bitmap glyph
594 * rendering in several viewers.
596 pix2charu = 72. * 1000. / ((double) base_dpi) / point_size;
597 bbox.llx = bbox.lly = HUGE_VAL;
598 bbox.urx = bbox.ury = -HUGE_VAL;
599 while ((opcode = fgetc(fp)) >= 0 && opcode != PK_POST) {
601 struct pk_header_ pkh;
603 error = read_pk_char_header(&pkh, opcode, fp);
605 ERROR("Error in reading PK character header.");
606 else if (charavail[pkh.chrcode & 0xff])
607 WARN("More than two bitmap image for single glyph?: font=\"%s\" code=0x%02x",
610 if (!usedchars[pkh.chrcode & 0xff])
611 do_skip(fp, pkh.pkt_len);
615 unsigned char *pkt_ptr;
619 /* Charwidth in PDF units */
620 charwidth = ROUND(1000.0 * pkh.wd / (((double) (1<<20))*pix2charu), 0.1);
621 widths[pkh.chrcode & 0xff] = charwidth;
623 /* Update font BBox info */
624 bbox.llx = MIN(bbox.llx, -pkh.bm_hoff);
625 bbox.lly = MIN(bbox.lly, pkh.bm_voff - pkh.bm_ht);
626 bbox.urx = MAX(bbox.urx, pkh.bm_wd - pkh.bm_hoff);
627 bbox.ury = MAX(bbox.ury, pkh.bm_voff);
629 pkt_ptr = NEW(pkh.pkt_len, unsigned char);
630 if ((bytesread = fread(pkt_ptr, 1, pkh.pkt_len, fp))!= pkh.pkt_len) {
631 ERROR("Only %ld bytes PK packet read. (expected %ld bytes)",
632 bytesread, pkh.pkt_len);
634 charproc = create_pk_CharProc_stream(&pkh, charwidth, pkt_ptr, bytesread);
637 ERROR("Unpacking PK character data failed.");
639 if (encoding_id >= 0 && enc_vec) {
640 charname = (char *) enc_vec[pkh.chrcode & 0xff];
642 WARN("\".notdef\" glyph used in font (code=0x%02x): %s", pkh.chrcode, ident);
643 charname = work_buffer;
644 pk_char2name(charname, pkh.chrcode);
648 #endif /* ENABLE_GLYPHENC */
650 charname = work_buffer;
651 pk_char2name(charname, pkh.chrcode);
654 pdf_add_dict(charprocs, pdf_new_name(charname), pdf_ref_obj(charproc)); /* _FIXME_ */
655 pdf_release_obj(charproc);
657 charavail[pkh.chrcode & 0xff] = 1;
658 } else { /* A command byte */
660 case PK_NO_OP: break;
661 case PK_XXX1: do_skip(fp, get_unsigned_byte(fp)); break;
662 case PK_XXX2: do_skip(fp, get_unsigned_pair(fp)); break;
663 case PK_XXX3: do_skip(fp, get_unsigned_triple(fp)); break;
664 case PK_XXX4: do_skip(fp, get_unsigned_quad(fp)); break;
665 case PK_YYY: do_skip(fp, 4); break;
666 case PK_PRE: do_preamble(fp); break;
672 /* Check if we really got all glyphs needed. */
673 for (code = 0; code < 256; code++) {
674 if (usedchars[code] && !charavail[code])
675 WARN("Missing glyph code=0x%02x in PK font \"%s\".", code, ident);
678 /* Now actually fill fontdict. */
679 fontdict = pdf_font_get_resource(font);
681 pdf_add_dict(fontdict,
682 pdf_new_name("CharProcs"), pdf_ref_obj(charprocs));
683 pdf_release_obj(charprocs);
688 * PDF Reference 4th ed. describes it as "Optional but strongly recommended".
689 * There are no reason to put it in our case, but we will put this.
690 * We do not care about compatibility with Acrobat 2.x. (See implementation
691 * note 47, Appendix H of PDF Ref., 4th ed.).
693 procset = pdf_new_dict();
694 tmp_array = pdf_new_array();
695 pdf_add_array(tmp_array, pdf_new_name("PDF"));
696 pdf_add_array(tmp_array, pdf_new_name("ImageB"));
697 pdf_add_dict(procset,
698 pdf_new_name("ProcSet"), tmp_array);
699 pdf_add_dict(fontdict,
700 pdf_new_name("Resources"), procset);
703 tmp_array = pdf_new_array();
704 prev = -2; firstchar = 255; lastchar = 0;
705 for (code = 0; code < 256; code++) {
707 if (usedchars[code]) {
708 if (code < firstchar) firstchar = code;
709 if (code > lastchar) lastchar = code;
710 if (code != prev + 1)
711 pdf_add_array(tmp_array, pdf_new_number(code));
714 if (encoding_id >= 0 && enc_vec) {
715 charname = (char *) enc_vec[(unsigned char) code];
717 charname = work_buffer;
718 pk_char2name(charname, code);
722 #endif /* ENABLE_GLYPHENC */
724 charname = work_buffer;
725 pk_char2name(charname, code);
727 pdf_add_array(tmp_array, pdf_new_name(charname));
731 if (firstchar > lastchar) {
732 ERROR("Unexpected error: firstchar > lastchar (%d %d)",
733 firstchar, lastchar);
734 pdf_release_obj(tmp_array);
738 if (encoding_id < 0 || !enc_vec) {
741 #endif /* ENABLE_GLYPHENC */
742 encoding = pdf_new_dict();
743 pdf_add_dict(encoding,
744 pdf_new_name("Type"), pdf_new_name("Encoding"));
745 pdf_add_dict(encoding,
746 pdf_new_name("Differences"), tmp_array);
747 pdf_add_dict(fontdict,
748 pdf_new_name("Encoding"), pdf_ref_obj(encoding));
749 pdf_release_obj(encoding);
751 pdf_release_obj(tmp_array);
753 /* FontBBox: Accurate value is important.
755 tmp_array = pdf_new_array();
756 pdf_add_array(tmp_array, pdf_new_number(bbox.llx));
757 pdf_add_array(tmp_array, pdf_new_number(bbox.lly));
758 pdf_add_array(tmp_array, pdf_new_number(bbox.urx));
759 pdf_add_array(tmp_array, pdf_new_number(bbox.ury));
760 pdf_add_dict (fontdict , pdf_new_name("FontBBox"), tmp_array);
763 * Indirect reference preffered. (See PDF Reference)
765 tmp_array = pdf_new_array();
766 for (code = firstchar; code <= lastchar; code++) {
768 pdf_add_array(tmp_array, pdf_new_number(widths[code]));
770 pdf_add_array(tmp_array, pdf_new_number(0));
773 pdf_add_dict(fontdict,
774 pdf_new_name("Widths"), pdf_ref_obj(tmp_array));
775 pdf_release_obj(tmp_array);
778 tmp_array = pdf_new_array();
779 pdf_add_array(tmp_array, pdf_new_number(0.001 * pix2charu));
780 pdf_add_array(tmp_array, pdf_new_number(0.0));
781 pdf_add_array(tmp_array, pdf_new_number(0.0));
782 pdf_add_array(tmp_array, pdf_new_number(0.001 * pix2charu));
783 pdf_add_array(tmp_array, pdf_new_number(0.0));
784 pdf_add_array(tmp_array, pdf_new_number(0.0));
785 pdf_add_dict (fontdict , pdf_new_name("FontMatrix"), tmp_array);
788 pdf_add_dict(fontdict,
789 pdf_new_name("FirstChar"), pdf_new_number(firstchar));
790 pdf_add_dict(fontdict,
791 pdf_new_name("LastChar"), pdf_new_number(lastchar));